mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 03:05:29 -05:00
use Seq, remove Stream entirely to be ready for OCaml 5.0; add of_gen_once
This commit is contained in:
parent
65ab9376b0
commit
173da38366
5 changed files with 55 additions and 71 deletions
|
|
@ -13,6 +13,7 @@ build: [
|
|||
depends: [
|
||||
"base-bytes"
|
||||
"result"
|
||||
"seq"
|
||||
"ocaml" { >= "4.03.0" }
|
||||
"dune" { >= "1.1" }
|
||||
"dune-configurator"
|
||||
|
|
|
|||
80
src/Iter.ml
80
src/Iter.ml
|
|
@ -344,14 +344,11 @@ module MList = struct
|
|||
|
||||
let to_gen l = _to_next () l
|
||||
|
||||
let to_stream l =
|
||||
Stream.from (_to_next 42 l) (* 42=magic cookiiiiiie *)
|
||||
|
||||
let to_klist l =
|
||||
let to_seq l =
|
||||
let rec make (l,i) () = match l with
|
||||
| Nil -> `Nil
|
||||
| Nil -> Seq.Nil
|
||||
| Cons (_, n, tl) when i = !n -> make (!tl,0) ()
|
||||
| Cons (a, _, _) -> `Cons (a.(i), make (l,i+1))
|
||||
| Cons (a, _, _) -> Seq.Cons (a.(i), make (l,i+1))
|
||||
in make (l,0)
|
||||
end
|
||||
|
||||
|
|
@ -361,31 +358,22 @@ let persistent seq =
|
|||
|
||||
(*$R
|
||||
let printer = pp_ilist in
|
||||
let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
|
||||
let seq = of_stream stream in
|
||||
OUnit.assert_equal ~printer [0;1;2;3;4] (seq |> to_list);
|
||||
OUnit.assert_equal ~printer [] (seq |> to_list);
|
||||
let iter = of_gen_once (let i=ref (-1) in fun() -> incr i; if !i < 5 then Some !i else None) in
|
||||
(* consume iter into a persistent version of itself *)
|
||||
let iter' = persistent iter in
|
||||
OUnit.assert_raises OneShotSequence (fun () -> iter |> to_list);
|
||||
OUnit.assert_equal ~printer [0;1;2;3;4] (iter' |> to_list);
|
||||
OUnit.assert_equal ~printer [0;1;2;3;4] (iter' |> to_list);
|
||||
OUnit.assert_equal ~printer [0;1;2;3;4] (iter' |> to_seq_persistent |> of_seq |> to_list);
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let printer = pp_ilist in
|
||||
let stream = Stream.from (fun i -> if i < 5 then Some i else None) in
|
||||
let seq = of_stream stream in
|
||||
(* consume seq into a persistent version of itself *)
|
||||
let seq' = persistent seq in
|
||||
OUnit.assert_equal ~printer [] (seq |> to_list);
|
||||
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_list);
|
||||
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_list);
|
||||
OUnit.assert_equal ~printer [0;1;2;3;4] (seq' |> to_stream |> of_stream |> to_list);
|
||||
*)
|
||||
|
||||
(*$R
|
||||
let printer = pp_ilist in
|
||||
let seq = (0 -- 10_000) in
|
||||
let seq' = persistent seq in
|
||||
OUnit.assert_equal 10_001 (length seq');
|
||||
OUnit.assert_equal 10_001 (length seq');
|
||||
OUnit.assert_equal ~printer [0;1;2;3] (seq' |> take 4 |> to_list);
|
||||
let iter = (0 -- 10_000) in
|
||||
let iter' = persistent iter in
|
||||
OUnit.assert_equal 10_001 (length iter');
|
||||
OUnit.assert_equal 10_001 (length iter');
|
||||
OUnit.assert_equal ~printer [0;1;2;3] (iter' |> take 4 |> to_list);
|
||||
*)
|
||||
|
||||
type 'a lazy_state =
|
||||
|
|
@ -542,8 +530,7 @@ let[@inline] product outer inner k =
|
|||
outer (fun x -> inner (fun y -> k (x,y)))
|
||||
|
||||
(*$R
|
||||
let stream = Stream.from (fun i -> if i < 3 then Some i else None) in
|
||||
let a = of_stream stream in
|
||||
let a = 0 -- 2 in
|
||||
let b = of_list ["a";"b";"c"] in
|
||||
let s = product a b |> map (fun (x,y) -> y,x)
|
||||
|> to_list |> List.sort compare in
|
||||
|
|
@ -1041,11 +1028,13 @@ let array_slice a i j k =
|
|||
k a.(idx); (* iterate on sub-array *)
|
||||
done
|
||||
|
||||
let of_stream s k = Stream.iter k s
|
||||
let rec of_seq l k = match l() with
|
||||
| Seq.Nil -> ()
|
||||
| Seq.Cons (x,tl) -> k x; of_seq tl k
|
||||
|
||||
let to_stream seq =
|
||||
let to_seq_persistent seq =
|
||||
let l = MList.of_iter seq in
|
||||
MList.to_stream l
|
||||
MList.to_seq l
|
||||
|
||||
let[@inline] to_stack s seq = iter (fun x -> Stack.push x s) seq
|
||||
|
||||
|
|
@ -1169,29 +1158,26 @@ let to_set (type s) (type v) m seq =
|
|||
S.empty seq
|
||||
|
||||
type 'a gen = unit -> 'a option
|
||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||
|
||||
(* consume the generator to build a MList *)
|
||||
let rec of_gen1_ g k = match g () with
|
||||
| None -> ()
|
||||
| Some x -> k x; of_gen1_ g k
|
||||
|
||||
let of_gen_once g =
|
||||
let first = ref true in
|
||||
fun k ->
|
||||
if !first then first := false else raise OneShotSequence;
|
||||
of_gen1_ g k
|
||||
|
||||
let of_gen g =
|
||||
(* consume the generator to build a MList *)
|
||||
let rec iter1 k = match g () with
|
||||
| None -> ()
|
||||
| Some x -> k x; iter1 k
|
||||
in
|
||||
let l = MList.of_iter iter1 in
|
||||
let l = MList.of_iter (of_gen1_ g) in
|
||||
MList.to_iter l
|
||||
|
||||
let to_gen seq =
|
||||
let l = MList.of_iter seq in
|
||||
MList.to_gen l
|
||||
|
||||
let rec of_klist l k = match l() with
|
||||
| `Nil -> ()
|
||||
| `Cons (x,tl) -> k x; of_klist tl k
|
||||
|
||||
let to_klist seq =
|
||||
let l = MList.of_iter seq in
|
||||
MList.to_klist l
|
||||
|
||||
(** {2 Functorial conversions between sets and iterators} *)
|
||||
|
||||
module Set = struct
|
||||
|
|
|
|||
25
src/Iter.mli
25
src/Iter.mli
|
|
@ -25,7 +25,7 @@
|
|||
(i.e. calling it several times always iterates on the same set of
|
||||
elements, for instance List.iter or Map.iter), then
|
||||
the resulting {!t} object is also repeatable. For {b one-time iter functions}
|
||||
such as iteration on a file descriptor or a {!Stream},
|
||||
such as iteration on a file descriptor or a {!Seq},
|
||||
the {!persistent} function can be used to iterate and store elements in
|
||||
a memory structure; the result is an iterator that iterates on the elements
|
||||
of this memory structure, cheaply and repeatably.
|
||||
|
|
@ -567,11 +567,14 @@ val of_opt : 'a option -> 'a t
|
|||
(** Iterate on 0 or 1 values.
|
||||
@since 0.5.1 *)
|
||||
|
||||
val of_stream : 'a Stream.t -> 'a t
|
||||
(** Iterator of elements of a stream (usable only once) *)
|
||||
val of_seq : 'a Seq.t -> 'a t
|
||||
(** Iterator of elements of a {!Seq.t}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val to_stream : 'a t -> 'a Stream.t
|
||||
(** Convert to a stream. linear in memory and time (a copy is made in memory) *)
|
||||
val to_seq_persistent : 'a t -> 'a Seq.t
|
||||
(** Convert to a {!Seq}. Linear in memory and time (a copy is made in memory).
|
||||
This does not work on infinite iterators.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val to_stack : 'a Stack.t -> 'a t -> unit
|
||||
(** Push elements of the iterator on the stack *)
|
||||
|
|
@ -648,20 +651,18 @@ val to_set : (module Set.S with type elt = 'a and type t = 'b) -> 'a t -> 'b
|
|||
(** Convert the iterator to a set, given the proper set module *)
|
||||
|
||||
type 'a gen = unit -> 'a option
|
||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||
|
||||
val of_gen : 'a gen -> 'a t
|
||||
(** Traverse eagerly the generator and build an iterator from it *)
|
||||
|
||||
val of_gen_once : 'a gen -> 'a t
|
||||
(** One shot iterator using this generator.
|
||||
It must not be traversed twice.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val to_gen : 'a t -> 'a gen
|
||||
(** Make the iterator persistent (O(n)) and then iterate on it. Eager. *)
|
||||
|
||||
val of_klist : 'a klist -> 'a t
|
||||
(** Iterate on the lazy list *)
|
||||
|
||||
val to_klist : 'a t -> 'a klist
|
||||
(** Make the iterator persistent and then iterate on it. Eager. *)
|
||||
|
||||
(** {2 Sets} *)
|
||||
|
||||
module Set : sig
|
||||
|
|
|
|||
|
|
@ -531,11 +531,14 @@ val of_opt : 'a option -> 'a t
|
|||
(** Iterate on 0 or 1 values.
|
||||
@since 0.5.1 *)
|
||||
|
||||
val of_stream : 'a Stream.t -> 'a t
|
||||
(** Iterator of elements of a stream (usable only once) *)
|
||||
val of_seq : 'a Seq.t -> 'a t
|
||||
(** Iterator of elements of a {!Seq.t}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val to_stream : 'a t -> 'a Stream.t
|
||||
(** Convert to a stream. linear in memory and time (a copy is made in memory) *)
|
||||
val to_seq_persistent : 'a t -> 'a Seq.t
|
||||
(** Convert to a {!Seq}. Linear in memory and time (a copy is made in memory).
|
||||
This does not work on infinite iterators.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val to_stack : 'a Stack.t -> 'a t -> unit
|
||||
(** Push elements of the iterator on the stack *)
|
||||
|
|
@ -613,7 +616,6 @@ val to_set : (module Set.S with type elt = 'a and type t = 'b) -> 'a t -> 'b
|
|||
(** Convert the iterator to a set, given the proper set module *)
|
||||
|
||||
type 'a gen = unit -> 'a option
|
||||
type 'a klist = unit -> [`Nil | `Cons of 'a * 'a klist]
|
||||
|
||||
val of_gen : 'a gen -> 'a t
|
||||
(** Traverse eagerly the generator and build an iterator from it *)
|
||||
|
|
@ -621,12 +623,6 @@ val of_gen : 'a gen -> 'a t
|
|||
val to_gen : 'a t -> 'a gen
|
||||
(** Make the iterator persistent (O(n)) and then iterate on it. Eager. *)
|
||||
|
||||
val of_klist : 'a klist -> 'a t
|
||||
(** Iterate on the lazy list *)
|
||||
|
||||
val to_klist : 'a t -> 'a klist
|
||||
(** Make the iterator persistent and then iterate on it. Eager. *)
|
||||
|
||||
(** {3 Sets} *)
|
||||
|
||||
module Set : sig
|
||||
|
|
|
|||
2
src/dune
2
src/dune
|
|
@ -15,7 +15,7 @@
|
|||
(wrapped false)
|
||||
(modules Iter IterLabels Iter_shims_)
|
||||
(flags :standard -nolabels)
|
||||
(libraries bytes result))
|
||||
(libraries bytes result seq))
|
||||
|
||||
|
||||
(env
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue