Search code examples
f#monadscomputation-expression

F# Computation Expressions and Return statement


On the Try F# website they give an example of a computation expression:

type Age =
| PossiblyAlive of int
| NotAlive

type AgeBuilder() =
    member this.Bind(x, f) =
        match x with
        | PossiblyAlive(x) when x >= 0 && x <= 120 -> f(x)
        | _ -> NotAlive
    member this.Delay(f) = f()
    member this.Return(x) = PossiblyAlive x

let age = new AgeBuilder()

let willBeThere (a:int) (y:int) =
  age { 
    let! current = PossiblyAlive a
    let! future = PossiblyAlive (current + y)

    return future
  }

which seems a bit like the standard Maybe monad found in Haskell.

However, in true Haskell form I would want to use return for the two lines:

let! current = PossiblyAlive a
let! future = PossiblyAlive (current + y)

to be:

let! current = return a
let! future = return (current + y)

however it doesn't work. The closest I get to is:

let! current = age.Return a
let! future = age.Return (current + y)

but this looks dirty. Is there any way to use return without using the computation builders function explicitly?


Solution

  • You can create a nested expression:

    let! current = age { return a }
    let! future = age { return (current + y) }
    

    although you could just use let instead:

    let current = a
    let future = current + y
    

    Be aware that this builder breaks the monad laws since

    return 150 >>= return is not the same as return 150