+sophisticated techniques than the super-simple Option/Maybe Monad.
+
+To illustrate some of the polymorphism, here's how we could `map1` the `is_even` function:
+
+ # let is_even x = (x mod 2 = 0);;
+ val is_even : int -> bool = <fun>
+ # let map (g : 'a -> 'b) (u : 'a option) = u >>= fun x -> Some (g x);;
+ val map : ('a -> 'b) -> 'a option -> 'b option = <fun>
+ # map (is_even);;
+ - : int option -> bool option = <fun>
+
+Wherever we have a well-defined monad, we can define the `mapN` operations for them in terms
+of their `>>=` and `mid`. The general pattern is:
+
+ mapN (g : 'a1 -> ... 'an -> 'result) (u1 : 'a1 option) ... (un : 'an option) : 'result option =
+ u1 >>= (fun x1 -> ... un >>= (fun xn -> mid (g x1 ... xn)) ...)
+
+Our above definitions of `map` and `mapN` were of this form, except we just
+explicitly supplied the definition of `mid` for the Option/Maybe monad (namely, in OCamlese, the constructor `Some`).
+If you substitute in the definition of `>>=`, you can see these are equivalent to:
+
+ map (g : 'a -> 'b) (u : 'a option) =
+ match u with
+ | None -> None
+ | Some x -> Some (g x)
+
+ map2 (g : 'a -> 'b -> 'c) (u : 'a option) (v : 'b option) =
+ match u with
+ | None -> None
+ | Some x ->
+ (match v with
+ | None -> None
+ | Some y -> Some (g x y));;