| 0 -> None
| _ -> Some (x / y);;
-(*
+(* an Ocaml session could continue with OCaml's response:
val safe_div : int -> int -> int option = fun
# safe_div 12 2;;
- : int option = Some 6
| Some 0 -> None
| Some y -> Some (x / y));;
-(*
+(* an Ocaml session could continue with OCaml's response:
val safe_div2 : int option -> int option -> int option = <fun>
# safe_div2 (Some 12) (Some 2);;
- : int option = Some 6
| (_, None) -> None
| (Some x, Some y) -> Some (x + y);;
-(*
+(* an Ocaml session could continue with OCaml's response:
val safe_add : int option -> int option -> int option = <fun>
# safe_add (Some 12) (Some 4);;
- : int option = Some 16
Let's see our new functions in action:
<pre>
-(*
+(* an Ocaml session could continue with OCaml's response:
# safe_div3 (safe_div3 (Some 12) (Some 2)) (Some 3);;
- : int option = Some 2
# safe_div3 (safe_div3 (Some 12) (Some 0)) (Some 3);;
not surprisingly, these refinements will require some more
sophisticated techniques than the super-simple Option/Maybe monad.)
+
+## Scratch, more... ##
+
+We've just seen a way to separate thinking about error conditions
+(such as trying to divide by zero) from thinking about normal
+arithmetic computations. We did this by making use of the `option`
+type: in each place where we had something of type `int`, we put
+instead something of type `int option`, which is a sum type consisting
+either of one choice with an `int` payload, or else a `None` choice
+which we interpret as signaling that something has gone wrong.
+
+The goal was to make normal computing as convenient as possible: when
+we're adding or multiplying, we don't have to worry about generating
+any new errors, so we would rather not think about the difference
+between `int`s and `int option`s.