From: Jim Pryor Date: Sun, 21 Nov 2010 18:35:16 +0000 (-0500) Subject: week9 tweak X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=commitdiff_plain;h=17cc72057c692e7f28926e6646a4d63733400e49;hp=6a45c3860fc064728f0fa65fd7b2869f48f49878 week9 tweak Signed-off-by: Jim Pryor --- diff --git a/week9.mdwn b/week9.mdwn index ba99a79f..41de4762 100644 --- a/week9.mdwn +++ b/week9.mdwn @@ -376,7 +376,7 @@ It's possible to do all of this monadically, and so using a language's existing We call this a State monad. It's a lot like the Reader monad, except that with the Reader monad, we could only read from the environment. We did have the possibility of interpreting sub-expressions inside a "shifted" environment, but as you'll see, that corresponds to the "shadowing" behavior described before, not to the mutation behavior that we're trying to implement now. -With a State monad, we call our book-keeping apparatus a "state" or "store" instead of an evironment, and this time we are able to both read from it and write to it. To keep things simple, we'll work here with the simplest possible kind of store, which only holds a single value. One could also have stores that were composed of a list of values, of a length that could expand or shrink, or even more complex structures. +With a State monad, we call our book-keeping apparatus a "state" or "store" instead of an environment, and this time we are able to both read from it and write to it. To keep things simple, we'll work here with the simplest possible kind of store, which only holds a single value. One could also have stores that were composed of a list of values, of a length that could expand or shrink, or even more complex structures. Here's the implementation of the State monad, together with an implementation of the Reader monad for comparison: @@ -412,9 +412,9 @@ With the Reader monad, we also had some special-purpose operations, beyond its g This passes through the current store unaltered, and also returns a copy of the store as its value. We can use this operation like this: - some_existing_state_monad >>= fun _ -> get_state >>= (fun cur_state -> ...) + some_existing_state_monad_value >>= fun _ -> get_state >>= (fun cur_state -> ...) -The `fun _ ->` part here discards the value wrapped by `some_existing_state_monad`. We're only going to pass through, unaltered, whatever *store* is generated by that monadic value. We also wrap that store as *our own value*, which can be retrieved by further operations in the `... >>= ...` chain, such as `(fun cur_state -> ...)`. +The `fun _ ->` part here discards the value wrapped by `some_existing_state_monad_value`. We're only going to pass through, unaltered, whatever *store* is generated by that monadic value. We also wrap that store as *our own value*, which can be retrieved by further operations in the `... >>= ...` chain, such as `(fun cur_state -> ...)`. The other operation for the State monad will be to update the existing store to a new one. This operation looks like this: @@ -423,11 +423,11 @@ The other operation for the State monad will be to update the existing store to If we want to stick this in a `... >>= ...` chain, we'll need to prefix it with `fun _ ->` too, like this: - some_existing_state_monad >>= fun _ -> set_state 100 >>= ... + some_existing_state_monad_value >>= fun _ -> set_state 100 >>= ... -In this usage, we don't care what value is wrapped by `some_existing_state_monad`. We don't even care what store it generates, since we're going to replace that store with our own new store. A more complex kind of `set_state` operation might insert not just some constant value as the new store, but rather the result of applying some function to the existing store. For example, we might want to increment the current store. Here's how we could do that: +In this usage, we don't care what value is wrapped by `some_existing_state_monad_value`. We don't even care what store it generates, since we're going to replace that store with our own new store. A more complex kind of `set_state` operation might insert not just some constant value as the new store, but rather the result of applying some function to the existing store. For example, we might want to increment the current store. Here's how we could do that: - some_existing_state_monad >>= fun _ -> get_state >>= (fun cur_state -> set_state (cur_state + 1) >>= ... + some_existing_state_monad_value >>= fun _ -> get_state >>= (fun cur_state -> set_state (cur_state + 1) >>= ... We can of course define more complex functions that perform the `get_state >>= (fun cur_state -> set_state (cur_state + 1)` as a single operation.