Sum Types and Pattern Matching
Defining sum types
Section titled “Defining sum types”Sum types are declared with the type keyword. Each variant either carries named fields or is a plain unit variant:
type Direction { North, South, East, West,}
type Shape { Circle(radius: Double), Rectangle(width: Double, height: Double),}Constructing variants
Section titled “Constructing variants”let dir = North // unit variant. No parentheseslet c = Circle(radius: 5.0) // named fieldslet c2 = Circle(5.0) // positional. Same as aboveUnit variants are referenced by name alone. North() is a compile error.
Exhaustive match
Section titled “Exhaustive match”match is Vertex’s primary tool for working with sum types. The compiler verifies that every variant is covered:
fn area(s: Shape): Double { match s { Circle(radius: r) => 3.14159 * r * r, Rectangle(width: w, height: h) => w * h, }}Field shorthand (punning)
Section titled “Field shorthand (punning)”When the binding name matches the field name, use field: instead of field: field:
// Long formmatch s { Circle(radius: radius) => radius * 2.0 }
// Shorthand. Equivalentmatch s { Circle(radius:) => radius * 2.0 }Match guards
Section titled “Match guards”match score { n if n >= 90 => "A", n if n >= 80 => "B", _ => "F", // wildcard: matches anything}Multi-subject match
Section titled “Multi-subject match”let msg = match isAdmin, isActive { true, true => "Active admin", true, false => "Inactive admin", false, _ => "User",}OR-patterns
Section titled “OR-patterns”match status { "active" | "pending" => true, _ => false,}Direct field access
Section titled “Direct field access”When the compiler knows the exact variant statically, you can access fields directly:
let c = Circle(radius: 5.0)debug c.radius // 5.0. No match needed; static type is CircleWhen every variant shares a field with the same name and type, you can access it on the parent type too:
type Ticket { VIP(price: Int, available: Int), Standard(price: Int, available: Int),}
fn getAvailable(t: Ticket): Int { t.available // valid. Both variants have 'available: Int'}let assert: unsafe extraction
Section titled “let assert: unsafe extraction”let assert Ok(value) = safe_divide(10, 2)Prefer if let for conditional extraction or match for exhaustive dispatch.
Next steps
Section titled “Next steps”- Sum Types reference
- Pattern Matching reference: list patterns, OR-patterns,
let assert - Option<T> and Result<T, E>. The built-in sum types