Documentation
containers lib
CCGen
Module
GeneratorsValues of type 'a Gen.t
represent a possibly infinite sequence of values of type 'a. One can only iterate once on the sequence, as it is consumed by iteration/deconstruction/access. None
is returned when the generator is exhausted. Most functions consume elements.
The submodule Restart
provides utilities to work with restartable generators , that is, functions unit -> 'a Gen.t
that allow to build as many generators from the same source as needed.
Global type declarationstype 'a t = unit -> 'a option
A generator may be called several times, yielding the next value each time. It returns None
when no elements remain
Common signature for transient and restartable generatorsThe signature S
abstracts on a type 'a t
, where the t
can be the type of transient or restartable generators. Some functions specify explicitely that they use 'a gen
(transient generators).
module type S = sig ... end
Transient generatorsval get : 'a t -> 'a option
val next : 'a t -> 'a option
Get the next value, or fails
Drop the next value, discarding it.
val repeatedly : (unit -> 'a ) -> 'a t
Call the same function an infinite number of times (useful for instance if the function is a random generator).
Operations on transient generators
include S with type 'a t := 'a gen
Empty generator, with no elements
val singleton : 'a -> 'a gen
val repeat : 'a -> 'a gen
Repeat same element endlessly
val iterate : 'a -> ('a -> 'a ) -> 'a gen
iterate x f
is [x; f x; f (f x); f (f (f x)); ...]
val unfold : ('b -> ('a * 'b ) option ) -> 'b -> 'a gen
Dual of fold
, with a deconstructing operation. It keeps on unfolding the 'b
value into a new 'b
, and a 'a
which is yielded, until None
is returned.
val init : ?limit :int -> (int -> 'a ) -> 'a gen
Calls the function, starting from 0, on increasing indices. If limit
is provided and is a positive int, iteration will stop at the limit (excluded). For instance init ~limit:4 id
will yield 0, 1, 2, and 3.
Basic combinatorsval is_empty : _ gen -> bool
Check whether the genertor is empty. Consumes one element if the generator isn't empty.
val fold : ('b -> 'a -> 'b ) -> 'b -> 'a gen -> 'b
Fold on the generator, tail-recursively; consumes it
val reduce : ('a -> 'a -> 'a ) -> 'a gen -> 'a
Fold on non-empty sequences
val scan : ('b -> 'a -> 'b ) -> 'b -> 'a gen -> 'b gen
Like fold
, but keeping successive values of the accumulator
val iter : ('a -> unit) -> 'a gen -> unit
Iterate on the generator, consuming it
val iteri : (int -> 'a -> unit) -> 'a gen -> unit
Iterate on elements with their index in the enum, from 0. Consumes it.
val length : _ gen -> int
Length of a generator (linear time, consumes its input)
val map : ('a -> 'b ) -> 'a gen -> 'b gen
Lazy map. No iteration is performed now, the function will be called when the result is traversed.
Append the two enums; the result contains the elements of the first, then the elements of the second enum.
Flatten the enumeration of generators
val flat_map : ('a -> 'b gen ) -> 'a gen -> 'b gen
Monadic bind; each element is transformed to a sub-enum which is then iterated on, before the next element is processed, and so on.
val mem : ?eq :('a -> 'a -> bool) -> 'a -> 'a gen -> bool
Is the given element, member of the enum?
val take : int -> 'a gen -> 'a gen
val drop : int -> 'a gen -> 'a gen
val nth : int -> 'a gen -> 'a
n-th element, or Not_found
val take_nth : int -> 'a gen -> 'a gen
take_nth n g
returns every element of g
whose index is a multiple of n
. For instance take_nth 2 (1--10) |> to_list
will return 1;3;5;7;9
val filter : ('a -> bool) -> 'a gen -> 'a gen
Filter out elements that do not satisfy the predicate.
val take_while : ('a -> bool) -> 'a gen -> 'a gen
Take elements while they satisfy the predicate
val drop_while : ('a -> bool) -> 'a gen -> 'a gen
Drop elements while they satisfy the predicate
val filter_map : ('a -> 'b option ) -> 'a gen -> 'b gen
Maps some elements to 'b, drop the other ones
val zip_index : 'a gen -> (int * 'a ) gen
Zip elements with their index in the enum
Unzip into two sequences, splitting each pair
val partition : ('a -> bool) -> 'a gen -> 'a gen * 'a gen
partition p l
returns the elements that satisfy p
, and the elements that do not satisfy p
val for_all : ('a -> bool) -> 'a gen -> bool
Is the predicate true for all elements?
val exists : ('a -> bool) -> 'a gen -> bool
Is the predicate true for at least one element?
val min : ?lt :('a -> 'a -> bool) -> 'a gen -> 'a
Minimum element, according to the given comparison function.
val max : ?lt :('a -> 'a -> bool) -> 'a gen -> 'a
val eq : ?eq :('a -> 'a -> bool) -> 'a gen -> 'a gen -> bool
val lexico : ?cmp :('a -> 'a -> int) -> 'a gen -> 'a gen -> int
Lexicographic comparison of generators. If a generator is a prefix of the other one, it is considered smaller.
val compare : ?cmp :('a -> 'a -> int) -> 'a gen -> 'a gen -> int
val find : ('a -> bool) -> 'a gen -> 'a option
find p e
returns the first element of e
to satisfy p
, or None.
Multiple iteratorsval map2 : ('a -> 'b -> 'c ) -> 'a gen -> 'b gen -> 'c gen
Map on the two sequences. Stops once one of them is exhausted.
val iter2 : ('a -> 'b -> unit) -> 'a gen -> 'b gen -> unit
Iterate on the two sequences. Stops once one of them is exhausted.
val fold2 : ('acc -> 'a -> 'b -> 'acc ) -> 'acc -> 'a gen -> 'b gen -> 'acc
Fold the common prefix of the two iterators
val for_all2 : ('a -> 'b -> bool) -> 'a gen -> 'b gen -> bool
Succeeds if all pairs of elements satisfy the predicate. Ignores elements of an iterator if the other runs dry.
val exists2 : ('a -> 'b -> bool) -> 'a gen -> 'b gen -> bool
Succeeds if some pair of elements satisfy the predicate. Ignores elements of an iterator if the other runs dry.
val zip_with : ('a -> 'b -> 'c ) -> 'a gen -> 'b gen -> 'c gen
Combine common part of the enums (stops when one is exhausted)
Zip together the common part of the enums
Complex combinatorsPick elements fairly in each sub-generator. The merge of enums e1, e2, ...
picks elements in e1
, e2
, in e3
, e1
, e2
.... Once a generator is empty, it is skipped; when they are all empty, and none remains in the input, their merge is also empty. For instance, merge [1;3;5] [2;4;6]
will be, in disorder, 1;2;3;4;5;6
.
val intersection : ?cmp :('a -> 'a -> int) -> 'a gen -> 'a gen -> 'a gen
Intersection of two sorted sequences. Only elements that occur in both inputs appear in the output
val sorted_merge : ?cmp :('a -> 'a -> int) -> 'a gen -> 'a gen -> 'a gen
Merge two sorted sequences into a sorted sequence
val sorted_merge_n : ?cmp :('a -> 'a -> int) -> 'a gen list -> 'a gen
Sorted merge of multiple sorted sequences
val tee : ?n :int -> 'a gen -> 'a gen list
Duplicate the enum into n
generators (default 2). The generators share the same underlying instance of the enum, so the optimal case is when they are consumed evenly
val round_robin : ?n :int -> 'a gen -> 'a gen list
Split the enum into n
generators in a fair way. Elements with index = k mod n
with go to the k-th enum. n
default value is 2.
interleave a b
yields an element of a
, then an element of b
, and so on. When a generator is exhausted, this behaves like the other generator.
val intersperse : 'a -> 'a gen -> 'a gen
Put the separator element between all elements of the given enum
val product : 'a gen -> 'b gen -> ('a * 'b ) gen
Cartesian product, in no predictable order. Works even if some of the arguments are infinite.
val group : ?eq :('a -> 'a -> bool) -> 'a gen -> 'a list gen
Group equal consecutive elements together.
val uniq : ?eq :('a -> 'a -> bool) -> 'a gen -> 'a gen
Remove consecutive duplicate elements. Basically this is like fun e -> map List.hd (group e)
.
val sort : ?cmp :('a -> 'a -> int) -> 'a gen -> 'a gen
Sort according to the given comparison function. The enum must be finite.
val sort_uniq : ?cmp :('a -> 'a -> int) -> 'a gen -> 'a gen
Sort and remove duplicates. The enum must be finite.
val chunks : int -> 'a gen -> 'a array gen
chunks n e
returns a generator of arrays of length n
, composed of successive elements of e
. The last array may be smaller than n
Basic conversion functionsval of_list : 'a list -> 'a gen
Enumerate elements of the list
val to_list : 'a gen -> 'a list
non tail-call trasnformation to list, in the same order
val to_rev_list : 'a gen -> 'a list
Tail call conversion to list, in reverse order (more efficient)
val to_array : 'a gen -> 'a array
Convert the enum to an array (not very efficient)
val of_array : ?start :int -> ?len :int -> 'a array -> 'a gen
Iterate on (a slice of) the given array
val rand_int : int -> int gen
Random ints in the given range.
val int_range : int -> int -> int gen
int_range a b
enumerates integers between a
and b
, included. a
is assumed to be smaller than b
.
module Infix : sig ... end
val (--) : int -> int -> int gen
val (>>=) : 'a gen -> ('a -> 'b gen ) -> 'b gen
val pp :
?start :string ->
?stop :string ->
?sep :string ->
?horizontal :bool ->
(Format .formatter -> 'a -> unit) ->
Format .formatter ->
'a gen ->
unit
Pretty print the content of the generator on a formatter.
Restartable generators UtilsStore content of the transient generator in memory, to be able to iterate on it several times later. If possible, consider using combinators from Restart
directly instead.
Create a new transient generator. start gen
is the same as gen ()
but is included for readability.