mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 19:25:30 -05:00
code cleaning;
exception raised in of_in_channel upon second iteration
This commit is contained in:
parent
77d74953fd
commit
4475d52b0f
2 changed files with 164 additions and 248 deletions
408
sequence.ml
408
sequence.ml
|
|
@ -36,17 +36,11 @@ type (+'a, +'b) t2 = ('a -> 'b -> unit) -> unit
|
||||||
(** Build a sequence from a iter function *)
|
(** Build a sequence from a iter function *)
|
||||||
let from_iter f = f
|
let from_iter f = f
|
||||||
|
|
||||||
(** Call the function repeatedly until it returns None. This
|
let rec from_fun f k = match f () with
|
||||||
sequence is transient, use {!persistent} if needed! *)
|
| None -> ()
|
||||||
let from_fun f =
|
| Some x -> k x; from_fun f k
|
||||||
fun k ->
|
|
||||||
let rec next () =
|
|
||||||
match f () with
|
|
||||||
| None -> ()
|
|
||||||
| Some x -> (k x; next ())
|
|
||||||
in next ()
|
|
||||||
|
|
||||||
let empty = fun k -> ()
|
let empty k = ()
|
||||||
|
|
||||||
let singleton x k = k x
|
let singleton x k = k x
|
||||||
let return x k = k x
|
let return x k = k x
|
||||||
|
|
@ -57,101 +51,70 @@ let doubleton x y k = k x; k y
|
||||||
let cons x l k = k x; l k
|
let cons x l k = k x; l k
|
||||||
let snoc l x k = l k; k x
|
let snoc l x k = l k; k x
|
||||||
|
|
||||||
(** Infinite sequence of the same element *)
|
let repeat x k = while true do k x done
|
||||||
let repeat x = fun k -> while true do k x done
|
|
||||||
|
|
||||||
(** [iterate f x] is the infinite sequence (x, f(x), f(f(x)), ...) *)
|
let rec iterate f x k =
|
||||||
let iterate f x =
|
k x;
|
||||||
let rec iterate k x = k x; iterate k (f x) in
|
iterate f (f x) k
|
||||||
from_iter (fun k -> iterate k x)
|
|
||||||
|
|
||||||
(** Sequence that calls the given function to produce elements *)
|
let rec forever f k =
|
||||||
let forever f =
|
k (f ());
|
||||||
let rec forever k = k (f ()); forever k in
|
forever f k
|
||||||
from_iter forever
|
|
||||||
|
|
||||||
(** Cycle forever through the given sequence. O(n). *)
|
let cycle s k = while true do s k; done
|
||||||
let cycle s = fun k -> while true do s k; done
|
|
||||||
|
|
||||||
(** Consume the sequence, passing all its arguments to the function *)
|
|
||||||
let iter f seq = seq f
|
let iter f seq = seq f
|
||||||
|
|
||||||
(** Iterate on elements and their index in the sequence *)
|
|
||||||
let iteri f seq =
|
let iteri f seq =
|
||||||
let r = ref 0 in
|
let r = ref 0 in
|
||||||
let k x =
|
seq
|
||||||
f !r x;
|
(fun x ->
|
||||||
incr r
|
f !r x;
|
||||||
in seq k
|
incr r)
|
||||||
|
|
||||||
(** Fold over elements of the sequence, consuming it *)
|
|
||||||
let fold f init seq =
|
let fold f init seq =
|
||||||
let r = ref init in
|
let r = ref init in
|
||||||
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 foldi f init seq =
|
||||||
let i = ref 0 in
|
let i = ref 0 in
|
||||||
let r = ref init in
|
let r = ref init in
|
||||||
seq (fun elt ->
|
seq
|
||||||
r := f !r !i elt;
|
(fun elt ->
|
||||||
incr i);
|
r := f !r !i elt;
|
||||||
|
incr i);
|
||||||
!r
|
!r
|
||||||
|
|
||||||
(** Map objects of the sequence into other elements, lazily *)
|
let map f seq k = seq (fun x -> k (f x))
|
||||||
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 k =
|
||||||
let mapi f seq =
|
let i = ref 0 in
|
||||||
let seq_fun' k =
|
seq (fun x -> k (f !i x); incr i)
|
||||||
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 k = seq (fun x -> if p x then k x)
|
||||||
let filter p seq =
|
|
||||||
let seq_fun' k = seq (fun x -> if p x then k x) in
|
|
||||||
seq_fun'
|
|
||||||
|
|
||||||
(** Append two sequences *)
|
let append s1 s2 k = s1 k; s2 k
|
||||||
let append s1 s2 =
|
|
||||||
let seq_fun k = s1 k; s2 k in
|
|
||||||
seq_fun
|
|
||||||
|
|
||||||
(** Concatenate a sequence of sequences into one sequence *)
|
let concat s k = s (fun s' -> s' k)
|
||||||
let concat s =
|
|
||||||
from_iter (fun k ->
|
|
||||||
(* function that is called on every sub-sequence *)
|
|
||||||
let k_seq seq = iter k seq in
|
|
||||||
s k_seq)
|
|
||||||
|
|
||||||
let flatten s = concat s
|
let flatten s = concat s
|
||||||
|
|
||||||
(** Monadic bind. It applies the function to every element of the
|
let flatMap f seq k = seq (fun x -> f x k)
|
||||||
initial sequence, and calls [concat]. *)
|
|
||||||
let flatMap f seq =
|
|
||||||
from_iter
|
|
||||||
(fun k -> seq (fun x -> (f x) k))
|
|
||||||
|
|
||||||
let flat_map = flatMap
|
let flat_map = flatMap
|
||||||
|
|
||||||
let fmap f seq =
|
let fmap f seq k =
|
||||||
from_iter
|
seq (fun x -> match f x with
|
||||||
(fun k ->
|
| None -> ()
|
||||||
seq (fun x -> match f x with
|
| Some y -> k y
|
||||||
| None -> ()
|
)
|
||||||
| Some y -> k y))
|
|
||||||
|
|
||||||
let filter_map = fmap
|
let filter_map = fmap
|
||||||
|
|
||||||
(** Insert the given element between every element of the sequence *)
|
let intersperse elem seq k =
|
||||||
let intersperse elem seq =
|
let first = ref true in
|
||||||
fun k ->
|
seq (fun x -> (if !first then first := false else k elem); k x)
|
||||||
let first = ref true in
|
|
||||||
seq (fun x -> (if !first then first := false else k elem); k x)
|
|
||||||
|
|
||||||
(** Mutable unrolled list to serve as intermediate storage *)
|
(** Mutable unrolled list to serve as intermediate storage *)
|
||||||
module MList = struct
|
module MList = struct
|
||||||
|
|
@ -255,8 +218,6 @@ module MList = struct
|
||||||
in make (l,0)
|
in make (l,0)
|
||||||
end
|
end
|
||||||
|
|
||||||
(** Iterate on the sequence, storing elements in a data structure.
|
|
||||||
The resulting sequence can be iterated on as many times as needed. *)
|
|
||||||
let persistent seq =
|
let persistent seq =
|
||||||
let l = MList.of_seq seq in
|
let l = MList.of_seq seq in
|
||||||
MList.to_seq l
|
MList.to_seq l
|
||||||
|
|
@ -275,49 +236,45 @@ let persistent_lazy (seq:'a t) =
|
||||||
let seq' = MList.of_seq_with seq k in
|
let seq' = MList.of_seq_with seq k in
|
||||||
r := LazyCached (MList.to_seq seq')
|
r := LazyCached (MList.to_seq seq')
|
||||||
|
|
||||||
(** Sort the sequence. Eager, O(n) ram and O(n ln(n)) time. *)
|
|
||||||
let sort ?(cmp=Pervasives.compare) seq =
|
let sort ?(cmp=Pervasives.compare) seq =
|
||||||
(* use an intermediate list, then sort the list *)
|
(* use an intermediate list, then sort the list *)
|
||||||
let l = fold (fun l x -> x::l) [] seq in
|
let l = fold (fun l x -> x::l) [] seq in
|
||||||
let l = List.fast_sort cmp l in
|
let l = List.fast_sort cmp l in
|
||||||
fun k -> List.iter k l
|
fun k -> List.iter k l
|
||||||
|
|
||||||
(** Group equal consecutive elements. *)
|
let group ?(eq=fun x y -> x = y) seq k =
|
||||||
let group ?(eq=fun x y -> x = y) seq =
|
let cur = ref [] in
|
||||||
fun k ->
|
seq (fun x ->
|
||||||
let cur = ref [] in
|
match !cur with
|
||||||
seq (fun x ->
|
| [] -> cur := [x]
|
||||||
match !cur with
|
| (y::_) as l when eq x y ->
|
||||||
| [] -> cur := [x]
|
cur := x::l (* [x] belongs to the group *)
|
||||||
| (y::_) as l when eq x y ->
|
| (_::_) as l ->
|
||||||
cur := x::l (* [x] belongs to the group *)
|
k l; (* yield group, and start another one *)
|
||||||
| (_::_) as l ->
|
cur := [x]);
|
||||||
k l; (* yield group, and start another one *)
|
(* last list *)
|
||||||
cur := [x]);
|
if !cur <> [] then k !cur
|
||||||
(* last list *)
|
|
||||||
if !cur <> [] then k !cur
|
|
||||||
|
|
||||||
(** Remove consecutive duplicate elements. Basically this is
|
let uniq ?(eq=fun x y -> x = y) seq k =
|
||||||
like [fun seq -> map List.hd (group seq)]. *)
|
let has_prev = ref false
|
||||||
let uniq ?(eq=fun x y -> x = y) seq =
|
and prev = ref (Obj.magic 0) in (* avoid option type, costly *)
|
||||||
fun k ->
|
seq (fun x ->
|
||||||
let has_prev = ref false
|
if !has_prev && eq !prev x
|
||||||
and prev = ref (Obj.magic 0) in (* avoid option type, costly *)
|
then () (* duplicate *)
|
||||||
seq (fun x ->
|
else begin
|
||||||
if !has_prev && eq !prev x
|
has_prev := true;
|
||||||
then () (* duplicate *)
|
prev := x;
|
||||||
else begin
|
k x
|
||||||
has_prev := true;
|
end)
|
||||||
prev := x;
|
|
||||||
k x
|
|
||||||
end)
|
|
||||||
|
|
||||||
(** Sort the sequence and remove duplicates. Eager, same as [sort] *)
|
let sort_uniq (type elt) ?(cmp=Pervasives.compare) seq =
|
||||||
let sort_uniq ?(cmp=Pervasives.compare) seq =
|
let module S = Set.Make(struct
|
||||||
let seq' = sort ~cmp seq in
|
type t = elt
|
||||||
uniq ~eq:(fun x y -> cmp x y = 0) seq'
|
let compare = cmp
|
||||||
|
end) in
|
||||||
|
let set = fold (fun acc x -> S.add x acc) S.empty seq in
|
||||||
|
fun k -> S.iter k set
|
||||||
|
|
||||||
(** Cartesian product of the sequences. *)
|
|
||||||
let product outer inner k =
|
let product outer inner k =
|
||||||
outer (fun x ->
|
outer (fun x ->
|
||||||
inner (fun y -> k (x,y))
|
inner (fun y -> k (x,y))
|
||||||
|
|
@ -328,35 +285,25 @@ let product2 outer inner k =
|
||||||
inner (fun y -> k x y)
|
inner (fun y -> k x y)
|
||||||
)
|
)
|
||||||
|
|
||||||
(** [join ~join_row a b] combines every element of [a] with every
|
let join ~join_row s1 s2 k =
|
||||||
element of [b] using [join_row]. If [join_row] returns None, then
|
s1 (fun a ->
|
||||||
the two elements do not combine. Assume that [b] allows for multiple
|
s2 (fun b ->
|
||||||
iterations. *)
|
match join_row a b with
|
||||||
let join ~join_row s1 s2 =
|
| None -> ()
|
||||||
fun k ->
|
| Some c -> k c
|
||||||
s1 (fun a ->
|
)
|
||||||
s2 (fun b ->
|
) (* yield the combination of [a] and [b] *)
|
||||||
match join_row a b with
|
|
||||||
| None -> ()
|
|
||||||
| Some c -> k c)) (* yield the combination of [a] and [b] *)
|
|
||||||
|
|
||||||
(** [unfoldr f b] will apply [f] to [b]. If it
|
let rec unfoldr f b k = match f b with
|
||||||
yields [Some (x,b')] then [x] is returned
|
| None -> ()
|
||||||
and unfoldr recurses with [b']. *)
|
| Some (x, b') ->
|
||||||
let unfoldr f b =
|
k x;
|
||||||
let rec unfold k b = match f b with
|
unfoldr f b' k
|
||||||
| None -> ()
|
|
||||||
| Some (x, b') -> k x; unfold k b'
|
|
||||||
in
|
|
||||||
from_iter (fun k -> unfold k b)
|
|
||||||
|
|
||||||
(** Sequence of intermediate results *)
|
let scan f acc seq k =
|
||||||
let scan f acc seq =
|
k acc;
|
||||||
from_iter
|
let acc = ref acc in
|
||||||
(fun k ->
|
seq (fun elt -> let acc' = f !acc elt in k acc'; acc := acc')
|
||||||
k acc;
|
|
||||||
let acc = ref acc in
|
|
||||||
seq (fun elt -> let acc' = f !acc elt in k acc'; acc := acc'))
|
|
||||||
|
|
||||||
let max ?(lt=fun x y -> x < y) seq =
|
let max ?(lt=fun x y -> x < y) seq =
|
||||||
let ret = ref None in
|
let ret = ref None in
|
||||||
|
|
@ -374,28 +321,24 @@ let min ?(lt=fun x y -> x < y) seq =
|
||||||
|
|
||||||
exception ExitSequence
|
exception ExitSequence
|
||||||
|
|
||||||
(** Take at most [n] elements from the sequence *)
|
let take n seq k =
|
||||||
let take n seq =
|
|
||||||
let count = ref 0 in
|
let count = ref 0 in
|
||||||
if n = 0 then empty
|
try
|
||||||
else fun k ->
|
seq (fun x ->
|
||||||
try
|
incr count;
|
||||||
seq (fun x ->
|
k x;
|
||||||
incr count;
|
if !count = n then raise ExitSequence
|
||||||
k x;
|
)
|
||||||
if !count = n then raise ExitSequence)
|
with ExitSequence -> ()
|
||||||
with ExitSequence -> ()
|
|
||||||
|
|
||||||
let take_while p seq k =
|
let take_while p seq k =
|
||||||
try
|
try
|
||||||
seq (fun x -> if p x then k x else raise ExitSequence)
|
seq (fun x -> if p x then k x else raise ExitSequence)
|
||||||
with ExitSequence -> ()
|
with ExitSequence -> ()
|
||||||
|
|
||||||
(** Drop the [n] first elements of the sequence *)
|
let drop n seq k =
|
||||||
let drop n seq =
|
|
||||||
let count = ref 0 in
|
let count = ref 0 in
|
||||||
fun k -> seq
|
seq (fun x -> if !count >= n then k x else incr count)
|
||||||
(fun x -> if !count >= n then k x else incr count)
|
|
||||||
|
|
||||||
let drop_while p seq k =
|
let drop_while p seq k =
|
||||||
let drop = ref true in
|
let drop = ref true in
|
||||||
|
|
@ -404,12 +347,10 @@ let drop_while p seq k =
|
||||||
then if p x then () else (drop := false; k x)
|
then if p x then () else (drop := false; k x)
|
||||||
else k x)
|
else k x)
|
||||||
|
|
||||||
(** Reverse the sequence. O(n) memory. *)
|
|
||||||
let rev seq =
|
let rev seq =
|
||||||
let l = MList.of_seq seq in
|
let l = MList.of_seq seq in
|
||||||
from_iter (fun k -> MList.iter_rev k l)
|
fun k -> MList.iter_rev k l
|
||||||
|
|
||||||
(** Do all elements satisfy the predicate? *)
|
|
||||||
let for_all p seq =
|
let for_all p seq =
|
||||||
try
|
try
|
||||||
seq (fun x -> if not (p x) then raise ExitSequence);
|
seq (fun x -> if not (p x) then raise ExitSequence);
|
||||||
|
|
@ -436,21 +377,18 @@ let find f seq =
|
||||||
end;
|
end;
|
||||||
!r
|
!r
|
||||||
|
|
||||||
(** How long is the sequence? *)
|
|
||||||
let length seq =
|
let length seq =
|
||||||
let r = ref 0 in
|
let r = ref 0 in
|
||||||
seq (fun _ -> incr r);
|
seq (fun _ -> incr r);
|
||||||
!r
|
!r
|
||||||
|
|
||||||
(** Is the sequence empty? *)
|
|
||||||
let is_empty seq =
|
let is_empty seq =
|
||||||
try seq (fun _ -> raise ExitSequence); true
|
try seq (fun _ -> raise ExitSequence); true
|
||||||
with ExitSequence -> false
|
with ExitSequence -> false
|
||||||
|
|
||||||
(** {2 Transform a sequence} *)
|
(** {2 Transform a sequence} *)
|
||||||
|
|
||||||
let empty2 =
|
let empty2 k = ()
|
||||||
fun k -> ()
|
|
||||||
|
|
||||||
let is_empty2 seq2 =
|
let is_empty2 seq2 =
|
||||||
try ignore (seq2 (fun _ _ -> raise ExitSequence)); true
|
try ignore (seq2 (fun _ _ -> raise ExitSequence)); true
|
||||||
|
|
@ -461,32 +399,25 @@ let length2 seq2 =
|
||||||
seq2 (fun _ _ -> incr r);
|
seq2 (fun _ _ -> incr r);
|
||||||
!r
|
!r
|
||||||
|
|
||||||
let zip seq2 =
|
let zip seq2 k = seq2 (fun x y -> k (x,y))
|
||||||
fun k -> seq2 (fun x y -> k (x,y))
|
|
||||||
|
|
||||||
let unzip seq =
|
let unzip seq k = seq (fun (x,y) -> k x y)
|
||||||
fun k -> seq (fun (x,y) -> k x y)
|
|
||||||
|
|
||||||
(** Zip elements of the sequence with their index in the sequence *)
|
let zip_i seq k =
|
||||||
let zip_i seq =
|
let r = ref 0 in
|
||||||
fun k ->
|
seq (fun x -> let n = !r in incr r; k n x)
|
||||||
let r = ref 0 in
|
|
||||||
seq (fun x -> let n = !r in incr r; k n x)
|
|
||||||
|
|
||||||
let fold2 f acc seq2 =
|
let fold2 f acc seq2 =
|
||||||
let acc = ref acc in
|
let acc = ref acc in
|
||||||
seq2 (fun x y -> acc := f !acc x y);
|
seq2 (fun x y -> acc := f !acc x y);
|
||||||
!acc
|
!acc
|
||||||
|
|
||||||
let iter2 f seq2 =
|
let iter2 f seq2 = seq2 f
|
||||||
seq2 f
|
|
||||||
|
|
||||||
let map2 f seq2 =
|
let map2 f seq2 k = seq2 (fun x y -> k (f x y))
|
||||||
fun k -> seq2 (fun x y -> k (f x y))
|
|
||||||
|
|
||||||
(** [map2_2 f g seq2] maps each [x, y] of seq2 into [f x y, g x y] *)
|
let map2_2 f g seq2 k =
|
||||||
let map2_2 f g seq2 =
|
seq2 (fun x y -> k (f x y) (g x y))
|
||||||
fun k -> seq2 (fun x y -> k (f x y) (g x y))
|
|
||||||
|
|
||||||
(** {2 Basic data structures converters} *)
|
(** {2 Basic data structures converters} *)
|
||||||
|
|
||||||
|
|
@ -494,7 +425,7 @@ let to_list seq = List.rev (fold (fun y x -> x::y) [] seq)
|
||||||
|
|
||||||
let to_rev_list seq = fold (fun y x -> x :: y) [] seq
|
let to_rev_list seq = fold (fun y x -> x :: y) [] seq
|
||||||
|
|
||||||
let of_list l = from_iter (fun k -> List.iter k l)
|
let of_list l k = List.iter k l
|
||||||
|
|
||||||
let to_array seq =
|
let to_array seq =
|
||||||
let l = MList.of_seq seq in
|
let l = MList.of_seq seq in
|
||||||
|
|
@ -507,60 +438,46 @@ let to_array seq =
|
||||||
a
|
a
|
||||||
end
|
end
|
||||||
|
|
||||||
let of_array a =
|
let of_array a k =
|
||||||
fun k ->
|
for i = 0 to Array.length a - 1 do
|
||||||
for i = 0 to Array.length a - 1 do
|
k (Array.unsafe_get a i)
|
||||||
k (Array.unsafe_get a i)
|
done
|
||||||
done
|
|
||||||
|
|
||||||
let of_array_i a =
|
let of_array_i a k =
|
||||||
fun k ->
|
for i = 0 to Array.length a - 1 do
|
||||||
for i = 0 to Array.length a - 1 do
|
k (i, Array.unsafe_get a i)
|
||||||
k (i, Array.unsafe_get a i)
|
done
|
||||||
done
|
|
||||||
|
|
||||||
let of_array2 a =
|
let of_array2 a k =
|
||||||
fun k ->
|
for i = 0 to Array.length a - 1 do
|
||||||
for i = 0 to Array.length a - 1 do
|
k i (Array.unsafe_get a i)
|
||||||
k i (Array.unsafe_get a i)
|
done
|
||||||
done
|
|
||||||
|
|
||||||
(** [array_slice a i j] Sequence of elements whose indexes range
|
let array_slice a i j k =
|
||||||
from [i] to [j] *)
|
|
||||||
let array_slice a i j =
|
|
||||||
assert (i >= 0 && j < Array.length a);
|
assert (i >= 0 && j < Array.length a);
|
||||||
fun k ->
|
for idx = i to j do
|
||||||
for idx = i to j do
|
k a.(idx); (* iterate on sub-array *)
|
||||||
k a.(idx); (* iterate on sub-array *)
|
done
|
||||||
done
|
|
||||||
|
|
||||||
(** Sequence of elements of a stream (usable only once) *)
|
let of_stream s k = Stream.iter k s
|
||||||
let of_stream s =
|
|
||||||
let seq k = Stream.iter k s in
|
|
||||||
from_iter seq
|
|
||||||
|
|
||||||
(** Convert to a stream. The sequence is made persistent. *)
|
|
||||||
let to_stream seq =
|
let to_stream seq =
|
||||||
let l = MList.of_seq seq in
|
let l = MList.of_seq seq in
|
||||||
MList.to_stream l
|
MList.to_stream l
|
||||||
|
|
||||||
(** 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
|
||||||
|
|
||||||
(** Sequence of elements of the stack (same order as [Stack.iter]) *)
|
let of_stack s k = Stack.iter k s
|
||||||
let of_stack s = from_iter (fun k -> Stack.iter k s)
|
|
||||||
|
|
||||||
(** Push elements of the sequence into the queue *)
|
let to_queue q seq = seq (fun x -> Queue.push x q)
|
||||||
let to_queue q seq = iter (fun x -> Queue.push x q) seq
|
|
||||||
|
|
||||||
(** Sequence of elements contained in the queue, FIFO order *)
|
let of_queue q k = Queue.iter k q
|
||||||
let of_queue q = from_iter (fun k -> Queue.iter k q)
|
|
||||||
|
|
||||||
let hashtbl_add h seq =
|
let hashtbl_add h seq =
|
||||||
iter (fun (k,v) -> Hashtbl.add h k v) seq
|
seq (fun (k,v) -> Hashtbl.add h k v)
|
||||||
|
|
||||||
let hashtbl_replace h seq =
|
let hashtbl_replace h seq =
|
||||||
iter (fun (k,v) -> Hashtbl.replace h k v) seq
|
seq (fun (k,v) -> Hashtbl.replace h k v)
|
||||||
|
|
||||||
let to_hashtbl seq =
|
let to_hashtbl seq =
|
||||||
let h = Hashtbl.create 3 in
|
let h = Hashtbl.create 3 in
|
||||||
|
|
@ -572,19 +489,15 @@ let to_hashtbl2 seq2 =
|
||||||
seq2 (fun k v -> Hashtbl.replace h k v);
|
seq2 (fun k v -> Hashtbl.replace h k v);
|
||||||
h
|
h
|
||||||
|
|
||||||
let of_hashtbl h =
|
let of_hashtbl h k = Hashtbl.iter (fun a b -> k (a, b)) h
|
||||||
from_iter (fun k -> Hashtbl.iter (fun a b -> k (a, b)) h)
|
|
||||||
|
|
||||||
let of_hashtbl2 h =
|
let of_hashtbl2 h k = Hashtbl.iter k h
|
||||||
fun k -> Hashtbl.iter k h
|
|
||||||
|
|
||||||
let hashtbl_keys h =
|
let hashtbl_keys h k = Hashtbl.iter (fun a b -> k a) h
|
||||||
from_iter (fun k -> Hashtbl.iter (fun a b -> k a) h)
|
|
||||||
|
|
||||||
let hashtbl_values h =
|
let hashtbl_values h k = Hashtbl.iter (fun a b -> k b) h
|
||||||
from_iter (fun k -> Hashtbl.iter (fun a b -> k b) h)
|
|
||||||
|
|
||||||
let of_str s = from_iter (fun k -> String.iter k s)
|
let of_str s k = String.iter k s
|
||||||
|
|
||||||
let to_str seq =
|
let to_str seq =
|
||||||
let b = Buffer.create 64 in
|
let b = Buffer.create 64 in
|
||||||
|
|
@ -596,32 +509,36 @@ let concat_str seq =
|
||||||
iter (Buffer.add_string b) seq;
|
iter (Buffer.add_string b) seq;
|
||||||
Buffer.contents b
|
Buffer.contents b
|
||||||
|
|
||||||
let of_in_channel ic =
|
exception OneShotSequence
|
||||||
from_iter (fun k ->
|
|
||||||
try while true do
|
let of_in_channel ic =
|
||||||
let c = input_char ic in k c
|
let first = ref true in
|
||||||
done with End_of_file -> ())
|
fun k ->
|
||||||
|
if not !first
|
||||||
|
then raise OneShotSequence
|
||||||
|
else (
|
||||||
|
first := false;
|
||||||
|
try
|
||||||
|
while true do
|
||||||
|
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 =
|
let to_buffer seq buf =
|
||||||
iter (fun c -> Buffer.add_char buf c) seq
|
seq (fun c -> Buffer.add_char buf c)
|
||||||
|
|
||||||
(** 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 k =
|
||||||
fun k ->
|
for i = start to stop do k i done
|
||||||
for i = start to stop do k i done
|
|
||||||
|
|
||||||
let int_range_dec ~start ~stop =
|
let int_range_dec ~start ~stop k =
|
||||||
fun k ->
|
for i = start downto stop do k i done
|
||||||
for i = start downto stop do k i done
|
|
||||||
|
|
||||||
(** Convert the given set to a sequence. The set module must be provided. *)
|
|
||||||
let of_set (type s) (type v) m set =
|
let of_set (type s) (type v) m set =
|
||||||
let module S = (val m : Set.S with type t = s and type elt = v) in
|
let module S = (val m : Set.S with type t = s and type elt = v) in
|
||||||
from_iter
|
fun k -> S.iter k set
|
||||||
(fun k -> S.iter k set)
|
|
||||||
|
|
||||||
(** Convert the sequence to a set, given the proper set module *)
|
|
||||||
let to_set (type s) (type v) m seq =
|
let to_set (type s) (type v) m seq =
|
||||||
let module S = (val m : Set.S with type t = s and type elt = v) in
|
let module S = (val m : Set.S with type t = s and type elt = v) in
|
||||||
fold
|
fold
|
||||||
|
|
@ -716,15 +633,12 @@ let random_bool = forever Random.bool
|
||||||
|
|
||||||
let random_float bound = forever (fun () -> Random.float bound)
|
let random_float bound = forever (fun () -> Random.float bound)
|
||||||
|
|
||||||
(** Sequence of choices of an element in the array *)
|
let random_array a k =
|
||||||
let random_array a =
|
|
||||||
assert (Array.length a > 0);
|
assert (Array.length a > 0);
|
||||||
let seq k =
|
while true do
|
||||||
while true do
|
let i = Random.int (Array.length a) in
|
||||||
let i = Random.int (Array.length a) in
|
k a.(i);
|
||||||
k a.(i);
|
done
|
||||||
done in
|
|
||||||
from_iter seq
|
|
||||||
|
|
||||||
let random_list l = random_array (Array.of_list l)
|
let random_list l = random_array (Array.of_list l)
|
||||||
|
|
||||||
|
|
@ -753,7 +667,7 @@ include Infix
|
||||||
to print each elements. An optional separator string can be provided. *)
|
to print each elements. An optional separator string can be provided. *)
|
||||||
let pp_seq ?(sep=", ") pp_elt formatter seq =
|
let pp_seq ?(sep=", ") pp_elt formatter seq =
|
||||||
let first = ref true in
|
let first = ref true in
|
||||||
iter
|
seq
|
||||||
(fun x ->
|
(fun x ->
|
||||||
(if !first then first := false
|
(if !first then first := false
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -761,15 +675,13 @@ let pp_seq ?(sep=", ") pp_elt formatter seq =
|
||||||
Format.pp_print_cut formatter ();
|
Format.pp_print_cut formatter ();
|
||||||
end);
|
end);
|
||||||
pp_elt formatter x)
|
pp_elt formatter x)
|
||||||
seq
|
|
||||||
|
|
||||||
let pp_buf ?(sep=", ") pp_elt buf seq =
|
let pp_buf ?(sep=", ") pp_elt buf seq =
|
||||||
let first = ref true in
|
let first = ref true in
|
||||||
iter
|
seq
|
||||||
(fun x ->
|
(fun x ->
|
||||||
if !first then first := false else Buffer.add_string buf sep;
|
if !first then first := false else Buffer.add_string buf sep;
|
||||||
pp_elt buf x)
|
pp_elt buf x)
|
||||||
seq
|
|
||||||
|
|
||||||
let to_string ?sep pp_elt seq =
|
let to_string ?sep pp_elt seq =
|
||||||
let buf = Buffer.create 25 in
|
let buf = Buffer.create 25 in
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,10 @@ val concat_str : string t -> string
|
||||||
Also see {!intersperse} to add a separator.
|
Also see {!intersperse} to add a separator.
|
||||||
@since NEXT_VERSION *)
|
@since NEXT_VERSION *)
|
||||||
|
|
||||||
|
exception OneShotSequence
|
||||||
|
(** Raised when the user tries to iterate several times on
|
||||||
|
a transient iterator *)
|
||||||
|
|
||||||
val of_in_channel : in_channel -> char t
|
val of_in_channel : in_channel -> char t
|
||||||
(** Iterates on characters of the input (can block when one
|
(** Iterates on characters of the input (can block when one
|
||||||
iterates over the sequence). If you need to iterate
|
iterates over the sequence). If you need to iterate
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue