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

_: head. tail.

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.

Primitive Matching

Match on literal values of primitive types:

Integer

fib: n:Integer. Integer
  match n:
    0: 0
    1: 1
    _: fib (n - 1) + fib (n - 2)

Boolean

messageSimple: b:Boolean. Text
  match b:
    true: "yes"
    false: "no"

Text

greet: name:Text. Text
  match name:
    "Alice": "Hello Alice"
    "Bob": "Hey Bob"
    _: "Hi there"

Char

charName: c:Char. Text
  match c:
    'a': "alpha"
    'b': "bravo"
    _: "unknown"

Integer, Text, Char, and Boolean literals can all appear as match patterns.

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