module BatLazyList:sig..end
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.
Author(s): David Teller
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
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 Lazy.t
type 'a node_t =
| |
Nil |
|||
| |
Cons of |
(* |
The type of an item in the list.
| *) |
include BatEnum.Enumerable
include BatInterfaces.Mappable
val nil : 'a tval cons : 'a -> 'a t -> 'a tval (^:^) : 'a -> 'a t -> 'a tcons: x^:^l is the lazy list with head x and tail lval 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 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.val seq : 'a -> ('a -> 'a) -> ('a -> bool) -> 'a tseq init step cond creates a sequence of data, which starts
from init, extends by step, until the condition cond
fails. E.g. seq 1 ((+) 1) ((>) 100) returns [^1, 2, ... 99^]. If cond
init is false, the result is empty.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 the function returns Noneval init : int -> (int -> 'a) -> 'a tArray.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 tString.make, make n x returns a
list containing n elements x.val range : int -> int -> int t
The range is empty if b <= a.
val iter : ('a -> 'b) -> 'a t -> unit
iter f [^ a0; a1; ...; an ^] applies function f in turn to a0;
a1; ...; an. It is equivalent to begin f a0; f a1; ...; f an; ()
end. In particular, it causes all the elements of the list to be
evaluated.
val iteri : (int -> 'a -> unit) -> 'a t -> unit
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; ()
end. In particular, it causes all the elements of the list to be
evaluated.
val map : ('a -> 'b) -> 'a t -> 'b t
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 t
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 -> 'a
LazyList.fold_left f a [^ b0; b1; ...; bn ^] is f (... (f (f
a b0) b1) ...) bn. This causes evaluation of all the elements of
the list.
val fold_right : ('a -> 'b -> 'b) -> 'b -> 'a t -> 'b
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.
Since 2.2.0
val eager_fold_right : ('a -> 'b -> 'b) -> 'a t -> 'b -> 'b
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 Lazy.t -> 'b) -> 'a t -> 'b Lazy.t -> 'b Lazy.tlazy_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.
Since 2.1
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 -> boolmem, but with physical equalityval 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 -> 'afind_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 * 'afindi 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 lval index_ofq : 'a -> 'a t -> int optionindex_ofq e l behaves as index_of e l except it uses
physical equalityval 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 lval rindex_ofq : 'a -> 'a t -> int optionrindex_ofq e l behaves as rindex_of e l except it uses
physical equalityval next : 'a t -> 'a node_tval length : 'a t -> int
Causes the evaluation of all the elements of the list.
val is_empty : 'a t -> booltrue 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 otherwiseval hd : 'a t -> 'aEmpty_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 tEmpty_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 -> 'ahdval last : 'a t -> 'aEmpty_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 -> 'aat
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 -> 'bBatLazyList.assoc but with physical equalityval mem_assoc : 'a -> ('a * 'b) t -> bool
val mem_assq : 'a -> ('a * 'b) t -> boolBatLazyList.mem_assoc but with physical equality.val rev : 'a t -> 'a tval eager_append : 'a t -> 'a t -> 'a t
Cost is linear in the length of the first list, not tail-recursive.
val rev_append : 'a t -> 'a t -> 'a t
Cost is linear in the length of the first list, tail-recursive.
val append : 'a t -> 'a t -> 'a t
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 tval concat : 'a t t -> 'a tval flatten : 'a t list -> 'a tval 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 tsplit_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 tunique except only uses an equality function. Use for
short lists when comparing is expensive compared to equality
testingval 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 listval to_stream : 'a t -> 'a Stream.tval to_array : 'a t -> 'a arrayval enum : 'a t -> 'a BatEnum.tval of_list : 'a list -> 'a t
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 Stream.t -> 'a tval of_enum : 'a BatEnum.t -> 'a tval eager_of_list : 'a list -> 'a t
This function is much faster than BatLazyList.of_list but will freeze on cyclic lists.
val of_array : 'a array -> 'a tval filter : ('a -> bool) -> 'a t -> 'a t
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 -> bool
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 -> bool
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 t
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 tval sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a tcompare).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 -> boolBatLazyList.for_all, but for a two-argument predicate.Different_list_size if the two lists have
different lengths.val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> boolBatLazyList.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) tcombine [^ 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 tmodule Infix:sig..end
val print : ?first:string ->
?last:string ->
?sep:string ->
('a BatInnerIO.output -> 'b -> unit) ->
'a BatInnerIO.output -> 'b t -> unitLazyList 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
module Labels:sig..end
LazyList with labels.