Pattern Matching
Pattern matching destructures values by their shape. It is introduced with match expr: followed by indented case branches.
Union Matching
Match on union tags with tag names and optional bindings:
union Species
cat
dog: Breed
horse
describe: s:Species. Text
match s:
cat: "a cat"
dog: breed. "a dog of breed " ++ breed as Text
horse: "a horse"
Nullary tags match by name. Tags with payloads bind the carried value to a variable.
Array Matching
Match arrays by their structure:
reduce: xs:[a]. f:(a. b. b). b:b. b
match xs:
[]: b
_: head. tail. f head (reduce tail f b)
| Pattern | Meaning |
|---|---|
|
Empty array |
|
Non-empty array, binding first element and rest |
Array destructuring binds head to the first element and tail to the remaining array.
Sets and Optionals
Sets and optionals cannot be matched directly. To match on a set, cast it to an array first with as:
match (mySet as [Text]):
[]: "empty"
_: head. tail. "has " ++ head
For optionals, use the ? operator to provide a default, or use for to map over the value when present.
Returning Products from Match
When a match expression’s expected type is a product, the constructor name can be omitted from branch bodies. The fields are written directly, indented under the case pattern:
type Foo
name: Text
wack: Text
mkFoo: n:Text. Foo
match n:
"wat":
name: "howdy"
wack: "frog"
_:
name: n
wack: "WAT"
This is equivalent to writing Foo: before each set of fields:
mkFoo: n:Text. Foo
match n:
"wat": Foo:
name: "howdy"
wack: "frog"
_: Foo:
name: n
wack: "WAT"
The compiler infers the product constructor from the return type of the enclosing function. Both forms produce identical output.
Anonymous product literals also work with captures:
union Result
ok: Data
err: Text
handle: r:Result. Response
match r:
ok: d.
status: 200
body: d
err: msg.
status: 500
body: msg
Default Pattern
The _ wildcard matches anything:
match country:
usa: species = Species.cat
_: true
When used as the last branch, serves as the default case. In non-wildcard position for collections, introduces a destructuring pattern.
Nested Matching
Match expressions can be nested:
take: n:Natural. xs:[a]. [a]
match xs:
[]: []
_: head. tail. match n:
1: [head]
_: [head] ++ take ((n as Integer - 1) as Natural) xs
Match in Validation
Match expressions appear inside valid blocks to dispatch on field values:
valid Pet
match species:
cat: age > 1
horse: (name as Text) = "tonto"
dog: true
Each branch must evaluate to a Boolean.
Exhaustiveness
Match expressions should cover all possible cases. For union types, list each tag. For collections and optionals, include both the empty and non-empty cases. Use _ as a catch-all when full enumeration is not needed.
See Also
-
Types — Union, array, set, and optional types
-
Expressions — Match is one form of expression
-
Validation — Using match inside valid blocks