Skip to main content
View

Unions, Tags & Pattern Matching

This page covers tagged union types and the match expression in TypR.

Defining tagged unions​

type Shape <- .Circle(num) | .Square(num);
let s <- .Circle(3.14);
let n <- .None;                              # tag without payload

Each variant is prefixed with a dot (.) to distinguish it from regular type names.


The match expression​

# --- setup, from the previous block ---
type Shape <- .Circle(num) | .Square(num);
let s: Shape <- .Circle(3.14);
# --------------------------------------

match s {
    .Circle(r) => r * 2.0,
    .Square(side) => side,
}

Available patterns​

PatternExampleDescription
Tag with binding.Some(a) => adestructures and binds the payload
Tag without binding.None => 0matches a zero-payload tag
Type patternx as int => x + 1type cast/refinement
Record pattern:{nom: n, age: a} => adestructures a record
Tuple pattern:{a, b} => adestructures a tuple
Wildcard_ => defaultmatches anything
Variablev => vbinds and returns

Qualified union constructors​

type Color <- .Red | .Blue;
Color.Red;                      # qualified reference to a tag (bare, no :{...})

type Rgb <- list { r: int, g: int, b: int };
type Palette <- .Red | .Blue | Rgb;
Palette.Rgb:{ r = 10, g = 20, b = 30 };  # Rgb is a record alias used as a union member

Important: Union.Variant:{ field = val } syntax only works when Variant is a record alias used directly as a union member — never for a real tag .Variant(...). To construct a tag, use .Variant(value), and .Variant(:{ ... }) when the payload is itself a record.


Generic tagged unions​

Tagged unions work with generics for reusable patterns:

type Option<T> <- .Some(T) | .None;

let val: Option<int> <- .Some(42);
let empty: Option<int> <- .None;

match val {
    .Some(n) => n,
    .None => 0,
}