X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=topics%2Fweek9_state_monad_tutorial.mdwn;h=13310a1a85f2d9c9bd4c557e3dc9db164b34154d;hp=14628f7b1e043988ea19dc8219e13007b92cd8a3;hb=41ff76222e4686a052961903d371afe635fe4f58;hpb=d4db8b488a6fc9f4413368daf88e573da19961a9
diff --git a/topics/week9_state_monad_tutorial.mdwn b/topics/week9_state_monad_tutorial.mdwn
index 14628f7b..13310a1a 100644
--- a/topics/week9_state_monad_tutorial.mdwn
+++ b/topics/week9_state_monad_tutorial.mdwn
@@ -74,7 +74,7 @@ The main benefit of these techniques is that it gives you better type-checking:
OK, back to our walk-through of "A State Monad Tutorial". What shall we use for a store? Instead of a plain `int`, let's suppose our store is a structure of two values: a running total, and a count of how many times the store has been modified. We'll implement this with a record. Hence:
- type store' = { total : int; modifications: int };;
+ type store' = { total : int; modifications: int }
State monads employing this store will then have *three* salient values at any point in the computation: the `total` and `modifications` field in the store, and also the `'a` payload that is currently wrapped in the monadic box.
@@ -95,7 +95,7 @@ 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/Juli8 monad library:
- # (* have Juli8 loaded, as explained elsewhere *)
+ (* have Juli8 loaded, as explained elsewhere *)
# module S = Monad.State(struct type store = store' end);;
# let increment_store'' : 'a S.t =
S.(get >>= fun cur ->
@@ -127,12 +127,12 @@ 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 value = s0.total
- in (value, { total = s0.total + 2; modifications = s0.modifications + 2};;
+ in (value, { total = s0.total + 2; modifications = s0.modifications + 2})
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};;
+ 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.
@@ -184,13 +184,13 @@ Here's an example from "A State Monad Tutorial":
increment_store >> get >>= fun cur ->
State (fun s -> ((), { total = s.total / 2; modifications = succ s.modifications })) >>
- increment_store >> mid cur.total
+ increment_store >> mid cur.total
Or, as you'd have to write it using our OCaml monad library:
increment_store'' >> get >>= fun cur ->
put { total = cur.total / 2; modifications = succ cur.modifications } >>
- increment_store'' >> mid cur.total
+ increment_store'' >> mid cur.total
The last topic covered in "A State Monad Tutorial" is the use of do-notation to work with monads in Haskell. We discuss that on our [translation page](/translating_between_OCaml_Scheme_and_Haskell).