forked from formal-land/coq-of-ocaml
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmonad.ml
51 lines (40 loc) · 1.15 KB
/
monad.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
(** A monad to:
* have a code without side-effects;
* handle errors;
* report as much errors as possible (many branches of the AST can be explored
in parallel and errors of each branch are reported);
* handle the current position in the source [Loc.t];
* handle the current environment [Env.t]. *)
module Command = struct
type 'a t =
| GetEnv : Env.t t
| GetLoc : Loc.t t
| Raise : string -> 'a t
end
module Wrapper = struct
type t =
| Env of Env.t
| Loc of Loc.t
end
type 'a t =
| All : 'a t * 'b t -> ('a * 'b) t
| Bind : 'b t * ('b -> 'a t) -> 'a t
| Command of 'a Command.t
| Return of 'a
| Wrapper of Wrapper.t * 'a t
let all (x1 : 'a t) (x2 : 'b t) : ('a * 'b) t =
All (x1, x2)
let return (x : 'a) : 'a t =
Return x
let (>>=) (x : 'a t) (f : 'a -> 'b t) : 'b t =
Bind (x, f)
let get_env : Env.t t =
Command Command.GetEnv
let get_loc : Loc.t t =
Command Command.GetLoc
let raise (message : string) : 'a t =
Command (Command.Raise message)
let set_env (env : Env.t) (x : 'a t) : 'a t =
Wrapper (Wrapper.Env env, x)
let set_loc (loc : Loc.t) (x : 'a t) : 'a t =
Wrapper (Wrapper.Loc loc, x)