Variants are dual to structs. Whereas structs represent “this and that and the other”, variants represent “this or that or the other”, in other words, alternatives.
We have already met a common variant, the option type:
variant opt[t] = | None | Some of t ;
The names None and Some are sometimes called type constructors. When they’re used to make a value of a variant type, they’re functions, known as injection functions because they inject their argument into the variant type.
Here’s how we can make values of the option type:
var n = None[int]; var s = Some 42;
Notice that for the None case we have to provide the instance type of t, in this case int. For the Some case, the instance int of t is deduced by overload resolution and so can be elided.
Injections are conditionally invertible, that is, the inverses are partial functions which I call extractors. You use these with pattern matches:
fun show (x:opt[int]) => match x with | None => "None" | Some i => "Some(" + i.str + ")" ;
Felix “knows” which injection was used to construct a variant value, and selects the matching branch from the match expression. This ensures the extractor is well defined. For the Some branch, the extract sets i to the argument of the injection function used to construct the value.