Pattern Matching
Match expressions, destructuring, and exhaustive patterns.
Pattern matching is the primary control flow in Qosm. There's no if/else — use match instead.
Basic syntax
match expr with (
| pattern1 -> result1
| pattern2 -> result2
| _ -> default_result)
Branches are parenthesized and separated by |.
Variable patterns
Variables bind the matched value:
match 42 with (
| x -> x + 1)
// 43
Wildcard
_ matches anything without binding:
match some_value with (
| _ -> "matched anything")
Scalar patterns
Match exact values:
match n with (
| 0 -> "zero"
| 1 -> "one"
| _ -> "many")
Boolean matching (instead of if/else)
let abs x =
match x >= 0 with (
| true -> x
| false -> 0 - x);
let max a b =
match a > b with (
| true -> a
| false -> b);
Variant patterns
Nullary variants
match color with (
| Red -> "#ff0000"
| Green -> "#00ff00"
| Blue -> "#0000ff")
Named field destructuring
match result with (
| Ok{value: v} -> "Success: " ++ to_string v
| Err{value: e} -> "Error: " ++ .message e)
Positional destructuring (single-field variants)
match opt with (
| Some n -> n + 1
| None -> 0)
Record patterns
Destructure record fields:
match person with (
| {name: n, age: a} -> n ++ " is " ++ to_string a)
Array patterns
match arr with (
| [] -> "empty"
| [x] -> "one element: " ++ to_string x
| [x, y] -> "two elements"
| [x, ...rest] -> "head: " ++ to_string x)
The [x, ...rest] pattern binds the first element to x and the remaining array to rest.
[x, ...rest] is pattern-only. To build arrays, use append [x] rest, not [x, ...rest].
Nested patterns
Patterns can be nested:
match result with (
| Ok{value: {name: n}} -> "Name: " ++ n
| Err{value: ParseError{message: m}} -> "Parse error: " ++ m
| Err{value: _} -> "Other error")
Common Result/Option patterns
// Option from head/nth
let first_or_zero arr =
match head arr with (
| Some{value: x} -> x
| None -> 0);
// Result from capability calls
let safe_fetch url =
match http_get {url: url, headers: []} with (
| Ok{value: body} -> body
| Err{value: e} -> "Error: " ++ .message e);
// Chaining Results with and_then
let pipeline input =
http_get {url: input, headers: []}
|> and_then (λ body -> parse_json @{name: String} body);