Unit
The unit type — spelled !
— has a single value, also !
.
def Unit: ! = !
Unit is frequently used as an end-marker for other types. All composite types — such as pairs, eithers, and choices — have an obligatory “and then” part. The unit type does the job for the case of “and then nothing”.
For example, the pre-defined List<a>
type has this definition:
type List<a> = recursive either {
.end!,
.item(a) self,
}
Each variant in an either
type has an obligatory payload. For the node marking the
end of the list, the payload is empty, and so it’s !
.
Construction
The expression !
has type !
and is the only possible value for this type.
def Unit = ! // infers `Unit` to be of type `!`
Destruction
Being a data type, variables of type !
can be left unused.
If !
is a part of a larger type, it may be needed to assign it as a part of a pattern. For this
purpose, the pattern !
will destruct a !
value without assigning it to a variable.
def TestUnitDestruction = do {
let unit = !
let ! = unit
} in !
This is useful when matching an end of a list:
dec GetFirstOrZero : [List<Int>] Int
def GetFirstOrZero = [list] list.case {
.end! => 0, // `!` is a pattern here
.item(x) _ => x,
}
Or when destructing a !
-ended tuple:
dec SumPair : [(Int, Int)!] Int
def SumPair = [pair]
let (x, y)! = pair // `!` is a pattern here
in Int.Add(x, y)
def Five =
let pair = (2, 3)!
in SumPair(pair)