mirror of
https://github.com/c-cube/iter.git
synced 2025-12-06 11:15:32 -05:00
wip: add to_seq and of_seq, the former using effects.
We need effects to invert control flow and transform the straightforward iteration (say, on a tree), into a resumable Seq.t.
This commit is contained in:
parent
b4ceba4cb0
commit
06f49690e5
2 changed files with 69 additions and 0 deletions
61
src/Iter.ml
61
src/Iter.ml
|
|
@ -1007,6 +1007,67 @@ let[@inline] of_list l k = List.iter k l
|
||||||
let on_list f l =
|
let on_list f l =
|
||||||
to_list (f (of_list l))
|
to_list (f (of_list l))
|
||||||
|
|
||||||
|
let of_seq seq k =
|
||||||
|
Seq.iter k seq
|
||||||
|
|
||||||
|
let to_seq (type a) (self:a t) : a Seq.t =
|
||||||
|
let stop = ref false in
|
||||||
|
let cur = ref None in
|
||||||
|
|
||||||
|
let module M = struct
|
||||||
|
type _ EffectHandlers.eff +=
|
||||||
|
| Yield : a -> unit EffectHandlers.eff
|
||||||
|
end in
|
||||||
|
|
||||||
|
let iter () : unit =
|
||||||
|
self (fun x -> EffectHandlers.perform (M.Yield x));
|
||||||
|
stop := true;
|
||||||
|
cur := None;
|
||||||
|
in
|
||||||
|
|
||||||
|
let k: _ EffectHandlers.Shallow.continuation ref
|
||||||
|
= ref (EffectHandlers.Shallow.fiber iter) in
|
||||||
|
|
||||||
|
let effc
|
||||||
|
: type c. c EffectHandlers.eff -> ((c,_) EffectHandlers.Shallow.continuation -> _) option
|
||||||
|
= function
|
||||||
|
| M.Yield x ->
|
||||||
|
cur := Some x;
|
||||||
|
Some (fun k' -> k := k')
|
||||||
|
| _ -> None
|
||||||
|
in
|
||||||
|
|
||||||
|
let handler = {
|
||||||
|
EffectHandlers.Shallow.retc=ignore; exnc=ignore; effc;
|
||||||
|
} in
|
||||||
|
|
||||||
|
let rec next () =
|
||||||
|
if !stop then Seq.Nil
|
||||||
|
else (
|
||||||
|
EffectHandlers.Shallow.continue_with !k () handler;
|
||||||
|
match !cur with
|
||||||
|
| None -> Seq.Nil
|
||||||
|
| Some x -> Seq.Cons (x, next)
|
||||||
|
)
|
||||||
|
in
|
||||||
|
next
|
||||||
|
|
||||||
|
(*$R
|
||||||
|
let seq = ref @@ to_seq (1 -- 5) in
|
||||||
|
|
||||||
|
let next () = match (!seq) () with
|
||||||
|
| Seq.Nil -> None
|
||||||
|
| Seq.Cons (x,tl) -> seq := tl; Some x
|
||||||
|
in
|
||||||
|
|
||||||
|
assert_equal ~printer:(Q.Print.(option int)) (Some 1) (next ());
|
||||||
|
assert_equal ~printer:(Q.Print.(option int)) (Some 2) (next ());
|
||||||
|
assert_equal ~printer:(Q.Print.(option int)) (Some 3) (next ());
|
||||||
|
assert_equal ~printer:(Q.Print.(option int)) (Some 4) (next ());
|
||||||
|
assert_equal ~printer:(Q.Print.(option int)) (Some 5) (next ());
|
||||||
|
assert_equal ~printer:(Q.Print.(option int)) None (next ());
|
||||||
|
*)
|
||||||
|
|
||||||
let pair_with_idx seq k =
|
let pair_with_idx seq k =
|
||||||
let r = ref 0 in
|
let r = ref 0 in
|
||||||
seq (fun x -> let n = !r in incr r; k (n,x))
|
seq (fun x -> let n = !r in incr r; k (n,x))
|
||||||
|
|
|
||||||
|
|
@ -542,6 +542,14 @@ val on_list : ('a t -> 'b t) -> 'a list -> 'b list
|
||||||
@since 0.5.2
|
@since 0.5.2
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
val of_seq : 'a Seq.t -> 'a t
|
||||||
|
(** Iterate on the sequence.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val to_seq : 'a t -> 'a Seq.t
|
||||||
|
(** Sequence from the iterator (using effects).
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val pair_with_idx : 'a t -> (int * 'a) t
|
val pair_with_idx : 'a t -> (int * 'a) t
|
||||||
(** Similar to {!zip_i} but returns a normal iterator of tuples
|
(** Similar to {!zip_i} but returns a normal iterator of tuples
|
||||||
@since 0.11 *)
|
@since 0.11 *)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue