Pattern Matching
Novah supports pattern matching using the case ... of
syntax.
It also supports pattern destructuring for functions and let declarations.
Pattern | Example | Description |
---|---|---|
Wildcard | _ | Always matches |
Variable | a, foo | Always matches and binds the value to the variable |
Literal | 1, 4.5, "foo", 'a', true | Matches the exact literal |
Unit | () | Matches the value to unit |
Constructor | Nil, Some x, None | Matches the specified constructor of a type |
List | [], [x, _], [head :: tail], [x, y, z :: rest] | Matches a list that can be empty, contain some elements and a tail |
Regex | #"\d", #"\w+" | Matches the whole regex against the input |
Record | {x, y}, {name} | Matches the specified fields of a record |
Named pattern | [x :: _] as list, {name} as person | Binds the whole pattern to the given name |
Type test | :? String, :? File as file | Matches the value to the specified runtime type |
Pattern guards
Patterns can have guards for additional filtering.
Begin code:
module guards
foo : Int -> Int
foo x = case x of
0 -> 0
n if n < 0 -> n * -1
n -> n
End code.
Multiple patterns
Case expressions can match on multiple patterns at the same time.
Begin code:
module multipatterns
foo : Option Int -> Option Int -> Option Int
foo x y = case x, y of
Some v1, Some v2 -> Some (v1 + v2)
_, _ -> None
End code.
Destructuring
Function parameters and let declarations can be destructured directly.
Incomplete patterns require a noWarn
attribute to compile.
Begin code:
module destructuring
foo : { x : Int, y : Int } -> Unit
foo {x, y} = printfln "Point %d %d" [x, y]
#[noWarn]
bar () =
let [match, group1, group2] = Re.find #"(\d), (\d)" "3, 9"
let sum = int group1 + int group2
printfln "the sum of %s is %s" [match, show sum]
End code.