manip trees tweak
[lambda.git] / monad_transformers.mdwn
index 9f26d61..a1e6d45 100644 (file)
@@ -116,6 +116,10 @@ Then if you want to use an `S`-specific monad like `puts succ` inside `MS`, you'
 
        # MS.(...elevate (S.puts succ) ...)
 
+Each monad transformer's `elevate` function will be defined differently. They have to obey the following laws:
+
+*      `Outer.elevate (Inner.unit a) <~~> Outer.unit a`
+*      `Outer.elevate (Inner.bind u f) <~~> Outer.bind (Outer.elevate u) (fun a -> Outer.elevate (f a))`
 
 We said that when T encloses M, you can rely on T's interface to be most exposed. That is intuitive. What you cannot also assume is that the implementing type has a Tish structure surrounding an Mish structure. Often it will be reverse: a ListT(Maybe) is implemented by a `'a list option`, not by an `'a option list`. Until you've tried to write the code to a monadic transformer library yourself, this will probably remain counter-intuitive. But you don't need to concern yourself with it in practise. Think of what you have as a ListT(Maybe); don't worry about whether the underlying implementation is as an `'a list option` or an `'a option list` or as something more complicated.
 
@@ -156,7 +160,7 @@ When Maybe is on the inside, on the other hand, a failure means the whole comput
        Exception: Failure "bye".
 -->
 
-Here's an example wrapping List around Maybe, and vice versa:
+Here's an example wrapping Maybe around List, and vice versa:
 
        # module LM = List_monad.T(Maybe_monad);;
        # module ML = Maybe_monad.T(List_monad);;