module BatLazyList:sig..end
Lazy lists of elements.
Lazy lists are similar to lists, with the exception that their contents are only computed whenever requested. This makes them particularly useful in contexts where streams of data are to be handled.
Note For this documentation, we will assume the existence of
a lazy list syntax extension such that [^ ^] is the empty lazy
list and [^ a;b;c ^] is the lazy list containing elements a,
b, c.
Note Enumerations (as featured in module BatEnum) and lazy
lists (as featured in this module) are quite similar in
purpose. Lazy lists are slightly higher level, insofar as no
cloning is required to get them to work, which makes them
slightly more useful in contexts where backtracking is
common. Enumerations, on the other hand, are closer to
traditional stream processing, and require more low-level marking
whenever backtracking is required, but may be faster and more
memory-efficient when used properly. Either choice is recommended
over OCaml's built-in Stream.
exception Empty_list
Empty_list is raised when an operation applied on an empty list
is invalid. For instance, hd nil will raise Empty_list.
exception Invalid_index of int
Invalid_index is raised when an indexed access on a list is
out of list bounds.
exception Different_list_size of string
Different_list_size is raised when applying functions such as
iter2 on two lists having different size.
exception No_more_elements
See BatLazyList.from and BatLazyList.from_loop for more information on this exception.
Note The types are kept concrete so as to allow pattern-matching.
However, it is generally easier to manipulate BatLazyList.nil and BatLazyList.cons.
type'at ='a node_t Stdlib.Lazy.t
The type of a lazy list.
type 'a node_t =
| |
Nil |
|||
| |
Cons of |
(* | The type of an item in the list. | *) |
include BatEnum.Enumerable
include BatInterfaces.Mappable
val nil : 'a tThe empty list.
val cons : 'a -> 'a t -> 'a tBuild a list from a head and a tail.
val (^:^) : 'a -> 'a t -> 'a tAs cons: x^:^l is the lazy list with head x and tail l
val peek : 'a t -> 'a optionpeek l returns the first element of l, if it exists.
val get : 'a t -> ('a * 'a t) optionget l returns the head and tail of l, if l is not empty.
val from : (unit -> 'a) -> 'a tfrom next creates a (possibly infinite) lazy list from the successive
results of next.
LazyList.No_more_elements to denote the end of the list.val from_while : (unit -> 'a option) -> 'a tfrom next creates a (possibly infinite) lazy list from the successive
results of next.
The list ends whenever next returns None.
val seq : 'a -> ('a -> 'a) -> ('a -> bool) -> 'a tseq data next cond creates a lazy list from the successive results
of applying next to data, then to the result, etc. The list
continues until the condition cond fails. For example,
seq 1 ((+) 1) ((>) 100) returns [^1, 2, ... 99^]. If cond init
is false, the result is empty. To create an infinite lazy list, pass
(fun _ -> true) as cond.
val unfold : 'b -> ('b -> ('a * 'b) option) -> 'a tunfold data next creates a (possibly infinite) lazy list from
the successive results of applying next to data, then to the
result, etc. The list ends whenever next returns None. The function
next should return a pair option whose first element will be the
current value of the sequence; the second element will be passed
(lazily) to next in order to compute the following element. One example
of a use of unfold is to make each element of the resulting sequence to
depend on the previous two elements, as in this Fibonacci sequence
definition:
let data = (1, 1)
let next (x, y) = Some (x, (y, x + y))
let fib = unfold data next
The first element x of the pair within Some will be the current
value of the sequence; the next value of the sequence, and the one after
that, are recorded as y and x + y respectively.
val from_loop : 'b -> ('b -> 'a * 'b) -> 'a tfrom_loop data next creates a (possibly infinite) lazy list from
the successive results of applying next to data, then to the
result, etc. The list ends whenever the function raises
LazyList.No_more_elements. (For further information see unfold;
ignore references to option and Some.)
val init : int -> (int -> 'a) -> 'a tSimilar to Array.init, init n f returns the lazy list
containing the results of (f 0),(f 1).... (f (n-1)).
Invalid_argument "LazyList.init" if n < 0.val make : int -> 'a -> 'a tSimilar to String.make, make n x returns a
list containing n elements x.
val range : int -> int -> int tCompute lazily a range of integers a .. b as a lazy list.
The range is empty if b <= a.
val iter : ('a -> 'b) -> 'a t -> unitEager iteration
iter f [^ a0; a1; ...; an ^] applies function f in turn to a0;. It is equivalent to
a1; ...; anbegin f a0; f a1; ...; f an; (). In particular, it causes all the elements of the list to be
evaluated.
end
val iteri : (int -> 'a -> unit) -> 'a t -> unitEager iteration, with indices
iteri f [^ a0; a1; ...; an ^] applies function f in turn to
a0; a1;...; an, along with the corresponding 0,1..n index. It
is equivalent to begin f 0 a0; f 1 a1; ...; f n an; (). In particular, it causes all the elements of the list to be
evaluated.
end
val map : ('a -> 'b) -> 'a t -> 'b tLazy map
map f [^ a0; a1; ... ^] builds the list [^ f a0; f a1; ... ^]
with the results returned by f. Not tail-recursive. Evaluations
of f take place only when the contents of the list are forced.
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b tLazy map, with indices
mapi f [^ a0; a1; ... ^] builds the list [^ f 0 a0; f 1 a1; with the results returned by
... ^]f. Not
tail-recursive. Evaluations of f take place only when the
contents of the list are forced.
val fold_left : ('a -> 'b -> 'a) -> 'a -> 'b t -> 'aEager fold_left
LazyList.fold_left f a [^ b0; b1; ...; bn ^] is f (... (f (f. This causes evaluation of all the elements of
the list.
a b0) b1) ...) bn
val fold_right : ('a -> 'b -> 'b) -> 'b -> 'a t -> 'bEager fold_right
fold_right f b [^ a0; a1; ...; an ^] is f a0 (f a1 (... (f an b) ...)).
This causes evaluation of all the elements of the list. Not
tail-recursive.
Note that the argument order of this function is the same as
fold_left above, but inconsistent with other fold_right
functions in Batteries. We hope to fix this inconsistency in the
next compatibility-breaking release, so you should rather use the
more consistent eager_fold_right.
val eager_fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'bEager fold_right
As fold_right above, but with the usual argument order for
a fold_right.
Just as fold_left on a structure 'a t turns an element-level
function of type ('b -> 'a -> 'b), with the accumulator argument
'b on the left, into a structure-level function
'b -> 'a t -> 'b, fold_right turns a function
('a -> 'b -> 'b) (accumulator on the right) into
a 'a t -> 'b -> 'b.
val lazy_fold_right : ('a -> 'b Stdlib.Lazy.t -> 'b) ->
'a t -> 'b Stdlib.Lazy.t -> 'b Stdlib.Lazy.tLazy fold_right
lazy_fold_right f (Cons (a0, Cons (a1, Cons (a2, nil)))) b is
lazy (f a0 (lazy (f a1 (lazy (f a2 b))))).
Forcing the result of lazy_fold_right forces the first element of
the list; the rest is forced only if/when the function f forces
its accumulator argument.
val mem : 'a -> 'a t -> boolmem x l determines if x is part of l.
Evaluates all the elements of l which appear
before x.
val memq : 'a -> 'a t -> boolAs mem, but with physical equality
val find : ('a -> bool) -> 'a t -> 'afind p l returns the first element of l such as p x
returns true.
Not_found if such an element has not been found.val rfind : ('a -> bool) -> 'a t -> 'arfind p l returns the last element x of l such as p x returns
true.
Not_found if such element as not been found.val find_exn : ('a -> bool) -> exn -> 'a t -> 'afind_exn p e l returns the first element of l such as p x
returns true or raises e if such an element has not been found.
val rfind_exn : ('a -> bool) -> exn -> 'a t -> 'arfind_exn p e l returns the last element of l such as p x
returns true or raises e if such an element has not been found.
val findi : (int -> 'a -> bool) -> 'a t -> int * 'afindi p e l returns the first element ai of l along with its
index i such that p i ai is true.
Not_found if no such element has been found.val rfindi : (int -> 'a -> bool) -> 'a t -> int * 'arfindi p e l returns the last element ai of l along with its
index i such that p i ai is true.
Not_found if no such element has been found.val index_of : 'a -> 'a t -> int optionindex_of e l returns the index of the first occurrence of e
in l, or None if there is no occurrence of e in l
val index_ofq : 'a -> 'a t -> int optionindex_ofq e l behaves as index_of e l except it uses
physical equality
val rindex_of : 'a -> 'a t -> int optionindex_of e l returns the index of the last occurrence of e
in l, or None if there is no occurrence of e in l
val rindex_ofq : 'a -> 'a t -> int optionrindex_ofq e l behaves as rindex_of e l except it uses
physical equality
val next : 'a t -> 'a node_tCompute and return the first node from the list as a Cons. This
differs from hd, which returns the first element (the first component of
the first node).
val length : 'a t -> intReturn the length (number of elements) of the given list.
Causes the evaluation of all the elements of the list.
val is_empty : 'a t -> boolReturns true if the list is empty, false otherwise.
val would_at_fail : 'a t -> int -> boolwould_at_fail l n returns true if l contains strictly less
than n elements, false otherwise
val hd : 'a t -> 'aReturn the first element of the given list.
Empty_list if the list is empty.
Note: this function does not comply with the usual exceptionless error-management
recommendations, as doing so would essentially render it useless.val tl : 'a t -> 'a tReturn the given list without its first element.
Empty_list if the list is empty.
Note: this function does not comply with the usual exceptionless error-management
recommendations, as doing so would essentially render it useless.val first : 'a t -> 'aAs hd
val last : 'a t -> 'aReturns the last element of the list.
Empty_list if
the list is empty. This function takes linear time and causes the
evaluation of all elements of the listval at : 'a t -> int -> 'aat l n returns the element at index n (starting from 0) in
the list l.
Invalid_index is the index is outside of
l bounds.val nth : 'a t -> int -> 'aObsolete. As at
These lists behave essentially as HashMap, although they are
typically faster for short number of associations, and much
slower for for large number of associations.
val assoc : 'a -> ('a * 'b) t -> 'bassoc a l returns the value associated with key a in the list of
pairs l. That is, assoc a [^ ...; (a,b); ...^] = b
if (a,b) is the leftmost binding of a in list l.
Not_found if there is no value associated with a in the
list l.val assq : 'a -> ('a * 'b) t -> 'bAs BatLazyList.assoc but with physical equality
val mem_assoc : 'a -> ('a * 'b) t -> boolAs BatLazyList.assoc but simply returns true if a binding exists, false
otherwise.
val mem_assq : 'a -> ('a * 'b) t -> boolAs BatLazyList.mem_assoc but with physical equality.
val rev : 'a t -> 'a tEager list reversal.
val eager_append : 'a t -> 'a t -> 'a tEvaluate a list and append another list after this one.
Cost is linear in the length of the first list, not tail-recursive.
val rev_append : 'a t -> 'a t -> 'a tEager reverse-and-append
Cost is linear in the length of the first list, tail-recursive.
val append : 'a t -> 'a t -> 'a tLazy append
Cost is constant. All evaluation is delayed until the contents of the list are actually read. Reading itself is delayed by a constant.
val (^@^) : 'a t -> 'a t -> 'a tAs lazy append
val concat : 'a t t -> 'a tLazy concatenation of a lazy list of lazy lists
val flatten : 'a t list -> 'a tLazy concatenation of a list of lazy lists
val split_at : int -> 'a t -> 'a t * 'a tsplit_at n l returns two lists l1 and l2, l1 containing the
first n elements of l and l2 the others.
Invalid_index if
n is outside of l size bounds.val split_nth : int -> 'a t -> 'a t * 'a tObsolete. As split_at.
val unique : ?cmp:('a -> 'a -> int) -> 'a t -> 'a tunique cmp l returns the list l without any duplicate element.
Default comparator ( = ) is used if no comparison function specified.
val unique_eq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a tas unique except only uses an equality function. Use for
short lists when comparing is expensive compared to equality
testing
val remove : 'a -> 'a t -> 'a tremove l x returns the list l without the first element x found
or returns l if no element is equal to x. Elements are compared
using ( = ).
val remove_if : ('a -> bool) -> 'a t -> 'a tremove_if cmp l is similar to remove, but with cmp used
instead of ( = ).
val remove_all : 'a -> 'a t -> 'a tremove_all l x is similar to remove but removes all elements that
are equal to x and not only the first one.
val remove_all_such : ('a -> bool) -> 'a t -> 'a tremove_all_such f l is similar to remove but removes all elements
that satisfy the predicate f and not only the first one.
val take : int -> 'a t -> 'a ttake n l returns up to the n first elements from list l, if
available.
val drop : int -> 'a t -> 'a tdrop n l returns l without the first n elements, or the empty
list if l have less than n elements.
val take_while : ('a -> bool) -> 'a t -> 'a ttake_while f xs returns the first elements of list xs
which satisfy the predicate f.
val drop_while : ('a -> bool) -> 'a t -> 'a tdrop_while f xs returns the list xs with the first
elements satisfying the predicate f dropped.
val to_list : 'a t -> 'a listEager conversion to string.
val to_stream : 'a t -> 'a Stdlib.Stream.tLazy conversion to stream.
val to_array : 'a t -> 'a arrayEager conversion to array.
val enum : 'a t -> 'a BatEnum.tLazy conversion to enumeration
val of_list : 'a list -> 'a tLazy conversion from lists
Albeit slower than eager conversion, this is the default mechanism for converting from regular lists to lazy lists. This for two reasons : * if you're using lazy lists, total speed probably isn't as much an issue as start-up speed * this will let you convert regular infinite lists to lazy lists.
val of_stream : 'a Stdlib.Stream.t -> 'a tLazy conversion from stream.
val of_enum : 'a BatEnum.t -> 'a tLazy conversion from enum.
val eager_of_list : 'a list -> 'a tEager conversion from lists.
This function is much faster than BatLazyList.of_list but will freeze on cyclic lists.
val of_array : 'a array -> 'a tEager conversion from array
val filter : ('a -> bool) -> 'a t -> 'a tLazy filtering.
filter p l returns all the elements of the list l that satisfy the predicate p.
The order of the elements in the input list is preserved.
val exists : ('a -> bool) -> 'a t -> boolEager existential.
exists p [^ a0; a1; ... ^] checks if at least one element of the list satisfies the predicate p.
That is, it returns (p a0) || (p a1) || ... .
val for_all : ('a -> bool) -> 'a t -> boolEager universal.
for_all p [^ a0; a1; ... ^] checks if all elements of the list satisfy the predicate p.
That is, it returns (p a0) && (p a1) && ... .
val filter_map : ('a -> 'b option) -> 'a t -> 'b tLazily eliminate some elements and transform others.
filter_map f [^ a0; a1; ... ^] applies lazily f to each a0,
a1... If f ai evaluates to None, the element is not included
in the result. Otherwise, if f ai evaluates to Some x, element
x is included in the result.
This is equivalent to
match f a0 with.
| Some x0 -> x0 ^:^ (match f a1 with
| Some x1 -> x1 ^:^ ...
| None -> [^ ^])
| None -> [^ ^]
val eternity : unit tAn infinite list of nothing
val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a tSort the list using optional comparator (by default compare).
val stable_sort : ('a -> 'a -> int) -> 'a t -> 'a tval map2 : ('a -> 'b -> 'c) -> 'a t -> 'b t -> 'c tmap2 f [^ a0; a1; ...^] [^ b0; b1; ... ^] is [^ f a0 b0; f a1.
b1; ... ^]
Different_list_size if the two lists have
different lengths. Not tail-recursive, lazy. In particular, the
exception is raised only after the shortest list has been
entirely consumed.val iter2 : ('a -> 'b -> unit) -> 'a t -> 'b t -> unititer2 f [^ a0; ...; an ^] [^ b0; ...; bn ^] calls in turn
f a0 b0; ...; f an bn. Tail-recursive, eager.
Different_list_size if the two lists have
different lengths.val fold_left2 : ('a -> 'b -> 'c -> 'a) -> 'a -> 'b t -> 'c t -> 'afold_left2 f a [^ b0; b1; ...; bn ^] [^ c0; c1; ...; cn ^] is
f (... (f (f a b0 c0) b1 c1) ...) bn cn. Eager.
Different_list_size if the two lists have
different lengths.val fold_right2 : ('a -> 'b -> 'c -> 'c) -> 'a t -> 'b t -> 'c -> 'cfold_right2 f [^ a0; a1; ...; an ^] [^ b0; b1; ...; bn ^] c is
f a0 b0 (f a1 b1 (... (f an bn c) ...)). Eager.
Different_list_size if the two lists have
different lengths. Tail-recursive.val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> boolSame as BatLazyList.for_all, but for a two-argument predicate.
Different_list_size if the two lists have
different lengths.val equal : ('a -> 'b -> bool) -> 'a t -> 'b t -> boolequal eq s1 s2 compares elements of s1 and s2 pairwise using eq
and returns true if all elements pass the test and the lists have the same
length; otherwise it returns false. Examples:
equal (=) (range 0 4) (range 0 4) (* true *)
(* Make lazy lists of lazy lists: *)
let s1 = init 5 (range 0)
let s2 = init 5 (range 0)
equal (equal (=)) s1 s2 (* true *)
(Calling = directly on a pair of lazy lists may succeed but is not
guaranteed to behave consistently.)
Note that on lists of equal length, equal and for_all2 can perform
the same function; their intended uses differ, however, as signaled by
behavior on lists of different lengths.
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> boolSame as BatLazyList.exists, but for a two-argument predicate.
Different_list_size if the two lists have
different lengths.val combine : 'a t -> 'b t -> ('a * 'b) tTransform a pair of lists into a list of pairs:
combine [^ a0; a1; ... ^] [^ b0; b1; ... ^] is
[^ (a0, b0); (a1, b1); ... ^].
Different_list_size if the two lists
have different lengths. Tail-recursive, lazy.val uncombine : ('a * 'b) t -> 'a t * 'b tDivide a list of pairs into a pair of lists.
module Infix:sig..end
Infix submodule regrouping all infix operators
val print : ?first:string ->
?last:string ->
?sep:string ->
('a BatInnerIO.output -> 'b -> unit) ->
'a BatInnerIO.output -> 'b t -> unitThe following modules replace functions defined in LazyList with functions
behaving slightly differently but having the same name. This is by design:
the functions meant to override the corresponding functions of LazyList.
module Exceptionless:sig..end
Exceptionless counterparts for error-raising operations
module Labels:sig..end
Operations on LazyList with labels.