Let's say we want to save a value on the left-hand side of the case statements for use when evaluating the expression on the right-hand side. Let's do that below:
magicNumber : Nat -> Text
magicNumber guess = match guess with
42 -> "magic 🪄"
n -> toText n ++ " is not the magic number. Guess again."
Here n
is a variable that will bind to any value of type Nat
. It's also functioning as a fallback value, and in the example above whatever value it has can be used to produce a desired Text
result.
Guard patterns are a way we can build further conditions for the match expression. They can reference variables in the case statement to further refine if the right side of the arrow should be run. A guard pattern is started with pipe character |
where the right of the |
needs to return something of type Boolean
. If the value to the right side of the pipe |
is true
, the block on the right of the arrow will be executed.
matchNum : Nat -> Text
matchNum num = match num with
oneTwo | (oneTwo === 1) || (oneTwo === 2) -> "one or two"
threeFour | (threeFour === 3) || (threeFour === 4) -> "three or four"
fiveSix | (fiveSix === 5) || (fiveSix === 6) -> "five or six"
_ -> "no match"
We've combined variables with guard patterns and boolean operators in our pattern match statement. The variable oneTwo
without the guard pattern would match anything of type Nat
, but we can specify in the pattern guard that the variable oneTwo
should either be the literal value 1
or 2
.
You might see multiple guard patterns being used for the same match expression case. For example:
myMatch : Nat -> Text
myMatch num = match num with
n
| n < 3 -> "small number"
| n > 100 -> "big number"
| otherwise -> "medium number"
Each pipe |
is followed by a boolean expression and an expression to execute if the boolean is true
. The last case | otherwise ->
in this syntax is a pass-through to catch all other cases. In the context of this pattern match form, otherwise
simply means true
.