index 4fcf5e0..e3fb42d 100644 (file)
@@ -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

let callcc body = fun outk -> body (fun v localk -> outk v) outk

-<!-- GOTCHAS?? -->
+       <!-- GOTCHAS?? -->

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:

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

Callcc examples
@@ -401,41 +401,41 @@ Here are some more examples of using delimited control operators. We present eac

Example 1:

Example 1:

-       ; (+ 100 (+ 10 (abort 1))) ~~> 1
+       ; (+ 1000 (+ 100 (abort 11))) ~~> 11

-       app2 (op2 plus) (var hundred)
-         (app2 (op2 plus) (var ten) (abort (var one)))
+       app2 (op2 plus) (var thousand)
+         (app2 (op2 plus) (var hundred) (abort (var eleven)))

# Continuation_monad.(run0(

# Continuation_monad.(run0(
-           abort 1 >>= fun i ->
-           unit (10+i) >>= fun j ->
-           unit (100+j)));;
-       - : int = 1
+           abort 11 >>= fun i ->
+           unit (100+i) >>= fun j ->
+           unit (1000+j)));;
+       - : int = 11

When no `reset` is specified, there's understood to be an implicit one surrounding the entire computation (but unlike in the case of `callcc`, you still can't capture up to *and including* the end of the computation). So it makes no difference if we say instead:

# Continuation_monad.(run0(
reset (

When no `reset` is specified, there's understood to be an implicit one surrounding the entire computation (but unlike in the case of `callcc`, you still can't capture up to *and including* the end of the computation). So it makes no difference if we say instead:

# Continuation_monad.(run0(
reset (
-             abort 1 >>= fun i ->
-             unit (10+i) >>= fun j ->
-             unit (100+j))));;
-       - : int = 1
+             abort 11 >>= fun i ->
+             unit (100+i) >>= fun j ->
+             unit (1000+j))));;
+       - : int = 11

Example 2:

Example 2:

-       ; (+ 100 (reset (+ 10 (abort 1)))) ~~> 101
+       ; (+ 1000 (reset (+ 100 (abort 11)))) ~~> 1011

-       app2 (op2 plus) (var hundred)
-         (reset (app2 (op2 plus) (var ten) (abort (var one))))
+       app2 (op2 plus) (var thousand)
+         (reset (app2 (op2 plus) (var hundred) (abort (var eleven))))

# Continuation_monad.(run0(
reset (

# Continuation_monad.(run0(
reset (
-             abort 1 >>= fun i ->
-             unit (10+i)
+             abort 11 >>= fun i ->
+             unit (100+i)
) >>= fun j ->
) >>= fun j ->
-           unit (100+j)));;
-       - : int = 101
+           unit (1000+j)));;
+       - : int = 1011

Example 3:

Example 3:

@@ -478,10 +478,10 @@ To demonstrate the different adding order between Examples 4 and 5, we use `::`
(shift (\k. ((op2 plus) (var ten) (app (var k) (var one)))))))

Continuation_monad.(let v = reset (
(shift (\k. ((op2 plus) (var ten) (app (var k) (var one)))))))

Continuation_monad.(let v = reset (
-         let u = shift (fun k -> k  >>= fun x -> unit (10 :: x))
+           let u = shift (fun k -> k  >>= fun x -> unit (10 :: x))
in u >>= fun x -> unit (100 :: x)
) in let w = v >>= fun x -> unit (1000 :: 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]

- : int list = [1000; 10; 100; 1]

@@ -493,7 +493,23 @@ Example 6:
(app (reset (app2 (op2 plus) (var ten)
(shift (\k. (var k))))) (var one))

(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
+
+<!--
+# type either = Left of (int -> either) | Right of int;;
+# let getleft e = match e with Left lft -> lft | Right _ -> failwith "not a Left";;
+# let getright e = match e with Right rt -> rt | Left _ -> failwith "not a Right";;
+# 100 + getright (let v = reset (fun p () -> Right (10 + shift p (fun k -> Left k))) in getleft v 1);;
+-->

Example 7:

Example 7:

@@ -504,7 +520,7 @@ Example 7:
(shift (\k. app (var k) (app (var k) (var one))))))

Continuation_monad.(let v = reset (
(shift (\k. app (var k) (app (var k) (var one))))))

Continuation_monad.(let v = reset (
-         let u = shift (fun k -> k 1 >>= fun x -> k x)
+           let u = shift (fun k -> k 1 >>= fun x -> k x)
in u >>= fun x -> unit (10 + x)
) in let w = v >>= fun x -> unit (100 + x)
in run0 w)
in u >>= fun x -> unit (10 + x)
) in let w = v >>= fun x -> unit (100 + x)
in run0 w)