Skip to content

Pattern Matching

match is an expression in Shape. It returns a value and is statically checked.

fn sign(n: int) -> string {
match n {
x: int where x < 0 => "negative"
x: int where x == 0 => "zero"
_ => "positive"
}
}

Type matching is useful for union types:

fn normalize(value: int | string) -> string {
match value {
n: int => f"int:{n}"
s: string => f"str:{s}"
}
}
enum Status {
Ok(int),
Error(string)
}
fn render(status: Status) -> string {
match status {
Status::Ok(code) => f"ok({code})"
Status::Error(msg) => f"error({msg})"
}
}

Constructor patterns match enum variants directly. Variants with payloads bind values; variants without payloads (like None) match as-is:

fn unwrap_or(opt: Option<int>, default: int) -> int {
match opt {
Some(v) => v
None => default
}
}
fn describe(result: Result<string>) -> string {
match result {
Ok(value) => f"success: {value}"
Err(e) => f"failed: {e}"
}
}
fn bucket(n: int) -> int {
match n {
x: int where x < 10 => 0
x: int where x < 100 => 1
_ => 2
}
}

When the compiler can prove all cases, you do not need _. When not all cases are covered, add _ explicitly.

Use separate arms for clarity. Avoid large if/else chains when matching by type or variant.