package batteries
Install
Dune Dependency
Authors
Maintainers
Sources
md5=ea26b5c72e6731e59d856626049cca4d
sha512=55975b62c26f6db77433a3ac31f97af609fc6789bb62ac38b267249c78fd44ff37fe81901f1cf560857b9493a6046dd37b0d1c0234c66bd59e52843aac3ce6cb
doc/batteries.unthreaded/BatLazyList/index.html
Module BatLazyList
Source
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
.
Exceptions
Empty_list
is raised when an operation applied on an empty list is invalid. For instance, hd nil
will raise Empty_list
.
Invalid_index
is raised when an indexed access on a list is out of list bounds.
Different_list_size
is raised when applying functions such as iter2
on two lists having different size.
Type
Note The types are kept concrete so as to allow pattern-matching. However, it is generally easier to manipulate nil
and cons
.
include BatEnum.Enumerable with type 'a enumerable = 'a t
include BatInterfaces.Mappable with type 'a mappable = 'a t
Access
List creation
from next
creates a (possibly infinite) lazy list from the successive results of next
.
from next
creates a (possibly infinite) lazy list from the successive results of next
. The list ends whenever next
returns None
.
seq 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
.
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 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.
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
. (For further information see unfold
; ignore references to option
and Some
.)
Similar to Array.init
, init n f
returns the lazy list containing the results of (f 0),(f 1).... (f (n-1)).
Similar to String.make
, make n x
returns a list containing n
elements x
.
Compute lazily a range of integers a .. b as a lazy list.
The range is empty if b <= a.
Higher-order functions
Eager iteration
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.
Eager 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; () end
. In particular, it causes all the elements of the list to be evaluated.
Lazy 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.
Lazy 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.
Eager fold_left
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.
Eager 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
.
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.
Finding
mem x l
determines if x
is part of l
. Evaluates all the elements of l
which appear before x
.
find p l
returns the first element of l
such as p x
returns true
.
rfind p l
returns the last element x
of l
such as p x
returns true
.
find_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.
rfind_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.
findi p e l
returns the first element ai
of l
along with its index i
such that p i ai
is true.
rfindi p e l
returns the last element ai
of l
along with its index i
such that p i ai
is true.
index_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
index_ofq e l
behaves as index_of e l
except it uses physical equality
index_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
rindex_ofq e l
behaves as rindex_of e l
except it uses physical equality
Common functions
Compute 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).
Return the length (number of elements) of the given list.
Causes the evaluation of all the elements of the list.
would_at_fail l n
returns true
if l
contains strictly less than n
elements, false
otherwise
Return the first element of the given list.
Note: this function does not comply with the usual exceptionless error-management recommendations, as doing so would essentially render it useless.
Return the given list without its first element.
Note: this function does not comply with the usual exceptionless error-management recommendations, as doing so would essentially render it useless.
Returns the last element of the list.
This function takes linear time and causes the evaluation of all elements of the list
at l n
returns the element at index n
(starting from 0
) in the list l
.
Association lists
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
.
As assoc
but simply returns true
if a binding exists, false
otherwise.
Transformations
Evaluate a list and append another list after this one.
Cost is linear in the length of the first list, not tail-recursive.
Eager reverse-and-append
Cost is linear in the length of the first list, tail-recursive.
Lazy append
Cost is constant. All evaluation is delayed until the contents of the list are actually read. Reading itself is delayed by a constant.
split_at n l
returns two lists l1
and l2
, l1
containing the first n
elements of l
and l2
the others.
Dropping elements
unique cmp l
returns the list l
without any duplicate element. Default comparator ( = ) is used if no comparison function specified.
as unique
except only uses an equality function. Use for short lists when comparing is expensive compared to equality testing
remove 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 ( = ).
remove_if cmp l
is similar to remove
, but with cmp
used instead of ( = ).
remove_all l x
is similar to remove
but removes all elements that are equal to x
and not only the first one.
remove_all_such f l
is similar to remove
but removes all elements that satisfy the predicate f
and not only the first one.
take n l
returns up to the n
first elements from list l
, if available.
drop n l
returns l
without the first n
elements, or the empty list if l
have less than n
elements.
take_while f xs
returns the first elements of list xs
which satisfy the predicate f
.
drop_while f xs
returns the list xs
with the first elements satisfying the predicate f
dropped.
Combinatorics
combinations l
yields a list of all combinations of elements of l
. Each combination selects a "subset" of the elements of l
(duplicates are considered as distinct elements).
permutations l
yields a lazy list of all permutations of the list l
. Every permutation has the same elements as l
, but in a different order. There are factorial (length l)
permutations.
Conversions
Lazy 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.
Eager conversion from lists.
This function is much faster than of_list
but will freeze on cyclic lists.
Predicates
Lazy 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.
Eager 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) || ...
.
Eager 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) && ...
.
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 -> [^ ^]
.
Misc.
Sorting
Sort the list using optional comparator (by default compare
).
Operations on two lists
map2 f [^ a0; a1; ...^] [^ b0; b1; ... ^]
is [^ f a0 b0; f a1 b1; ... ^]
.
iter2 f [^ a0; ...; an ^] [^ b0; ...; bn ^]
calls in turn f a0 b0; ...; f an bn
. Tail-recursive, eager.
fold_left2 f a [^ b0; b1; ...; bn ^] [^ c0; c1; ...; cn ^]
is f (... (f (f a b0 c0) b1 c1) ...) bn cn
. Eager.
fold_right2 f [^ a0; a1; ...; an ^] [^ b0; b1; ...; bn ^] c
is f a0 b0 (f a1 b1 (... (f an bn c) ...))
. Eager.
Same as for_all
, but for a two-argument predicate.
equal 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.
Same as exists
, but for a two-argument predicate.
Transform a pair of lists into a list of pairs: combine [^ a0; a1; ... ^] [^ b0; b1; ... ^]
is [^ (a0, b0); (a1, b1); ... ^]
.
Boilerplate code
Printing
val print :
?first:string ->
?last:string ->
?sep:string ->
('a BatInnerIO.output -> 'b -> unit) ->
'a BatInnerIO.output ->
'b t ->
unit
Override modules
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
.
Exceptionless counterparts for error-raising operations