Source file builtins_getter.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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
let getter =
let a = Lang.univ_t () in
Lang.add_builtin ~category:`Getter "getter" ~descr:"Create a getter."
[
( "",
Lang.getter_t a,
None,
Some "Value from which the getter should be created." );
]
(Lang.getter_t a)
(fun p -> List.assoc "" p)
let _ =
let a = Lang.univ_t () in
let b = Lang.univ_t () in
Lang.add_builtin ~category:`Getter ~base:getter "case"
~descr:"Return a value depending on whether the getter is constant or not."
[
("", Lang.getter_t a, None, Some "Getter to inspect.");
("", Lang.fun_t [(false, "", a)] b, None, None);
("", Lang.fun_t [(false, "", Lang.fun_t [] a)] b, None, None);
]
b
(fun p ->
let x = Lang.assoc "" 1 p in
let f = Lang.assoc "" 2 p in
let g = Lang.assoc "" 3 p in
match x with
| Fun { fun_args = [] } | FFI { ffi_args = []; _ } ->
Lang.apply ~pos:(Lang.pos p) g [("", x)]
| _ -> Lang.apply ~pos:(Lang.pos p) f [("", x)])
let _ =
let a = Lang.univ_t () in
Lang.add_builtin ~category:`Getter ~base:getter "get"
~descr:"Get the value of a getter."
[("", Lang.getter_t a, None, None)]
a
(fun p ->
let x = List.assoc "" p |> Lang.to_getter in
x ())
let getter_map =
let a = Lang.univ_t () in
let b = Lang.univ_t () in
Lang.add_builtin ~category:`Getter ~base:getter "map"
~descr:"Apply a function on a getter."
[
("", Lang.fun_t [(false, "", a)] b, None, Some "Function to apply.");
("", Lang.getter_t a, None, None);
]
(Lang.getter_t b)
(fun p ->
let f = Lang.assoc "" 1 p in
let x = Lang.assoc "" 2 p in
match x with
| Fun { fun_args = [] } | FFI { ffi_args = []; _ } ->
Lang.val_fun [] (fun p' ->
Lang.apply ~pos:(Lang.pos p') f
[("", Lang.apply ~pos:(Lang.pos p') x [])])
| _ -> Lang.apply ~pos:(Lang.pos p) f [("", x)])
let _ =
let a = Lang.univ_t ~constraints:[Type.ord_constr] () in
let b = Lang.univ_t () in
Lang.add_builtin ~category:`Getter ~base:getter_map "memoize"
~descr:
"Apply a function on a getter. If the input value has not changed \
compared to last call, the previous result is returned without \
computing the function again."
[
("", Lang.fun_t [(false, "", a)] b, None, Some "Function to apply.");
("", Lang.getter_t a, None, None);
]
(Lang.getter_t b)
(fun p ->
let f = Lang.assoc "" 1 p in
let x = Lang.assoc "" 2 p in
match x with
| Fun { fun_args = [] } | FFI { ffi_args = []; _ } ->
let last_x = ref (Lang.apply ~pos:(Lang.pos p) x []) in
let last_y = ref (Lang.apply ~pos:(Lang.pos p) f [("", !last_x)]) in
Lang.val_fun [] (fun p' ->
let x = Lang.apply ~pos:(Lang.pos p') x [] in
if Value.compare x !last_x = 0 then !last_y
else (
let y = Lang.apply ~pos:(Lang.pos p') f [("", x)] in
last_x := x;
last_y := y;
y))
| _ -> Lang.apply ~pos:(Lang.pos p) f [("", x)])