module LList:A module for lazy list management.sig..end
If you use syntax extension pa_comprehension, you'll probably want to take advantage of the syntax for lazy lists.
In the original syntax, lazy lists may be written as [^ ^] (the empty list),
[^ 1;2;3;4;5 ^] (the list containing 1, 2, 3, 4, 5) or
1 ^:^ [^ 2;3;4;5 ^] (again the list containing 1, 2, 3, 4, 5)
In the revised syntax, lazy lists may be written as [^ ^] (the empty list),
[^ 1;2;3;4;5 ^] (the list containing 1, 2, 3, 4, 5) or
[^ 1 :: [^ 2;3;4;5 ^]] (again the list containing 1, 2, 3, 4, 5).
exception LazyListFailure of string
type 'a node_t =
| |
Nil |
| |
Cons of |
type'at ='a node_t Lazy.t
val nil : 'a node_t lazy_tval iter : ('a -> 'b) -> 'a node_t Lazy.t -> unit
LList.iter f [^ a1; ...; an ^] applies function f in turn to a1; ...; an.
It is equivalent to begin f a1; f a2; ...; f an; () end. In particular, it
causes all the elements of the list to be evaluated.
val iteri : (int -> 'a -> 'b) -> 'a node_t Lazy.t -> unit
LList.iteri f [^ a1; ...; an ^] applies function f in turn to a1 0; ...; an (n - 1).
It is equivalent to begin f a1 0; f a2 0; ...; f an (n-1); () end. In particular, it
causes all the elements of the list to be evaluated.
val map : ('a -> 'b) -> 'a t -> 'b t
LList.map f [^ a1; ...; an ^] applies function f to a1, ..., an, and builds the list
^ f a1; ...; f an ^ 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 node_t Lazy.t -> 'a
LList.fold_left f a [^ b1; ...; bn ^] is f (... (f (f a b1) b2) ...) bn. This causes
evaluation of all the elements of the list.
val fold_right : ('a -> 'b -> 'b) -> 'b -> 'a node_t Lazy.t -> 'b
LList.fold_left f a [^ b1; ...; bn ^] is f ( f (... (f (f a bn) ...) b2) b1. This causes
evaluation of all the elements of the list. Not tail-recursive.
val length : int node_t Lazy.t -> int
Causes the evaluation of all the elements of the list.
val hd : 'a node_t Lazy.t -> 'aLazyListFailure "hd" if the list is empty.val tl : 'a node_t Lazy.t -> 'a tLazyListFailure "tl" if the list is empty.val nth : 'a node_t Lazy.t -> int -> 'anth l i raises LazyListFailure "nth" if i < 0 or i >= length l.val rev : 'a node_t Lazy.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 factor.
val concat : 'a t list -> 'a tval flatten : 'a t t -> 'a tval to_list : 'a node_t Lazy.t -> 'a listval to_stream : 'a node_t Lazy.t -> 'a Stream.tval to_array : 'a node_t Lazy.t -> 'a arrayval 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 eager_of_list : 'a list -> 'a tval of_array : 'a array -> 'a tval filter : ('a -> bool) -> 'a node_t Lazy.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 node_t Lazy.t -> bool
exists p [^ a1; ...; an ^] checks if at least one element of the list satisfies the predicate p.
That is, it returns (p a1) || (p a2) || ... || (p an) .
val for_all : ('a -> bool) -> 'a node_t Lazy.t -> bool
for_all p [^ a1; ...; an ^] checks if all elements of the list satisfy the predicate p.
That is, it returns (p a1) && (p a2) && ... && (p an).
val range : int -> int -> int t
The range is never empty. If a <= b, the range contains a, a+1 ... b.
Otherwise, it contains a, a-1, ..., b.
val map_filter : ('a -> 'b option) -> 'a node_t Lazy.t -> 'b t
map_filter f [^ a1; a2; ... ;an ^] applies f to each
a1, ..., an. 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 a1 with
| Some x1 -> x1 ^:^ (match f a2 with
|Some x2 -> x2 ^:^ (match ...
(match f an with
| Some xn -> [^ xn ^]
| None -> [^ ^]
) ... )
| ...)
| None -> ... .