Enums
Enums are algebraic data types. Variants can carry associated data. Pattern matching on enums is exhaustiveness-checked.
enum Direction { North, South, East, West }
let d = Direction::North
println(d) -- Direction::North
match d {
Direction::North => println("going north")
Direction::South => println("going south")
Direction::East => println("going east")
Direction::West => println("going west")
}
Variants can hold one or more values. Construct them like function calls.
enum Shape {
Circle(radius),
Rect(w, h),
Triangle(a, b, c)
}
let s1 = Shape::Circle(5)
let s2 = Shape::Rect(3, 4)
let s3 = Shape::Triangle(3, 4, 5)
println(s1) -- Shape::Circle(5)
println(s2) -- Shape::Rect(3, 4)
The semantic analyser verifies that all variants are covered. A missing variant is a compile-time error (unless a wildcard is present).
enum Shape {
Circle(radius),
Rect(w, h),
Triangle(a, b, c)
}
fn area(shape) {
match shape {
Shape::Circle(r) => 3.14159 * r * r
Shape::Rect(w, h) => w * h
Shape::Triangle(a, b, c) => {
let s = (a + b + c) / 2.0
(s * (s - a) * (s - b) * (s - c)) ** 0.5
}
}
}
println(area(Shape::Circle(5)))
println(area(Shape::Rect(3, 4)))
enum Status {
Loading,
Done(value),
Error(msg)
}
fn describe(s) {
match s {
Status::Loading => "loading..."
Status::Done(v) => "done: {v}"
Status::Error(msg) => "error: {msg}"
}
}
println(describe(Status::Loading))
println(describe(Status::Done(42)))
println(describe(Status::Error("timeout")))
XS has built-in Ok, Err, Some, and None constructors for common result/option patterns. They are regular values you can match on.
fn safe_div(a, b) {
if b == 0 { return Err("division by zero") }
return Ok(a / b)
}
let result = safe_div(10, 2)
match result {
Ok(val) => println("result: {val}")
Err(msg) => println("error: {msg}")
}
let bad = safe_div(5, 0)
match bad {
Ok(val) => println("result: {val}")
Err(msg) => println("error: {msg}")
}