include module type of Seq
A sequence xs of type 'a t is a delayed list of elements of type 'a. Such a sequence is queried by performing a function application xs(). This function application returns a node, allowing the caller to determine whether the sequence is empty or nonempty, and in the latter case, to obtain its head and tail.
Sourceand +'a node = | Nil| Cons of 'a * 'a t
A node is either Nil, which means that the sequence is empty, or Cons (x, xs), which means that x is the first element of the sequence and that xs is the remainder of the sequence.
Consuming sequences
The functions in this section consume their argument, a sequence, either partially or completely:
is_empty and uncons consume the sequence down to depth 1. That is, they demand the first argument of the sequence, if there is one.iter, fold_left, length, etc., consume the sequence all the way to its end. They terminate only if the sequence is finite.for_all, exists, find, etc. consume the sequence down to a certain depth, which is a priori unpredictable.
Similarly, among the functions that consume two sequences, one can distinguish two groups:
iter2 and fold_left2 consume both sequences all the way to the end, provided the sequences have the same length.for_all2, exists2, equal, compare consume the sequences down to a certain depth, which is a priori unpredictable.
The functions that consume two sequences can be applied to two sequences of distinct lengths: in that case, the excess elements in the longer sequence are ignored. (It may be the case that one excess element is demanded, even though this element is not used.)
None of the functions in this section is lazy. These functions are consumers: they force some computation to take place.
Sourceval find_index : ('a -> bool) -> 'a t -> int option find_index p xs returns Some i, where i is the index of the first element of the sequence xs that satisfies p x, if there is such an element.
It returns None if there is no such element.
The sequence xs must be finite.
Sourceval find_mapi : (int -> 'a -> 'b option) -> 'a t -> 'b option Same as find_map, but the predicate is applied to the index of the element as first argument (counting from 0), and the element itself as second argument.
The sequence xs must be finite.
Constructing sequences
The functions in this section are lazy: that is, they return sequences whose elements are computed only when demanded.
The functions in this section are lazy: that is, they return sequences whose elements are computed only when demanded.
This exception is raised when a sequence returned by once (or a suffix of it) is queried more than once.
The sequence once xs has the same elements as the sequence xs.
Regardless of whether xs is ephemeral or persistent, once xs is an ephemeral sequence: it can be queried at most once. If it (or a suffix of it) is queried more than once, then the exception Forced_twice is raised. This can be useful, while debugging or testing, to ensure that a sequence is consumed at most once.
If xss is a matrix (a sequence of rows), then transpose xss is the sequence of the columns of the matrix xss.
The rows of the matrix xss are not required to have the same length.
The matrix xss is not required to be finite (in either direction).
The matrix xss must be persistent.
Combining sequences
Splitting a sequence into two sequences
partition_map f xs returns a pair of sequences (ys, zs), where:
ys is the sequence of the elements y such that f x = Left y, where x ranges over xs;
zs is the sequence of the elements z such that f x = Right z, where x ranges over xs.
partition_map f xs is equivalent to a pair of filter_map Either.find_left (map f xs) and filter_map Either.find_right (map f xs).
Querying either of the sequences returned by partition_map f xs causes xs to be queried. Therefore, querying both of them causes xs to be queried twice. Thus, xs must be persistent and cheap. If that is not the case, use partition_map f (memoize xs).
Sourceval partition : ('a -> bool) -> 'a t -> 'a t * 'a t partition p xs returns a pair of the subsequence of the elements of xs that satisfy p and the subsequence of the elements of xs that do not satisfy p.
partition p xs is equivalent to filter p xs, filter (fun x -> not (p x)) xs.
Consuming both of the sequences returned by partition p xs causes xs to be consumed twice and causes the function f to be applied twice to each element of the list. Therefore, f should be pure and cheap. Furthermore, xs should be persistent and cheap. If that is not the case, use partition p (memoize xs).
Converting between sequences and dispensers
A dispenser is a representation of a sequence as a function of type unit -> 'a option. Every time this function is invoked, it returns the next element of the sequence. When there are no more elements, it returns None. A dispenser has mutable internal state, therefore is ephemeral: the sequence that it represents can be consumed at most once.
Sourceval of_dispenser : (unit -> 'a option) -> 'a t of_dispenser it is the sequence of the elements produced by the dispenser it. It is an ephemeral sequence: it can be consumed at most once. If a persistent sequence is needed, use memoize (of_dispenser it).
Sourceval to_dispenser : 'a t -> unit -> 'a option to_dispenser xs is a fresh dispenser on the sequence xs.
This dispenser has mutable internal state, which is not protected by a lock; so, it must not be used by several threads concurrently.
Sequences of integers
ints i is the infinite sequence of the integers beginning at i and counting up.