Rosetta Monad Did It Again

Let e be an expression (e.g. x*x), m a monad instance instance (e.g. [1, 2, 3]) and M its type (list here).
Here is a small translation table, found buried in Memphis under a pill of pizza boxes:

Haskell, list comprehension [ e | x <- m ]
Haskell, do notation1 do {x <- m; return (e)}
Haskell, bind m >>= \x -> return (e)
Scala, yield for (x <- m) yield e
Scala, flatMap m.flatMap(x => M(e))
Scala, map m.map(x => e)

In the same spirit, let’s paint the monad laws in different colors.

Left identity Right identity Associativity
Haskell, list comprehension [ x | x <- m]m
Haskell, do notation do {x <- [a]; f x}f a do {x <- m ; x}m do {y <- do {x <- m; f x } g y}do { x <- m; do { y <- f x; g y }}2
Haskell, bind return a >>= ff a m >>= returnm (m >>= f) >>= gm >>= (\x -> f x >>= g)
Scala, yield for (x <- m) yield xm
Scala, flatMap M(a).flatMap(f)f a m.flatMap(M)m m.flatMap(f).flatMap(g)m.flatMap(x => f(x).flatMap(g))
References: docs.scala-lang, wiki.haskell

MetaPostNote:
  • Find a proper way to have a nice style from markdown.
  • Link or embed runnable code.
Written with StackEdit. Messed up in the process.




  1. Although optional, the braces make clear that the scope of dois the whole block. ↩︎
  2. Equivalent to do { x <- m; y <- f x; g y } ↩︎

Comments