revisions
authorjim <jim@web>
Mon, 6 Apr 2015 21:56:31 +0000 (17:56 -0400)
committerLinux User <ikiwiki@localhost.members.linode.com>
Mon, 6 Apr 2015 21:56:31 +0000 (17:56 -0400)
topics/_week9_state_monad_tutorial.mdwn

index e586ae0..14628f7 100644 (file)
@@ -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 ->
-              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:
 
@@ -111,7 +111,7 @@ Let's try it out:
 
 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!
@@ -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:
 
-    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.
 
@@ -136,17 +136,17 @@ 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.
 
-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:
 
-    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.
 
-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 payload. You use it like this:
 
@@ -164,7 +164,7 @@ What are the special-purpose operations that the `State_monad` module defines fo
 
         ... >> 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:
 
@@ -172,25 +172,25 @@ What are the special-purpose operations that the `State_monad` module defines fo
 
     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 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 })) >>
-    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 } >>
-    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).