mdgriffith / elm-codegen

https://package.elm-lang.org/packages/mdgriffith/elm-codegen/latest/
BSD 3-Clause "New" or "Revised" License
138 stars 16 forks source link

Pattern API #63

Closed dillonkearns closed 1 year ago

dillonkearns commented 1 year ago

Package Docs: https://elm-doc-preview.netlify.app/Elm-Pattern?repo=dillonkearns%2Felm-codegen&version=patterns

This PR introduces a Pattern API that lets you use more general pattern matching beyond the helpers like Elm.Case.result, etc.

Motiviation

For example, with the existing API if you want to pattern match a Custom Type variant within a Result, you currently need to unwrap it twice using:

Elm.Case.result (Elm.val "userIdResult")
    { ok =
        Tuple.pair "userId" <|
            \userId ->
                Elm.Case.custom userId
                    Type.unit
                    [ Elm.Case.branch1 "AdminId" ( "id", Type.string ) <|
                        \adminId ->
                            Elm.just adminId
                    , Elm.Case.otherwise (\_ -> Elm.nothing)
                    ]
    , err =
        Tuple.pair "err" <|
            \err ->
                err
    }
case userIdResult of
    Ok userId ->
        case userId of
            AdminId id ->
                Just id

            otherwise ->
                Nothing

    Err err ->
        Nothing

With the Elm.Pattern module, we can directly pattern match on this:

Elm.Case.custom
    (Elm.val "userIdResult")
    Type.unit
    [ Pattern.ok
        (Pattern.variant1
            "AdminId"
            (Pattern.var "id"
                |> Pattern.map (\id -> Elm.just id)
            )
        )
        |> Elm.Case.fromPattern
    , Pattern.ignore
        |> Pattern.map (\() -> Elm.nothing)
        |> Elm.Case.fromPattern
    ]

Which results in:

case userIdResult of
    Ok (AdminId id) ->
        Just id

    _ ->
        Nothing

I've found this to be important in a lot of my uses of elm-codegen both to make it easier to reach in and grab values in more complex generated code, as well as for generating more presentable code (for example in the scaffolding helpers in elm-pages v3). Using nested pattern matches results in code that isn't idiomatic so this feature is really valuable for these scaffolding helpers in elm-pages.

PR Status

I addressed all of the API design feedback you gave me on our call. Very happy to get more feedback if you have any with these changes.

Besides that, the one thing that remains is the indexes. I played around with it but couldn't get those wired in properly and could use some help on that.

Thanks again for the awesome project!

mdgriffith commented 1 year ago

This is awesome, thank youuuu!