Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 555 lines (472 sloc) 24.828 kb
fccc685 Initial open-source release
MLstate authored
1 (*
2 Copyright © 2011 MLstate
3
4 This file is part of OPA.
5
6 OPA is free software: you can redistribute it and/or modify it under the
7 terms of the GNU Affero General Public License, version 3, as published by
8 the Free Software Foundation.
9
10 OPA is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
13 more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with OPA. If not, see <http://www.gnu.org/licenses/>.
17 *)
18 (**
19 Generic Ast Rewriter Interfaces
20
21 This module defines the interfaces of modules used in [Traverse].
22 Since the module Traverse has a documented mli and there is a need
23 to define severals module sig, putting them in this module dedicated
24 for interfaces only, avoid the duplication of modules sig
25 in [traverse.ml] and [traverse.mli]
26
27 @author Louis Gesbert
28 @author Valentin Gatien-Baron
29 @author Mathieu Barbin
30 *)
31
32 (** The TRAVERSE main interface. *)
33 module type TRAVERSE =
34 sig
35 (**
36 The type of your trees, e.g. AST (expr). With up to 3 type variables for parametric trees.
37 If you need more than 3 parameters, you can either go to hell, or patch this module (choose
38 the less painful)
39 *)
40 type 'p t constraint 'p = _ * _ * _
41
42 (**
43 The type of elt which contain some [expr] inside. (like e.g. [code_elt])
44 In the default TRAVERSE, [container = t], the type [expr] is recursive.
45 When you use the [MakeLift] functor, you'll get [container <> t], with
46 [container] a non recursive type containing some [t].
47 *)
48 type 'p container constraint 'p = _ * _ * _
49
50 (** {6 Higher-order traverse functions} *)
51
52 (**
53 The function you specify controls the
54 recursive calls by applying its argument. All the more simple functions
55 below are implemented using those. Usually, you would use these functions
56 somewhat like this:
57
58 [ let f x = traverse_map (fun tra x -> ...) x ]
59
60 where in the body of your function, you can do treatments on [x] and
61 control the recursive calls by applying [tra]: [tra] corresponds to the
62 recursive call on all children. Hence, you can apply a transformation and
63 then descend on the result, or first descend and then transform, or choose
64 not to descend in some cases, etc.
65
66 You can also control, in the case of folds:
67 - the information that goes up (it's that returned by your call to [tra])
68 - the information that goes down (it's that passed to your call to [tra])
69 - the information that goes to your brothers (it's your return value)
70 - the information that comes from your brothers (it's the [acc] you write as parameter)
71
72 Please see the implementation of the usual traverse functions below for
73 examples.
74 *)
75 val traverse_iter : (('p t -> unit) -> 'p t -> unit) -> 'p container -> unit
76 val traverse_map : (('p t -> 'p t) -> 'p t -> 'p t) -> 'p container -> 'p container
77 val traverse_fold : (('a -> 'p t -> 'a) -> 'a -> 'p t -> 'a) -> 'a -> 'p container -> 'a
78 val traverse_foldmap : (('a -> 'p t -> 'a * 'p t) -> 'a -> 'p t -> 'a * 'p t) -> 'a -> 'p container -> 'a * 'p container
79 val traverse_exists : (('p t -> bool) -> 'p t -> bool) -> 'p container -> bool
80 val traverse_forall : (('p t -> bool) -> 'p t -> bool) -> 'p container -> bool
81 val traverse_findmap : (('p t -> 'a option) -> 'p t -> 'a option) -> 'p container -> 'a option
82
83 val traverse_foldmap_context_down : (('env -> 'acc -> 'p t -> 'acc * 'p t) -> 'env -> 'acc -> 'p t -> 'acc * 'p t) -> 'env -> 'acc -> 'p container -> 'acc * 'p container
84 val traverse_map_context_down : (('env -> 'p t -> 'p t) -> 'env -> 'p t -> 'p t) -> 'env -> 'p container -> 'p container
85 val traverse_fold_context_down : (('env -> 'acc -> 'p t -> 'acc) -> 'env -> 'acc -> 'p t -> 'acc) -> 'env -> 'acc -> 'p container -> 'acc
86 val traverse_iter_context_down : (('env -> 'p t -> unit) -> 'env -> 'p t -> unit) -> 'env -> 'p container -> unit
87 val traverse_forall_context_down : (('env -> 'p t -> bool) -> 'env -> 'p t -> bool) -> 'env -> 'p container -> bool
88 val traverse_exists_context_down : (('env -> 'p t -> bool) -> 'env -> 'p t -> bool) -> 'env -> 'p container -> bool
89
90 (**
91 These functions behave almost like their equivalent without "self_"
92 Their are meant to replace patterns as:
93 [let rec aux tra acc e = ... aux tra acc e ... in
94 traverse_foldmap aux acc e]
95 by
96 [self_traverse_foldmap (fun self tra acc e -> ... self acc e ...)]
97 *)
98 val self_traverse_iter : (('p t -> unit) -> ('p t -> unit) -> 'p t -> unit) -> 'p container -> unit
99 val self_traverse_map : (('p t -> 'p t) -> ('p t -> 'p t) -> 'p t -> 'p t) -> 'p container -> 'p container
100 val self_traverse_fold : (('a -> 'p t -> 'a) -> ('a -> 'p t -> 'a) -> 'a -> 'p t -> 'a) -> 'a -> 'p container -> 'a
101 val self_traverse_foldmap : (('a -> 'p t -> 'a * 'p t) -> ('a -> 'p t -> 'a * 'p t) -> 'a -> 'p t -> 'a * 'p t) -> 'a -> 'p container -> 'a * 'p container
102 val self_traverse_exists : (('p t -> bool) -> ('p t -> bool) -> 'p t -> bool) -> 'p container -> bool
103 val self_traverse_forall : (('p t -> bool) -> ('p t -> bool) -> 'p t -> bool) -> 'p container -> bool
104 val self_traverse_findmap : (('p t -> 'a option) -> ('p t -> 'a option) -> 'p t -> 'a option) -> 'p container -> 'a option
105
106 val self_traverse_foldmap_context_down : (('env -> 'acc -> 'p t -> 'acc * 'p t) -> ('env -> 'acc -> 'p t -> 'acc * 'p t) -> 'env -> 'acc -> 'p t -> 'acc * 'p t) -> 'env -> 'acc -> 'p container -> 'acc * 'p container
107 val self_traverse_map_context_down : (('env -> 'p t -> 'p t) -> ('env -> 'p t -> 'p t) -> 'env -> 'p t -> 'p t) -> 'env -> 'p container -> 'p container
108 val self_traverse_fold_context_down : (('env -> 'acc -> 'p t -> 'acc) -> ('env -> 'acc -> 'p t -> 'acc) -> 'env -> 'acc -> 'p t -> 'acc) -> 'env -> 'acc -> 'p container -> 'acc
109 val self_traverse_iter_context_down : (('env -> 'p t -> unit) -> ('env -> 'p t -> unit) -> 'env -> 'p t -> unit) -> 'env -> 'p container -> unit
110 val self_traverse_forall_context_down : (('env -> 'p t -> bool) -> ('env -> 'p t -> bool) -> 'env -> 'p t -> bool) -> 'env -> 'p container -> bool
111 val self_traverse_exists_context_down : (('env -> 'p t -> bool) -> ('env -> 'p t -> bool) -> 'env -> 'p t -> bool) -> 'env -> 'p container -> bool
112
113 (** {6 Usual traverse functions} *)
114 (**
115 Usual traverse functions. Up is bottom-up, down is top-down. Among
116 brothers, the order is always that specified by the implementation of the module X
117
118 Note : when up/down is not specified, order is not specified.
119 Do not specify up/down only if it really does not matter to your pass.
120 *)
121
122 (** {9 iter} *)
123 (** *)
124 val iter : ('p t -> unit) -> 'p container -> unit
125 val iter_up : ('p t -> unit) -> 'p container -> unit
126 val iter_down : ('p t -> unit) -> 'p container -> unit
127
128 (** {9 map} *)
129 (** *)
130 val map : ('p t -> 'p t) -> 'p container -> 'p container
131 val map_up : ('p t -> 'p t) -> 'p container -> 'p container
132 val map_down : ('p t -> 'p t) -> 'p container -> 'p container
133
134 (** {9 fold} *)
135 (** *)
136 val fold : ('a -> 'p t -> 'a) -> 'a -> 'p container -> 'a
137 val fold_up : ('a -> 'p t -> 'a) -> 'a -> 'p container -> 'a
138 val fold_down : ('a -> 'p t -> 'a) -> 'a -> 'p container -> 'a
139
140 (** {9 foldmap} *)
141 (** *)
142 val foldmap : ('a -> 'p t -> 'a * 'p t) -> 'a -> 'p container -> 'a * 'p container
143 val foldmap_up : ('a -> 'p t -> 'a * 'p t) -> 'a -> 'p container -> 'a * 'p container
144 val foldmap_down : ('a -> 'p t -> 'a * 'p t) -> 'a -> 'p container -> 'a * 'p container
145
146 (** {9 exists} *)
147 (** *)
148 val exists : ('p t -> bool) -> 'p container -> bool
149 val exists_up : ('p t -> bool) -> 'p container -> bool
150 val exists_down : ('p t -> bool) -> 'p container -> bool
151
152 (** {9 find} *)
153 (** *)
154 val find : ('p t -> bool) -> 'p container -> 'p t option
155 val find_up : ('p t -> bool) -> 'p container -> 'p t option
156 val find_down : ('p t -> bool) -> 'p container -> 'p t option
157
158 (** {9 findmap} *)
159 (** *)
160 val findmap : ('p t -> 'a option) -> 'p container -> 'a option
161 val findmap_up : ('p t -> 'a option) -> 'p container -> 'a option
162 val findmap_down : ('p t -> 'a option) -> 'p container -> 'a option
163
164 (** {9 iterating with a context}*)
165 (** These functions allow you to keep some information about the context
166 (for example in which toplevel declaration you are) *)
167 (** *)
168 val foldmap_context_down : ('env -> 'acc -> 'p t -> 'env * 'acc * 'p t) -> 'env -> 'acc -> 'p container -> 'acc * 'p container
169 val fold_context_down : ('env -> 'acc -> 'p t -> 'env * 'acc) -> 'env -> 'acc -> 'p container -> 'acc
170 val map_context_down : ('env -> 'p t -> 'env * 'p t) -> 'env -> 'p container -> 'p container
171 val iter_context_down : ('env -> 'p t -> 'env) -> 'env -> 'p container -> unit
172
173
174 (** {9 non rec}*)
175 (**
176 Non rec functions are the exportation in this module of the function
177 taken as argument in the functor. ([X.iter], [X.map], [X.fold], [X.foldmap])
178
179 It just apply the function to all child, but non recursivly, only to the direct
180 children of the node.
181 *)
182 (** *)
183 val iter_nonrec : ('p t -> unit) -> 'p container -> unit
184 val map_nonrec : ('p t -> 'p t) -> 'p container -> 'p container
185 val fold_nonrec : ('a -> 'p t -> 'a) -> 'a -> 'p container -> 'a
186 val foldmap_nonrec : ('a -> 'p t -> 'a * 'p t) -> 'a -> 'p container -> 'a * 'p container
187 val exists_nonrec : ('p t -> bool) -> 'p container -> bool
188 val forall_nonrec : ('p t -> bool) -> 'p container -> bool
189 end
190
191 (** {6 Interfaces of Arguments for Traverse functors} *)
192
193 (** {9 A first version} *)
194 (**
195 based on list cons/decons.
196 After some bench, we'll see if this implementation will be keeped.
197 *)
198 module type S =
199 sig
200 type 'p t constraint 'p = _ * _ * _
201 val subs_cons : 'p t -> ('p t list -> 'p t) * 'p t list
202 end
203
204 (** {9 A second version} *)
205
206 (**
207 Based on implementation of explicit traversal functions, without list manipulation.
208 This implementation allow to be more specific about what should be reallocate,
209 and permit some optimisations on traverse functions.
210
211 After some bench to confirm this, we may keep only this version in a near future.
212 *)
213 module type S2 =
214 sig
215 type 'p t constraint 'p = _ * _ * _
216
217 (** the only function you need to define :
218 given a function [tra] to foldmap all children of tree, foldmap the tree *)
219 val foldmap : ('acc -> 'p t -> 'acc * 'p t) -> 'acc -> 'p t -> 'acc * 'p t
220
221 (** other specific function *)
222 (**
223 Used for optimization purpose.
224 If you dont want to write it for quick prototyping, use the constructor
225 [Traverse.Unoptimized] on your foldmap function
226 *)
227 (** *)
228
229 val iter : ('p t -> unit) -> 'p t -> unit
230 val map : ('p t -> 'p t) -> 'p t -> 'p t
231 val fold : ('acc -> 'p t -> 'acc) -> 'acc -> 'p t -> 'acc
232
233 (** *)
234 (** [exists], [find] and [findmap] are implemented from iter, using exceptions *)
235
236 end
237
238 (** {6 Lifting} *)
239 (**
240 The lifting feature is used whenever you manipulate some bigger containers,
241 which contains an arbitrary number of expressions
242 that you want to traverse.
243
244 It is almost the same interface than S2. If [container = t], you'll get S2.
245 It is needed, since a functor in [Traverse] takes as argument a module of sig S2,
246 and it is not possible to write something like :
247 {[
248 MakeLift ( LIFT2 with 'p t = 'p container )
249 ]}
250
251 *)
252 module type LIFT2 =
253 sig
254 type 'p t constraint 'p = _ * _ * _
255 type 'p container constraint 'p = _ * _ * _
256
257 val foldmap : ('acc -> 'p t -> 'acc * 'p t) -> 'acc -> 'p container -> 'acc * 'p container
258
259 (** You can use [Traverse.Unoptimized] for quick prototyping.*)
260 (** *)
261 val iter : ('p t -> unit) -> 'p container -> unit
262 val map : ('p t -> 'p t) -> 'p container -> 'p container
263 val fold : ('acc -> 'p t -> 'acc) -> 'acc -> 'p container -> 'acc
264
265 end
266
267
268 (** {6 Traverse AB} *)
269
270 (**
271 Traverse AB is a support for an ast defined with 2 mutual recursive types
272 {[
273 type 'a tA = phi('a tA, 'a tB)
274 and 'b tB = xhi('a tA, 'a tB)
275 ]}
276 The rest is less documented, since it is more or less like the previous TRAVERSE,
277 and mostly because it is used only by maniac geeks.
278 *)
279
280 module type TRAVERSE_12 =
281 sig
282
283 type 'p t1 constraint 'p = _ * _ * _
284 type 'p t2 constraint 'p = _ * _ * _
285
286 (** {6 Higher-order traverse functions} *)
287 (** *)
288 val traverse_iter :
289 (('p t1 -> unit) -> ('p t2 -> unit) -> 'p t1 -> unit) ->
290 (('p t2 -> unit) -> ('p t1 -> unit) -> 'p t2 -> unit) ->
291 'p t1 -> unit
292 val traverse_map :
293 (('p t1 -> 'p t1) -> ('p t2 -> 'p t2) -> 'p t1 -> 'p t1) ->
294 (('p t2 -> 'p t2) -> ('p t1 -> 'p t1) -> 'p t2 -> 'p t2) ->
295 'p t1 -> 'p t1
296 val traverse_fold :
297 (('acc -> 'p t1 -> 'acc) -> ('acc -> 'p t2 -> 'acc) -> 'acc -> 'p t1 -> 'acc) ->
298 (('acc -> 'p t2 -> 'acc) -> ('acc -> 'p t1 -> 'acc) -> 'acc -> 'p t2 -> 'acc) ->
299 'acc -> 'p t1 -> 'acc
300 val traverse_foldmap :
301 (('acc -> 'p t1 -> 'acc * 'p t1) -> ('acc -> 'p t2 -> 'acc * 'p t2) ->
302 'acc -> 'p t1 -> 'acc * 'p t1) ->
303 (('acc -> 'p t2 -> 'acc * 'p t2) -> ('acc -> 'p t1 -> 'acc * 'p t1) ->
304 'acc -> 'p t2 -> 'acc * 'p t2) ->
305 'acc -> 'p t1 -> 'acc * 'p t1
306 val traverse_exists :
307 (('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool) ->
308 (('p t2 -> bool) -> ('p t1 -> bool) -> 'p t2 -> bool) ->
309 'p t1 -> bool
310 val traverse_forall :
311 (('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool) ->
312 (('p t2 -> bool) -> ('p t1 -> bool) -> 'p t2 -> bool) ->
313 'p t1 -> bool
314 val traverse_findmap :
315 (('p t1 -> 'a option) -> ('p t2 -> 'a option) -> 'p t1 -> 'a option) ->
316 (('p t2 -> 'a option) -> ('p t1 -> 'a option) -> 'p t2 -> 'a option) ->
317 'p t1 -> 'a option
318
319 val self_traverse_iter :
320 (('p t1 -> unit) -> ('p t1 -> unit) -> ('p t2 -> unit) -> ('p t2 -> unit) -> 'p t1 -> unit) ->
321 (('p t2 -> unit) -> ('p t2 -> unit) -> ('p t1 -> unit) -> ('p t1 -> unit) -> 'p t2 -> unit) ->
322 'p t1 -> unit
323 val self_traverse_map :
324 (('p t1 -> 'p t1) -> ('p t1 -> 'p t1) -> ('p t2 -> 'p t2) -> ('p t2 -> 'p t2) -> 'p t1 -> 'p t1) ->
325 (('p t2 -> 'p t2) -> ('p t2 -> 'p t2) -> ('p t1 -> 'p t1) -> ('p t1 -> 'p t1) -> 'p t2 -> 'p t2) ->
326 'p t1 -> 'p t1
327 val self_traverse_fold :
328 (('acc -> 'p t1 -> 'acc) -> ('acc -> 'p t1 -> 'acc) -> ('acc -> 'p t2 -> 'acc) -> ('acc -> 'p t2 -> 'acc) -> 'acc -> 'p t1 -> 'acc) ->
329 (('acc -> 'p t2 -> 'acc) -> ('acc -> 'p t2 -> 'acc) -> ('acc -> 'p t1 -> 'acc) -> ('acc -> 'p t1 -> 'acc) -> 'acc -> 'p t2 -> 'acc) ->
330 'acc -> 'p t1 -> 'acc
331 val self_traverse_foldmap :
332 (('acc -> 'p t1 -> 'acc * 'p t1) -> ('acc -> 'p t1 -> 'acc * 'p t1) -> ('acc -> 'p t2 -> 'acc * 'p t2) -> ('acc -> 'p t2 -> 'acc * 'p t2) -> 'acc -> 'p t1 -> 'acc * 'p t1) ->
333 (('acc -> 'p t2 -> 'acc * 'p t2) -> ('acc -> 'p t2 -> 'acc * 'p t2) -> ('acc -> 'p t1 -> 'acc * 'p t1) -> ('acc -> 'p t1 -> 'acc * 'p t1) -> 'acc -> 'p t2 -> 'acc * 'p t2) ->
334 'acc -> 'p t1 -> 'acc * 'p t1
335 val self_traverse_exists :
336 (('p t1 -> bool) -> ('p t1 -> bool) -> ('p t2 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool) ->
337 (('p t2 -> bool) -> ('p t2 -> bool) -> ('p t1 -> bool) -> ('p t1 -> bool) -> 'p t2 -> bool) ->
338 'p t1 -> bool
339 val self_traverse_forall :
340 (('p t1 -> bool) -> ('p t1 -> bool) -> ('p t2 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool) ->
341 (('p t2 -> bool) -> ('p t2 -> bool) -> ('p t1 -> bool) -> ('p t1 -> bool) -> 'p t2 -> bool) ->
342 'p t1 -> bool
343 val self_traverse_findmap :
344 (('p t1 -> 'a option) -> ('p t1 -> 'a option) -> ('p t2 -> 'a option) -> ('p t2 -> 'a option) -> 'p t1 -> 'a option) ->
345 (('p t2 -> 'a option) -> ('p t2 -> 'a option) -> ('p t1 -> 'a option) -> ('p t1 -> 'a option) -> 'p t2 -> 'a option) ->
346 'p t1 -> 'a option
347
348 (** {6 Usual traverse functions} *)
349
350 (** {9 iter} *)
351 (** *)
352 val iter : ('p t1 -> unit) -> ('p t2 -> unit) -> 'p t1 -> unit
353 val iter_up : ('p t1 -> unit) -> ('p t2 -> unit) -> 'p t1 -> unit
354 val iter_down : ('p t1 -> unit) -> ('p t2 -> unit) -> 'p t1 -> unit
355
356 (** {9 map} *)
357 (** *)
358 val map : ('p t1 -> 'p t1) -> ('p t2 -> 'p t2) -> 'p t1 -> 'p t1
359 val map_up : ('p t1 -> 'p t1) -> ('p t2 -> 'p t2) -> 'p t1 -> 'p t1
360 val map_down : ('p t1 -> 'p t1) -> ('p t2 -> 'p t2) -> 'p t1 -> 'p t1
361
362 (** {9 fold} *)
363 (** *)
364 val fold : ('a -> 'p t1 -> 'a) -> ('a -> 'p t2 -> 'a) -> 'a -> 'p t1 -> 'a
365 val fold_up : ('a -> 'p t1 -> 'a) -> ('a -> 'p t2 -> 'a) -> 'a -> 'p t1 -> 'a
366 val fold_down : ('a -> 'p t1 -> 'a) -> ('a -> 'p t2 -> 'a) -> 'a -> 'p t1 -> 'a
367
368 (** {9 foldmap} *)
369 (** *)
370 val foldmap : ('a -> 'p t1 -> 'a * 'p t1) -> ('a -> 'p t2 -> 'a * 'p t2) -> 'a -> 'p t1 -> 'a * 'p t1
371 val foldmap_up : ('a -> 'p t1 -> 'a * 'p t1) -> ('a -> 'p t2 -> 'a * 'p t2) -> 'a -> 'p t1 -> 'a * 'p t1
372 val foldmap_down : ('a -> 'p t1 -> 'a * 'p t1) -> ('a -> 'p t2 -> 'a * 'p t2) -> 'a -> 'p t1 -> 'a * 'p t1
373
374 (** {9 exists} *)
375 (** *)
376 val exists : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool
377 val exists_up : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool
378 val exists_down : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool
379
380 (** {9 find} *)
381 (** *)
382 val find : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> ('p t1, 'p t2) Base.either option
383 val find_up : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> ('p t1, 'p t2) Base.either option
384 val find_down : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> ('p t1, 'p t2) Base.either option
385
386 (** {9 findmap} *)
387 (** *)
388 val findmap : ('p t1 -> 'a option) -> ('p t2 -> 'a option) -> 'p t1 -> 'a option
389 val findmap_up : ('p t1 -> 'a option) -> ('p t2 -> 'a option) -> 'p t1 -> 'a option
390 val findmap_down : ('p t1 -> 'a option) -> ('p t2 -> 'a option) -> 'p t1 -> 'a option
391
392 val traverse_foldmap_context_down :
393 (('env -> 'acc -> 'p t1 -> 'acc * 'p t1) -> ('env -> 'acc -> 'p t2 -> 'acc * 'p t2) ->
394 'env -> 'acc -> 'p t1 -> 'acc * 'p t1) ->
395 (('env -> 'acc -> 'p t2 -> 'acc * 'p t2) -> ('env -> 'acc -> 'p t1 -> 'acc * 'p t1) ->
396 'env -> 'acc -> 'p t2 -> 'acc * 'p t2) ->
397 'env -> 'acc -> 'p t1 -> 'acc * 'p t1
398 val traverse_map_context_down :
399 (('env -> 'p t1 -> 'p t1) -> ('env -> 'p t2 -> 'p t2) ->
400 'env -> 'p t1 -> 'p t1) ->
401 (('env -> 'p t2 -> 'p t2) -> ('env -> 'p t1 -> 'p t1) ->
402 'env -> 'p t2 -> 'p t2) ->
403 'env -> 'p t1 -> 'p t1
404 val traverse_fold_context_down :
405 (('env -> 'acc -> 'p t1 -> 'acc) -> ('env -> 'acc -> 'p t2 -> 'acc) ->
406 'env -> 'acc -> 'p t1 -> 'acc) ->
407 (('env -> 'acc -> 'p t2 -> 'acc) -> ('env -> 'acc -> 'p t1 -> 'acc) ->
408 'env -> 'acc -> 'p t2 -> 'acc) ->
409 'env -> 'acc -> 'p t1 -> 'acc
410 val traverse_iter_context_down :
411 (('env -> 'p t1 -> unit) -> ('env -> 'p t2 -> unit) ->
412 'env -> 'p t1 -> unit) ->
413 (('env -> 'p t2 -> unit) -> ('env -> 'p t1 -> unit) ->
414 'env -> 'p t2 -> unit) ->
415 'env -> 'p t1 -> unit
416 val traverse_forall_context_down :
417 (('env -> 'p t1 -> bool) -> ('env -> 'p t2 -> bool) ->
418 'env -> 'p t1 -> bool) ->
419 (('env -> 'p t2 -> bool) -> ('env -> 'p t1 -> bool) ->
420 'env -> 'p t2 -> bool) ->
421 'env -> 'p t1 -> bool
422 val traverse_exists_context_down :
423 (('env -> 'p t1 -> bool) -> ('env -> 'p t2 -> bool) ->
424 'env -> 'p t1 -> bool) ->
425 (('env -> 'p t2 -> bool) -> ('env -> 'p t1 -> bool) ->
426 'env -> 'p t2 -> bool) ->
427 'env -> 'p t1 -> bool
428
429 val self_traverse_foldmap_context_down :
430 (('env -> 'acc -> 'p t1 -> 'acc * 'p t1) -> ('env -> 'acc -> 'p t1 -> 'acc * 'p t1) -> ('env -> 'acc -> 'p t2 -> 'acc * 'p t2) -> ('env -> 'acc -> 'p t2 -> 'acc * 'p t2) -> 'env -> 'acc -> 'p t1 -> 'acc * 'p t1) ->
431 (('env -> 'acc -> 'p t2 -> 'acc * 'p t2) -> ('env -> 'acc -> 'p t2 -> 'acc * 'p t2) -> ('env -> 'acc -> 'p t1 -> 'acc * 'p t1) -> ('env -> 'acc -> 'p t1 -> 'acc * 'p t1) -> 'env -> 'acc -> 'p t2 -> 'acc * 'p t2) ->
432 'env -> 'acc -> 'p t1 -> 'acc * 'p t1
433 val self_traverse_map_context_down :
434 (('env -> 'p t1 -> 'p t1) -> ('env -> 'p t1 -> 'p t1) -> ('env -> 'p t2 -> 'p t2) -> ('env -> 'p t2 -> 'p t2) -> 'env -> 'p t1 -> 'p t1) ->
435 (('env -> 'p t2 -> 'p t2) -> ('env -> 'p t2 -> 'p t2) -> ('env -> 'p t1 -> 'p t1) -> ('env -> 'p t1 -> 'p t1) -> 'env -> 'p t2 -> 'p t2) ->
436 'env -> 'p t1 -> 'p t1
437 val self_traverse_fold_context_down :
438 (('env -> 'acc -> 'p t1 -> 'acc) -> ('env -> 'acc -> 'p t1 -> 'acc) -> ('env -> 'acc -> 'p t2 -> 'acc) -> ('env -> 'acc -> 'p t2 -> 'acc) -> 'env -> 'acc -> 'p t1 -> 'acc) ->
439 (('env -> 'acc -> 'p t2 -> 'acc) -> ('env -> 'acc -> 'p t2 -> 'acc) -> ('env -> 'acc -> 'p t1 -> 'acc) -> ('env -> 'acc -> 'p t1 -> 'acc) -> 'env -> 'acc -> 'p t2 -> 'acc) ->
440 'env -> 'acc -> 'p t1 -> 'acc
441 val self_traverse_iter_context_down :
442 (('env -> 'p t1 -> unit) -> ('env -> 'p t1 -> unit) -> ('env -> 'p t2 -> unit) -> ('env -> 'p t2 -> unit) -> 'env -> 'p t1 -> unit) ->
443 (('env -> 'p t2 -> unit) -> ('env -> 'p t2 -> unit) -> ('env -> 'p t1 -> unit) -> ('env -> 'p t1 -> unit) -> 'env -> 'p t2 -> unit) ->
444 'env -> 'p t1 -> unit
445 val self_traverse_forall_context_down :
446 (('env -> 'p t1 -> bool) -> ('env -> 'p t1 -> bool) -> ('env -> 'p t2 -> bool) -> ('env -> 'p t2 -> bool) -> 'env -> 'p t1 -> bool) ->
447 (('env -> 'p t2 -> bool) -> ('env -> 'p t2 -> bool) -> ('env -> 'p t1 -> bool) -> ('env -> 'p t1 -> bool) -> 'env -> 'p t2 -> bool) ->
448 'env -> 'p t1 -> bool
449 val self_traverse_exists_context_down :
450 (('env -> 'p t1 -> bool) -> ('env -> 'p t1 -> bool) -> ('env -> 'p t2 -> bool) -> ('env -> 'p t2 -> bool) -> 'env -> 'p t1 -> bool) ->
451 (('env -> 'p t2 -> bool) -> ('env -> 'p t2 -> bool) -> ('env -> 'p t1 -> bool) -> ('env -> 'p t1 -> bool) -> 'env -> 'p t2 -> bool) ->
452 'env -> 'p t1 -> bool
453
454 (** {9 iterating with a context}*)
455 (** *)
456 val foldmap_context_down :
457 ('env -> 'acc -> 'p t1 -> 'env * 'acc * 'p t1) ->
458 ('env -> 'acc -> 'p t2 -> 'env * 'acc * 'p t2) ->
459 'env -> 'acc -> 'p t1 -> 'acc * 'p t1
460 val map_context_down :
461 ('env -> 'p t1 -> 'env * 'p t1) ->
462 ('env -> 'p t2 -> 'env * 'p t2) ->
463 'env -> 'p t1 -> 'p t1
464 val iter_context_down :
465 ('env -> 'p t1 -> 'env) ->
466 ('env -> 'p t2 -> 'env) ->
467 'env -> 'p t1 -> unit
468
469 (** {9 non rec}*)
470 (** *)
471 val iter_nonrec : ('p t1 -> unit) -> ('p t2 -> unit) -> 'p t1 -> unit
472 val map_nonrec : ('p t1 -> 'p t1) -> ('p t2 -> 'p t2) -> 'p t1 -> 'p t1
473 val fold_nonrec : ('a -> 'p t1 -> 'a) -> ('a -> 'p t2 -> 'a) -> 'a -> 'p t1 -> 'a
474 val foldmap_nonrec : ('a -> 'p t1 -> 'a * 'p t1) -> ('a -> 'p t2 -> 'a * 'p t2) -> 'a -> 'p t1 -> 'a * 'p t1
475 val exists_nonrec : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool
476 val forall_nonrec : ('p t1 -> bool) -> ('p t2 -> bool) -> 'p t1 -> bool
477 end
478
479 (** {6 Interfaces of Arguments for Traverse functors} *)
480 module type AB =
481 sig
482 type 'p tA constraint 'p = _ * _ * _
483 type 'p tB constraint 'p = _ * _ * _
484
485 val foldmapA :
486 ('acc -> 'p tA -> 'acc * 'p tA) ->
487 ('acc -> 'p tB -> 'acc * 'p tB) ->
488 'acc -> 'p tA -> 'acc * 'p tA
489
490 val foldmapB :
491 ('acc -> 'p tB -> 'acc * 'p tB) ->
492 ('acc -> 'p tA -> 'acc * 'p tA) ->
493 'acc -> 'p tB -> 'acc * 'p tB
494
495 (** other specific function *)
496 (**
497 Used for optimization purpose.
498 If you dont want to write it for quick prototyping, use the constructor
499 [Traverse.Unoptimized] on your [foldmapA/B] function
500 *)
501 (** *)
502
503 val iterA : ('p tA -> unit) -> ('p tB -> unit) -> 'p tA -> unit
504 val iterB : ('p tB -> unit) -> ('p tA -> unit) -> 'p tB -> unit
505
506 val mapA : ('p tA -> 'p tA) -> ('p tB -> 'p tB) -> 'p tA -> 'p tA
507 val mapB : ('p tB -> 'p tB) -> ('p tA -> 'p tA) -> 'p tB -> 'p tB
508
509 val foldA : ('acc -> 'p tA -> 'acc) -> ('acc -> 'p tB -> 'acc) -> 'acc -> 'p tA -> 'acc
510 val foldB : ('acc -> 'p tB -> 'acc) -> ('acc -> 'p tA -> 'acc) -> 'acc -> 'p tB -> 'acc
511 end
512
513 module type TRAVERSE_AB =
514 sig
515 type 'p tA constraint 'p = _ * _ * _
516 type 'p tB constraint 'p = _ * _ * _
517
518 module A : TRAVERSE_12
519 with type 'p t1 = 'p tA
520 and type 'p t2 = 'p tB
521
522 module B : TRAVERSE_12
523 with type 'p t1 = 'p tB
524 and type 'p t2 = 'p tA
525
526 module AinB : TRAVERSE
527 with type 'p t = 'p tA
528 and type 'p container = 'p tB
529
530 module BinA : TRAVERSE
531 with type 'p t = 'p tB
532 and type 'p container = 'p tA
533
534 module AinA : TRAVERSE
535 with type 'p t = 'p tA
536 and type 'p container = 'p tA
537
538 module BinB : TRAVERSE
539 with type 'p t = 'p tB
540 and type 'p container = 'p tB
541
542 module OnlyA : TRAVERSE
543 with type 'p t = 'p tA
544 and type 'p container = 'p tA
545
546 module OnlyB : TRAVERSE
547 with type 'p t = 'p tB
548 and type 'p container = 'p tB
549 end
550
551 (** {6 Lifting} *)
552 (**
553 Are you serious ?
554 *)
Something went wrong with that request. Please try again.