You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jan 5, 2025. It is now read-only.
Copy file name to clipboardExpand all lines: functional-programming-lean/src/monad-transformers/order.md
+91-1
Original file line number
Diff line number
Diff line change
@@ -1,20 +1,41 @@
1
-
<!-- # Ordering Monad Transformers -->
1
+
<!--
2
+
# Ordering Monad Transformers
3
+
-->
2
4
3
5
# モナド変換子の順序
4
6
7
+
<!--
5
8
When composing a monad from a stack of monad transformers, it's important to be aware that the order in which the monad transformers are layered matters.
6
9
Different orderings of the same set of transformers result in different monads.
This version of `countLetters` is just like the previous version, except it uses type classes to describe the set of available effects instead of providing a concrete monad:
It might be tempting to think that `M2` is superior to `M1` because it provides more information that might be useful when debugging.
53
89
The same program might compute _different_ answers in `M1` than it does in `M2`, and there's no principled reason to say that one of these answers is necessarily better than the other.
54
90
This can be seen by adding a step to the program that handles exceptions:
In the jargon of functional programming, two monad transformers are said to _commute_ if they can be re-ordered without the meaning of the program changing.
100
164
The fact that the result of the program can differ when `StateT` and `ExceptT` are reordered means that state and exceptions do not commute.
101
165
In general, monad transformers should not be expected to commute.
Even though not all monad transformers commute, some do.
104
172
For example, two uses of `StateT` can be re-ordered.
105
173
Expanding the definitions in `{{#example_in Examples/MonadTransformers/Defs.lean StateTDoubleA}}` yields the type `{{#example_out Examples/MonadTransformers/Defs.lean StateTDoubleA}}`, and `{{#example_in Examples/MonadTransformers/Defs.lean StateTDoubleB}}` yields `{{#example_out Examples/MonadTransformers/Defs.lean StateTDoubleB}}`.
106
174
In other words, the differences between them are that they nest the `σ` and `σ'` types in different places in the return type, and they accept their arguments in a different order.
107
175
Any client code will still need to provide the same inputs, and it will still receive the same outputs.
Most programming languages that have both mutable state and exceptions work like `M2`.
110
182
In those languages, state that _should_ be rolled back when an exception is thrown is difficult to express, and it usually needs to be simulated in a manner that looks much like the passing of explicit state values in `M1`.
111
183
Monad transformers grant the freedom to choose an interpretation of effect ordering that works for the problem at hand, with both choices being equally easy to program with.
112
184
However, they also require care to be taken in the choice of ordering of transformers.
113
185
With great expressive power comes the responsibility to check that what's being expressed is what is intended, and the type signature of `countWithFallback` is probably more polymorphic than it should be.
* Construct a monad transformer `ManyT` based on the definition of `Many`, with a suitable `Alternative` instance. Check that it satisfies the `Monad` contract.
* Does `ManyT` commute with `StateT`? If so, check your answer by expanding definitions and reasoning about the resulting types. If not, write a program in `ManyT (StateT σ Id)` and a program in `StateT σ (ManyT Id)`. Each program should be one that makes more sense for the given ordering of monad transformers.
0 commit comments