Pattern Matching

let classify x =
    match x with
    | 0 -> "zero"                                  // constant pattern
    | 1 | 2 | 3 -> "small"                         // OR pattern
    | n when n < 0 -> "negative"                   // guard
    | n when n % 2 = 0 -> "even"
    | _ -> "odd"                                   // wildcard

// Tuples
let fizzbuzz n =
    match n % 3, n % 5 with
    | 0, 0 -> "FizzBuzz"
    | 0, _ -> "Fizz"
    | _, 0 -> "Buzz"
    | _ -> string n
[1 .. 15] |> List.map fizzbuzz

// Lists
let rec sum list =
    match list with
    | [] -> 0
    | head :: tail -> head + sum tail

let describeList = function
    | [] -> "empty"
    | [ x ] -> $"one element: {x}"
    | [ x; y ] -> $"two elements: {x}, {y}"
    | x :: _ -> $"starts with {x}"

// Arrays, records, options, unions
let firstOfArray = function [| |] -> None | arr -> Some arr[0]
let greeting = function { Name = "Ana" } -> "Hi Ana!" | p -> $"Hello {p.Name}"
let showOpt = function Some v -> $"value {v}" | None -> "nothing"

// as patterns, nested patterns, type test patterns
let (a, b) as whole = (1, 2)
let describeObj (o: obj) =
    match o with
    | :? int as i -> $"int {i}"
    | :? string as s -> $"string 
…