Source file 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
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
(** {1 Lwt, result, and Lwt-result monad operators}
This module provides the necessary functions and operators to use Lwt,
result and Lwt-result as a monad.
{2 Basics}
The three, tiered monads have each their full set of operators:
The Lwt monad:
{ul
{li {!Lwt.return} for return,}
{li {!Lwt.bind} or {!(>>=)} for bind, and}
{li {!Lwt.map} or {!(>|=)} for map.}
}
The result monad:
{ul
{li {!Result.ok} or {!ok} for return,}
{li {!Result.bind} or {!(>>?)} for bind, and}
{li {!Result.map} {!(>|?)} for map.}
}
In addition, {!Result.error} or {!error} is for failures within the result
monad.
The Lwt-result monad:
{ul
{li {!return} or {!Lwt.return_ok} for return,}
{li {!(>>=?)} for bind, and}
{li {!(>|=?)} for map.}
}
In addition, {!fail} is for the failure within the Lwt-result combined
monad.
Note that future improvements are planned to (a) make those more uniform,
(b) allow the opening of selected infix operators only, and (c) provide
[let*]-binds.
{2 Preallocated values}
The module also provides preallocated values for the common types:
- {!unit_s} (resp {!unit_e}) (resp {!unit_es}) is [Lwt.return ()] (resp
[Ok ()]) (resp [Lwt.return (Ok ())]),
- {!none_s} (resp {!none_e}) (resp {!none_es}) is [Lwt.return None] (resp
[Ok None]) (resp [Lwt.return (Ok None)]),
- etc. (see full inventory below)
Note that some of these values are also available in their dedicated
modules. E.g., [none_*] are available in {!Option}.
{2 Joins}
The {!join_p} function takes a list of promises [ps] and returns a single
promise [p] that resolves with [()] when all the promises of [ps] have
resolved.
The {!all_p} function takes a list of promises [ps] and returns a single
promise [p] that resolves when all the promises of [ps] have resolved. The
value [p] resolves to is the list of values the promises of [ps] resolve to.
The order is preserved.
The {!both_p} function takes two promises [p1] and [p2] and returns a single
promise [p] that resolves when both promises [p1] and [p2] have resolved.
The value [p] resolves to is the tuple of values the promises [p1] and [p2]
resolve to.
Note that like all [_p] functions, these functions have a best-effort
semantic: they only resolve once all the underlying promises have resolved.
The [_e] variants are equivalent for the result monad: the final result is
[Ok] if all the underlying results are [Ok].
The [_es] variants are equivalent for the Lwt-result monad: the final
promise resolves to [Ok] if all the underlying promise resolve to [Ok].
*)
module type S = sig
(** lwt monad *)
val ( >>= ) : 'a Lwt.t -> ('a -> 'b Lwt.t) -> 'b Lwt.t
val ( >|= ) : 'a Lwt.t -> ('a -> 'b) -> 'b Lwt.t
(** result monad *)
val ok : 'a -> ('a, 'trace) result
val error : 'error -> ('a, 'error) result
val ( >>? ) :
('a, 'trace) result -> ('a -> ('b, 'trace) result) -> ('b, 'trace) result
val ( >|? ) : ('a, 'trace) result -> ('a -> 'b) -> ('b, 'trace) result
(** lwt-result combined monad *)
val ok_s : 'a -> ('a, 'trace) result Lwt.t
val return : 'a -> ('a, 'trace) result Lwt.t
val error_s : 'error -> ('a, 'error) result Lwt.t
val fail : 'error -> ('a, 'error) result Lwt.t
val ( >>=? ) :
('a, 'trace) result Lwt.t ->
('a -> ('b, 'trace) result Lwt.t) ->
('b, 'trace) result Lwt.t
val ( >|=? ) :
('a, 'trace) result Lwt.t -> ('a -> 'b) -> ('b, 'trace) result Lwt.t
(** Mixing operators *)
(** All operators follow this naming convention:
- the first character is [>]
- the second character is [>] for [bind] and [|] for [map]
- the next character is [=] for Lwt or [?] for Error
- the next character (if present) is [=] for Lwt or [?] for Error, it is
only used for operator that are within both monads. *)
val ( >>?= ) :
('a, 'trace) result ->
('a -> ('b, 'trace) result Lwt.t) ->
('b, 'trace) result Lwt.t
val ( >|?= ) :
('a, 'trace) result -> ('a -> 'b Lwt.t) -> ('b, 'trace) result Lwt.t
(** preallocated in-monad values *)
val unit_s : unit Lwt.t
val unit_e : (unit, 'trace) result
val unit_es : (unit, 'trace) result Lwt.t
val none_s : 'a option Lwt.t
val none_e : ('a option, 'trace) result
val none_es : ('a option, 'trace) result Lwt.t
val some_s : 'a -> 'a option Lwt.t
val some_e : 'a -> ('a option, 'trace) result
val some_es : 'a -> ('a option, 'trace) result Lwt.t
val nil_s : 'a list Lwt.t
val nil_e : ('a list, 'trace) result
val nil_es : ('a list, 'trace) result Lwt.t
val true_s : bool Lwt.t
val true_e : (bool, 'trace) result
val true_es : (bool, 'trace) result Lwt.t
val false_s : bool Lwt.t
val false_e : (bool, 'trace) result
val false_es : (bool, 'trace) result Lwt.t
(** additional preallocated in-monad values
this is for backwards compatibility and for similarity with Lwt *)
val ok_unit : (unit, 'error) result
val return_unit : (unit, 'error) result Lwt.t
(** joins *)
val join_p : unit Lwt.t list -> unit Lwt.t
val all_p : 'a Lwt.t list -> 'a list Lwt.t
val both_p : 'a Lwt.t -> 'b Lwt.t -> ('a * 'b) Lwt.t
val join_e : (unit, 'trace) result list -> (unit, 'trace list) result
val all_e : ('a, 'trace) result list -> ('a list, 'trace list) result
val both_e :
('a, 'trace) result -> ('b, 'trace) result -> ('a * 'b, 'trace list) result
val join_ep :
(unit, 'trace) result Lwt.t list -> (unit, 'trace list) result Lwt.t
val all_ep :
('a, 'trace) result Lwt.t list -> ('a list, 'trace list) result Lwt.t
val both_ep :
('a, 'trace) result Lwt.t ->
('b, 'trace) result Lwt.t ->
('a * 'b, 'trace list) result Lwt.t
end