tweak monads-lib, start T2
[lambda.git] / week7.mdwn
index 961b024..7544425 100644 (file)
@@ -313,7 +313,7 @@ singing box (the end result of evaluting `u`) and bind the variable
 `x`".
 
 (Note that the above "do" notation comes from Haskell. We're mentioning it here
-because you're likely to see it when reading about monads. It won't work in
+because you're likely to see it when reading about monads. (See our page on [[Translating between OCaml Scheme and Haskell]].) It won't work in
 OCaml. In fact, the `<-` symbol already means something different in OCaml,
 having to do with mutable record fields. We'll be discussing mutation someday
 soon.)
@@ -402,11 +402,16 @@ them from hurting the people that use them or themselves.
 
 *      **Associativity: bind obeys a kind of associativity**. Like this:
 
-               (u >>= f) >>= g == u >>= (fun x -> f x >>= g)
+               (u >>= f) >>= g  ==  u >>= (fun x -> f x >>= g)
 
        If you don't understand why the lambda form is necessary (the
        "fun x -> ..." part), you need to look again at the type of `bind`.
 
+       Wadler and others try to make this look nicer by phrasing it like this,
+       where U, V, and W are schematic for any expressions with the relevant monadic type:
+
+               (U >>= fun x -> V) >>= fun y -> W  ==  U >>= fun x -> (V >>= fun y -> W)
+
        Some examples of associativity in the Option monad (bear in
        mind that in the Ocaml implementation of integer division, 2/3
        evaluates to zero, throwing away the remainder):
@@ -426,15 +431,15 @@ them from hurting the people that use them or themselves.
                # Some 3 >>= (fun x -> divide 2 x >>= divide 6);;
                - : int option = None
 
-Of course, associativity must hold for *arbitrary* functions of
-type `'a -> 'b m`, where `m` is the monad type.  It's easy to
-convince yourself that the `bind` operation for the Option monad
-obeys associativity by dividing the inputs into cases: if `u`
-matches `None`, both computations will result in `None`; if
-`u` matches `Some x`, and `f x` evalutes to `None`, then both
-computations will again result in `None`; and if the value of
-`f x` matches `Some y`, then both computations will evaluate
-to `g y`.
+       Of course, associativity must hold for *arbitrary* functions of
+       type `'a -> 'b m`, where `m` is the monad type.  It's easy to
+       convince yourself that the `bind` operation for the Option monad
+       obeys associativity by dividing the inputs into cases: if `u`
+       matches `None`, both computations will result in `None`; if
+       `u` matches `Some x`, and `f x` evalutes to `None`, then both
+       computations will again result in `None`; and if the value of
+       `f x` matches `Some y`, then both computations will evaluate
+       to `g y`.
 
 *      **Right identity: unit is a right identity for bind.**  That is, 
        `u >>= unit == u` for all monad objects `u`.  For instance,
@@ -458,7 +463,16 @@ arguments of a monoid operation) the two arguments of the bind are of
 different types.  But it's possible to make the connection between
 monads and monoids much closer. This is discussed in [Monads in Category
 Theory](/advanced_topics/monads_in_category_theory).
-See also <http://www.haskell.org/haskellwiki/Monad_Laws>.
+
+See also:
+
+*      [Haskell wikibook on Monad Laws](http://www.haskell.org/haskellwiki/Monad_Laws).
+*      [Yet Another Haskell Tutorial on Monad Laws](http://en.wikibooks.org/wiki/Haskell/YAHT/Monads#Definition)
+*      [Haskell wikibook on Understanding Monads](http://en.wikibooks.org/wiki/Haskell/Understanding_monads)
+*      [Haskell wikibook on Advanced Monads](http://en.wikibooks.org/wiki/Haskell/Advanced_monads)
+*      [Haskell wikibook on do-notation](http://en.wikibooks.org/wiki/Haskell/do_Notation)
+*      [Yet Another Haskell Tutorial on do-notation](http://en.wikibooks.org/wiki/Haskell/YAHT/Monads#Do_Notation)
+
 
 Here are some papers that introduced monads into functional programming: