Legend:
Library
Module
Module type
Parameter
Class
Class type
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.
author David Teller
Exceptions
exceptionEmpty_list
Empty_list is raised when an operation applied on an empty list is invalid. For instance, hd nil will raise Empty_list.
exceptionInvalid_indexof int
Invalid_index is raised when an indexed access on a list is out of list bounds.
exceptionDifferent_list_sizeof string
Different_list_size is raised when applying functions such as iter2 on two lists having different size.
exceptionNo_more_elements
See from and from_loop for more information on this exception.
Type
Note The types are kept concrete so as to allow pattern-matching. However, it is generally easier to manipulate nil and cons.
from_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.
seq 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.
unfold 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 None
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.
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.
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.
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.
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.
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.
Lazy 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.
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.
assoc 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.
raisesNot_found
if there is no value associated with a in the list l.
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.
Lazily 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 -> [^ ^] .
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.
The 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.