X-Git-Url: http://lambda.jimpryor.net/git/gitweb.cgi?p=lambda.git;a=blobdiff_plain;f=cps_and_continuation_operators.mdwn;h=2c3f35603d9110ed565013c45c68e1c8fb3e6f6c;hp=258f7227f66f093cf5d7e5f1989ea25f943ecc6e;hb=2d0d8e91618b921c03f4764bc7937060f0bec739;hpb=9a23d7fc448e48268a7b60ce9ff3e55222cd833a diff --git a/cps_and_continuation_operators.mdwn b/cps_and_continuation_operators.mdwn index 258f7227..2c3f3560 100644 --- a/cps_and_continuation_operators.mdwn +++ b/cps_and_continuation_operators.mdwn @@ -173,15 +173,15 @@ So too will examples. We'll give some examples, and show you how to try them out let callcc body = fun outk -> body (fun v localk -> outk v) outk - + 3. `callcc` was originally introduced in Scheme. There it's written `call/cc` and is an abbreviation of `call-with-current-continuation`. Instead of the somewhat bulky form: - (call/cc (lambda (k) ...)) + (call/cc (lambda (k) ...)) -I prefer instead to use the lighter, and equivalent, shorthand: + I prefer instead to use the lighter, and equivalent, shorthand: - (let/cc k ...) + (let/cc k ...) Callcc examples @@ -268,11 +268,13 @@ That won't work because `k 1` doesn't have type `int`, but we're trying to add i This also works and as you can see, delivers the expected answer `101`. -At the moment, I'm not able to get the third example working with the monadic library. I thought that this should do it, but it doesn't type-check: +The third example is more difficult to make work with the monadic library, because its types are tricky. I was able to get this to work, which uses OCaml's "polymorphic variants." These are generally more relaxed about typing. There may be a version that works with regular OCaml types, but I haven't yet been able to identify it. Here's what does work: - # C.(run0 (callcc (fun k -> unit (1,k)) >>= fun (p1,p2) -> p2 (2,unit) >>= fun p2' -> unit (p1,p2')));; + # C.(run0 (callcc (fun k -> unit (1,`Box k)) >>= fun (p1,`Box p2) -> p2 (2,`Box unit) >>= fun p2' -> unit (p1,p2')));; + - : int * (int * [ `Box of 'b -> ('a, 'b) C.m ] as 'b) as 'a = + (2, (2, `Box )) -If we figure this out later (or anyone else does), we'll come back and report. + @@ -481,7 +483,7 @@ To demonstrate the different adding order between Examples 4 and 5, we use `::` let u = shift (fun k -> k [1] >>= fun x -> unit (10 :: x)) in u >>= fun x -> unit (100 :: x) ) in let w = v >>= fun x -> unit (1000 :: x) - in run0 w) + in run0 w);; - : int list = [1000; 10; 100; 1] @@ -493,7 +495,23 @@ Example 6: (app (reset (app2 (op2 plus) (var ten) (shift (\k. (var k))))) (var one)) - (* not sure if this example can be typed as-is in OCaml. We may need a sum-type *) + (* not sure if this example can be typed as-is in OCaml... this is the best I an do at the moment... *) + + # type 'x either = Left of (int -> ('x,'x either) Continuation_monad.m) | Right of int;; + # Continuation_monad.(let v = reset ( + shift (fun k -> unit (Left k)) >>= fun i -> unit (Right (10+i)) + ) in let w = v >>= fun (Left k) -> + k 1 >>= fun (Right i) -> + unit (100+i) + in run0 w);; + - : int = 111 + + Example 7: