mirror of
https://github.com/c-cube/iter.git
synced 2025-12-05 19:00:31 -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 =
|
||||
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 r = ref 0 in
|
||||
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
|
||||
*)
|
||||
|
||||
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
|
||||
(** Similar to {!zip_i} but returns a normal iterator of tuples
|
||||
@since 0.11 *)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue