Records, sums and constraints
Records
Section titled “Records”A record (product type) has named, typed fields. Two spellings declare the same type:
type Point = { Int x; Int y; };type Size = { w: Int, h: Int };
Int main() { Point p = Point {.x = 3, .y = 4}; Size s = Size { w = 10, h = 20 }; println(f"{p} {s.w * s.h}"); Point { x, y } = p; // destructuring println(f"{x + y}"); return 0;}Point { x: 3, y: 4 } 2007Records are values: to “change” a field, build a new record. == is
defined on numbers, Bool and Str; give a record an Eq instance to
compare it with == (see your own behaviors),
or compare its fields.
A sum type is one of several variants, each with an optional payload:
type Json = Num(Int) | Text(Str) | Flag(Bool) | Null;
Str kind(Json j) { return match j { Num(n) => f"number {n}", Text(s) => f"text {s}", Flag(b) => f"flag {b}", Null => "null", };}
Int main() { println(kind(Num(3))); println(kind(Text("hi"))); println(f"{Flag(true)} {Null}"); return 0;}number 3text hiFlag(true) NullSum types may take type parameters; Option and Result are built this
way:
type Box(T) = Full(T) | Nothing;
Int unbox(Box(Int) b) { return match b { Full(x) => x, Nothing => 0, };}
Int main() { println(f"{unbox(Full(3))} {unbox(Nothing)}"); return 0;}3 0Constraint types
Section titled “Constraint types”A constraint type is a base type plus a predicate over value:
type Percent = Float[value >= 0.0 && value <= 1.0];type Even = Int where value % 2 == 0;
@requires(args)Int main() { Percent p = 0.42; // checked while compiling Even e = args.count() * 2; // checked when bound, at run time println(f"{p:percent} {e}"); return 0;}42% 2A known value that breaks the constraint is a compile-time error (E0301);
a runtime value that breaks it aborts at the binding with a message naming
the constraint. The predicate is reduced like any other expression, so a
Float constraint is checked just as an Int one is — but only a Float(64)
predicate reduces: another float width, a division by zero, or a value with no
decimal literal to write it as stays a run-time check.
Type aliases
Section titled “Type aliases”type Meters = Int; names a type without adding a constraint.
Generic types
Section titled “Generic types”A record or sum can take type parameters, single uppercase letters:
type Pair(T) = { T a; T b; };
Int main() { Pair(Int) p = Pair {.a = 1, .b = 2}; Pair(Str) q = Pair {.a = "x", .b = "y"}; println(f"{p.a + p.b} {q}"); return 0;}3 Pair { a: "x", b: "y" }Functions can be generic too; see Generic functions and records.
