A monad transformer combines effects that would otherwise live in separate monadic computations. A plain do-block is specialized to one monad, so code that needs both IO and Maybe-style absence handling cannot use both effects directly in the same block. A transformer nests one monad inside another, producing a compound monad—a monad stack—that can itself be used normally. section 2.1.2
StateT is a common transformer for applications that need a pure, pseudo-mutable state alongside another effect. It provides the familiar get and put operations of State while leaving an underlying monad available. For example, StateT Board IO can carry a Minesweeper board through a script while also printing messages to the console. section 7.2.3 section 7.2.3
Figure 7.6 StateT and IO monadic stack
This stack places StateT above IO: board updates belong to the state layer, while console actions remain in the underlying IO layer. section 7.2.3
Updating state while performing IO
A reveal-cell action gets the current board, checks the selected cell, and puts an updated board when appropriate. Console output must be lifted because the active do-block is StateT rather than IO. Here, lift acts as an adapter from an IO action into the BoardMonad stack. section 7.2.3
Stacks can grow when an application needs distinct state contexts:
- StateT Board IO models board state together with console IO. section 7.2.3
- StateT Score BoardMonad adds a score context above the existing board context. section 7.2.3
- Accessing a lower layer requires lift; accessing IO beneath two StateT layers requires lift twice. section 7.2.3
- A single StateT holding a pair such as (Score, Board) can represent the same two pieces of state without separate layers. section 7.2.3
A stack remains a monad, so ordinary monadic sequencing still applies. Its layers become visible at the boundaries: runStateT, execStateT, and evalStateT unwrap stateful computations one layer at a time. This makes it possible to run a scripted action with an initial board and assert the resulting board in a test. section 7.2.3 section 7.2.3
Monad transformers support architectural separation: state can move out of regular function arguments and into a monadic context, while a lower layer supplies application capabilities such as IO or a Free-based control language. They also impose a practical cost: deeper stacks require additional lifting, and a single combined state context is sometimes an alternative. section 7.2.3 section 7.3

