Search code examples
haskellf#monadscomputation-expression

Computation expressions for a Haskell programmer


I'm looking to learn F#, but one thing that's confusing to me is the computation expression (do-notation??) syntax and desugaring.

In haskell, you have a very simple Monad typeclass and rules for desugaring do-notation into bind and return. There's no magic involved in adding keywords; the only thing must match up are the types.

In F# there's a bunch of builders, and keywords, and complexity.

Is there a good explanation of how to map one concept to the other?

I basically want to know how I map

do
  x <- monadicComputation
  foo x
  someOtherMonadicComputation
  let y = somePureComputation x
  return $ bar y

to F#.

The only keywords in the haskell are do, (<-) and let.


Solution

  • You can't write generic monadic code in F#, instead you have to specify the monad you're working in by naming the builder associated with the expression. Your example code would look like:

    let example = async {
        let! a = someAsyncComputation
        foo a
        do! someOtherAsyncComputation
        let y = somePureComputation a
        return (bar y)
    }
    

    for the async computation expression type. The 'bang' pattern (do!, let! etc.) is used when binding monadic values, while the regular keywords are used for non-monadic values.

    let! corresponds to bind (>>=) while let corresponds to let in do notation. return corresponds to return, while return! is used to yield an existing monadic value. do! is similar to (>>) which executes a monadic value for its effects, while do is for non-monadic effects, which has no parallel in Haskell.