|
| 1 | +Require Import Coq.Lists.List. |
| 2 | +Require Import FunctionNinjas.All. |
| 3 | +Require Import Io.All. |
| 4 | +Require Io.List. |
| 5 | + |
| 6 | +Import ListNotations. |
| 7 | +Import C.Notations. |
| 8 | + |
| 9 | +Module Command. |
| 10 | + Inductive t (E : Effect.t) (Exc : Type) := |
| 11 | + | Ok (command : Effect.command E) |
| 12 | + | Exc (exc : Exc). |
| 13 | + Arguments Ok [E Exc] _. |
| 14 | + Arguments Exc [E Exc] _. |
| 15 | +End Command. |
| 16 | + |
| 17 | +Definition answer {E : Effect.t} {Exc : Type} (c : Command.t E Exc) : Type := |
| 18 | + match c with |
| 19 | + | Command.Ok c => Effect.answer E c |
| 20 | + | Command.Exc exc => Empty_set |
| 21 | + end. |
| 22 | + |
| 23 | +Definition effect (E : Effect.t) (Exc : Type) : Effect.t := |
| 24 | + Effect.New (Command.t E Exc) answer. |
| 25 | + |
| 26 | +Definition lift {E : Effect.t} {Exc A : Type} (x : C.t E A) |
| 27 | + : C.t (effect E Exc) A := |
| 28 | + C.run (fun c => C.Call (effect E Exc) (Command.Ok c)) x. |
| 29 | + |
| 30 | +Definition raise {E : Effect.t} {Exc A : Type} (exc : Exc) |
| 31 | + : C.t (effect E Exc) A := |
| 32 | + let! absurd := C.Call (effect E Exc) (Command.Exc exc) in |
| 33 | + match absurd with end. |
| 34 | + |
| 35 | +Fixpoint run {E : Effect.t} {Exc A : Type} (x : C.t (effect E Exc) A) |
| 36 | + : C.t E (A + list Exc) := |
| 37 | + match x with |
| 38 | + | C.Ret _ x => ret @@ inl x |
| 39 | + | C.Call (Command.Ok c) => |
| 40 | + let! answer := C.Call E c in |
| 41 | + ret @@ inl answer |
| 42 | + | C.Call (Command.Exc exc) => ret @@ inr [exc] |
| 43 | + | C.Let _ _ x f => |
| 44 | + let! x := run x in |
| 45 | + match x with |
| 46 | + | inl x => run (f x) |
| 47 | + | inr exc => ret @@ inr exc |
| 48 | + end |
| 49 | + | C.Join _ _ x y => |
| 50 | + let! xy := join (run x) (run y) in |
| 51 | + match xy with |
| 52 | + | (inl x, inl y) => ret @@ inl (x, y) |
| 53 | + | (inr exc, inl _) | (inl _, inr exc) => ret @@ inr exc |
| 54 | + | (inr exc_x, inr exc_y) => ret @@ inr (exc_x ++ exc_y) |
| 55 | + end |
| 56 | + | C.First _ _ x y => |
| 57 | + let! xy := first (run x) (run y) in |
| 58 | + match xy with |
| 59 | + | inl (inl x) => ret @@ inl @@ inl x |
| 60 | + | inr (inl y) => ret @@ inl @@ inr y |
| 61 | + | inl (inr exc) | inr (inr exc) => ret @@ inr exc |
| 62 | + end |
| 63 | + end. |
| 64 | + |
| 65 | +Definition handle {E : Effect.t} {Exc : Type} (run_exc : Exc -> C.t E unit) |
| 66 | + (x : C.t E (unit + list Exc)) : C.t E unit := |
| 67 | + let! x := x in |
| 68 | + match x with |
| 69 | + | inl x => ret x |
| 70 | + | inr exc => Io.List.iter_seq run_exc exc |
| 71 | + end. |
0 commit comments