From de7a141b23248017c50e05b407e7b5550eedcb3c Mon Sep 17 00:00:00 2001 From: Jim Pryor Date: Sun, 12 Dec 2010 21:31:19 -0500 Subject: [PATCH 1/1] add elevate laws Signed-off-by: Jim Pryor --- monad_transformers.mdwn | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/monad_transformers.mdwn b/monad_transformers.mdwn index 0e9d9284..a1e6d45e 100644 --- a/monad_transformers.mdwn +++ b/monad_transformers.mdwn @@ -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. -- 2.11.0