type MaybeBuilder() =
member this.Bind(m, f) =
match m with
| None -> None
| Some x ->
printfn "Got `%A`" x
f x
member this.Return(x) =
printfn "Returning `Some(%A)`" x
Some x
let maybe_worker = new MaybeBuilder()
// MaybeBuilder was defined so that in this context, `let!`
// unwraps the value immediately.
let result1 = maybe_worker {
// x is 3
let! x = Some 3
// y is 4
let! y = Some 4
// z is 5
let! z = Some 5
// returns the computation rewrapped
return x * y + z
}
// This one is different. This entire construct desugars to a
// functional construct from Option -> Option -> Option -> return
// and so the None will be passed to the end result
let result2 = maybe_worker {
let! x = None
let! y = Some 4
let! z = Some 5
return x * y + z
}
printfn "%A" result1 // Results in Some 17
printfn "%A" result2 // <null> is None