X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=list_monad_as_continuation_monad.mdwn;h=53bbde1ae713f9f195278edee68f068c60e1cacc;hp=438e2a8076ea0e5d0ad7e6971b03158f40096d0e;hb=8cf1fe240800a66d644f907fad8d618b014efd7d;hpb=787a842deca12cc0a1d2bc14006f000a5eb4c07d diff --git a/list_monad_as_continuation_monad.mdwn b/list_monad_as_continuation_monad.mdwn index 438e2a80..53bbde1a 100644 --- a/list_monad_as_continuation_monad.mdwn +++ b/list_monad_as_continuation_monad.mdwn @@ -2,9 +2,9 @@ We're going to come at continuations from three different directions, and each time we're going to end up at the same place: a particular monad, which we'll -call the continuation monad. +call the Continuation monad. -Rethinking the list monad +Rethinking the List monad ------------------------- To construct a monad, the key element is to settle on how to implement its type, and @@ -16,7 +16,7 @@ pattern for the new discussion further below, and it will tie together some previously unconnected elements of the course (more specifically, version 3 lists and monads). -For instance, take the **Reader Monad**. Once we decide to define its type as: +For instance, take the **Reader monad**. Once we decide to define its type as: type 'a reader = env -> 'a @@ -28,7 +28,7 @@ The reason this is a fairly natural choice is that because the type of an `'a reader` is `env -> 'a` (by definition), the type of the `r_unit` function is `'a -> env -> 'a`, which is an instance of the type of the **K** combinator. So it makes sense that **K** is the unit -for the reader monad. +for the Reader monad. Since the type of the `bind` operator is required to be @@ -70,7 +70,7 @@ constructions we provided in earlier lectures. We use the condensed version here in order to emphasize similarities of structure across monads.] -The **State Monad** is similar. Once we've decided to use the following type constructor: +The **State monad** is similar. Once we've decided to use the following type constructor: type 'a state = store -> ('a, store) @@ -95,18 +95,18 @@ Abstracting over the `s` and adjusting the types gives the result: let s_bind (u : 'a state) (f : 'a -> 'b state) : 'b state = fun (s : store) -> let (a, s') = u s in f a s' -The **Option/Maybe Monad** doesn't follow the same pattern so closely, so we +The **Option/Maybe monad** doesn't follow the same pattern so closely, so we won't pause to explore it here, though conceptually its unit and bind follow just as naturally from its type constructor. -Our other familiar monad is the **List Monad**, which we were told +Our other familiar monad is the **List monad**, which we were told looks like this: (* type 'a list = ['a];; *) l_unit (a : 'a) = [a];; l_bind u f = List.concat (List.map f u);; -Thinking through the list monad will take a little time, but doing so +Thinking through the List monad will take a little time, but doing so will provide a connection with continuations. Recall that `List.map` takes a function and a list and returns the @@ -141,7 +141,7 @@ the object returned by the second argument of `bind` to always be of type `('something list) list`. We can eliminate that restriction by flattening the list of lists into a single list: this is just `List.concat` applied to the output of `List.map`. So there is some logic to the -choice of unit and bind for the list monad. +choice of unit and bind for the List monad. Yet we can still desire to go deeper, and see if the appropriate bind behavior emerges from the types, as it did for the previously @@ -367,14 +367,14 @@ and: (* an intermediate version, and the fully eta-reduced: *) fun k -> u (fun a -> f a k) -Consider the most eta-reduced versions of `l'_unit` and `l'_bind`. They're the same as the unit and bind for the Montague continuation monad! In other words, the behavior of our v3-list monad and the behavior of the continuations monad are +Consider the most eta-reduced versions of `l'_unit` and `l'_bind`. They're the same as the unit and bind for the Montague Continuation monad! In other words, the behavior of our v3-List monad and the behavior of the continuations monad are parallel in a deep sense. Have we really discovered that lists are secretly continuations? Or have we merely found a way of simulating lists using list continuations? Well, strictly speaking, what we have done is shown that one particular implementation of lists---the right fold -implementation---gives rise to a continuation monad fairly naturally, +implementation---gives rise to a Continuation monad fairly naturally, and that this monad can reproduce the behavior of the standard list monad. But what about other list implementations? Do they give rise to monads that can be understood in terms of continuations?