more Sequence constructors and consumers

This commit is contained in:
Simon Cruanes 2013-02-15 17:20:33 +01:00
parent d0c858ab9d
commit 45e331861d
2 changed files with 49 additions and 2 deletions

View file

@ -55,12 +55,28 @@ let fold f init seq =
let r = ref init in
seq (fun elt -> r := f !r elt);
!r
(** Fold over elements of the sequence and their index, consuming it *)
let foldi f init seq =
let i = ref 0 in
let r = ref init in
seq (fun elt ->
r := f !r !i elt;
incr i);
!r
(** Map objects of the sequence into other elements, lazily *)
let map f seq =
let seq_fun' k = seq (fun x -> k (f x)) in
seq_fun'
(** Map objects, along with their index in the sequence *)
let mapi f seq =
let seq_fun' k =
let i = ref 0 in
seq (fun x -> k (f !i x); incr i) in
seq_fun'
(** Filter on elements of the sequence *)
let filter p seq =
let seq_fun' k = seq (fun x -> if p x then k x) in
@ -156,6 +172,11 @@ let to_array seq =
let of_array a = from_iter (fun k -> Array.iter k a)
let of_array_i a =
let seq k =
for i = 0 to Array.length a - 1 do k (i, a.(i)) done
in from_iter seq
(** [array_slice a i j] Sequence of elements whose indexes range
from [i] to [j] *)
let array_slice a i j =
@ -165,6 +186,11 @@ let array_slice a i j =
k a.(idx); (* iterate on sub-array *)
done
(** Sequence of elements of a stream *)
let of_stream s =
let seq k = Stream.iter k s in
from_iter seq
(** Push elements of the sequence on the stack *)
let to_stack s seq = iter (fun x -> Stack.push x s) seq
@ -210,6 +236,10 @@ let of_in_channel ic =
let c = input_char ic in k c
done with End_of_file -> ())
(** Copy content of the sequence into the buffer *)
let to_buffer seq buf =
iter (fun c -> Buffer.add_char buf c) seq
(** Iterator on integers in [start...stop] by steps 1 *)
let int_range ~start ~stop =
fun k ->

View file

@ -27,7 +27,7 @@ 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
(** Sequence abstract iterator type, representing a finite sequence of
values of type ['a]. *)
@ -57,9 +57,15 @@ val iteri : (int -> 'a -> unit) -> 'a t -> unit
val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** Fold over elements of the sequence, consuming it *)
val foldi : ('b -> int -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** Fold over elements of the sequence and their index, consuming it *)
val map : ('a -> 'b) -> 'a t -> 'b t
(** Map objects of the sequence into other elements, lazily *)
val mapi : (int -> 'a -> 'b) -> 'a t -> 'b t
(** Map objects, along with their index in the sequence *)
val for_all : ('a -> bool) -> 'a t -> bool
(** Do all elements satisfy the predicate? *)
@ -90,7 +96,7 @@ val drop : int -> 'a t -> 'a t
(** Drop the [n] first elements of the sequence *)
val rev : 'a t -> 'a t
(** Reverse the sequence. O(n) memory. *)
(** Reverse the sequence. O(n) memory and time. *)
(** {2 Basic data structures converters} *)
@ -102,13 +108,21 @@ val to_rev_list : 'a t -> 'a list
val of_list : 'a list -> 'a t
val to_array : 'a t -> 'a array
(** Convert to an array. Currently not very efficient because
and intermediate list is used. *)
val of_array : 'a array -> 'a t
val of_array_i : 'a array -> (int * 'a) t
(** Elements of the array, with their index *)
val array_slice : 'a array -> int -> int -> 'a t
(** [array_slice a i j] Sequence of elements whose indexes range
from [i] to [j] *)
val of_stream : 'a Stream.t -> 'a t
(** Sequence of elements of a stream *)
val to_stack : 'a Stack.t -> 'a t -> unit
(** Push elements of the sequence on the stack *)
@ -142,6 +156,9 @@ val of_str : string -> char t
val to_str : char t -> string
val of_in_channel : in_channel -> char t
val to_buffer : char t -> Buffer.t -> unit
(** Copy content of the sequence into the buffer *)
val int_range : start:int -> stop:int -> int t
(** Iterator on integers in [start...stop] by steps 1 *)