Prev: Table of Contents TOC: Contents Next: Meet the Monads

Introduction


What is a monad?

A monad is a way to structure computations in terms of values and sequences of computations using those values. Monads allow the programmer to build up computations using sequential building blocks, which can themselves be sequences of computations. The monad determines how combined computations form a new computation and frees the programmer from having to code the combination manually each time it is required.

It is useful to think of a monad as a strategy for combining computations into more complex computations. For example, you should be familiar with the Maybe type in Haskell:

data Maybe a = Nothing | Just a
which represents the type of computations which may fail to return a result. The Maybe type suggests a strategy for combining computations which return Maybe values: if a combined computation consists of one computation B that depends on the result of another computation A, then the combined computation should yield Nothing whenever either A or B yield Nothing and the combined computation should yield the result of B applied to the result of A when both computations succeed.

Other monads exist for building computations that perform I/O, have state, may return multiple results, etc. There are as many different type of monads as there are strategies for combining computations, but there are certain monads that are especially useful and are common enough that they are part of the standard Haskell 98 libraries. These monads are each described in Part II.

Why should I make the effort to understand monads?

The sheer number of different monad tutorials on the internet is a good indication of the difficulty many people have understanding the concept. This is due to the abstract nature of monads and to the fact that they are used in several different capacities, which can confuse the picture of exactly what a monad is and what it is good for.

In Haskell, monads play a central role in the I/O system. It is not essential to understand monads to do I/O in Haskell, but understanding the I/O monad will improve your code and extend your capabilities.

For the programmer, monads are useful tools for structuring functional programs. They have three properties that make them especially useful:

  1. Modularity - They allow computations to be composed from simpler computations and separate the combination strategy from the actual computations being performed.
  2. Flexibility - They allow functional programs to be much more adaptable than equivalent programs written without monads. This is because the monad distills the computational strategy into a single place instead of requiring it be distributed throughout the entire program.
  3. Isolation - They can be used to create imperative-style computational structures which remain safely isolated from the main body of the functional program. This is useful for incorporating side-effects (such as I/O) and state (which violates referential transparency) into a pure functional language like Haskell.
Each of these features will be revisited later in the tutorial in the context of specific monads.


Prev: Table of Contents TOC: Contents Next: Meet the Monads