4. 数据建模:ADT 与 record

代数数据类型(ADT)用 | 列出各构造器。加 derive Show 让它能打印:

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))))
}
在 Playground 打开
Circle(2.0)
12.0

record 是带命名字段的乘积类型,用花括号构造与更新:

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)))
}
在 Playground 打开
Point { x: 11.0, y: 2.0 }

type 声明的永远是新类型;给已有类型起别名alias——两边可以互换使用, 常用来给元组或函数类型一个说话用的名字:

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)))
}
在 Playground 打开
(4, 2)