From b109e99c0042f798eebfc33d9137181f62a1b3ee Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Thu, 7 Mar 2013 19:39:34 +0100 Subject: [PATCH] Sequence.t2 type for efficient iteration on pairs of elements; some combinators are adapted to Sequence.t2; zip, unzip and zip_i to convert between t and t2 --- sequence.ml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ sequence.mli | 29 ++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/sequence.ml b/sequence.ml index 99ae6e9..18e1a87 100644 --- a/sequence.ml +++ b/sequence.ml @@ -28,6 +28,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (** Sequence abstract iterator type *) type 'a t = ('a -> unit) -> unit +type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit + (** Sequence of pairs of values of type ['a] and ['b]. *) + (** Build a sequence from a iter function *) let from_iter f = f @@ -291,6 +294,49 @@ let is_empty seq = try seq (fun _ -> raise ExitSequence); true with ExitSequence -> false +(** {2 Transform a sequence} *) + +let empty2 = + fun k -> () + +let is_empty2 seq2 = + try ignore (seq2 (fun _ _ -> raise ExitSequence)); true + with ExitSequence -> false + +let length2 seq2 = + let r = ref 0 in + seq2 (fun _ _ -> incr r); + !r + +let zip seq2 = + fun k -> seq2 (fun x y -> k (x,y)) + +let unzip seq = + fun k -> seq (fun (x,y) -> k x y) + +(** Zip elements of the sequence with their index in the sequence *) +let zip_i seq = + fun k -> + let r = ref 0 in + seq (fun x -> let n = !r in incr r; k n x) + +let fold2 f acc seq2 = + let acc = ref acc in + seq2 (fun x y -> acc := f !acc x y); + !acc + +let iter2 f seq2 = + seq2 f + +let map2 f seq2 = + fun k -> seq2 (fun x y -> k (f x y)) + +(** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *) +let map2_2 f g seq2 = + fun k -> seq2 (fun x y -> k (f x y) (g x y)) + +(** {2 Basic data structures converters} *) + let to_list seq = List.rev (fold (fun y x -> x::y) [] seq) let to_rev_list seq = fold (fun y x -> x :: y) [] seq diff --git a/sequence.mli b/sequence.mli index aab1f0d..0acb12b 100644 --- a/sequence.mli +++ b/sequence.mli @@ -27,10 +27,13 @@ for any direct, indirect, incidental, special, exemplary, or consequential are designed to allow easy transfer (mappings) between data structures, without defining n^2 conversions between the n types. *) -type +'a t +type +'a t = ('a -> unit) -> unit (** Sequence abstract iterator type, representing a finite sequence of values of type ['a]. *) +type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit + (** Sequence of pairs of values of type ['a] and ['b]. *) + (** {2 Build a sequence} *) val from_iter : (('a -> unit) -> unit) -> 'a t @@ -138,6 +141,30 @@ val drop : int -> 'a t -> 'a t val rev : 'a t -> 'a t (** Reverse the sequence. O(n) memory and time. *) +(** {2 Binary sequences} *) + +val empty2 : ('a, 'b) t2 + +val is_empty2 : (_, _) t2 -> bool + +val length2 : (_, _) t2 -> int + +val zip : ('a, 'b) t2 -> ('a * 'b) t + +val unzip : ('a * 'b) t -> ('a, 'b) t2 + +val zip_i : 'a t -> (int, 'a) t2 + (** Zip elements of the sequence with their index in the sequence *) + +val fold2 : ('c -> 'a -> 'b -> 'c) -> 'c -> ('a, 'b) t2 -> 'c + +val iter2 : ('a -> 'b -> unit) -> ('a, 'b) t2 -> unit + +val map2 : ('a -> 'b -> 'c) -> ('a, 'b) t2 -> 'c t + +val map2_2 : ('a -> 'b -> 'c) -> ('a -> 'b -> 'd) -> ('a, 'b) t2 -> ('c, 'd) t2 + (** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *) + (** {2 Basic data structures converters} *) val to_list : 'a t -> 'a list