Tagged Unions
Declaration
tape
tagged Shape {
Circle { radius: f64 }
Rect { width: f64, height: f64 }
Point;
}A tagged union stores exactly one variant at a time, with a hidden discriminant tag. Variants with no fields use ; instead of {}.
Construction
tape
let s = Shape.Circle { radius: 5.0 };
let r = Shape.Rect { width: 3.0, height: 4.0 };Pattern matching
tape
fn area(s: Shape) -> f64 {
match (s) {
Shape.Circle { radius } => { return 3.14159 * radius * radius; }
Shape.Rect { width; height } => { return width * height; }
Shape.Point => { return 0.0; }
}
}Match arms use Type.Variant { field_bindings } syntax. Fields are bound by name. Use .. to ignore remaining fields, or : alias to rename a binding.
Type narrowing with is
Planned
is narrowing for tagged union variants is not yet implemented. Currently is only works with component constraint types.tape
if (s is Shape.Circle) {
io.print_f64(s.radius);
}Untagged unions (t0/t1 only)
tape
union Register {
i: i64;
f: f64;
bytes: [8]u8;
}Like C’s union — all fields occupy the same memory, no discriminant tag. You’re responsible for knowing which interpretation is valid. Only available in t0/t1 profiles; no managed types (strings, slices, GC pointers) allowed inside. Use tagged unions for the safe “one of several types” case.
Last modified: