X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=towards_monads.mdwn;h=3671d2730cf38bb5639032ce7a25920787ff53d8;hp=223c592bc128b77b34c94de0db6420690b478fd5;hb=34c70399625b1a258682e542622d3c26d3b3795a;hpb=93d67277339f0aed8184a14bbc35ec5060a0c031 diff --git a/towards_monads.mdwn b/towards_monads.mdwn index 223c592b..3671d273 100644 --- a/towards_monads.mdwn +++ b/towards_monads.mdwn @@ -1,7 +1,7 @@ Dividing by zero ---------------- -Integer division operation presupposes that its second argument +Integer division presupposes that its second argument (the divisor) is not zero, upon pain of presupposition failure. Here's what my OCaml interpreter says: @@ -10,7 +10,7 @@ Here's what my OCaml interpreter says: So we want to explicitly allow for the possibility that division will return something other than a number. -We'll use OCaml's option type, which works like this: +We'll use OCaml's `option` type, which works like this: # type 'a option = None | Some of 'a;; # None;; @@ -19,12 +19,13 @@ We'll use OCaml's option type, which works like this: - : int option = Some 3 So if a division is normal, we return some number, but if the divisor is -zero, we return None. As a mnemonic aid, we'll append a `'` to the end of our new divide function. +zero, we return `None`. As a mnemonic aid, we'll append a `'` to the end of our new divide function.
let div' (x:int) (y:int) = - match y with 0 -> None | - _ -> Some (x / y);; + match y with + 0 -> None + | _ -> Some (x / y);; (* val div' : int -> int -> int option = fun @@ -48,10 +49,12 @@ operations. So we have to jack up the types of the inputs:let div' (x:int option) (y:int option) = - match y with None -> None | - Some 0 -> None | - Some n -> (match x with None -> None | - Some m -> Some (m / n));; + match y with + None -> None + | Some 0 -> None + | Some n -> (match x with + None -> None + | Some m -> Some (m / n));; (* val div' : int option -> int option -> int option =@@ -72,10 +75,11 @@ built-in tuple type: let div' (x:int option) (y:int option) = - match (x, y) with (None, _) -> None | - (_, None) -> None | - (_, Some 0) -> None | - (Some m, Some n) -> Some (m / n);; + match (x, y) with + (None, _) -> None + | (_, None) -> None + | (_, Some 0) -> None + | (Some m, Some n) -> Some (m / n);;So far so good. But what if we want to combine division with @@ -85,9 +89,10 @@ presupposition failure:let add' (x:int option) (y:int option) = - match (x, y) with (None, _) -> None | - (_, None) -> None | - (Some m, Some n) -> Some (m + n);; + match (x, y) with + (None, _) -> None + | (_, None) -> None + | (Some m, Some n) -> Some (m + n);; (* val add' : int option -> int option -> int option =@@ -108,8 +113,9 @@ well chosen to resonate with linguists, but what can you do). To continue our mn let bind' (x: int option) (f: int -> (int option)) = - match x with None -> None | - Some n -> f n;; + match x with + None -> None + | Some n -> f n;; let add' (x: int option) (y: int option) = bind' x (fun x -> bind' y (fun y -> Some (x + y)));;