{{One source|date=November 2023}} 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).
==Definition== A monad transformer consists of: # A type constructor <code>t</code> of kind <code>(* -> *) -> * -> *</code> # Monad operations <code>return</code> and <code>bind</code> (or an equivalent formulation) for all <code>t m</code> where <code>m</code> is a monad, satisfying the monad laws # An additional operation, <code>lift :: m a -> t m a</code>, satisfying the following laws:<ref name="modular-interpreters"> {{cite conference | first = Sheng | last = Liang |author2=Hudak, Paul |author3=Jones, Mark | title = Monad transformers and modular interpreters | book-title = Proceedings of the 22nd ACM SIGPLAN-SIGACT symposium on Principles of programming languages | pages = 333–343 | publisher = ACM | year = 1995 | location = New York, NY | url = http://portal.acm.org/citation.cfm?id=199528 | format = PDF | doi = 10.1145/199448.199528 | doi-access = free }} </ref> (the notation <code>`bind`</code> below indicates infix application): ## <code>lift . return = return</code> ## <code>lift (m `bind` k) = (lift m) `bind` (lift . k)</code>
==Examples== ===The option monad transformer=== Given any monad <math>\mathrm{M} \, A</math>, the option monad transformer <math>\mathrm{M} \left( A^{?} \right)</math> (where <math>A^{?}</math> denotes the option type) is defined by: :<math>\begin{array}{ll} \mathrm{return}: & A \rarr \mathrm{M} \left( A^{?} \right)\\ & a \mapsto \mathrm{return} (\mathrm{Just}\,a) \\ \mathrm{bind}: & \mathrm{M} \left( A^{?} \right) \rarr \left( A \rarr \mathrm{M} \left( B^{?} \right) \right) \rarr \mathrm{M} \left( B^{?} \right)\\ & m \mapsto f \mapsto \mathrm{bind} \, m \, \left(a \mapsto \begin{cases} \mbox{return Nothing} & \mbox{if } a = \mathrm{Nothing}\\ f \, a' & \mbox{if } a = \mathrm{Just} \, a' \end{cases} \right) \\ \mathrm{lift}: & \mathrm{M} (A) \rarr \mathrm{M} \left( A^{?} \right)\\ & m \mapsto \mathrm{bind} \, m \, (a \mapsto \mathrm{return} (\mathrm{Just} \, a)) \end{array}</math> ===The exception monad transformer=== Given any monad <math>\mathrm{M} \, A</math>, the exception monad transformer <math>\mathrm{M} (A + E)</math> (where {{mvar|E}} is the type of exceptions) is defined by: :<math>\begin{array}{ll} \mathrm{return}: & A \rarr \mathrm{M} (A + E)\\ & a \mapsto \mathrm{return} (\mathrm{value}\,a) \\ \mathrm{bind}: & \mathrm{M} (A + E) \rarr (A \rarr \mathrm{M} (B + E)) \rarr \mathrm{M} (B + E)\\ & m \mapsto f \mapsto \mathrm{bind} \, m \,\left( a \mapsto \begin{cases} \mbox{return err } e & \mbox{if } a = \mathrm{err} \, e\\ f \, a' & \mbox{if } a = \mathrm{value} \, a' \end{cases} \right) \\ \mathrm{lift}: & \mathrm{M} \, A \rarr \mathrm{M} (A + E)\\ & m \mapsto \mathrm{bind} \, m \, (a \mapsto \mathrm{return} (\mathrm{value} \, a)) \\ \end{array}</math> ===The reader monad transformer=== Given any monad <math>\mathrm{M} \, A</math>, the reader monad transformer <math>E \rarr \mathrm{M}\,A</math> (where {{mvar|E}} is the environment type) is defined by: :<math>\begin{array}{ll} \mathrm{return}: & A \rarr E \rarr \mathrm{M} \, A\\ & a \mapsto e \mapsto \mathrm{return} \, a \\ \mathrm{bind}: & (E \rarr \mathrm{M} \, A) \rarr (A \rarr E \rarr \mathrm{M}\,B) \rarr E \rarr \mathrm{M}\,B\\ & m \mapsto k \mapsto e \mapsto \mathrm{bind} \, (m \, e) \,( a \mapsto k \, a \, e) \\ \mathrm{lift}: & \mathrm{M} \, A \rarr E \rarr \mathrm{M} \, A\\ & a \mapsto e \mapsto a \\ \end{array}</math> ===The state monad transformer=== Given any monad <math>\mathrm{M} \, A</math>, the state monad transformer <math>S \rarr \mathrm{M}(A \times S)</math> (where {{mvar|S}} is the state type) is defined by: :<math>\begin{array}{ll} \mathrm{return}: & A \rarr S \rarr \mathrm{M} (A \times S)\\ & a \mapsto s \mapsto \mathrm{return} \, (a, s) \\ \mathrm{bind}: & (S \rarr \mathrm{M}(A \times S)) \rarr (A \rarr S \rarr \mathrm{M}(B \times S)) \rarr S \rarr \mathrm{M}(B \times S)\\ & m \mapsto k \mapsto s \mapsto \mathrm{bind} \, (m \, s) \,((a, s') \mapsto k \, a \, s') \\ \mathrm{lift}: & \mathrm{M} \, A \rarr S \rarr \mathrm{M}(A \times S)\\ & m \mapsto s \mapsto \mathrm{bind} \, m \, (a \mapsto \mathrm{return} \, (a, s)) \end{array}</math> ===The writer monad transformer=== Given any monad <math>\mathrm{M} \, A</math>, the writer monad transformer <math>\mathrm{M}(W \times A)</math> (where {{mvar|W}} is endowed with a monoid operation {{math|∗}} with identity element <math>\varepsilon</math>) is defined by: :<math>\begin{array}{ll} \mathrm{return}: & A \rarr \mathrm{M} (W \times A)\\ & a \mapsto \mathrm{return} \, (\varepsilon, a) \\ \mathrm{bind}: & \mathrm{M}(W \times A) \rarr (A \rarr \mathrm{M}(W \times B)) \rarr \mathrm{M}(W \times B)\\ & m \mapsto f \mapsto \mathrm{bind} \, m \,((w, a) \mapsto \mathrm{bind} \, (f \, a) \, ((w', b) \mapsto \mathrm{return} \, (w * w', b))) \\ \mathrm{lift}: & \mathrm{M} \, A \rarr \mathrm{M}(W \times A)\\ & m \mapsto \mathrm{bind} \, m \, (a \mapsto \mathrm{return} \, (\varepsilon, a)) \\ \end{array}</math>
===The continuation monad transformer=== Given any monad <math>\mathrm{M} \, A</math>, the continuation monad transformer maps an arbitrary type {{mvar|R}} into functions of type <math>(A \rarr \mathrm{M} \, R) \rarr \mathrm{M} \, R</math>, where {{mvar|R}} is the result type of the continuation. It is defined by: :<math>\begin{array}{ll} \mathrm{return} \colon & A \rarr \left( A \rarr \mathrm{M} \, R \right) \rarr \mathrm{M} \, R\\ & a \mapsto k \mapsto k \, a \\ \mathrm{bind} \colon & \left( \left( A \rarr \mathrm{M} \, R \right) \rarr \mathrm{M} \, R \right) \rarr \left( A \rarr \left( B \rarr \mathrm{M} \, R \right) \rarr \mathrm{M} \, R \right) \rarr \left( B \rarr \mathrm{M} \, R \right) \rarr \mathrm{M} \, R\\ & c \mapsto f \mapsto k \mapsto c \, \left( a \mapsto f \, a \, k \right) \\ \mathrm{lift} \colon & \mathrm{M} \, A \rarr (A \rarr \mathrm{M} \, R) \rarr \mathrm{M} \, R\\ & \mathrm{bind} \end{array}</math> Note that monad transformations are usually not commutative: for instance, applying the state transformer to the option monad yields a type <math>S \rarr \left(A \times S \right)^{?}</math> (a computation which may fail and yield no final state), whereas the converse transformation has type <math>S \rarr \left(A^{?} \times S \right)</math> (a computation which yields a final state and an optional return value).
==See also== *Monads in functional programming
==References== {{Reflist}}
==External links== {{Wikibooks|Haskell|Monad transformers}} *[http://conway.rutgers.edu/~ccshan/wiki/blog/posts/Monad_transformers/ A blog post briefly reviewing some of the literature on monad transformers and related concepts, with a focus on categorical-theoretic treatment] {{Expand section|date=May 2008}}
Category:Functional programming