Active Patterns

// Complete (multi-case) active pattern: classify input into named cases
let (|Even|Odd|) n = if n % 2 = 0 then Even else Odd
let describe n = match n with Even -> $"{n} is even" | Odd -> $"{n} is odd"

// Partial active pattern: may fail to match (returns option)
let (|Int|_|) (s: string) =
    match System.Int32.TryParse s with
    | true, v -> Some v
    | _ -> None

let (|Float|_|) (s: string) =
    match System.Double.TryParse s with
    | true, v -> Some v
    | _ -> None

let parse input =
    match input with
    | Int i -> $"int {i}"
    | Float f -> $"float {f}"
    | _ -> "not a number"

parse "42"        // "int 42"
parse "3.14"      // "float 3.14"

// Parameterized active patterns
let (|DivisibleBy|_|) divisor n = if n % divisor = 0 then Some () else None
let fizzbuzz n =
    match n with
    | DivisibleBy 15 -> "FizzBuzz"
    | DivisibleBy 3 -> "Fizz"
    | DivisibleBy 5 -> "Buzz"
    | _ -> string n

// Regex active pattern
open System.Text.RegularExpressions
let (|Regex|_|) pattern input =
    let m = Regex.Match(input, pattern)
    if m.Success then Some [ for g in m.Groups |> Seq.skip 1 -> g.Value ] else None

match "2025-10-24" with
| Regex @"(\d{4})-(\d{2})-(\d
…