In functional programming, a monad transformer is a type constructor which takes a monad as an argument and returns a monad as a result.
Monad transformers can be used to compose features encapsulated by monads – such as state, exception handling, and I/O – in a modular way. Typically, a monad transformer is created by generalising an existing monad; applying the resulting monad transformer to the identity monad yields a monad which is equivalent to the original monad (ignoring any necessary boxing and unboxing).
A monad transformer consists of:
t
of kind (* -> *) -> * -> *
return
and bind
(or an equivalent formulation) for all t m
where m
is a monad, satisfying the monad lawslift :: m a -> t m a
, satisfying the following laws:[1] (the notation `bind`
below indicates infix application):lift . return = return
lift (m `bind` k) = (lift m) `bind` (lift . k)
Given any monad
MA
M\left(A?\right)
A?
\begin{array}{ll} return:&A\rarrM\left(A?\right)=a\mapstoreturn(Justa)\\ bind:&M\left(A?\right)\rarr\left(A\rarrM\left(B?\right)\right)\rarrM\left(B?\right)=m\mapstof\mapstobindm\left(a\mapsto\begin{cases}returnNothing&ifa=Nothing\ fa'&ifa=Justa'\end{cases}\right)\\ lift:&M(A)\rarrM\left(A?\right)=m\mapstobindm(a\mapstoreturn(Justa))\end{array}
Given any monad
MA
M(A+E)
\begin{array}{ll} return:&A\rarrM(A+E)=a\mapstoreturn(valuea)\\ bind:&M(A+E)\rarr(A\rarrM(B+E))\rarrM(B+E)=m\mapstof\mapstobindm\left(a\mapsto\begin{cases}returnerre&ifa=erre\ fa'&ifa=valuea'\end{cases}\right)\\ lift:&MA\rarrM(A+E)=m\mapstobindm(a\mapstoreturn(valuea))\\ \end{array}
Given any monad
MA
E\rarrMA
\begin{array}{ll} return:&A\rarrE\rarrMA=a\mapstoe\mapstoreturna\\ bind:&(E\rarrMA)\rarr(A\rarrE\rarrMB)\rarrE\rarrMB=m\mapstok\mapstoe\mapstobind(me)(a\mapstokae)\\ lift:&MA\rarrE\rarrMA=a\mapstoe\mapstoa\\ \end{array}
Given any monad
MA
S\rarrM(A x S)
\begin{array}{ll} return:&A\rarrS\rarrM(A x S)=a\mapstos\mapstoreturn(a,s)\\ bind:&(S\rarrM(A x S))\rarr(A\rarrS\rarrM(B x S))\rarrS\rarrM(B x S)=m\mapstok\mapstos\mapstobind(ms)((a,s')\mapstokas')\\ lift:&MA\rarrS\rarrM(A x S)=m\mapstos\mapstobindm(a\mapstoreturn(a,s))\end{array}
Given any monad
MA
M(W x A)
\varepsilon
\begin{array}{ll} return:&A\rarrM(W x A)=a\mapstoreturn(\varepsilon,a)\\ bind:&M(W x A)\rarr(A\rarrM(W x B))\rarrM(W x B)=m\mapstof\mapstobindm((w,a)\mapstobind(fa)((w',b)\mapstoreturn(w*w',b)))\\ lift:&MA\rarrM(W x A)=m\mapstobindm(a\mapstoreturn(\varepsilon,a))\\ \end{array}
Given any monad
MA
(A\rarrMR)\rarrMR
\begin{array}{ll} return\colon&A\rarr\left(A\rarrMR\right)\rarrMR=a\mapstok\mapstoka\\ bind\colon&\left(\left(A\rarrMR\right)\rarrMR\right)\rarr\left(A\rarr\left(B\rarrMR\right)\rarrMR\right)\rarr\left(B\rarrMR\right)\rarrMR=c\mapstof\mapstok\mapstoc\left(a\mapstofak\right)\\ lift\colon&MA\rarr(A\rarrMR)\rarrMR=bind\end{array}
S\rarr\left(A x S\right)?
S\rarr\left(A? x S\right)