-
Notifications
You must be signed in to change notification settings - Fork 9
/
gen.mli
159 lines (120 loc) · 5.29 KB
/
gen.mli
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
(* This file is free software, part of gen. See file "license" for more details. *)
(** {1 Generators}
Values of type ['a Gen.t] represent a possibly infinite sequence of values
of type 'a. One can only iterate once on the sequence, as it is consumed
by iteration/deconstruction/access. [None] is returned when the generator
is exhausted.
The submodule {!Restart} provides utilities to work with
{b restartable generators}, that is, functions [unit -> 'a Gen.t] that
allow to build as many generators from the same source as needed.
*)
(** {2 Global type declarations} *)
type 'a t = unit -> 'a option
(** A generator may be called several times, yielding the next value
each time. It returns [None] when no elements remain *)
type 'a gen = 'a t
module type S = Gen_intf.S
(** {2 Transient generators} *)
val get : 'a t -> 'a option
(** Get the next value *)
val next : 'a t -> 'a option
(** Synonym for {!get} *)
val get_exn : 'a t -> 'a
(** Get the next value, or fails
@raise Invalid_argument if no element remains *)
val junk : 'a t -> unit
(** Drop the next value, discarding it. *)
val repeatedly : (unit -> 'a) -> 'a t
(** Call the same function an infinite number of times (useful for instance
if the function is a random generator). *)
include S with type 'a t := 'a gen
(** Operations on {b transient} generators *)
(** {2 Restartable generators}
A {i restartable generator} is a function that produces copies of the
same generator, on demand. It has the type [unit -> 'a gen] and it is
assumed that every generated returned by the function behaves the same
(that is, that it traverses the same sequence of elements). *)
module Restart : sig
type 'a t = unit -> 'a gen
type 'a restartable = 'a t
include S with type 'a t := 'a restartable
val cycle : 'a t -> 'a t
(** Cycle through the enum, endlessly. The enum must not be empty. *)
val lift : ('a gen -> 'b) -> 'a t -> 'b
val lift2 : ('a gen -> 'b gen -> 'c) -> 'a t -> 'b t -> 'c
val of_gen :
?caching:bool -> ?max_chunk_size:int ->
'a gen -> 'a t
(** Use {!persistent_lazy} to convert a one-shot generator into a
restartable one.
See {!GenMList.of_gen_lazy} for more details on parameters.
@since 0.4 *)
end
(** {2 Utils} *)
val persistent : 'a t -> 'a Restart.t
(** Store content of the transient generator in memory, to be able to iterate
on it several times later. If possible, consider using combinators
from {!Restart} directly instead. *)
val persistent_lazy :
?caching:bool -> ?max_chunk_size:int ->
'a t -> 'a Restart.t
(** Same as {!persistent}, but consumes the generator on demand (by chunks).
This allows to make a restartable generator out of an ephemeral one,
without paying a big cost upfront (nor even consuming it fully).
Optional parameters: see {!GenMList.of_gen_lazy}.
@since 0.2.2 *)
val persistent_to_seq : 'a t -> 'a Seq.t
(** Same as {!persistent}, but returns a standard Seq.
@since 1.0 *)
val persistent_lazy_to_seq :
?caching:bool -> ?max_chunk_size:int ->
'a t -> 'a Seq.t
(** Same as {!persistent_lazy}, but returns a standard Seq.
@since 1.0 *)
val peek : 'a t -> ('a * 'a option) t
(** [peek g] transforms the generator [g] into a generator
of [x, Some next] if [x] was followed by [next] in [g], or [x, None] if [x]
was the last element of [g]
@since 0.4 *)
val peek_n : int -> 'a t -> ('a * 'a array) t
(** [peek_n n g] iterates on [g], returning along with each element
the array of the (at most) [n] elements that follow it immediately
@raise Invalid_argument if the int is [< 1]
@since 0.4 *)
val start : 'a Restart.t -> 'a t
(** Create a new transient generator.
[start gen] is the same as [gen ()] but is included for readability. *)
(** {2 Basic IO}
Very basic interface to manipulate files as sequence of chunks/lines.
@since 0.2.3 *)
module IO : sig
val with_in : ?mode:int -> ?flags:open_flag list ->
string ->
(char t -> 'a) -> 'a
(** [with_in filename f] opens [filename] and calls [f g],
where [g] is a generator of characters from the file.
The generator is only valid within
the scope in which [f] is called. *)
val with_lines : ?mode:int -> ?flags:open_flag list ->
string -> (string t -> 'a) -> 'a
(** [with_lines filename f] opens file [filename] and calls [f g],
where [g] is a generator that iterates on the lines from the file.
Do not use the generator outside of the scope of [f]
@since 0.4 *)
val write_str : ?mode:int -> ?flags:open_flag list -> ?sep:string ->
string -> string t -> unit
(** [write_to filename g] writes all strings from [g] into the given
file. It takes care of opening and closing the file. Does not
add [sep] after the last string.
@param mode default [0o644]
@param flags used by [open_out_gen]. Default: [[Open_creat;Open_wronly]].
@param sep separator between each string (e.g. newline) *)
val write : ?mode:int -> ?flags:open_flag list ->
string -> char t -> unit
(** Same as {!write_str} but with individual characters *)
val write_lines : ?mode:int -> ?flags:open_flag list ->
string -> string t -> unit
(** [write_lines file g] is similar to [write_str file g ~sep:"\n"] but
also adds ['\n'] at the end of the file
@since 0.4 *)
end