2
* Enum - enumeration over abstract collection of elements.
3
* Copyright (C) 2003 Nicolas Cannasse
4
* 2009 David Rajchenbach-Teller, LIFO, Universite d'Orleans
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version,
10
* with the special exception on linking described in file LICENSE.
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
Enumeration over abstract collection of elements.
24
Enumerations are a representation of finite or infinite sequences
25
of elements. In Batteries Included, enumerations are used
26
pervasively, both as a uniform manner of reading and manipulating
27
the contents of a data structure, or as a simple manner of reading
28
or writing sequences of characters, numbers, strings, etc. from/to
29
files, network connections or other inputs/outputs.
31
Enumerations are typically computed as needed, which allows the
32
definition and manipulation of huge (possibly infinite) sequences.
33
Manipulating an enumeration is a uniform and often comfortable way
34
of extracting subsequences (function {!filter} or operator [//] et
35
al), converting sequences into other sequences (function {!map} or
36
operators [/@] and [@/] et al), gathering information (function
37
{!scanl} et al) or performing loops (functions {!iter} and
40
For instance, function {!ExtRandom.Random.enum_int} creates an
41
infinite enumeration of random numbers. Combined with [//]
42
and {!map}, we may turn this into an infinite enumeration of
43
squares of random even numbers:
44
[map (fun x -> x * x) ( (Random.enum_int 100) // even )]
46
Similarly, to obtain an enumeration of 50 random integers,
47
we may use {!take}, as follows:
48
[take 50 (Random.enum_int 100)]
50
As most data structures in Batteries can be enumerated and built
51
from enumerations, these operations may be used also on lists,
52
arrays, hashtables, etc. When designing a new data structure, it
53
is usuallly a good idea to allow enumeration and construction
56
{b Note} Enumerations are not thread-safe. You should not attempt
57
to access one enumeration from different threads.
59
@author Nicolas Cannasse
60
@author David Rajchenbach-Teller
65
(** A signature for data structures which may be converted to and from [enum].
67
If you create a new data structure, you should make it compatible
70
module type Enumerable = sig
71
type 'a enumerable (** The data structure, e.g. ['a List.t] *)
73
val enum : 'a enumerable -> 'a t
74
(** Return an enumeration of the elements of the data structure *)
76
val of_enum : 'a t -> 'a enumerable
77
(** Build a data structure from an enumeration *)
80
include Enumerable with type 'a enumerable = 'a t
81
include Interfaces.Mappable with type 'a mappable = 'a t
84
(** {6 Final functions}
86
These functions consume the enumeration until
87
it ends or an exception is raised by the first
91
val iter : ('a -> unit) -> 'a t -> unit
92
(** [iter f e] calls the function [f] with each elements of [e] in turn. *)
94
val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unit
95
(** [iter2 f e1 e2] calls the function [f] with the next elements of [e] and
96
[e2] repeatedly until one of the two enumerations ends. *)
98
val exists: ('a -> bool) -> 'a t -> bool
99
(** [exists f e] returns [true] if there is some [x] in [e] such
102
val for_all: ('a -> bool) -> 'a t -> bool
103
(** [for_all f e] returns [true] if for every [x] in [e], [f x] is true*)
105
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
106
(** A general loop on an enumeration.
108
If [e] is empty, [fold f v e] returns [v]. Otherwise, [fold v e]
109
returns [f (... (f (f v a1) a2) ...) aN] where a1..N are the
110
elements of [e]. This function may be used, for instance, to
111
compute the sum of all elements of an enumeration [e] as follows:
115
val reduce : ('a -> 'a -> 'a) -> 'a t -> 'a
116
(** A simplified version of [fold], which uses the first element
117
of the enumeration as a default value.
119
[fold f e] throws [Not_found] if [e] is empty, returns its only
120
element if e is a singleton, otherwise [f (... (f (f a1 a2)
121
a3)...) aN] where a1..N are the elements of [e]. *)
123
val fold2 : ('a -> 'b -> 'c -> 'c) -> 'c -> 'a t -> 'b t -> 'c
124
(** [fold2] is similar to [fold] but will fold over two enumerations at the
125
same time until one of the two enumerations ends. *)
127
val scanl : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b t
128
(** A variant of [fold] producing an enumeration of its intermediate values.
129
If [e] contains [x1], [x2], ..., [scanl f init e] is the enumeration
130
containing [init], [f init x1], [f (f init x1) x2]... *)
132
val scan : ('a -> 'a -> 'a) -> 'a t -> 'a t
133
(** [scan] is similar to [scanl] but without the [init] value: if [e]
134
contains [x1], [x2], [x3] ..., [scan f e] is the enumeration containing
135
[x1], [f x1 x2], [f (f x1 x2) x3]...
138
For instance, [scan ( * ) (1 -- 10)] will produce an enumeration
139
containing the successive values of the factorial function.*)
144
(** Indexed functions : these functions are similar to previous ones
145
except that they call the function with one additional argument which
146
is an index starting at 0 and incremented after each call to the function. *)
148
val iteri : (int -> 'a -> unit) -> 'a t -> unit
150
val iter2i : ( int -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit
152
val foldi : (int -> 'a -> 'b -> 'b) -> 'b -> 'a t -> 'b
154
val fold2i : (int -> 'a -> 'b -> 'c -> 'c) -> 'c -> 'a t -> 'b t -> 'c
156
(** {6 Useful functions} *)
158
val find : ('a -> bool) -> 'a t -> 'a
159
(** [find f e] returns the first element [x] of [e] such that [f x] returns
160
[true], consuming the enumeration up to and including the
161
found element, or, raises [Not_found] if no such element exists
162
in the enumeration, consuming the whole enumeration in the search.
164
Since [find] consumes a prefix of the enumeration, it can be used several
165
times on the same enumeration to find the next element. *)
167
val is_empty : 'a t -> bool
168
(** [is_empty e] returns true if [e] does not contains any element. *)
170
val peek : 'a t -> 'a option
171
(** [peek e] returns [None] if [e] is empty or [Some x] where [x] is
172
the next element of [e]. The element is not removed from the
175
val get : 'a t -> 'a option
176
(** [get e] returns [None] if [e] is empty or [Some x] where [x] is
177
the next element of [e], in which case the element is removed
178
from the enumeration. *)
180
val push : 'a t -> 'a -> unit
181
(** [push e x] will add [x] at the beginning of [e]. *)
183
val junk : 'a t -> unit
184
(** [junk e] removes the first element from the enumeration, if any. *)
186
val clone : 'a t -> 'a t
187
(** [clone e] creates a new enumeration that is copy of [e]. If [e]
188
is consumed by later operations, the clone will not get affected. *)
190
val force : 'a t -> unit
191
(** [force e] forces the application of all lazy functions and the
192
enumeration of all elements, exhausting the enumeration.
194
An efficient intermediate data structure
195
of enumerated elements is constructed and [e] will now enumerate over
196
that data structure. *)
198
val take : int -> 'a t -> 'a t
199
(** [take n e] returns the prefix of [e] of length [n], or [e]
200
itself if [n] is greater than the length of [e] *)
202
val drop : int -> 'a t -> unit
203
(** [drop n e] removes the first [n] element from the enumeration, if any. *)
205
val skip: int -> 'a t -> 'a t
206
(** [skip n e] removes the first [n] element from the enumeration, if any,
209
This function has the same behavior as [drop] but is often easier to
210
compose with, e.g., [skip 5 |- take 3] is a new function which skips
211
5 elements and then returns the next 3 elements.*)
213
val take_while : ('a -> bool) -> 'a t -> 'a t
214
(** [take_while f e] produces a new enumeration in which only remain
215
the first few elements [x] of [e] such that [f x] *)
217
val drop_while : ('a -> bool) -> 'a t -> 'a t
218
(** [drop_while p e] produces a new enumeration in which only
219
all the first elements such that [f e] have been junked.*)
221
val span : ('a -> bool) -> 'a t -> 'a t * 'a t
222
(** [span test e] produces two enumerations [(hd, tl)], such that
223
[hd] is the same as [take_while test e] and [tl] is the same
224
as [drop_while test e]. *)
226
val break : ('a -> bool) -> 'a t -> 'a t * 'a t
228
[break test e] is equivalent to [span (fun x -> not (test x)) e] *)
230
val group : ('a -> bool) -> 'a t -> 'a t t
231
(** [group test e] devides [e] into an enumeration of enumerations, where
232
each sub-enumeration is the longest continuous enumeration of elements whose [test]
233
results are the same. *)
235
val clump : int -> ('a -> unit) -> (unit -> 'b) -> 'a t -> 'b t
236
(** [clump size add get e] runs [add] on [size] (or less at the end)
237
elements of [e] and then runs [get] to produce value for the
238
result enumeration. Useful to convert a char enum into string
241
(** {6 Lazy constructors}
243
These functions are lazy which means that they will create a new modified
244
enumeration without actually enumerating any element until they are asked
245
to do so by the programmer (using one of the functions above).
247
When the resulting enumerations of these functions are consumed, the
248
underlying enumerations they were created from are also consumed. *)
250
val map : ('a -> 'b) -> 'a t -> 'b t
251
(** [map f e] returns an enumeration over [(f a1, f a2, ... , f aN)] where
252
a1...N are the elements of [e]. *)
254
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t
255
(** [mapi] is similar to [map] except that [f] is passed one extra argument
256
which is the index of the element in the enumeration, starting from 0. *)
258
val filter : ('a -> bool) -> 'a t -> 'a t
259
(** [filter f e] returns an enumeration over all elements [x] of [e] such
260
as [f x] returns [true]. *)
262
val filter_map : ('a -> 'b option) -> 'a t -> 'b t
263
(** [filter_map f e] returns an enumeration over all elements [x] such as
264
[f y] returns [Some x] , where [y] is an element of [e]. *)
266
val append : 'a t -> 'a t -> 'a t
267
(** [append e1 e2] returns an enumeration that will enumerate over all
268
elements of [e1] followed by all elements of [e2].
270
{b Note} The behavior of appending [e] to itself or to something
271
derived from [e] is not specified. In particular, cloning [append e e]
272
may destroy any sharing between the first and the second argument.*)
274
val prefix_action : (unit -> unit) -> 'a t -> 'a t
275
(** [prefix_action f e] will behave as [e] but guarantees that [f ()]
276
will be invoked exactly once before the current first element of [e]
279
If [prefix_action f e] is cloned, [f] is invoked only once, during
280
the cloning. If [prefix_action f e] is counted, [f] is invoked
281
only once, during the counting.
283
May be used for signalling that reading starts or for performing
284
delayed evaluations.*)
286
val suffix_action : (unit -> unit) -> 'a t -> 'a t
287
(** [suffix_action f e] will behave as [e] but guarantees that [f ()]
288
will be invoked after the contents of [e] are exhausted.
290
If [suffix_action f e] is cloned, [f] is invoked only once, when
291
the original enumeration is exhausted. If [suffix_action f e]
292
is counted, [f] is only invoked if the act of counting
293
requires a call to [force].
295
May be used for signalling that reading stopped or for performing
296
delayed evaluations.*)
299
val concat : 'a t t -> 'a t
300
(** [concat e] returns an enumeration over all elements of all enumerations
303
val flatten : 'a t t -> 'a t
304
(** Synonym of {!concat}*)
308
In this section the word {i shall} denotes a semantic
309
requirement. The correct operation of the functions in this
310
interface are conditional on the client meeting these
314
exception No_more_elements
315
(** This exception {i shall} be raised by the [next] function of [make]
316
or [from] when no more elements can be enumerated, it {i shall not}
317
be raised by any function which is an argument to any
318
other function specified in the interface.
321
exception Infinite_enum
322
(** As a convenience for debugging, this exception {i may} be raised by
323
the [count] function of [make] when attempting to count an infinite enum.*)
325
val empty : unit -> 'a t
326
(** The empty enumeration : contains no element *)
328
val make : next:(unit -> 'a) -> count:(unit -> int) -> clone:(unit -> 'a t) -> 'a t
329
(** This function creates a fully defined enumeration.
331
{ul {li the [next] function {i shall} return the next element of the
332
enumeration or raise [No_more_elements] if the underlying data structure
333
does not have any more elements to enumerate.}
334
{li the [count] function {i shall} return the actual number of remaining
335
elements in the enumeration or {i may} raise [Infinite_enum] if it is known
336
that the enumeration is infinite.}
337
{li the [clone] function {i shall} create a clone of the enumeration
338
such as operations on the original enumeration will not affect the
341
For some samples on how to correctly use [make], you can have a look
342
at implementation of [ExtList.enum].
345
val from : (unit -> 'a) -> 'a t
346
(** [from next] creates an enumeration from the [next] function.
347
[next] {i shall} return the next element of the enumeration or raise
348
[No_more_elements] when no more elements can be enumerated. Since the
349
enumeration definition is incomplete, a call to [count] will result in
350
a call to [force] that will enumerate all elements in order to
351
return a correct value. *)
353
val from_while : (unit -> 'a option) -> 'a t
354
(** [from_while next] creates an enumeration from the [next] function.
355
[next] {i shall} return [Some x] where [x] is the next element of the
356
enumeration or [None] when no more elements can be enumerated. Since the
357
enumeration definition is incomplete, a call to [clone] or [count] will
358
result in a call to [force] that will enumerate all elements in order to
359
return a correct value. *)
361
val from_loop: 'b -> ('b -> ('a * 'b)) -> 'a t
362
(**[from_loop data next] creates a (possibly infinite) enumeration from
363
the successive results of applying [next] to [data], then to the
364
result, etc. The list ends whenever the function raises
365
{!Enum.No_more_elements}*)
367
val seq : 'a -> ('a -> 'a) -> ('a -> bool) -> 'a t
368
(** [seq init step cond] creates a sequence of data, which starts
369
from [init], extends by [step], until the condition [cond]
370
fails. E.g. [seq 1 ((+) 1) ((>) 100)] returns [1, 2, ... 99]. If [cond
371
init] is false, the result is empty. *)
374
val unfold: 'b -> ('b -> ('a * 'b) option) -> 'a t
375
(**More powerful version of [seq], with the ability of hiding data.
377
[unfold data next] creates a (possibly infinite) enumeration from
378
the successive results of applying [next] to [data], then to the
379
result, etc. The enumeration ends whenever the function returns [None]*)
381
val init : int -> (int -> 'a) -> 'a t
382
(** [init n f] creates a new enumeration over elements
383
[f 0, f 1, ..., f (n-1)] *)
385
val singleton : 'a -> 'a t
386
(** Create an enumeration consisting in exactly one element.*)
388
val repeat : ?times:int -> 'a -> 'a t
389
(** [repeat ~times:n x] creates a enum sequence filled with [n] times of
390
[x]. It return infinite enum when [~times] is absent. It returns empty
391
enum when [times <= 0] *)
393
val cycle : ?times:int -> 'a t -> 'a t
394
(** [cycle] is similar to [repeat], except that the content to fill is a
395
subenum rather than a single element. Note that [times] represents the
396
times of repeating not the length of enum. *)
398
val delay : (unit -> 'a t) -> 'a t
399
(** [delay (fun () -> e)] produces an enumeration which behaves as [e].
400
The enumeration itself will only be computed when consumed.
402
A typical use of this function is to explore lazily non-trivial
403
data structures, as follows:
406
| Node of 'a * 'a tree * 'a tree
409
let rec aux = function
410
| Leaf -> Enum.empty ()
411
| Node (n, l, r) -> Enum.append (Enum.singleton n)
412
(Enum.append (delay (fun () -> aux l))
413
(delay (fun () -> aux r)))
418
val to_object: 'a t -> (<next:'a; count:int; clone:'b> as 'b)
419
(**[to_object e] returns a representation of [e] as an object.*)
421
val of_object: (<next:'a; count:int; clone:'b> as 'b) -> 'a t
422
(**[of_object e] returns a representation of an object as an enumeration*)
424
val enum : 'a t -> 'a t
425
(** identity : added for consistency with the other data structures *)
426
val of_enum : 'a t -> 'a t
427
(** identity : added for consistency with the other data structures *)
431
val count : 'a t -> int
432
(** [count e] returns the number of remaining elements in [e] without
433
consuming the enumeration.
435
Depending of the underlying data structure that is implementing the
436
enumeration functions, the count operation can be costly, and even sometimes
437
can cause a call to [force]. *)
439
val fast_count : 'a t -> bool
440
(** For users worried about the speed of [count] you can call the [fast_count]
441
function that will give an hint about [count] implementation. Basically, if
442
the enumeration has been created with [make] or [init] or if [force] has
443
been called on it, then [fast_count] will return true. *)
445
val hard_count : 'a t -> int
446
(** [hard_count] returns the number of remaining in elements in [e],
447
consuming the whole enumeration somewhere along the way. This
448
function is always at least as fast as the fastest of either
449
[count] or a [fold] on the elements of [t].
451
This function is useful when you have opened an enumeration for
452
the sole purpose of counting its elements (e.g. the number of
458
val range : ?until:int -> int -> int t
459
(** [range p until:q] creates an enumeration of integers [[p, p+1, ..., q]].
460
If [until] is omitted, the enumeration is not bounded. Behaviour is
461
not-specified once [max_int] has been reached.*)
463
val ( -- ) : int -> int -> int t
464
(** As [range], without the label.
466
[5 -- 10] is the enumeration 5,6,7,8,9,10.
467
[10 -- 5] is the empty enumeration*)
469
val ( --. ) : (float * float) -> float -> float t
470
(** [(a, step) --. b)] creates a float enumeration from [a] to [b] with an
471
increment of [step] between elements.
473
[(5.0, 1.0) --. 10.0] is the enumeration 5.0,6.0,7.0,8.0,9.0,10.0.
474
[(10.0, -1.0) --. 5.0] is the enumeration 10.0,9.0,8.0,7.0,6.0,5.0.
475
[(10.0, 1.0) --. 1.0] is the empty enumeration. *)
477
val ( --- ) : int -> int -> int t
478
(** As [--], but accepts enumerations in reverse order.
480
[5 --- 10] is the enumeration 5,6,7,8,9,10.
481
[10 --- 5] is the enumeration 10,9,8,7,6,5.*)
483
val ( --~ ) : char -> char -> char t
484
(** As ( -- ), but for characters.*)
486
val ( // ) : 'a t -> ('a -> bool) -> 'a t
487
(** Filtering (pronounce this operator name "such that").
489
For instance, [(1 -- 37) // odd] is the enumeration of all odd
490
numbers between 1 and 37.*)
492
val ( /@ ) : 'a t -> ('a -> 'b) -> 'b t
494
val ( @/ ) : ('a -> 'b) -> 'a t -> 'b t
498
These operators have the same meaning as function {!map} but are
499
sometimes more readable than this function, when chaining
500
several transformations in a row.
504
val dup : 'a t -> 'a t * 'a t
505
(** [dup stream] returns a pair of streams which are identical to [stream]. Note
506
that stream is a destructive data structure, the point of [dup] is to
507
return two streams can be used independently. *)
509
val combine : 'a t * 'b t -> ('a * 'b) t
510
(** [combine] transform a pair of stream into a stream of pairs of corresponding
511
elements. If one stream is short, excess elements of the longer stream are
514
val uncombine : ('a * 'b) t -> 'a t * 'b t
515
(** [uncombine] is the opposite of [combine] *)
517
val merge : ('a -> 'a -> bool) -> 'a t -> 'a t -> 'a t
518
(** [merge test (a, b)] merge the elements from [a] and [b] into a single
519
enumeration. At each step, [test] is applied to the first element of
520
[a] and the first element of [b] to determine which should get first
521
into resulting enumeration. If [a] or [b] runs out of elements,
522
the process will append all elements of the other enumeration to
526
val uniq : 'a t -> 'a t
527
(** [uniq e] returns a duplicate of [e] with repeated values
528
omitted. (similar to unix's [uniq] command) *)
530
val compare : ('a -> 'a -> int) -> 'a t -> 'a t -> int
531
(** [compare cmp a b] compares enumerations [a] and [b]
532
by lexicographical order using comparison [cmp].
534
@return 0 if [a] and [b] are equal wrt [cmp]
535
@return -1 if [a] is empty and [b] is not
536
@return 1 if [b] is empty and [a] is not
537
@return [cmp x y], where [x] is the first element of [a]
538
and [y] is the first element of [b], if [cmp x y <> 0]
539
@return [compare cmp a' b'], where [a'] and [b'] are
540
respectively equal to [a] and [b] without their first
541
element, if both [a] and [b] are non-empty and [cmp x y = 0],
542
where [x] is the first element of [a] and [y] is the first
546
val switch : ('a -> bool) -> 'a t -> 'a t * 'a t
547
(** [switch test enum] splits [enum] into two enums, where the first enum have
548
all the elements satisfying [test], the second enum is opposite. The
549
order of elements in the source enum is preserved. *)
551
(*val switchn: int -> ('a -> int) -> 'a t -> 'a t array
552
(** [switchn] is the array version of [switch]. [switch n f fl] split [fl] to an array of [n] enums, [f] is
553
applied to each element of [fl] to decide the id of its destination
556
(** {6 Trampolining} *)
557
val while_do : ('a -> bool) -> ('a t -> 'a t) -> 'a t -> 'a t
558
(** [while_do cont f e] is a loop on [e] using [f] as body and [cont] as
559
condition for continuing.
561
If [e] contains elements [x1], [x2], [x3]..., then if [cont x1] is [false],
562
[x1] is returned as such and treatment stops. On the other hand, if [cont x1]
563
is [true], [f x1] is returned and the loop proceeds with [x2]...*)
567
(** {6 Boilerplate code}*)
569
val print : ?first:string -> ?last:string -> ?sep:string -> ('a InnerIO.output -> 'b -> unit) -> 'a InnerIO.output -> 'b t -> unit
570
(** Print and consume the contents of an enumeration.*)
572
val t_printer : 'a Value_printer.t -> 'a t Value_printer.t
574
(** {6 Override modules}*)
577
The following modules replace functions defined in {!Enum} with functions
578
behaving slightly differently but having the same name. This is by design:
579
the functions meant to override the corresponding functions of {!Enum}.
581
To take advantage of these overrides, you probably want to
582
{{:../extensions.html#multiopen}{open several modules in one
583
operation}} or {{:../extensions.html#multialias}{alias several
584
modules to one name}}. For instance, to open a version of {!Enum}
585
with exceptionless error management, you may write [open Enum,
586
Exceptionless]. To locally replace module {!Enum} with a module of
587
the same name but with exceptionless error management, you may
588
write {v module Enum = Enum include Exceptionless v}.
592
(** Operations on {!Enum} without exceptions.*)
593
module Exceptionless : sig
594
val find : ('a -> bool) -> 'a t -> 'a option
595
(** [find f e] returns [Some x] where [x] is the first element [x] of [e]
596
such that [f x] returns [true], consuming the enumeration up to and
597
including the found element, or [None] if no such element exists
598
in the enumeration, consuming the whole enumeration in the search.
600
Since [find] consumes a prefix of the enumeration, it can be used several
601
times on the same enumeration to find the next element. *)
605
(** Operations on {!Enum} with labels.
607
This module overrides a number of functions of {!Enum} by
608
functions in which some arguments require labels. These labels are
609
there to improve readability and safety and to let you change the
610
order of arguments to functions. In every case, the behavior of the
611
function is identical to that of the corresponding function of {!Enum}.
614
val iter: f:('a -> unit) -> 'a t -> unit
615
val iter2: f:('a -> 'b -> unit) -> 'a t -> 'b t -> unit
616
val exists: f:('a -> bool) -> 'a t -> bool
617
val for_all: f:('a -> bool) -> 'a t -> bool
618
val fold: f:('b -> 'a -> 'b) -> init:'b -> 'a t -> 'b
619
val fold2: f:('a -> 'b -> 'c -> 'c) -> init:'c -> 'a t -> 'b t -> 'c
620
val iteri: f:(int -> 'a -> unit) -> 'a t -> unit
621
val iter2i: f:( int -> 'a -> 'b -> unit) -> 'a t -> 'b t -> unit
622
val foldi: f:(int -> 'a -> 'b -> 'b) -> init:'b -> 'a t -> 'b
623
val fold2i: f:(int -> 'a -> 'b -> 'c -> 'c) -> init:'c -> 'a t -> 'b t -> 'c
624
val find: f:('a -> bool) -> 'a t -> 'a
625
val take_while: f:('a -> bool) -> 'a t -> 'a t
626
val drop_while: f:('a -> bool) -> 'a t -> 'a t
627
val map: f:('a -> 'b) -> 'a t -> 'b t
628
val mapi: f:(int -> 'a -> 'b) -> 'a t -> 'b t
629
val filter: f:('a -> bool) -> 'a t -> 'a t
630
val filter_map: f:('a -> 'b option) -> 'a t -> 'b t
631
val from: f:(unit -> 'a) -> 'a t
632
val from_while: f:(unit -> 'a option) -> 'a t
633
val from_loop: init:'b -> f:('b -> ('a * 'b)) -> 'a t
634
val seq: init:'a -> f:('a -> 'a) -> cnd:('a -> bool) -> 'a t
635
val unfold: init:'b -> f:('b -> ('a * 'b) option) -> 'a t
636
val init: int -> f:(int -> 'a) -> 'a t
637
val switch: f:('a -> bool) -> 'a t -> 'a t * 'a t
638
val compare: ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> int
639
(** [compare ~cmp a b] compares enumerations [a] and [b]
640
by lexicographical order using comparison [cmp].
642
@param cmp a comparison function. If left unspecified, {!Pervasives.compare}
644
@return 0 if [a] and [b] are equal wrt [cmp]
645
@return -1 if [a] is empty and [b] is not
646
@return 1 if [b] is empty and [a] is not
647
@return [cmp x y], where [x] is the first element of [a]
648
and [y] is the first element of [b], if [cmp x y <> 0]
649
@return [compare cmp a' b'], where [a'] and [b'] are
650
respectively equal to [a] and [b] without their first
651
element, if both [a] and [b] are non-empty and [cmp x y = 0],
652
where [x] is the first element of [a] and [y] is the first
656
module LExceptionless : sig
657
val find : f:('a -> bool) -> 'a t -> 'a option
663
(** {6 For system use only, not for the casual user}
665
For compatibility with {!Stream}
668
val iapp : 'a t -> 'a t -> 'a t
669
val icons : 'a -> 'a t -> 'a t
670
val ising : 'a -> 'a t
672
val lapp : (unit -> 'a t) -> 'a t -> 'a t
673
val lcons : (unit -> 'a) -> 'a t -> 'a t
674
val lsing : (unit -> 'a) -> 'a t
676
val slazy : (unit -> 'a t) -> 'a t