let span xs ~f =
(*Two possibilities: either the tail has been read
already -- in which case all head data has been
copied onto the queue -- or the tail hasn't been
read -- in which case, stuff should be read from
[xs] *)
let queue = Queue.create ()
and read_from_queue = ref false in
let head _ =
if !read_from_queue then (* Everything from the head has been copied *)
Queue.dequeue queue (* to the queue already *)
else
match peek xs with
| Some x as e when f x -> junk xs ; e
| _ -> None
and tail _ =
if not !read_from_queue then (*Copy everything to the queue *)
begin
read_from_queue := true;
let rec aux () =
match peek xs with
| Some x when f x -> Queue.enqueue queue x ; aux ()
| e -> e
in aux ()
end
else next xs
in
(from head, from tail)