From 0534a1fc2bc298673b0d7e349fd92c0a40af1474 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 28 Jan 2013 01:04:42 +0100 Subject: [PATCH] for_all, rev, iteri, exists added to sequence --- sequence.ml | 34 ++++++++++++++++++++++++++++++++++ sequence.mli | 12 ++++++++++++ 2 files changed, 46 insertions(+) diff --git a/sequence.ml b/sequence.ml index 68b6e8a..befc55b 100644 --- a/sequence.ml +++ b/sequence.ml @@ -14,6 +14,14 @@ let from_iter f = { (** Consume the sequence, passing all its arguments to the function *) let iter f seq = seq.seq_fun f +(** Iterate on elements and their index in the sequence *) +let iteri f seq = + let r = ref 0 in + let k x = + f !r x; + incr r + in seq.seq_fun k + (** Fold over elements of the sequence, consuming it *) let fold f init seq = let r = ref init in @@ -58,6 +66,32 @@ let drop n seq = (fun x -> if !count >= n then k x else incr count) in { seq_fun; } +(** Reverse the sequence. O(n) memory. *) +let rev seq = + let seq_fun k = + (* continuation for the prefix of the input sequence so far *) + let cont = ref (fun () -> ()) in + iter (fun x -> + let current_cont = !cont in + let cont' () = k x; current_cont () in + cont := cont') seq; + !cont () + in { seq_fun; } + +(** Do all elements satisfy the predicate? *) +let for_all p seq = + try + seq.seq_fun (fun x -> if not (p x) then raise Exit); + true + with Exit -> false + +(** Exists there some element satisfying the predicate? *) +let exists p seq = + try + seq.seq_fun (fun x -> if p x then raise Exit); + false + with Exit -> true + module List = struct let of_seq seq = List.rev (fold (fun y x -> x::y) [] seq) diff --git a/sequence.mli b/sequence.mli index 4445b2f..42052d9 100644 --- a/sequence.mli +++ b/sequence.mli @@ -14,6 +14,9 @@ val from_iter : (('a -> unit) -> unit) -> 'a t val iter : ('a -> unit) -> 'a t -> unit (** Consume the sequence, passing all its arguments to the function *) +val iteri : (int -> 'a -> unit) -> 'a t -> unit + (** Iterate on elements and their index in the sequence *) + val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b (** Fold over elements of the sequence, consuming it *) @@ -35,6 +38,15 @@ val take : int -> 'a t -> 'a t val drop : int -> 'a t -> 'a t (** Drop the [n] first elements of the sequence *) +val rev : 'a t -> 'a t + (** Reverse the sequence. O(n) memory. *) + +val for_all : ('a -> bool) -> 'a t -> bool + (** Do all elements satisfy the predicate? *) + +val exists : ('a -> bool) -> 'a t -> bool + (** Exists there some element satisfying the predicate? *) + (** {2 Basic data structures converters} *) module List :