Discriminated Unions

// A type that is ONE of several named cases, each with optional data
type Shape =
    | Circle of radius: float
    | Rectangle of width: float * height: float
    | Triangle of a: float * b: float * c: float

let area shape =
    match shape with
    | Circle r -> System.Math.PI * r * r
    | Rectangle (w, h) -> w * h
    | Triangle (a, b, c) ->
        let s = (a + b + c) / 2.0
        sqrt (s * (s - a) * (s - b) * (s - c))

let shapes = [ Circle 1.0; Rectangle (2.0, 3.0); Rectangle(width = 4.0, height = 5.0) ]
shapes |> List.map area

// Enum-like unions
type Color = Red | Green | Blue
let next = function Red -> Green | Green -> Blue | Blue -> Red

// Recursive unions: trees and expressions
type Tree<'T> =
    | Leaf
    | Node of left: Tree<'T> * value: 'T * right: Tree<'T>

let rec insert x tree =
    match tree with
    | Leaf -> Node (Leaf, x, Leaf)
    | Node (l, v, r) when x < v -> Node (insert x l, v, r)
    | Node (l, v, r) when x > v -> Node (l, v, insert x r)
    | t -> t

let rec toList tree =
    match tree with
    | Leaf -> []
    | Node (l, v, r) -> toList l @ [ v ] @ toList r

[5; 3; 8; 1] |> List.fold (fun t x -> insert x t) Leaf |> toList   // [1; 3; 5; 8]

ty
…