Option and ValueOption

Use Option instead of null for "may be missing". It forces callers to handle the absent case.

// type Option<'T> = Some of 'T | None
let tryDivide x y = if y = 0 then None else Some (x / y)

tryDivide 10 2                                // Some 5
tryDivide 10 0                                // None

match tryDivide 10 0 with
| Some v -> printfn "Result %d" v
| None -> printfn "Cannot divide by zero"

// Option module
Some 5 |> Option.map (fun x -> x * 2)         // Some 10
None |> Option.map (fun x -> x * 2)           // None
Some 5 |> Option.bind (fun x -> tryDivide 100 x)   // Some 20
Some 5 |> Option.defaultValue 0               // 5
None |> Option.defaultValue 0                 // 0
Some 5 |> Option.filter (fun x -> x > 10)     // None
Option.isSome (Some 1), Option.isNone None    // true, true
Some 3 |> Option.iter (printfn "got %d")
Option.ofObj (null: string)                   // None: convert nullable .NET values
Option.ofNullable (System.Nullable 5)         // Some 5
Some "x" |> Option.toList                     // ["x"]
[ Some 1; None; Some 3 ] |> List.choose id    // [1; 3]
Option.orElse (Some 2) None                   // Some 2

// Chaining with a computation expression (FsToolkit.ErrorHandling, or a custom builder; Module 31)
// option { let! a = tryDivide 100
…