X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=week7.mdwn;h=a05d2212b34312641baa6ba6972246e039f4c5cc;hp=65d528c45b0f13bf068fc31df047c9578f75ee6d;hb=3ef22cae11ec60126584496a6923b967510e70ad;hpb=e8a135f7bc1a0aa4118703baa78ec8d2ea9db490 diff --git a/week7.mdwn b/week7.mdwn index 65d528c4..a05d2212 100644 --- a/week7.mdwn +++ b/week7.mdwn @@ -58,12 +58,11 @@ operations. So we have to jack up the types of the inputs:
let div' (u:int option) (v:int option) = - match v with + match u with None -> None - | Some 0 -> None - | Some y -> (match u with - None -> None - | Some x -> Some (x / y));; + | Some x -> (match v with + Some 0 -> None + | Some y -> Some (x / y));; (* val div' : int option -> int option -> int option =@@ -237,7 +236,7 @@ that provides at least the following three elements: most straightforward way to lift an ordinary value into a monadic value of the monadic type in question. -* Thirdly, an operation that's often called `bind`. This is another +* Thirdly, an operation that's often called `bind`. As we said before, this is another unfortunate name: this operation is only very loosely connected to what linguists usually mean by "binding." In our option/maybe monad, the bind operation is: @@ -366,7 +365,7 @@ Just like good robots, monads must obey three laws designed to prevent them from hurting the people that use them or themselves. * **Left identity: unit is a left identity for the bind operation.** - That is, for all `f:'a -> 'a m`, where `'a m` is a monadic + That is, for all `f:'a -> 'b m`, where `'b m` is a monadic type, we have `(unit x) >>= f == f x`. For instance, `unit` is itself a function of type `'a -> 'a m`, so we can use it for `f`: @@ -379,14 +378,15 @@ them from hurting the people that use them or themselves. function to be defined (in this case, the name of the function is `>>=`, pronounced "bind") is an infix operator, so we write `u >>= f` or equivalently `( >>= ) u f` instead of `>>= u - f`. Now, for a less trivial instance of a function from `int`s - to `int option`s: + f`. # unit 2;; - : int option = Some 2 # unit 2 >>= unit;; - : int option = Some 2 + Now, for a less trivial instance of a function from `int`s to `int option`s: + # let divide x y = if 0 = y then None else Some (x/y);; val divide : int -> int -> int option = # divide 6 2;; @@ -404,8 +404,8 @@ them from hurting the people that use them or themselves. (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`. + 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`. Some examples of associativity in the option monad (bear in mind that in the Ocaml implementation of integer division, 2/3 @@ -427,7 +427,7 @@ them from hurting the people that use them or themselves. - : int option = None Of course, associativity must hold for *arbitrary* functions of -type `'a -> 'a m`, where `m` is the monad type. It's easy to +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 @@ -583,7 +583,7 @@ Continuation monad. But first, we'll look at several linguistic applications for monads, based on what's called the *Reader monad*. -##[[Reader monad]]## +##[[Reader monad for Variable Binding]]## -##[[Intensionality monad]]## +##[[Reader monad for Intensionality]]##