This commit is contained in:
Drup 2014-05-20 21:22:21 +00:00
commit 8288cb38e2
2 changed files with 24 additions and 18 deletions

View file

@ -149,9 +149,9 @@ module MList = struct
| Cons of 'a array * int ref * 'a node ref | Cons of 'a array * int ref * 'a node ref
(* build and call callback on every element *) (* build and call callback on every element *)
let of_seq_with seq k = let of_seq_with ?(init_size=8) seq k =
let start = ref Nil in let start = ref Nil in
let chunk_size = ref 8 in let chunk_size = ref init_size in
(* fill the list. prev: tail-reference from previous node *) (* fill the list. prev: tail-reference from previous node *)
let prev, cur = ref start, ref Nil in let prev, cur = ref start, ref Nil in
seq seq
@ -175,8 +175,8 @@ module MList = struct
!prev := !cur; !prev := !cur;
!start !start
let of_seq seq = let of_seq ?init_size seq =
of_seq_with seq (fun _ -> ()) of_seq_with seq ?init_size (fun _ -> ())
let is_empty = function let is_empty = function
| Nil -> true | Nil -> true
@ -239,22 +239,22 @@ end
(** Iterate on the sequence, storing elements in a data structure. (** Iterate on the sequence, storing elements in a data structure.
The resulting sequence can be iterated on as many times as needed. *) The resulting sequence can be iterated on as many times as needed. *)
let persistent seq = let persistent ?init_size seq =
let l = MList.of_seq seq in let l = MList.of_seq ?init_size seq in
MList.to_seq l MList.to_seq l
type 'a lazy_state = type 'a lazy_state =
| LazySuspend | LazySuspend
| LazyCached of 'a t | LazyCached of 'a t
let persistent_lazy (seq:'a t) = let persistent_lazy ?init_size (seq:'a t) =
let r = ref LazySuspend in let r = ref LazySuspend in
fun k -> fun k ->
match !r with match !r with
| LazyCached seq' -> seq' k | LazyCached seq' -> seq' k
| LazySuspend -> | LazySuspend ->
(* here if this traversal is interruted, no caching occurs *) (* here if this traversal is interruted, no caching occurs *)
let seq' = MList.of_seq_with seq k in let seq' = MList.of_seq_with ?init_size seq k in
r := LazyCached (MList.to_seq seq') r := LazyCached (MList.to_seq seq')
(** Sort the sequence. Eager, O(n) ram and O(n ln(n)) time. *) (** Sort the sequence. Eager, O(n) ram and O(n ln(n)) time. *)
@ -686,7 +686,7 @@ include Infix
let pp_seq ?(sep=", ") pp_elt formatter seq = let pp_seq ?(sep=", ") pp_elt formatter seq =
let first = ref true in let first = ref true in
iter iter
(fun x -> (fun x ->
(if !first then first := false (if !first then first := false
else begin else begin
Format.pp_print_string formatter sep; Format.pp_print_string formatter sep;
@ -698,7 +698,7 @@ let pp_seq ?(sep=", ") pp_elt formatter seq =
let pp_buf ?(sep=", ") pp_elt buf seq = let pp_buf ?(sep=", ") pp_elt buf seq =
let first = ref true in let first = ref true in
iter iter
(fun x -> (fun x ->
if !first then first := false else Buffer.add_string buf sep; if !first then first := false else Buffer.add_string buf sep;
pp_elt buf x) pp_elt buf x)
seq seq

View file

@ -32,7 +32,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
of many combinators. However, for transient iterators, the {!persistent} of many combinators. However, for transient iterators, the {!persistent}
function is provided, storing elements of a transient iterator function is provided, storing elements of a transient iterator
in memory; the iterator can then be used several times (See further). in memory; the iterator can then be used several times (See further).
Note that some combinators also return sequences (e.g. {!group}). The Note that some combinators also return sequences (e.g. {!group}). The
transformation is computed on the fly every time one iterates over transformation is computed on the fly every time one iterates over
the resulting sequence. If a transformation performs heavy computation, the resulting sequence. If a transformation performs heavy computation,
@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
until their result is iterated on. For instance, if one calls {!map} until their result is iterated on. For instance, if one calls {!map}
on a sequence, one gets a new sequence, but nothing else happens until on a sequence, one gets a new sequence, but nothing else happens until
this new sequence is used (by folding or iterating on it). this new sequence is used (by folding or iterating on it).
If a sequence is built from an iteration function that is {b repeatable} If a sequence is built from an iteration function that is {b repeatable}
(i.e. calling it several times always iterates on the same set of (i.e. calling it several times always iterates on the same set of
elements, for instance List.iter or Map.iter), then elements, for instance List.iter or Map.iter), then
@ -151,13 +151,16 @@ val fmap : ('a -> 'b option) -> 'a t -> 'b t
val intersperse : 'a -> 'a t -> 'a t val intersperse : 'a -> 'a t -> 'a t
(** Insert the single element between every element of the sequence *) (** Insert the single element between every element of the sequence *)
val persistent : 'a t -> 'a t val persistent : ?init_size:int -> 'a t -> 'a t
(** Iterate on the sequence, storing elements in a data structure. (** Iterate on the sequence, storing elements in a data structure.
The resulting sequence can be iterated on as many times as needed. The resulting sequence can be iterated on as many times as needed.
{b Note}: calling persistent on an already persistent sequence {b Note}: calling persistent on an already persistent sequence
will still make a new copy of the sequence! *) will still make a new copy of the sequence!
val persistent_lazy : 'a t -> 'a t The optional argument [init_size] control the initial size of the underlying data structure. For very small sequences, it is more efficient to have [init_size] bigger than the length of your sequence.
*)
val persistent_lazy : ?init_size:int -> 'a t -> 'a t
(** Lazy version of {!persistent}. When calling [persistent_lazy s], (** Lazy version of {!persistent}. When calling [persistent_lazy s],
a new sequence [s'] is immediately returned (without actually consuming a new sequence [s'] is immediately returned (without actually consuming
[s]) in constant time; the first time [s'] is iterated on, [s]) in constant time; the first time [s'] is iterated on,
@ -166,7 +169,10 @@ val persistent_lazy : 'a t -> 'a t
{b warning}: on the first traversal of [s'], if the traversal {b warning}: on the first traversal of [s'], if the traversal
is interrupted prematurely ({!take}, etc.) then [s'] will not be is interrupted prematurely ({!take}, etc.) then [s'] will not be
memorized, and the next call to [s'] will traverse [s] again. *) memorized, and the next call to [s'] will traverse [s] again.
The optional argument [init_size] control the initial size of the underlying data structure. For very small sequences, it is more efficient to have [init_size] bigger than the length of your sequence.
*)
val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t val sort : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t
(** Sort the sequence. Eager, O(n) ram and O(n ln(n)) time. (** Sort the sequence. Eager, O(n) ram and O(n ln(n)) time.
@ -194,7 +200,7 @@ val join : join_row:('a -> 'b -> 'c option) -> 'a t -> 'b t -> 'c t
the two elements do not combine. Assume that [b] allows for multiple the two elements do not combine. Assume that [b] allows for multiple
iterations. *) iterations. *)
val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t val unfoldr : ('b -> ('a * 'b) option) -> 'b -> 'a t
(** [unfoldr f b] will apply [f] to [b]. If it (** [unfoldr f b] will apply [f] to [b]. If it
yields [Some (x,b')] then [x] is returned yields [Some (x,b')] then [x] is returned
and unfoldr recurses with [b']. *) and unfoldr recurses with [b']. *)
@ -359,7 +365,7 @@ module Set : sig
(** Create an enriched Set module from the given one *) (** Create an enriched Set module from the given one *)
module Adapt(X : Set.S) : S with type elt = X.elt and type t = X.t module Adapt(X : Set.S) : S with type elt = X.elt and type t = X.t
(** Functor to build an extended Set module from an ordered type *) (** Functor to build an extended Set module from an ordered type *)
module Make(X : Set.OrderedType) : S with type elt = X.t module Make(X : Set.OrderedType) : S with type elt = X.t
end end