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)