Source file sigs2.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
(** {1 Common module signatures}
This compilation unit gathers module signatures which are used in the rest
of the library. Essentially, the rest of the library provides functors to
generate modules with the signatures below.
The Seqes library provides functors to produce specialised variants of the
{!Stdlib.Seq} type where the forcing of an element involves a monad. E.g.,
considering an I/O cooperative scheduling monad à la [Lwt] or [Async], which
we denote with the type ['a io], you can use Seqes to produce the following
type
{[
type 'a t = unit -> 'a node io
and 'a node =
| Nil
| Cons of 'a * 'a t
]}
In addition to specialised types, the library's functor produce an
assortment of functions to operate on values of this type. The assortment of
function is compatible with the {!Stdlib.Seq} (except for the monad part).
See [examples/seqseq/seqseq.ml] for a demonstration of this compatibility.
Familiarity with {!Stdlib.Seq} is assumed. *)
(** {1 Two type parameters}
Some monad have two type parameters. E.g., the result monad is over the type
[('a, 'e) result].
The Seqes library offers all the same features over those monads than it
does over the single-parameter monads. Accordingly, below are variants
of the module signatures from {!Sigs1}, but for two-parameter monads.
Note that the specialised type of sequence also carries these two
parameters:
{[
type ('a, 'e) t = unit -> (('a, 'e) node, 'e) io
and ('a, 'e) node =
| Nil
| Cons of 'a * ('a, 'e) t
]}
See [examples/seqres/seqres.ml] for an example of using Seqes for the result
monad. See [examples/seqlwtres/seqlwtres.ml] for an example of using Seqes
for the Lwt+result monad.
{2 Asymmetry}
Note that the two type parameters of the monad are not treated the same.
Seqes only requires a bind for the first parameter but not the second.
{[
val bind : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t
]}
*)
(** Equivalent to {!Sigs1.SEQMON1TRAVERSORS} but with two type parameters. *)
module type SEQMON2TRAVERSORS = sig
type ('a, 'e) callermon
type ('a, 'e) mon
type ('a, 'e) t
val iter : ('a -> (unit, 'e) callermon) -> ('a, 'e) t -> (unit, 'e) mon
val fold_left : ('a -> 'b -> ('a, 'e) callermon) -> 'a -> ('b, 'e) t -> ('a, 'e) mon
val iteri : (int -> 'a -> (unit, 'e) callermon) -> ('a, 'e) t -> (unit, 'e) mon
val fold_lefti : ('b -> int -> 'a -> ('b, 'e) callermon) -> 'b -> ('a, 'e) t -> ('b, 'e) mon
val for_all : ('a -> (bool, 'e) callermon) -> ('a, 'e) t -> (bool, 'e) mon
val exists : ('a -> (bool, 'e) callermon) -> ('a, 'e) t -> (bool, 'e) mon
val find : ('a -> (bool, 'e) callermon) -> ('a, 'e) t -> ('a option, 'e) mon
val find_map : ('a -> ('b option, 'e) callermon) -> ('a, 'e) t -> ('b option, 'e) mon
val iter2 : ('a -> 'b -> (unit, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t -> (unit, 'e) mon
val fold_left2 : ('a -> 'b -> 'c -> ('a, 'e) callermon) -> 'a -> ('b, 'e) t -> ('c, 'e) t -> ('a, 'e) mon
val for_all2 : ('a -> 'b -> (bool, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t -> (bool, 'e) mon
val exists2 : ('a -> 'b -> (bool, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t -> (bool, 'e) mon
end
(** Equivalent to {!Sigs1.SEQMON1TRANSFORMERS} but with two type parameters. *)
module type SEQMON2TRANSFORMERS = sig
type ('a, 'e) callermon
type ('a, 'e) mon
type ('a, 'e) t
include SEQMON2TRAVERSORS
with type ('a, 'e) callermon := ('a, 'e) callermon
with type ('a, 'e) mon := ('a, 'e) mon
with type ('a, 'e) t := ('a, 'e) t
val init : int -> (int -> ('a, 'e) callermon) -> ('a, 'e) t
val unfold : ('b -> (('a * 'b) option, 'e) callermon) -> 'b -> ('a, 'e) t
val forever : (unit -> ('a, 'e) callermon) -> ('a, 'e) t
val iterate : ('a -> ('a, 'e) callermon) -> 'a -> ('a, 'e) t
val map : ('a -> ('b, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t
val mapi : (int -> 'a -> ('b, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t
val filter : ('a -> (bool, 'e) callermon) -> ('a, 'e) t -> ('a, 'e) t
val filter_map : ('a -> ('b option, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t
val scan : ('b -> 'a -> ('b, 'e) callermon) -> 'b -> ('a, 'e) t -> ('b, 'e) t
val take_while : ('a -> (bool, 'e) callermon) -> ('a, 'e) t -> ('a, 'e) t
val drop_while : ('a -> (bool, 'e) callermon) -> ('a, 'e) t -> ('a, 'e) t
val group : ('a -> 'a -> (bool, 'e) callermon) -> ('a, 'e) t -> (('a, 'e) t, 'e) t
val map2 : ('a -> 'b -> ('c, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t -> ('c, 'e) t
val map_product : ('a -> 'b -> ('c, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t -> ('c, 'e) t
val partition_map : ('a -> (('b, 'c) Either.t, 'e) callermon) -> ('a, 'e) t -> ('b, 'e) t * ('c, 'e) t
val partition : ('a -> (bool, 'e) callermon) -> ('a, 'e) t -> ('a, 'e) t * ('a, 'e) t
end
(** Equivalent to {!Sigs1.SEQMON1ALL} but with two type parameters. *)
module type SEQMON2ALL = sig
type ('a, 'e) mon
type ('a, 'e) t
include SEQMON2TRANSFORMERS
with type ('a, 'e) mon := ('a, 'e) mon
with type ('a, 'e) callermon := 'a
with type ('a, 'e) t := ('a, 'e) t
val is_empty : ('a, 'e) t -> (bool, 'e) mon
val uncons : ('a, 'e) t -> (('a * ('a, 'e) t) option, 'e) mon
val length : ('a, 'e) t -> (int, 'e) mon
val equal : ('a -> 'b -> bool) -> ('a, 'e) t -> ('b, 'e) t -> (bool, 'e) mon
val compare : ('a -> 'b -> int) -> ('a, 'e) t -> ('b, 'e) t -> (int, 'e) mon
val empty : ('a, 'e) t
val return : 'a -> ('a, 'e) t
val cons : 'a -> ('a, 'e) t -> ('a, 'e) t
val repeat : 'a -> ('a, 'e) t
val cycle : ('a, 'e) t -> ('a, 'e) t
val take : int -> ('a, 'e) t -> ('a, 'e) t
val drop : int -> ('a, 'e) t -> ('a, 'e) t
val memoize : ('a, 'e) t -> ('a, 'e) t
val once : ('a, 'e) t -> ('a, 'e) t
val transpose : (('a, 'e) t, 'e) t -> (('a, 'e) t, 'e) t
val append : ('a, 'e) t -> ('a, 'e) t -> ('a, 'e) t
val concat : (('a, 'e) t, 'e) t -> ('a, 'e) t
val flat_map : ('a -> ('b, 'e) t) -> ('a, 'e) t -> ('b, 'e) t
val concat_map : ('a -> ('b, 'e) t) -> ('a, 'e) t -> ('b, 'e) t
val zip : ('a, 'e) t -> ('b, 'e) t -> (('a * 'b), 'e) t
val interleave : ('a, 'e) t -> ('a, 'e) t -> ('a, 'e) t
val sorted_merge : ('a -> 'a -> int) -> ('a, 'e) t -> ('a, 'e) t -> ('a, 'e) t
val product : ('a, 'e) t -> ('b, 'e) t -> (('a * 'b), 'e) t
val unzip : (('a * 'b), 'e) t -> ('a, 'e) t * ('b, 'e) t
val split : (('a * 'b), 'e) t -> ('a, 'e) t * ('b, 'e) t
val of_dispenser : (unit -> ('a option, 'e) mon) -> ('a, 'e) t
val to_dispenser : ('a, 'e) t -> (unit -> ('a option, 'e) mon)
val ints : int -> (int, 'e) t
val of_seq : 'a Seq.t -> ('a, 'e) t
end
(** Equivalent to {!Sigs1.MONAD} but with two type parameters. *)
module type MONAD2 = sig
type ('a, 'e) t
val return : 'a -> ('a, 'e) t
val bind : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t
end
(** Mixed-monad operations *)
module type GLUE2 = sig
type ('a, 'e) x
type ('a, 'e) f
type ('a, 'e) ret
val bind : ('a, 'e) x -> ('a -> ('b, 'e) f) -> ('b, 'e) ret
end
(**/**)
module type INJ_MONAD2 = sig
type (!'a, 'e) t
val return : 'a -> ('a, 'e) t
val bind : ('a, 'e) t -> ('a -> ('b, 'e) t) -> ('b, 'e) t
end