The iterators are designed to allow easy transfer (mappings) between data structures, without defining
n^2 conversions between the
n types. The implementation relies on the assumption that a sequence can be iterated on as many times as needed; this choice allows for high performance of many combinators. However, for transient iterators, the
persistent function is provided, storing elements of a transient iterator in memory; the iterator can then be used several times (See further).
Note that some combinators also return sequences (e.g.
group). The transformation is computed on the fly every time one iterates over the resulting sequence. If a transformation performs heavy computation,
persistent can also be used as intermediate storage.
Most functions are lazy, i.e. they do not actually use their arguments until their result is iterated on. For instance, if one calls
map on a sequence, one gets a new sequence, but nothing else happens until this new sequence is used (by folding or iterating on it).
If a sequence is built from an iteration function that is repeatable (i.e. calling it several times always iterates on the same set of elements, for instance List.iter or Map.iter), then the resulting
t object is also repeatable. For one-time iter functions such as iteration on a file descriptor or a
persistent function can be used to iterate and store elements in a memory structure; the result is a sequence that iterates on the elements of this memory structure, cheaply and repeatably.
A sequence of values of type
'a. If you give it a function
'a -> unit it will be applied to every element of the sequence successively.
type +'a sequence = 'a t
val from_iter : ( ( 'a -> unit ) -> unit ) -> 'a t
Build a sequence from a iter function
val from_fun : ( unit -> 'a option ) -> 'a t
Call the function repeatedly until it returns None. This sequence is transient, use
persistent if needed!
val empty : 'a t
Empty sequence. It contains no element.
val singleton : 'a -> 'a t
Singleton sequence, with exactly one element.
val doubleton : 'a -> 'a -> 'a t
Sequence with exactly two elements
val repeat : 'a -> 'a t
Infinite sequence of the same element. You may want to look at
take and the likes if you iterate on it.
val iterate : ( 'a -> 'a ) -> 'a -> 'a t
iterate f x is the infinite sequence
x, f(x), f(f(x)), ...
val forever : ( unit -> 'b ) -> 'b t
Cycle forever through the given sequence. Assume the given sequence can be traversed any amount of times (not transient). This yields an infinite sequence, you should use something like
take not to loop forever.
val iter : ( 'a -> unit ) -> 'a t -> unit
Consume the sequence, passing all its arguments to the function. Basically
iter f seq is just
val iteri : ( int -> 'a -> unit ) -> 'a t -> unit
Iterate on elements and their index in the sequence
val fold : ( 'b -> 'a -> 'b ) -> 'b -> 'a t -> 'b
Fold over elements of the sequence, consuming it
val foldi : ( 'b -> int -> 'a -> 'b ) -> 'b -> 'a t -> 'b
Fold over elements of the sequence and their index, consuming it
val for_all : ( 'a -> bool ) -> 'a t -> bool
Do all elements satisfy the predicate?
val exists : ( 'a -> bool ) -> 'a t -> bool
Exists there some element satisfying the predicate?
val mem : ?eq:( 'a -> 'a -> bool ) -> 'a -> 'a t -> bool
Is the value a member of the sequence?
val find : ( 'a -> 'b option ) -> 'a t -> 'b option
Find the first element on which the function doesn't return
val length : 'a t -> int
How long is the sequence? Forces the sequence.
val is_empty : 'a t -> bool
Is the sequence empty? Forces the sequence.
Append two sequences. Iterating on the result is like iterating on the first, then on the second.
Monadic bind. Intuitively, it applies the function to every element of the initial sequence, and calls
Iterate on the sequence, storing elements in an efficient internal structure.. The resulting sequence can be iterated on as many times as needed. Note: calling persistent on an already persistent sequence will still make a new copy of the sequence!
Lazy version of
persistent. When calling
persistent_lazy s, a new sequence
s' is immediately returned (without actually consuming
s) in constant time; the first time
s' is iterated on, it also consumes
s and caches its content into a inner data structure that will back
s' for future iterations.
warning: on the first traversal of
s', if the traversal is interrupted prematurely (
take, etc.) then
s' will not be memorized, and the next call to
s' will traverse
Sort the sequence. Eager, O(n) ram and O(n ln(n)) time. It iterates on elements of the argument sequence immediately, before it sorts them.
Sort the sequence and remove duplicates. Eager, same as
Remove consecutive duplicate elements. Basically this is like
fun seq -> map List.hd (group seq).
Cartesian product of the sequences. When calling
product a b, the caller MUST ensure that
b can be traversed as many times as required (several times), possibly by calling
persistent on it beforehand.
join ~join_row a b combines every element of
a with every element of
join_row returns None, then the two elements do not combine. Assume that
b allows for multiple iterations.
val unfoldr : ( 'b -> ('a * 'b) option ) -> 'b -> 'a t
unfoldr f b will apply
b. If it yields
Some (x,b') then
x is returned and unfoldr recurses with
val max : ?lt:( 'a -> 'a -> bool ) -> 'a t -> 'a option
Max element of the sequence, using the given comparison function.
val min : ?lt:( 'a -> 'a -> bool ) -> 'a t -> 'a option
Min element of the sequence, using the given comparison function. see
max for more details.
val head : 'a t -> 'a option
First element, if any, otherwise
val head_exn : 'a t -> 'a
First element, if any, fails
Take at most
n elements from the sequence. Works on infinite sequences.
Take elements while they satisfy the predicate, then stops iterating. Will work on an infinite sequence
s if the predicate is false for at least one element of
Reverse the sequence. O(n) memory and time, needs the sequence to be finite. The result is persistent and does not depend on the input being repeatable.
val empty2 : ( 'a, 'b ) t2
val is_empty2 : ( _, _ ) t2 -> bool
val length2 : ( _, _ ) t2 -> int
val fold2 : ( 'c -> 'a -> 'b -> 'c ) -> 'c -> ( 'a, 'b ) t2 -> 'c
val iter2 : ( 'a -> 'b -> unit ) -> ( 'a, 'b ) t2 -> unit
map2_2 f g seq2 maps each
x, y of seq2 into
f x y, g x y
val to_list : 'a t -> 'a list
Convert the sequence into a list. Preserves order of elements. This function is tail-recursive, but consumes 2*n memory. If order doesn't matter to you, consider
val to_rev_list : 'a t -> 'a list
Get the list of the reversed sequence (more efficient than
val of_list : 'a list -> 'a t
on_list f l is equivalent to
to_list @@ f @@ of_list l.
val to_array : 'a t -> 'a array
Convert to an array. Currently not very efficient because an intermediate list is used.
val of_array : 'a array -> 'a t
val of_array_i : 'a array -> (int * 'a) t
Elements of the array, with their index
val of_array2 : 'a array -> ( int, 'a ) t2
val array_slice : 'a array -> int -> int -> 'a t
array_slice a i j Sequence of elements whose indexes range from
val of_opt : 'a option -> 'a t
Iterate on 0 or 1 values.
Convert to a stream. linear in memory and time (a copy is made in memory)
Add elements of the sequence to the hashtable, with Hashtbl.add
Add elements of the sequence to the hashtable, with Hashtbl.replace (erases conflicting bindings)
Build a hashtable from a sequence of key/value pairs
Build a hashtable from a sequence of key/value pairs
Sequence of key/value pairs from the hashtable
val of_str : string -> char t
val to_str : char t -> string
val concat_str : string t -> string
Concatenate strings together, eagerly. Also see
intersperse to add a separator.
Raised when the user tries to iterate several times on a transient iterator
Iterates on characters of the input (can block when one iterates over the sequence). If you need to iterate several times on this sequence, use
val int_range : start:int -> stop:int -> int t
Iterator on integers in
start...stop by steps 1. Also see
(--) for an infix version.
val int_range_dec : start:int -> stop:int -> int t
Iterator on decreasing integers in
stop...start by steps -1. See
(--^) for an infix version
Convert the given set to a sequence. The set module must be provided.
Convert the sequence to a set, given the proper set module
type 'a klist = unit -> [ `Nil | `Cons of 'a * 'a klist ]
module Set : sig ... end
module Map : sig ... end
val random_int : int -> int t
Infinite sequence of random integers between 0 and the given higher bound (see Random.int)
val random_bool : bool t
Infinite sequence of random bool values
val random_float : float -> float t
val random_array : 'a array -> 'a t
Sequence of choices of an element in the array
val random_list : 'a list -> 'a t
Infinite sequence of random elements of the list. Basically the same as
module Infix : sig ... end
include module type of Infix
val (--) : int -> int -> int t
a -- b is the range of integers from
b, both included, in increasing order. It will therefore be empty if
a > b.
val (--^) : int -> int -> int t
a --^ b is the range of integers from
a, both included, in decreasing order (starts from
a). It will therefore be empty if
a < b.
Pretty print a sequence of
'a, using the given pretty printer to print each elements. An optional separator string can be provided.
Print into a buffer
val to_string : ?sep:string -> ( 'a -> string ) -> 'a t -> string
Print into a string
Very basic interface to manipulate files as sequence of chunks/lines. The sequences take care of opening and closing files properly; every time one iterates over a sequence, the file is opened/closed again.
Example: copy a file
"a" into file
"b", removing blank lines:
Sequence.(IO.lines_of "a" |> filter (fun l-> l<> "") |> IO.write_lines "b");;
By chunks of
Sequence.IO.(chunks_of ~size:4096 "a" |> write_to "b");;
Read the lines of a file into a list:
Sequence.IO.lines "a" |> Sequence.to_list
module IO : sig ... end