# Notes on 'Monads Are Not Metaphors'

This is a translation of 「モナドはメタファーではない」に関する補足 by Kenji Yoshida (@xuwei_k), one of the most active Scala bloggers in Japan covering wide range of topics from Play to Scalaz.

Daniel Spiewak's Monads Are Not Metaphors was written about two and a half years ago, but seeing how its Japanese translation is still being tweeted and being bookmarked by 250 users on Hantena, its popularity doesn't seem to cease. I just remembered something to note about the example code used in the post, which could be an unstylish critique, but I'm going to jot it down here. It's an *unstylish critique*, because I'll be digging into the part where *the author likely knew from the beginning but omitted it intentionally for the sake of illustration*. Also I'll be using Scalaz in this post.

### The example code that calculates `fullName`

from `firstName`

and `lastName`

only requires Applicative^{1} not Monad

Here's the original code

def firstName(id: Int): Option[String] = ... // fetch from database def lastName(id: Int): Option[String] = ... def fullName(id: Int): Option[String] = { firstName(id) bind { fname => lastName(id) bind { lname => Some(fname + " " + lname) } } }

We can rewrite this using Scalaz^{2} as follows:

import scalaz._,Scalaz._ def firstName(id: Int): Option[String] = ??? def lastName(id: Int): Option[String] = ??? def fullName(id: Int): Option[String] = ^(firstName(id), lastName(id))(_ + " " + _)

or

def fullName(id: Int): Option[String] = Apply[Option].apply2(firstName(id), lastName(id))(_ + " " + _)

To reiterate, the author likely knows this, since he's said something like this:

Don’t use a monad when an applicative will do.

— Daniel Spiewak (@djspiewak) December 31, 2012

### Monad's sequence function in Scalaz

First, in Scalaz 7 there's no function with the following signature:

def sequence[M[_], A](ms: List[M[A]])(implicit tc: Monad[M]): M[List[A]]

Instead it has the following under Applicative:

def sequence[A, G[_]: Traverse](as: G[F[A]]): F[G[A]] =

See https://github.com/scalaz/scalaz/blob/v7.0.0/core/src/main/scala/scalaz/Applicative.scala#L39. To cut to the chase, *the sequence function as described in 'Monads Are Not Metaphors'*

^{3}only exists in a

*generalized form*in Scalaz 7.

By the way, in Haskell, there's no corresponding function under `Applicative`

, but there's `sequenceA`

under `Traversable`

: http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html#v:sequenceA.

Coming back to Scalaz, here's what I mean by a *generalized form*.

def sequence[A, G[_]: Traverse](as: G[F[A]]): F[G[A]] =

If we fix the type parameter `G`

in the above to `List`

, it becomes

def sequence[A](as: List[F[A]]): F[List[A]]

and `sequence`

function defined in Scalaz becomes `sequence`

described in 'Monads Are Not Metaphors.' It might appear as if

(implicit tc: Monad[M])

disappeared, but this `sequence`

is a method of Scalaz's `Applicative`

, so `F`

is automatically an instance of Applicative. This is a long-winded way to say that even the `sequence`

function requires only Applicative, and not Monad.

In Haskell, the Monad directly definining `sqequence`

as

sequence :: Monad m => [m a] -> m [a]

and Traversal defining two similar functions

sequenceA :: Applicative f => t (f a) -> f (t a)

and

sequence :: Monad m => t (m a) -> m (t a)

are all artifacts of *historical reason that Monad does not inherit Applicative*, if I may say so at the risk of over-simplification.

To follow up again on the *generalized form*, the implementation of *the sequence function as described in 'Monads Are Not Metaphors'* uses

`List`

's `foldRight`

^{4}.

In other words, to generalize `sequence`

, we only need *a container that has equivalent function as foldLeft*, which is instances of

`Traverse`

typeclass ^{5}.

def sequence[A, G[_]: Traverse](as: G[F[A]]): F[G[A]]

This is the reason `Traverse`

appears in the above signature.

### Summary

So it turns out both

`fullName`

function`Monad`

's`sequence`

function

only require Applicative, and not Monad.

Either on purpose (for the sake of illustration) or by negligence, there are many other examples in Monad tutorials that fall into this "turns out Applicative would suffice instead of Monad" pattern. So readers should keep their eyes open for Applicatives instead of parroting "Monad ( ﾟ∀ﾟ)彡 Monad ( ﾟ∀ﾟ)彡."

- Login to post comments