A Practical Introduction to Monad Transformers
01 February 2015
Monad transformers combine the functionality of two monads into one. They are often used as a way to “flatten” nested monads, but are also used to enable interactions between monads that, when used seperately, would be incredibly difficult to implement.
The Task
You input a number and want to manipulate it while printing the result each time. If there were no intermediate IO operations we could use the state monad with the following state changes:
chain them together:
then get the result:
Now let’s consider how to print the state. If we want to preserve the above chaining syntax, we need a monad where:
 We can do stateful computations
 Our IO functions have access variables inside the computation
This monad is called the state monad transformer.
The Solution
The state monad transformer is defined as:
^{1}Meaning that given an initial state s
and a state transformer st
, we can call runStateT st s
to get
a monad containing the state tuple.
The real beauty (or magic, as some would say) of this monad comes from the bind function. Let’s take a look at its definition:
Time to break it down. m
is a state transformer. k
is a function that takes a result of type a
, and returns
a state transformer. The final state transformer, when run with an initial state, does the following:
 Gets the result and state of running the computation in
m
with the initial states
 Passes the result of (1) to the function
k
, returning a different state transformer  Runs the computation created in (2) using the state returned in (1)
 Wraps the result
This means that we will be able to keep using a simple chained sequence of monads.
How does this relate to the problem at hand?
The monad component of the state transformer allows us to execute IO operations which have access to the state
during the computation. Here is how the add
and subtract
functions can be written using the state transformer
monad:
We can still chain them using the same syntax as before:
and run it:

newtype
creates a strict, isomorphic type with a single value constructor. If all that was too much, just imagine thatnewtype
rearranges an existing type into a more pleasant one. ↩