24

I'm still learning functional programming (with f#) and I recently started reading about computation expressions. I still don't fully understand the concept and one thing that keeps me unsure when reading all the articles regarding monads (most of them are written basing on Haskell) is the relation between computation expressions and monads.

Having written all that, here's my question (two questions actually):

Is every F# computation expression a monad? Can every monad be expressed with F# computation expression?

I've read this post of Tomas Petricek and if I understand it well, it states that computation expressions are more than monads, but I'm not sure if I interpret this correctly.

2 Answers2

24

First of all, computation expressions are a language feature, while monads are mathematical abstractions, so from this point of view, they are completely different things.

But that would not be a very useful answer :-). Computation expressions are a language feature that gives you a syntax which can be used for programming with computations (or data types) that have the monadic structure, but they can be also used with other structures. You can read my F# computation expression zoo paper for more details, but computation expressions can be used with:

  • Monads, but also additive monads (what Haskellers call MonadPlus or MonadOr)
  • Composed computations (what Haskellers call monad transformers)
  • Computations that are monadic, but support other F# constructs like exception handling
  • Monoids (and a couple of variations without monadic bind)
  • Applicative functors (though this is only implemented in a research extension)

So, computation expressions are certainly closely linked to monads, but they are not linked to them that closely. This is in contrast e.g. with Haskell's do notation, which is much more closely linked to monads (although even that can be used with computations that are not strictly mathematically monads).

Tomas Petricek
  • 356
  • 1
  • 4
7

You can use computation expressions to express monads. There is an example here. Also, as you noted, you can use computation expressions for a lot more than just monads. There is an extended explanation about how they are different here. There isn't space here to explain the difference properly, but computation expressions are different from monads in that they reuse normal F# syntax and have the ability to add additional abstractions. A limitation is that its non-idiomatic (and difficult) to write a computation expression which is polymorphic over the type of computation.

N_A
  • 179
  • 3