index c89ce6c..b15ac29 100644 (file)
@@ -42,7 +42,7 @@ Of course you can do this:
in let final_result = Monad.run v 0
in ...

-The other heavyweight way to encapsulate the type of a monad is to use records. See [here] (/translating_between_OCaml_Scheme_and_Haskell) and [here](/coroutines_and_aborts/) for some introduction to these. We don't use this design in our OCaml monad library, but the Haskell monad libraries do, and it would be good for you to get acquainted with it so that you can see how to ignore it when you come across it in Haskell-based literature. (Or you might want to learn Haskell, who knows?)
+The other heavyweight way to encapsulate the type of a monad is to use records. See [here](/translating_between_OCaml_Scheme_and_Haskell) and [here](/coroutines_and_aborts/) for some introduction to these. We don't use this design in our OCaml monad library, but the Haskell monad libraries do, and it would be good for you to get acquainted with it so that you can see how to ignore it when you come across it in Haskell-based literature. (Or you might want to learn Haskell, who knows?)

We'll illustrate this technique in OCaml code, for uniformity. See the [translation page](/translating_between_OCaml_Scheme_and_Haskell) about how this looks in Haskell.

@@ -95,19 +95,19 @@ If we wanted to work with one of the encapsulation techniques described above, w

Here is how you'd have to do it using our OCaml monad library:

# module S = State_monad(struct type store = store' end);;
# let increment_store'' : ('x,'a) S.m =
S.(get >>= fun cur ->
let value = cur.total
-                  in let s = { total = succ cur.total; modifications = succ cur.modifications }
-           in put s >> unit value);;
+                  in let s' = { total = succ cur.total; modifications = succ cur.modifications }
+           in put s' >> unit value);;

Let's try it out:

-       # let s0 = {total = 42; modifications = 3 };;
+       # let s0 = { total = 42; modifications = 3 };;
# increment_store s0;;
-       - : int * store' = (42, {total = 43; modifications = 4})
+       - : int * store' = (42, {total = 43; modifications = 4})

Or if you used the OCaml monad library:

@@ -126,10 +126,15 @@ That ensures that the value we get at the end is the value returned by the first

You should start to see here how chaining monadic values together gives us a kind of programming language. Of course, it's a cumbersome programming language. It'd be much easier to write, directly in OCaml:

-       let { total = value } = s0
+       let value = s0.total
in (value, { total = s0.total + 2; modifications = s0.modifications + 2};;

-But **the point of learning how to do this monadically** is that (1) monads show us how to embed more sophisticated programming techniques, such as imperative state and continuations, into frameworks that don't natively possess them (such as the set-theoretic metalanguage of Groenendijk, Stockhof and Veltman's paper); and (2) monads are delicious.
+or, using pattern-matching on the record (you don't have to specify every field in the record):
+
+       let { total = value; _ } = s0
+       in (value, { total = s0.total + 2; modifications = s0.modifications + 2};;
+
+But **the point of learning how to do this monadically** is that (1) monads show us how to embed more sophisticated programming techniques, such as imperative state and continuations, into frameworks that don't natively possess them (such as the set-theoretic metalanguage of Groenendijk, Stokhof and Veltman's paper); (2) becoming familiar with monads will enable you to see patterns you'd otherwise miss, and implement some seemingly complex computations using the same simple patterns (same-fringe is an example); and finally, of course (3) monads are delicious.

Keep in mind that the final result of a bind chain doesn't have to be the same type as the starting value:

@@ -165,7 +170,7 @@ What are the special-purpose operations that the `State_monad` module defines fo

... >> put new_store >> fun () -> ...

-       As that code snippets suggests, the boxed value after the application of `puts new_store` is just `()`. If you want to preserve the existing boxed value but replace the store, do this:
+       As that code snippet suggests, the boxed value after the application of `puts new_store` is just `()`. If you want to preserve the existing boxed value but replace the store, do this:

... >>= fun value -> put new_store >> unit value >>= ...