Types and Annotations
Rex uses Hindley–Milner type inference, but you can (and often should) add annotations.
This page is about the “tools” you use to make types explicit when inference isn’t enough.
Type names
Examples of primitive and constructed types:
bool,i32,f32,string(a, b)for tuplesList a,Option a,Result a e(prelude)
Function types are right-associative:
i32 -> i32 -> i32
means:
i32 -> (i32 -> i32)
Record types
Record types use ::
{ x: i32, y: i32 }
Record values use =:
{ x = 1, y = 2 }
Let annotations
let x: i32 = 1 in x
Lambda parameter annotations
\(x: i32) -> x + 1
Annotating expressions
You can also annotate via a let-binding when you want to force a particular type:
let xs: List i32 = [1, 2, 3] in xs
Type ascription with is
Rex also supports an expression-level “ascription” form:
({ a = 1, b = 2 }) is Dict i32
You’ll see is used in examples for two common reasons:
- To force a dictionary type (
Dict a) instead of a specific record type. - To disambiguate overloaded values (similar to adding a let-annotation).
Warning: Use
iswhen it helps clarity, but don’t overuse it: most of the time, simpleletannotations are easier to read.