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 *) (** Take at most [n] elements from the sequence *)
let take n seq = let take n seq =
let count = ref 0 in let count = ref 0 in
let seq_fun k = seq.seq_fun let seq_fun k =
(fun x -> try
if !count < n then begin incr count; k x end) seq.seq_fun
(fun x -> if !count < n then begin incr count; k x end else raise Exit)
with Exit -> ()
in { seq_fun; } in { seq_fun; }
(** Drop the [n] first elements of the sequence *) (** Drop the [n] first elements of the sequence *)
@ -125,15 +127,54 @@ let exists p seq =
module List = module List =
struct struct
let of_seq seq = List.rev (fold (fun y x -> x::y) [] seq) 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) let to_seq l = from_iter (fun k -> List.iter k l)
end 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 = module Hashtbl =
struct 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 of_seq seq =
let h = Hashtbl.create 3 in let h = Hashtbl.create 3 in
iter (fun (k,v) -> Hashtbl.replace h k v) seq; replace_seq h seq;
h h
let to_seq h = let to_seq h =
from_iter (fun k -> Hashtbl.iter (fun a b -> k (a, b)) h) from_iter (fun k -> Hashtbl.iter (fun a b -> k (a, b)) h)
end end
@ -144,6 +185,10 @@ module Int =
let seq_fun k = let seq_fun k =
for i = start to stop do k i done for i = start to stop do k i done
in { seq_fun; } in { seq_fun; }
let repeat i =
let seq_fun k = while true do k i; done in
{ seq_fun; }
end end
module Set = 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. 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 type 'a t
(** Sequence abstract iterator type *) (** Sequence abstract iterator type, representing a finite sequence of
values of type ['a]. *)
(** {2 Build a sequence} *) (** {2 Build a sequence} *)
@ -36,7 +39,7 @@ val from_iter : (('a -> unit) -> unit) -> 'a t
val singleton : 'a -> 'a t val singleton : 'a -> 'a t
(** Singleton sequence *) (** Singleton sequence *)
(** {2 Use a sequence} *) (** {2 Consume a sequence} *)
val iter : ('a -> unit) -> 'a t -> unit val iter : ('a -> unit) -> 'a t -> unit
(** Consume the sequence, passing all its arguments to the function *) (** 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 val map : ('a -> 'b) -> 'a t -> 'b t
(** Map objects of the sequence into other elements, lazily *) (** 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 val filter : ('a -> bool) -> 'a t -> 'a t
(** Filter on elements of the sequence *) (** Filter on elements of the sequence *)
@ -68,31 +79,71 @@ val drop : int -> 'a t -> 'a t
val rev : 'a t -> 'a t val rev : 'a t -> 'a t
(** Reverse the sequence. O(n) memory. *) (** 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} *) (** {2 Basic data structures converters} *)
module List : module List :
sig sig
val of_seq : 'a t -> 'a list val of_seq : 'a t -> 'a list
val to_seq : 'a list -> 'a t val to_seq : 'a list -> 'a t
end 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 : module Hashtbl :
sig 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 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 val to_seq : ('a, 'b) Hashtbl.t -> ('a * 'b) t
(** Sequence of key/value pairs from the hashtable *)
end end
(** Iterate on ranges of ints *) (** Sequences of ints *)
module Int : module Int :
sig sig
val range : start:int -> stop:int -> int t val range : start:int -> stop:int -> int t
(** Iterator on [start...stop] by steps 1 *) (** 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 end
(** Iterate on sets. The Set module has to be provided. *) (** Iterate on sets. The Set module has to be provided. *)