X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=week7.mdwn;h=7544425c4bbcca2c3a1b72cf0cf088199a18586f;hp=8fb3a3cbc1cf3d3832b97aa2703c864aa62e38ec;hb=d9e25980d9b3e62e89ab731ed5fbc33126df57e6;hpb=b3fcd749ac69521ca598d3846043bb7aff1ac290;ds=sidebyside diff --git a/week7.mdwn b/week7.mdwn index 8fb3a3cb..7544425c 100644 --- a/week7.mdwn +++ b/week7.mdwn @@ -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, @@ -461,10 +466,12 @@ Theory](/advanced_topics/monads_in_category_theory). See also: -* [Haskell Wikibook on Monad Laws](http://www.haskell.org/haskellwiki/Monad_Laws). -* [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) +* [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: