Source file delimcc_of_fxhandler.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
open Effect
open Effect.Deep
type ('a, 'b) subcont = ('a, 'b) continuation
type 'a prompt = {
take : 'b. (('b, 'a) subcont -> 'a) -> 'b;
push : (unit -> 'a) -> 'a;
}
let new_prompt (type a) () : a prompt =
let module M = struct
type _ Effect.t += Prompt : (('b, a) subcont -> a) -> 'b t
end in
let take f = perform (M.Prompt f) in
let push f =
try_with f ()
{ effc =
(fun (type a) (e : a Effect.t) ->
match e with
| M.Prompt f -> Some (fun (k : (a, _) continuation) ->
Gc.finalise (fun k -> Multicont.Deep.drop_continuation k) k;
f k)
| _ -> None); }
in
{ take; push }
let push_prompt { push; _ } = push
let take_subcont { take; _ } = take
let push_subcont k v =
let k' = Multicont.Deep.clone_continuation k in
continue k' v
(** For the details of the implementation of control and shift0, see
https://hackage.haskell.org/package/CC-delcont-0.2.1.0/docs/src/Control-Monad-CC.html *)
let reset e =
let p = new_prompt () in
push_prompt p (fun () -> e p)
let shift p f =
take_subcont p (fun sk ->
push_prompt p (fun () ->
f (fun c -> push_prompt p (fun () -> push_subcont sk c))))
let control p f =
take_subcont p (fun sk ->
push_prompt p (fun () -> f (fun c -> push_subcont sk c)))
let shift0 p f =
take_subcont p (fun sk ->
f (fun c -> push_prompt p (fun () -> push_subcont sk c)))
let control0 p f = take_subcont p (fun sk -> f (fun c -> push_subcont sk c))
let abort p e = take_subcont p (fun _ -> e)