Content deleted Content added
m link exception handling using Find link |
m reformatted math environments to get rid of page-breaking expressions |
||
(13 intermediate revisions by 10 users not shown) | |||
Line 1:
{{One source|date=November 2023}}
{{Wikibooks|Haskell|Monad transformers}}▼
In [[functional programming]], a '''monad transformer''' is a type constructor which takes a [[monads in functional programming|monad]] as an argument and returns a monad as a result.
Monad transformers can be used to compose features encapsulated by monads
==
A monad transformer consists of:
# A type constructor <code>t</code> of [[kind (type theory)|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_(functional_programming)#Monad_laws|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
|
| pages =
| publisher = ACM
| year = 1995
Line 23 ⟶ 21:
| 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>
==
===
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}
*<math>\mathrm{return}: A \rarr \mathrm{M} \left( A^{?} \right) = a \mapsto \mathrm{return} (\mathrm{Just}\,a)</math>▼
& 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) & m \mapsto \mathrm{bind} \, m \, (a \mapsto \mathrm{return} (\mathrm{Just} \, a)) \end{array}</math> Given any monad <math>\mathrm{M} \, A</math>, the
:<math>\begin{array}{ll}
& a \mapsto \mathrm{return} (\mathrm{value}\,a) \\
& 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) \\
▲
\end{array}</math>
Given any monad <math>\mathrm{M} \, A</math>, the reader monad transformer <math>E \rarr \mathrm{M}\,A</math> (where
:<math>\begin{array}{ll}
& a \mapsto e \mapsto \mathrm{return} \, a \\
& 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>
Given any monad <math>\mathrm{M} \, A</math>, the
:<math>\begin{array}{ll}
& a \mapsto s \mapsto \mathrm{return} \, (a, s) \\
& m \mapsto k \mapsto s \mapsto \mathrm{bind} \, (m \, s) \,((a, s') \mapsto k \, a \, s') \\
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{lift}: & \mathrm{M} \, A \rarr \mathrm{M}(W \times A)\\
\end{array}</math>
===
Given any monad <math>\mathrm{M} \, A</math>, the
:<math>\begin{array}{ll}
▲*<math>\mathrm{return}: A \rarr \mathrm{M} (A + E) = a \mapsto \mathrm{return} (\mathrm{value}\,a)</math>
& a \mapsto k \mapsto k \, a \\
▲*<math>\mathrm{lift}: \mathrm{M} \, A \rarr \mathrm{M} (A + E) = m \mapsto \mathrm{bind} \, m \, (a \mapsto \mathrm{return} (\mathrm{value} \, a))</math>
& c \mapsto f \mapsto k \mapsto c \, \left( a \mapsto f \, a \, k \right) \\
& \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).▼
▲=== The reader monad transformer ===
▲Given any monad <math>\mathrm{M} \, A</math>, the reader monad transformer <math>E \rarr \mathrm{M}\,A</math> (where <math>E</math> is the environment type) is defined by:
▲*<math>\mathrm{return}: A \rarr E \rarr \mathrm{M} \, A = a \mapsto e \mapsto \mathrm{return} \, a</math>
▲*<math>\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)</math>
▲*<math>\mathrm{lift}: \mathrm{M} \, A \rarr E \rarr \mathrm{M} \, A = a \mapsto e \mapsto a</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 <math>S</math> is the state type) is defined by:
▲*<math>\mathrm{return}: A \rarr S \rarr \mathrm{M} (A \times S) = a \mapsto s \mapsto \mathrm{return} \, (a, s)</math>
▲*<math>\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')</math>
▲*<math>\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))</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 <math>W</math> is endowed with a [[monoid]] operation <math>*</math> with identity element <math>\varepsilon</math>) is defined by:
▲*<math>\mathrm{return}: A \rarr \mathrm{M} (W \times A) = a \mapsto \mathrm{return} \, (\varepsilon, a)</math>
▲*<math>\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)))</math>
▲*<math>\mathrm{lift}: \mathrm{M} \, A \rarr \mathrm{M}(W \times A) = m \mapsto \mathrm{bind} \, m \, (a \mapsto \mathrm{return} \, (\varepsilon, a))</math>
▲=== The continuation monad transformer ===
▲*<math>\mathrm{return} \colon A \rarr \left( A \rarr \mathrm{M} \, R \right) \rarr \mathrm{M} \, R = a \mapsto k \mapsto k \, a</math>
▲*<math>\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</math><math>= c \mapsto f \mapsto k \mapsto c \, \left( a \mapsto f \, a \, k \right)</math>
▲*<math>\mathrm{lift}: \mathrm{M} \, A \rarr (A \rarr \mathrm{M} \, R) \rarr \mathrm{M} \, R = \mathrm{bind}</math>
▲Note that monad transformations are 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}}
==
▲{{Wikibooks|Haskell|Monad transformers}}
*
{{Expand section|date=May 2008}}
|