mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 03:05:29 -05:00
add conversion from/to Stack, Queue, and add functions for Array and Ints;
also added more doc
This commit is contained in:
parent
2ca708d41a
commit
fbc4946a99
2 changed files with 110 additions and 14 deletions
53
sequence.ml
53
sequence.ml
|
|
@ -82,9 +82,11 @@ let concat s =
|
|||
(** Take at most [n] elements from the sequence *)
|
||||
let take n seq =
|
||||
let count = ref 0 in
|
||||
let seq_fun k = seq.seq_fun
|
||||
(fun x ->
|
||||
if !count < n then begin incr count; k x end)
|
||||
let seq_fun k =
|
||||
try
|
||||
seq.seq_fun
|
||||
(fun x -> if !count < n then begin incr count; k x end else raise Exit)
|
||||
with Exit -> ()
|
||||
in { seq_fun; }
|
||||
|
||||
(** Drop the [n] first elements of the sequence *)
|
||||
|
|
@ -125,15 +127,54 @@ let exists p seq =
|
|||
module List =
|
||||
struct
|
||||
let of_seq seq = List.rev (fold (fun y x -> x::y) [] seq)
|
||||
|
||||
let to_seq l = from_iter (fun k -> List.iter k l)
|
||||
end
|
||||
|
||||
module Array =
|
||||
struct
|
||||
let of_seq seq =
|
||||
(* intermediate list... *)
|
||||
let l = List.of_seq seq in
|
||||
Array.of_list l
|
||||
|
||||
let to_seq a = from_iter (fun k -> Array.iter k a)
|
||||
|
||||
let slice a i j =
|
||||
assert (i >= 0 && j < Array.length a);
|
||||
let seq_fun k =
|
||||
for idx = i to j do
|
||||
k a.(idx); (* iterate on sub-array *)
|
||||
done
|
||||
in { seq_fun; }
|
||||
end
|
||||
|
||||
module Stack =
|
||||
struct
|
||||
let push_seq s seq = iter (fun x -> Stack.push x s) seq
|
||||
|
||||
let to_seq s = from_iter (fun k -> Stack.iter k s)
|
||||
end
|
||||
|
||||
module Queue =
|
||||
struct
|
||||
let push_seq q seq = iter (fun x -> Queue.push x q) seq
|
||||
let to_seq q = from_iter (fun k -> Queue.iter k q)
|
||||
end
|
||||
|
||||
module Hashtbl =
|
||||
struct
|
||||
let add_seq h seq =
|
||||
iter (fun (k,v) -> Hashtbl.add h k v) seq
|
||||
|
||||
let replace_seq h seq =
|
||||
iter (fun (k,v) -> Hashtbl.replace h k v) seq
|
||||
|
||||
let of_seq seq =
|
||||
let h = Hashtbl.create 3 in
|
||||
iter (fun (k,v) -> Hashtbl.replace h k v) seq;
|
||||
replace_seq h seq;
|
||||
h
|
||||
|
||||
let to_seq h =
|
||||
from_iter (fun k -> Hashtbl.iter (fun a b -> k (a, b)) h)
|
||||
end
|
||||
|
|
@ -144,6 +185,10 @@ module Int =
|
|||
let seq_fun k =
|
||||
for i = start to stop do k i done
|
||||
in { seq_fun; }
|
||||
|
||||
let repeat i =
|
||||
let seq_fun k = while true do k i; done in
|
||||
{ seq_fun; }
|
||||
end
|
||||
|
||||
module Set =
|
||||
|
|
|
|||
71
sequence.mli
71
sequence.mli
|
|
@ -23,10 +23,13 @@ for any direct, indirect, incidental, special, exemplary, or consequential
|
|||
of this software, even if advised of the possibility of such damage.
|
||||
*)
|
||||
|
||||
(** {2 Transient iterators, that abstract on a finite sequence of elements.} *)
|
||||
(** Transient iterators, that abstract on a finite sequence of elements. They
|
||||
are designed to allow easy transfer (mappings) between data structures,
|
||||
without defining n^2 conversions between the n types. *)
|
||||
|
||||
type 'a t
|
||||
(** Sequence abstract iterator type *)
|
||||
(** Sequence abstract iterator type, representing a finite sequence of
|
||||
values of type ['a]. *)
|
||||
|
||||
(** {2 Build a sequence} *)
|
||||
|
||||
|
|
@ -36,7 +39,7 @@ val from_iter : (('a -> unit) -> unit) -> 'a t
|
|||
val singleton : 'a -> 'a t
|
||||
(** Singleton sequence *)
|
||||
|
||||
(** {2 Use a sequence} *)
|
||||
(** {2 Consume a sequence} *)
|
||||
|
||||
val iter : ('a -> unit) -> 'a t -> unit
|
||||
(** Consume the sequence, passing all its arguments to the function *)
|
||||
|
|
@ -50,6 +53,14 @@ val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
|
|||
val map : ('a -> 'b) -> 'a t -> 'b t
|
||||
(** Map objects of the sequence into other elements, lazily *)
|
||||
|
||||
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 Transform a sequence} *)
|
||||
|
||||
val filter : ('a -> bool) -> 'a t -> 'a t
|
||||
(** Filter on elements of the sequence *)
|
||||
|
||||
|
|
@ -68,31 +79,71 @@ val drop : int -> 'a t -> 'a t
|
|||
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 :
|
||||
sig
|
||||
val of_seq : 'a t -> 'a list
|
||||
|
||||
val to_seq : 'a list -> 'a t
|
||||
end
|
||||
|
||||
module Array :
|
||||
sig
|
||||
val of_seq : 'a t -> 'a array
|
||||
|
||||
val to_seq : 'a array -> 'a t
|
||||
|
||||
val slice : 'a array -> int -> int -> 'a t
|
||||
(** [slice a i j] Sequence of elements whose indexes range
|
||||
from [i] to [j] *)
|
||||
end
|
||||
|
||||
module Stack :
|
||||
sig
|
||||
val push_seq : 'a Stack.t -> 'a t -> unit
|
||||
(** Push elements of the sequence on the stack *)
|
||||
|
||||
val to_seq : 'a Stack.t -> 'a t
|
||||
(** Sequence of elements of the stack (same order as [Stack.iter]) *)
|
||||
end
|
||||
|
||||
module Queue :
|
||||
sig
|
||||
val push_seq : 'a Queue.t -> 'a t -> unit
|
||||
(** Push elements of the sequence into the queue *)
|
||||
|
||||
val to_seq : 'a Queue.t -> 'a t
|
||||
(** Sequence of elements contained in the queue, FIFO order *)
|
||||
end
|
||||
|
||||
module Hashtbl :
|
||||
sig
|
||||
val add_seq : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
|
||||
(** Add elements of the sequence to the hashtable, with
|
||||
Hashtbl.add *)
|
||||
|
||||
val replace_seq : ('a, 'b) Hashtbl.t -> ('a * 'b) t -> unit
|
||||
(** Add elements of the sequence to the hashtable, with
|
||||
Hashtbl.replace (erases conflicting bindings) *)
|
||||
|
||||
val of_seq : ('a * 'b) t -> ('a, 'b) Hashtbl.t
|
||||
(** Build a hashtable from a sequence *)
|
||||
|
||||
val to_seq : ('a, 'b) Hashtbl.t -> ('a * 'b) t
|
||||
(** Sequence of key/value pairs from the hashtable *)
|
||||
end
|
||||
|
||||
(** Iterate on ranges of ints *)
|
||||
(** Sequences of ints *)
|
||||
module Int :
|
||||
sig
|
||||
val range : start:int -> stop:int -> int t
|
||||
(** Iterator on [start...stop] by steps 1 *)
|
||||
|
||||
val repeat : int -> int t
|
||||
(** Infinite sequence of integers. Should be used only with
|
||||
transformers such as [take], that work even with infinite
|
||||
sequences. *)
|
||||
end
|
||||
|
||||
(** Iterate on sets. The Set module has to be provided. *)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue