4. Modeling data: ADTs and records
An algebraic data type (ADT) lists its constructors with |. Add derive Show to make
it printable:
type Shape =
| Circle(r: Float)
| Rect(w: Float, h: Float)
derive Show
fn area(s: Shape) -> Float =
match s {
Circle(r) -> 3.14159 * r * r
Rect(w, h) -> w * h
}
pub fn main() -> Unit !io = {
println(to_string(Circle(2.0)))
println(to_string(area(Rect(3.0, 4.0))))
}
Open in playground
Circle(2.0)
12.0
A record is a product type with named fields, constructed and updated with braces:
type Point = { x: Float, y: Float } derive Show
fn shift(p: Point, dx: Float) -> Point =
Point { ..p, x: p.x + dx }
pub fn main() -> Unit !io = {
let a = Point { x: 1.0, y: 2.0 }
println(to_string(shift(a, 10.0)))
}
Open in playground
Point { x: 11.0, y: 2.0 }
What type declares is always a new type; to give an existing one an alias, use
alias — the two spellings are interchangeable, and it is mostly used to give a tuple
or a function type a name you can say out loud:
alias Point = (Int, Int)
fn shift(p: Point, dx: Int) -> Point = {
let (x, y) = p
(x + dx, y)
}
pub fn main() -> Unit !io = {
let p: Point = (1, 2)
println(to_string(shift(p, 3)))
}
Open in playground
(4, 2)