What a Monad is not

From HaskellWiki
Revision as of 16:33, 14 November 2009 by Chowells (talk | contribs)
Jump to navigation Jump to search

In addition to Burritos, Monads aren't a couple of things:

Warning

This page is currently an unprocessed braindump. Feel free to dump additional stuff or massage stuff into didactic pleasures.

Monads are not a language feature

Really. They are defined in terms of Haskell, not Haskell in terms of them. Conversely,

Haskell doesn't need Monads

...well, apart from the Haskell standard defining the way IO is done in terms of Monads: It could be done differently and still work.

Monads are not impure

...In no way whatsoever. You don't even need flexible morals to claim it. To be more specific, it's IO that's impure. That makes the IO monad impure. But that's not a general property of monads - just IO.

Monads are not about state

While it is certainly possible to abstract away explicit state passing by using a Monad, that's not what a monad is.

Monads are not about strictness

There are monads that are strict (like IO), and monads that are lazy (like []). Then there are some that come in multiple flavours, like State.

Monads are not values

This point might be driven home best by pointing out that instance Monad Foo where ... is not a data type, but a declaration of a typeclass instance. However, to elaborate:

Monads are not values in the same sense that addition and multiplication are not numbers: They capture a -- very specific -- relationship between values of a specific domain into a common abstraction. We're going to call these values monads manage mobits, like this:

type Mobit a = Monad m => m a

The IO monad manages mobits representing side-effects ("IO actions").

The List monad manages mobits representing multiple values ("[a]")

The Reader monads manages mobits that are pure computations that use asks to propagate information instead of explicit arguments

...and while addition and multiplication are both monoids over the positive natural numbers, a monad is a monoid in a category of endofunctors. It's all very simple.


Monads are not a replacement for applicative functors

Instead, every monad is an applicative functor (as well as a functor). It is considered good practice not to use >>= if all you need is <*>, or even fmap.

Not confusing what features of monads are specific to monads only and which stem from applicative functors are vitally important for a deeper understanding of monads. As an example, the applicative functor interface of parser libraries can parse context-free grammars (and look just like EBNF), while the monadic interface can parse context-sensitive grammars: Monads allow you to influence further processing by inspecting the result of your parse. To understand why, have a look at the type of >>=. To understand why applicative functors by themselves are sufficient to track the current parsing position, have a look at the uu-parsinglib tutorial.

The exact differences are elaborated in even greater detail in Brent Yorgey's excellent Typeclassopedia.