add conversion from/to Stack, Queue, and add functions for Array and Ints;

also added more doc
This commit is contained in:
Simon Cruanes 2013-01-28 15:13:05 +01:00
parent 2ca708d41a
commit fbc4946a99
2 changed files with 110 additions and 14 deletions

View file

@ -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 =

View file

@ -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. *)