mdgriffith / elm-codegen / Elm.Case.Branch

This module is for creating more advanced pattern matches in your case expressions.

The general usage looks something like this

import Elm.Case as Case
import Elm.Case.Branch as Branch

example =
    Case.custom myValue
        (Elm.Annotation.named [] "Msg")
        -- Define all the branches in your case
        [ Branch.variant1 "ButtonClicked" (Branch.var "id") <|
            \id -> Elm.Op.append id (Elm.string " was clicked!")

        -- A branch which also destructures a record
        , Branch.variant1 "FormSubmitted" (Branch.record2 Tuple.pair "id" "isValid") <|
            \( id, isValid ) ->
                Elm.ifThen isValue
                    (Elm.string "Form is valid")
                    (Elm.string "Form is NOT valid")
        ]

Which generates

case myValue of
    ButtonClicked id ->
        "Button " ++ id ++ " was clicked!"

    FormSubmitted { id, isValid } ->
        if isValid then
            "Form is valid"

        else
            "Form is NOT valid"


type alias Branch =
Internal.Branch.Branch


type alias Pattern a =
Internal.Branch.Pattern a

map : (a -> b) -> Pattern a -> Pattern b

Variables

var : String -> Pattern Elm.Expression

This is the most basic kind of pattern - it matches anything and gives it a variable name.

import Elm.Case.Branch as Branch


Branch.variant1 "Username" (Branch.var "username") <|
    \username ->
        Elm.Op.append
            (Elm.string "Hello ")
            username

Results in

Username username ->
    "Hello " ++ username

Exact Matches

unit : value -> Pattern value

ignore : value -> Pattern value

Literals

int : Basics.Int -> value -> Pattern value

Pattern match with a literal Int.

import Elm.Case.Branch as Branch

Branch.just (Branch.int 2 (Elm.int 5))

Results in

Just 2 ->
    5

string : String -> value -> Pattern value

Matches a literal String.

example =
    Branch.just (Branch.string "admin")
        |> Branch.map
            (\str ->
                Elm.string "This user is an admin!"
            )

Results in

case user.kind of
    Just "admin" ->
        "This user is an admin!"

char : Char -> a -> Pattern a

Matches a literal Char.

Tuples and Triples

tuple : Pattern a -> Pattern b -> Pattern ( a, b )

Branch.tuple (Branch.var "one") (Branch.var "two")
    |> Branch.map
        (\( one, two ) ->
            Elm.Op.append one two
        )

triple : Pattern a -> Pattern b -> Pattern c -> Pattern ( a, b, c )

Lists

list : { patterns : List (Pattern item), gather : item -> gathered -> gathered, startWith : gathered, finally : gathered -> list } -> Pattern list

Match on a list of items

[ "first", "second" ] ->
    "firstsecond"

Could be represented like

Branch.list
    { patterns =
        [ Branch.string "first"
        , Branch.string "second"
        ]
    , gather = \item gathered -> item :: gathered
    , startWith = []
    , finally = Elm.string
    }

listWithRemaining : { patterns : List (Pattern item), remaining : Pattern remaining, gather : item -> gathered -> gathered, startWith : gathered, finally : gathered -> remaining -> list } -> Pattern list

Pattern match on an open list where you can have access to remaining "tail" of items.

So, something like this:

"first" :: "second" :: remaining ->
    remaining

Could be represented like

Branch.listWithRemaining
    { patterns =
        [ Branch.string "first"
        , Branch.string "second"
        ]
    , remaining = Branch.var "remaining"
    , gather = \item gathered -> item :: gathered
    , startWith = []
    , finally =
        \gathered remaining ->
            remaining
    }

Maybe

just : Pattern just -> Pattern just

nothing : value -> Pattern value

Result

err : Pattern err -> Pattern err

The Err value of a result.

ok : Pattern ok -> Pattern ok

The Ok value for a Result

Records

This will help destructure record fields if you know what fields you want.

Here's an example using an intermediate record to help us out!

{-| We define a record to help us out!
-}
type alias Details =
    { id : Elm.Expression
    , name : Elm.Expression
    }

Case.custom (Elm.val "msg") (Type.named [] "Msg")
    [ Branch.variant1 "ButtonClicked" (Branch.record2 Details "id" "name") <|
        \{ id, name } ->
           Elm.tuple id name
    ]

Which generates

case msg of
    ButtonClicked { id, name } ->
        ( id, name )

record0 : record -> Pattern record

An empty record pattern!

record1 : (Elm.Expression -> record) -> String -> Pattern record

record2 : (Elm.Expression -> Elm.Expression -> combined) -> String -> String -> Pattern combined

record3 : (Elm.Expression -> Elm.Expression -> Elm.Expression -> combined) -> String -> String -> String -> Pattern combined

record4 : (Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> combined) -> String -> String -> String -> String -> Pattern combined

record5 : (Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> combined) -> String -> String -> String -> String -> String -> Pattern combined

record6 : (Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> combined) -> String -> String -> String -> String -> String -> String -> Pattern combined

record7 : (Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> combined) -> String -> String -> String -> String -> String -> String -> String -> Pattern combined

record8 : (Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> combined) -> String -> String -> String -> String -> String -> String -> String -> String -> Pattern combined

record9 : (Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> Elm.Expression -> combined) -> String -> String -> String -> String -> String -> String -> String -> String -> String -> Pattern combined

Custom Types

variant0 : String -> value -> Pattern value

variant1 : String -> Pattern value -> (value -> result) -> Pattern result

variant2 : String -> Pattern value1 -> Pattern value2 -> (value1 -> value2 -> combined) -> Pattern combined

variant3 : String -> Pattern value1 -> Pattern value2 -> Pattern value3 -> (value1 -> value2 -> value3 -> combined) -> Pattern combined

variant4 : String -> Pattern value1 -> Pattern value2 -> Pattern value3 -> Pattern value4 -> (value1 -> value2 -> value3 -> value4 -> combined) -> Pattern combined

variant5 : String -> Pattern value1 -> Pattern value2 -> Pattern value3 -> Pattern value4 -> Pattern value5 -> (value1 -> value2 -> value3 -> value4 -> value5 -> combined) -> Pattern combined

variant6 : String -> Pattern value1 -> Pattern value2 -> Pattern value3 -> Pattern value4 -> Pattern value5 -> Pattern value6 -> (value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> combined) -> Pattern combined

variant7 : String -> Pattern value1 -> Pattern value2 -> Pattern value3 -> Pattern value4 -> Pattern value5 -> Pattern value6 -> Pattern value7 -> (value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> value7 -> combined) -> Pattern combined

variant8 : String -> Pattern value1 -> Pattern value2 -> Pattern value3 -> Pattern value4 -> Pattern value5 -> Pattern value6 -> Pattern value7 -> Pattern value8 -> (value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> value7 -> value8 -> combined) -> Pattern combined

variant9 : String -> Pattern value1 -> Pattern value2 -> Pattern value3 -> Pattern value4 -> Pattern value5 -> Pattern value6 -> Pattern value7 -> Pattern value8 -> Pattern value9 -> (value1 -> value2 -> value3 -> value4 -> value5 -> value6 -> value7 -> value8 -> value9 -> combined) -> Pattern combined

Custom Type Builder

These helpers let you define a Custom Type pattern with a builder.


type CustomType a

customType : String -> a -> CustomType a

withParam : Pattern a -> CustomType (a -> b) -> CustomType b

toPattern : CustomType a -> Pattern a

Alias (as)

aliasAs : String -> (Elm.Expression -> a -> b) -> Pattern a -> Pattern b