- Variants as data structures
type point = Point(float, float);
type shape =
| Rectangle(point, point)
| Circle(point, float);
let bottomLeft = Point(-1.0, -2.0);
let topRight = Point(7.0, 6.0);
Pattern Matching
let computeArea = (s: shape) =>
switch s {
| Rectangle(Point(x1, y1), Point(x2, y2)) =>
let width = abs_float(x2 -. x1);
let height = abs_float(y2 -. y1);
width *. height;
| Circle(_, radius) => pi *. (radius ** 2.0)
};
- Self-recursive data structures via variants
type intTree =
| Empty
| Node(int, intTree, intTree);
let rec computeSum = (t: intTree) =>
switch t {
| Empty => 0
| Node(i, leftTree, rightTree) =>
i + computeSum(leftTree) + computeSum(rightTree)
};
- Mutually recursive data structures via variants
type intTree =
| Empty
| IntTreeNode(intNode)
and intNode =
| IntNode(int, intTree, intTree);
- Parameterized variants
type tree('a) =
| Empty
| Node('a, tree('a), tree('a));
- Useful standard variants
type option('a) =
| None
| Some('a);
type result('good, 'bad) =
| Ok('good)
| Error('bad);
Example
type expression =
| Plus(expression, expression)
| Minus(expression, expression)
| Times(expression, expression)
| DividedBy(expression, expression)
| Literal(int);
/* (3 - (16 / (6 + 2)) */
let expr =
Minus(
Literal(3),
DividedBy(
Literal(16),
Plus(
Literal(6),
Literal(2)
)
)
);
let rec eval(e: expression) =
switch e {
| Plus(e1, e2) => eval(e1) + eval(e2)
| Minus(e1, e2) => eval(e1) - eval(e2)
| Times(e1, e2) => eval(e1) * eval(e2)
| DividedBy(e1, e2) => eval(e1) / eval(e2)
| Literal(i) => i
};