For instance, in Scheme this:
(require racket/control)
-
+
(reset
(let ([x 1])
(+ 10 (shift k x))))
let reset = Delimcc.push_prompt p;;
let shift = Delimcc.shift p;;
let abort = Delimcc.abort p;;
-
+
let foo x =
reset(fun () ->
- shift(fun continue ->
- if x = 1 then continue 10
- else 20
- ) + 100
+ shift(fun continue ->
+ if x = 1 then continue 10
+ else 20
+ ) + 100
)
in foo 2 + 1000;;
- : int = 1020
Example 1:
; (+ 100 (+ 10 (abort 1))) ~~> 1
-
+
app2 (op2 plus) (var hundred)
(app2 (op2 plus) (var ten) (abort (var one)))
-
+
# Continuation_monad.(run0(
- abort 1 >>= fun i ->
+ abort 1 >>= fun i ->
unit (10+i) >>= fun j ->
- unit (100+j)));;
+ unit (100+j)));;
- : int = 1
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))));;
+ reset (
+ abort 1 >>= fun i ->
+ unit (10+i) >>= fun j ->
+ unit (100+j))));;
- : int = 1
Example 2:
; (+ 100 (reset (+ 10 (abort 1)))) ~~> 101
-
+
app2 (op2 plus) (var hundred)
(reset (app2 (op2 plus) (var ten) (abort (var one))))
-
+
# Continuation_monad.(run0(
- reset (
- abort 1 >>= fun i ->
- unit (10+i)) >>= fun j ->
- unit (100+j)));;
+ reset (
+ abort 1 >>= fun i ->
+ unit (10+i)
+ ) >>= fun j ->
+ unit (100+j)));;
- : int = 101
Example 3:
app2 (op2 plus) (var thousand)
(reset (app2 (op2 plus) (var hundred)
- (shift (\k. ((op2 plus) (var ten) (var one))))))
+ (shift (\k. ((op2 plus) (var ten) (var one))))))
Continuation_monad.(
- let v = reset (
- let u = shift (fun k -> unit (10 + 1))
- in u >>= fun x -> unit (100 + x)
- ) in let w = v >>= fun x -> unit (1000 + x)
- in run0 w)
+ let v = reset (
+ let u = shift (fun k -> unit (10 + 1))
+ in u >>= fun x -> unit (100 + x)
+ ) in let w = v >>= fun x -> unit (1000 + x)
+ in run0 w);;
+ - : int = 1011
Example 4:
; (+ 1000 (reset (+ 100 (shift k (k (+ 10 1)))))) ~~> 1111
-
+
app2 (op2 plus) (var thousand)
(reset (app2 (op2 plus) (var hundred)
- (shift (\k. (app (var k) ((op2 plus) (var ten) (var one)))))))
-
+ (shift (\k. (app (var k) ((op2 plus) (var ten) (var one)))))))
+
Continuation_monad.(
let v = reset (
let u = shift (fun k -> k (10 :: [1]))
- in u >>= fun x -> unit (100 :: 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; 100; 10; 1]
To demonstrate the different adding order between Examples 4 and 5, we use `::` in the OCaml version instead of `+`. Here is Example 5:
app2 (op2 plus) (var thousand)
(reset (app2 (op2 plus) (var hundred)
- (shift (\k. ((op2 plus) (var ten) (app (var k) (var one)))))))
+ (shift (\k. ((op2 plus) (var ten) (app (var k) (var one)))))))
+
+ Continuation_monad.(let v = reset (
+ 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)
+ - : int list = [1000; 10; 100; 1]
- Continuation_monad.(let v = reset (
- 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)
Example 6:
; (+ 100 ((reset (+ 10 (shift k k))) 1)) ~~> 111
-
+
app2 (op2 plus) (var hundred)
(app (reset (app2 (op2 plus) (var ten)
- (shift (\k. (var k))))) (var one))
-
+ (shift (\k. (var k))))) (var one))
+
(* not sure if this example can be typed as-is in OCaml. We may need a sum-type *)
Example 7:
; (+ 100 (reset (+ 10 (shift k (k (k 1)))))) ~~> 121
-
+
app2 (op2 plus) (var hundred)
(reset (app2 (op2 plus) (var ten)
- (shift (\k. app (var k) (app (var k) (var one))))))
-
+ (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)
in u >>= fun x -> unit (10 + x)
) in let w = v >>= fun x -> unit (100 + x)
in run0 w)
+ - : int = 121
<!--