mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 03:05:29 -05:00
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
This commit is contained in:
parent
b308a8ae87
commit
b109e99c00
2 changed files with 74 additions and 1 deletions
46
sequence.ml
46
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
|
||||
|
|
|
|||
29
sequence.mli
29
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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue