revisions
[lambda.git] / topics / _week9_state_monad_tutorial.mdwn
index def82ba..14628f7 100644 (file)
@@ -16,7 +16,7 @@ The most lightweight way encapsulate it would be just to add a data constructor
     (* we assume that the store type has already been declared *)
     type 'a state = State of (store -> ('a * store))
 
     (* we assume that the store type has already been declared *)
     type 'a state = State of (store -> ('a * store))
 
-Then a function expecting an `'a store` will look for a value with the structure `State ...` rather than just one with the structure `...`.
+Then a function expecting an `'a state` will look for a value with the structure `State ...` rather than just one with the structure `...`.
 
 To take a `State (s -> (a,s))` and get at the `s -> (a,s)` it wraps, you use the same techniques you use to take an `Some int` and get at the `int` it wraps:
 
 
 To take a `State (s -> (a,s))` and get at the `s -> (a,s)` it wraps, you use the same techniques you use to take an `Some int` and get at the `int` it wraps:
 
@@ -38,7 +38,7 @@ with `run xx`. So you should only apply `run` when you've finished building up a
 
 Of course you can do this:
 
 
 Of course you can do this:
 
-    let xx = someMonad.(...) in
+    let xx = SomeMonad.(...) in
     let intermediate_result = SomeMonad.run xx 0 in
     let yy = SomeMonad.(xx >>= ...) in
     let final_result = SomeMonad.run yy 0 in
     let intermediate_result = SomeMonad.run xx 0 in
     let yy = SomeMonad.(xx >>= ...) in
     let final_result = SomeMonad.run yy 0 in
@@ -76,9 +76,9 @@ OK, back to our walk-through of "A State Monad Tutorial". What shall we use for
 
     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` value that is then wrapped in the monadic box.
+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.
 
 
-Here's a monadic box that encodes the operation of incrementing the store's `total` and wrapping the value that was the former `total`:
+Here's a monadic value that encodes the operation of incrementing the store's `total` and wrapping the value that was the former `total`:
 
     let increment_store : store' -> (int * store') = fun s ->
       let value = s.total in
 
     let increment_store : store' -> (int * store') = fun s ->
       let value = s.total in
@@ -99,9 +99,9 @@ Here is how you'd have to do it using our OCaml/Juli8 monad library:
     # module S = Monad.State(struct type store = store' end);;
     # let increment_store'' : 'a S.t =
         S.(get >>= fun cur ->
     # module S = Monad.State(struct type store = store' end);;
     # let increment_store'' : 'a S.t =
         S.(get >>= fun cur ->
-              let value = cur.total
-             in let s' = { total = succ cur.total; modifications = succ cur.modifications }
-                     in put s' >> mid value);;
+             let value = cur.total in
+             let s' = { total = succ cur.total; modifications = succ cur.modifications } in
+             put s' >> mid value);;
 
 Let's try it out:
 
 
 Let's try it out:
 
@@ -111,7 +111,7 @@ Let's try it out:
 
 Or if you used the OCaml/Juli8 monad library:
 
 
 Or if you used the OCaml/Juli8 monad library:
 
-    # S.(run increment_store'') s0;;
+    # S.run increment_store'' s0;;
     - : int * S.store = (42, {total = 43; modifications = 4})
 
 Great!
     - : int * S.store = (42, {total = 43; modifications = 4})
 
 Great!
@@ -120,7 +120,7 @@ Can you write a monadic value that instead of incrementing each of the `total` a
 
 What about a value that increments each of `total` and `modifications` twice? Well, you could custom-write that, as with the previous question. But we already have the tools to express it easily, using our existing `increment_store` value:
 
 
 What about a value that increments each of `total` and `modifications` twice? Well, you could custom-write that, as with the previous question. But we already have the tools to express it easily, using our existing `increment_store` value:
 
-    increment_store >>= fun value -> increment_store >> unit value
+    increment_store >>= fun value -> increment_store >> mid value
 
 That ensures that the value we get at the end is the value returned by the first application of `increment_store`, that is, the contents of the `total` field in the store before we started modifying the store at all.
 
 
 That ensures that the value we get at the end is the value returned by the first application of `increment_store`, that is, the contents of the `total` field in the store before we started modifying the store at all.
 
@@ -136,19 +136,19 @@ or, using pattern-matching on the record (you don't have to specify every field
 
 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.
 
 
 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:
+Keep in mind that the final result of a `mbind` chain doesn't have to be the same type as the starting value:
 
 
-    increment_store >>= fun value -> increment_store >> unit (string_of_int value)
+    increment_store >>= fun value -> increment_store >> mid (string_of_int value)
 
 Or:
 
 
 Or:
 
-    unit 1 >> unit "blah"
+    mid 1 >> mid "blah"
 
 The store keeps the same type throughout the computation, but the type of the wrapped value can change.
 
 
 The store keeps the same type throughout the computation, but the type of the wrapped value can change.
 
-What are the special-purpose operations that the `State_monad` module defines for us?
+What are the special-purpose operations that the `Monad.State` module defines for us?
 
 
-*    `get` is a monadic value that passes through the existing store unchanged, and also wraps that same store as its boxed value. You use it like this:
+*    `get` is a monadic value that passes through the existing store unchanged, and also wraps that same store as its boxed payload. You use it like this:
 
         ... >>= fun _ -> get >>= fun cur -> ... here we can use cur ...
 
 
         ... >>= fun _ -> get >>= fun cur -> ... here we can use cur ...
 
@@ -164,33 +164,33 @@ What are the special-purpose operations that the `State_monad` module defines fo
 
         ... >> gets (fun cur -> cur.total) >>= fun total -> ...
 
 
         ... >> gets (fun cur -> cur.total) >>= fun total -> ...
 
-    For more complex structured stores, consider using the `Ref_monad` version of the State monad in the OCaml library.
+    For more complex structured stores, consider using the `Monad.Ref` variant of the State monad in the OCaml library.
 
 *    `put new_store` replaces the existing store with `new_store`. Use it like this:
 
         ... >> put new_store >> fun () -> ...
 
 
 *    `put new_store` replaces the existing store with `new_store`. Use it like this:
 
         ... >> put new_store >> fun () -> ...
 
-    As that code snippet suggests, the boxed value after the application of `modify 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 payload after the application of `modify new_store` is just `()`. If you want to preserve the existing payload but replace the store, do this:
 
 
-        ... >>= fun value -> put new_store >> unit value >>= ...
+        ... >>= fun value -> put new_store >> mid value >>= ...
 
 
-*    Finally, `modify modifier` applies `modifier` to whatever the existing store is, and substitutes that as the new store. As with `put`, the boxed value afterwards is `()`.
+*    Finally, `modify modifier` applies `modifier` to whatever the existing store is, and substitutes that as the new store. As with `put`, the boxed payload afterwards is `()`.
 
     <!--
 
     <!--
-    Haskell calls this operation `modify`. We've called it `puts` because it seems to fit naturally with the convention of `get` vs `gets`. (See also `ask` vs `asks` in `Reader_monad`, which are also the names used in Haskell.)
+    Haskell calls this operation `modify`. We've called it `puts` because it seems to fit naturally with the convention of `get` vs `gets`. (See also `ask` vs `asks` in `Monad.Reader`, which are also the names used in Haskell.)
     -->
 
 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 })) >>
     -->
 
 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 >> unit 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 } >>
 
 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'' >> unit 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).
 
 
 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).