Search code examples
f#computation-expression

Implementing let! ... and! ... in a custom Computation Expression


I want to add support to my Computation Expression builder for this construct:

let f = 
  foo {
    let! x =
      foo {
        return 1
      }
    and! y =
      foo {
        return 2
      }

    return x + y
  }

The compiler says I must implement either Bind2 or MergeSource. However, I cannot find them in the docs.

What signatures should these have? Can you give a simple example?


Solution

  • Here's a simple builder that works with your example:

    type Foo<'t> = MkFoo of 't
    
    type FooBuilder() =
        member _.Bind(MkFoo x, f) = f x
        member _.Return(x) = MkFoo x
        member _.MergeSources(MkFoo x, MkFoo y) = MkFoo (x, y)
    
    let foo = FooBuilder()
    
    let f =
        foo {
            let! x = foo { return 1 }
            and! y = foo { return 2 }
            return x + y
        }
    printfn "%A" f   // output: MkFoo 3
    

    The purpose of MergeSources is to create a tuple of results that will be automatically de-tupled by the compiler. You might also find this example and this SO question useful.