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

@ -56,11 +56,27 @@ let fold f init seq =
seq (fun elt -> r := f !r elt); seq (fun elt -> r := f !r elt);
!r !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 *) (** Map objects of the sequence into other elements, lazily *)
let map f seq = let map f seq =
let seq_fun' k = seq (fun x -> k (f x)) in let seq_fun' k = seq (fun x -> k (f x)) in
seq_fun' 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 *) (** Filter on elements of the sequence *)
let filter p seq = let filter p seq =
let seq_fun' k = seq (fun x -> if p x then k x) in 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 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 (** [array_slice a i j] Sequence of elements whose indexes range
from [i] to [j] *) from [i] to [j] *)
let array_slice a i j = let array_slice a i j =
@ -165,6 +186,11 @@ let array_slice a i j =
k a.(idx); (* iterate on sub-array *) k a.(idx); (* iterate on sub-array *)
done 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 *) (** Push elements of the sequence on the stack *)
let to_stack s seq = iter (fun x -> Stack.push x s) seq 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 let c = input_char ic in k c
done with End_of_file -> ()) 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 *) (** Iterator on integers in [start...stop] by steps 1 *)
let int_range ~start ~stop = let int_range ~start ~stop =
fun k -> 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, are designed to allow easy transfer (mappings) between data structures,
without defining n^2 conversions between the n types. *) without defining n^2 conversions between the n types. *)
type 'a t type +'a t
(** Sequence abstract iterator type, representing a finite sequence of (** Sequence abstract iterator type, representing a finite sequence of
values of type ['a]. *) 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 val fold : ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b
(** Fold over elements of the sequence, consuming it *) (** 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 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 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 val for_all : ('a -> bool) -> 'a t -> bool
(** Do all elements satisfy the predicate? *) (** 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 *) (** Drop the [n] first elements of the sequence *)
val rev : 'a t -> 'a t 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} *) (** {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 of_list : 'a list -> 'a t
val to_array : 'a t -> 'a array 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 : '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 val array_slice : 'a array -> int -> int -> 'a t
(** [array_slice a i j] Sequence of elements whose indexes range (** [array_slice a i j] Sequence of elements whose indexes range
from [i] to [j] *) 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 val to_stack : 'a Stack.t -> 'a t -> unit
(** Push elements of the sequence on the stack *) (** 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 to_str : char t -> string
val of_in_channel : in_channel -> char t 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 val int_range : start:int -> stop:int -> int t
(** Iterator on integers in [start...stop] by steps 1 *) (** Iterator on integers in [start...stop] by steps 1 *)