feat(CCIO): add many Seq.t based functions

each generator function can now produce a seq.
This commit is contained in:
Simon Cruanes 2021-06-26 23:50:30 -04:00
parent 26af1f1297
commit 61b9762269
2 changed files with 69 additions and 3 deletions

View file

@ -52,6 +52,27 @@ let gen_flat_map f next_elem =
in
next
type 'a seq_of_gen_state_ =
| Of_gen_thunk of 'a gen
| Of_gen_saved of 'a Seq.node
let seq_of_gen_ g =
let rec consume r () = match !r with
| Of_gen_saved cons -> cons
| Of_gen_thunk g ->
begin match g() with
| None ->
r := Of_gen_saved Seq.Nil;
Nil
| Some x ->
let tl = consume (ref (Of_gen_thunk g)) in
let l = Seq.Cons (x, tl) in
r := Of_gen_saved l;
l
end
in
consume (ref (Of_gen_thunk g))
let finally_ f x ~h =
try
let res = f x in
@ -75,6 +96,9 @@ let read_chunks_gen ?(size=1024) ic =
in
next
let read_chunks_seq ?size ic =
seq_of_gen_ (read_chunks_gen ?size ic)
let read_line ic =
try Some (input_line ic)
with End_of_file -> None
@ -86,6 +110,9 @@ let read_lines_gen ic =
else try Some (input_line ic)
with End_of_file -> (stop:=true; None)
let read_lines_seq ic =
seq_of_gen_ (read_chunks_gen ic)
let read_lines_l ic =
let l = ref [] in
try
@ -152,17 +179,30 @@ let write_line oc s =
output_char oc '\n'
let write_gen ?(sep="") oc g =
let rec recurse () = match g() with
let rec recurse g = match g() with
| None -> ()
| Some s ->
output_string oc sep;
output_string oc s;
recurse ()
recurse g
in match g() with
| None -> ()
| Some s ->
output_string oc s;
recurse ()
recurse g
let write_seq ?(sep="") oc seq : unit =
let rec recurse g = match g() with
| Seq.Nil -> ()
| Seq.Cons(s,seq) ->
output_string oc sep;
output_string oc s;
recurse seq
in match seq() with
| Seq.Nil -> ()
| Seq.Cons(s,seq) ->
output_string oc s;
recurse seq
let rec write_lines oc g = match g () with
| None -> ()
@ -170,6 +210,9 @@ let rec write_lines oc g = match g () with
write_line oc l;
write_lines oc g
let write_lines_seq oc seq =
Seq.iter (write_line oc) seq
let write_lines_l oc l =
List.iter (write_line oc) l
@ -342,6 +385,8 @@ module File = struct
)
*)
let walk_seq d = seq_of_gen_ (walk d)
let walk_l d =
let l = ref [] in
let g = walk d in

View file

@ -71,6 +71,12 @@ val read_chunks_gen : ?size:int -> in_channel -> string gen
{b NOTE} the generator must be used within the lifetime of the channel,
see warning at the top of the file. *)
val read_chunks_seq : ?size:int -> in_channel -> string Seq.t
(** Read the channel's content into chunks of size [size].
{b NOTE} the generator must be used within the lifetime of the channel,
see warning at the top of the file.
@since NEXT_RELEASE *)
val read_line : in_channel -> string option
(** Read a line from the channel. Returns [None] if the input is terminated.
The "\n" is removed from the line. *)
@ -80,6 +86,12 @@ val read_lines_gen : in_channel -> string gen
{b NOTE} the generator must be used within the lifetime of the channel,
see warning at the top of the file. *)
val read_lines_seq : in_channel -> string Seq.t
(** Read all lines.
{b NOTE} the seq must be used within the lifetime of the channel,
see warning at the top of the file.
@since NEXT_RELEASE *)
val read_lines_l : in_channel -> string list
(** Read all lines into a list. *)
@ -115,9 +127,18 @@ val write_gen : ?sep:string -> out_channel -> string gen -> unit
(** Write the given strings on the output. If provided, add [sep] between
every two strings (but not at the end). *)
val write_seq : ?sep:string -> out_channel -> string Seq.t -> unit
(** Write the given strings on the output. If provided, add [sep] between
every two strings (but not at the end).
@since NEXT_RELEASE *)
val write_lines : out_channel -> string gen -> unit
(** Write every string on the output, followed by "\n". *)
val write_lines_seq : out_channel -> string Seq.t -> unit
(** Write every string on the output, followed by "\n".
@since NEXT_RELEASE *)
val write_lines_l : out_channel -> string list -> unit
(** {2 Both} *)