mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
use a new interface, unit -> 'a option, for Gen.
This commit is contained in:
parent
660b75e0b4
commit
48ef226efd
4 changed files with 510 additions and 429 deletions
44
gen.mli
44
gen.mli
|
|
@ -27,8 +27,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
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. The exception {!EOG} (end of generator)
|
||||
is raised when the generator is empty.
|
||||
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
|
||||
|
|
@ -37,12 +37,9 @@ allow to build as many generators from the same source as needed.
|
|||
|
||||
(** {2 Global type declarations} *)
|
||||
|
||||
exception EOG
|
||||
(** End of Generation *)
|
||||
|
||||
type 'a t = unit -> 'a
|
||||
type 'a t = unit -> 'a option
|
||||
(** A generator may be called several times, yielding the next value
|
||||
each time. It raises EOG when it reaches the end. *)
|
||||
each time. It returns [None] when no elements remain *)
|
||||
|
||||
type 'a gen = 'a t
|
||||
|
||||
|
|
@ -166,14 +163,20 @@ module type S = sig
|
|||
(** Is the predicate true for at least one element? *)
|
||||
|
||||
val for_all2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
|
||||
(** Succeeds if all pairs of elements satisfy the predicate.
|
||||
Ignores elements of an iterator if the other runs dry. *)
|
||||
|
||||
val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
|
||||
(** Succeeds if some pair of elements satisfy the predicate.
|
||||
Ignores elements of an iterator if the other runs dry. *)
|
||||
|
||||
val min : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
|
||||
(** Minimum element, according to the given comparison function *)
|
||||
(** Minimum element, according to the given comparison function.
|
||||
@raise Invalid_argument if the generator is empty *)
|
||||
|
||||
val max : ?lt:('a -> 'a -> bool) -> 'a t -> 'a
|
||||
(** Maximum element, see {!min} *)
|
||||
(** Maximum element, see {!min}
|
||||
@raise Invalid_argument if the generator is empty *)
|
||||
|
||||
val eq : ?eq:('a -> 'a -> bool) -> 'a t -> 'a t -> bool
|
||||
(** Equality of generators. *)
|
||||
|
|
@ -188,8 +191,7 @@ module type S = sig
|
|||
(** {2 Complex combinators} *)
|
||||
|
||||
val merge : 'a gen t -> 'a t
|
||||
(** Pick elements fairly in each sub-generator. The given enum
|
||||
must be finite (not its elements, though). The merge of enums
|
||||
(** Pick elements fairly in each sub-generator. The merge of enums
|
||||
[e1, e2, ... en] picks one element in [e1], then one element in [e2],
|
||||
then in [e3], ..., then in [en], and then starts again at [e1]. Once
|
||||
a generator is empty, it is skipped; when they are all empty,
|
||||
|
|
@ -203,7 +205,7 @@ module type S = sig
|
|||
val sorted_merge : ?cmp:('a -> 'a -> int) -> 'a t -> 'a t -> 'a t
|
||||
(** Merge two sorted sequences into a sorted sequence *)
|
||||
|
||||
val sorted_merge_n : ?cmp:('a -> 'a -> int) -> 'a gen t -> 'a t
|
||||
val sorted_merge_n : ?cmp:('a -> 'a -> int) -> 'a t list -> 'a t
|
||||
(** Sorted merge of multiple sorted sequences *)
|
||||
|
||||
val tee : ?n:int -> 'a t -> 'a gen list
|
||||
|
|
@ -218,7 +220,8 @@ module type S = sig
|
|||
|
||||
val interleave : 'a t -> 'a t -> 'a t
|
||||
(** [interleave a b] yields an element of [a], then an element of [b],
|
||||
and so on until the end of [a] or [b] is reached. *)
|
||||
and so on. When a generator is exhausted, this behaves like the
|
||||
other generator. *)
|
||||
|
||||
val intersperse : 'a -> 'a t -> 'a t
|
||||
(** Put the separator element between all elements of the given enum *)
|
||||
|
|
@ -297,19 +300,18 @@ end
|
|||
|
||||
(** {2 Transient generators} *)
|
||||
|
||||
val get : 'a t -> 'a
|
||||
(** Get the next value
|
||||
@raise EOG if there is no next value *)
|
||||
val get : 'a t -> 'a option
|
||||
(** Get the next value *)
|
||||
|
||||
val next : 'a t -> 'a
|
||||
val next : 'a t -> 'a option
|
||||
(** Synonym for {!get} *)
|
||||
|
||||
val get_safe : 'a t -> 'a option
|
||||
(** Get the next value, or return None *)
|
||||
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.
|
||||
@raise EOG if there is no next value *)
|
||||
(** Drop the next value, discarding it. *)
|
||||
|
||||
val repeatedly : (unit -> 'a) -> 'a t
|
||||
(** Call the same function an infinite number of times (useful for instance
|
||||
|
|
|
|||
|
|
@ -181,11 +181,11 @@ let gen l =
|
|||
let x = ref (next l.data 0) in
|
||||
fun () ->
|
||||
match !x with
|
||||
| Nil -> raise Gen.EOG
|
||||
| Nil -> None
|
||||
| Init _ -> assert false
|
||||
| Node (k, v, a) ->
|
||||
x := a.(0);
|
||||
k, !v
|
||||
Some (k, !v)
|
||||
|
||||
(** Add content of the iterator to the list *)
|
||||
let of_gen l gen =
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ let pstrlist l = Utils.sprintf "%a"
|
|||
|
||||
let test_singleton () =
|
||||
let gen = Gen.singleton 42 in
|
||||
OUnit.assert_equal 42 (Gen.get gen);
|
||||
OUnit.assert_raises Gen.EOG (fun () -> Gen.get gen);
|
||||
OUnit.assert_equal (Some 42) (Gen.get gen);
|
||||
OUnit.assert_equal None (Gen.get gen);
|
||||
let gen = Gen.singleton 42 in
|
||||
OUnit.assert_equal 1 (Gen.length gen);
|
||||
()
|
||||
|
|
@ -63,7 +63,7 @@ let test_persistent () =
|
|||
let i = ref 0 in
|
||||
let gen () =
|
||||
let j = !i in
|
||||
if j > 5 then raise Gen.EOG else (incr i; j)
|
||||
if j > 5 then None else (incr i; Some j)
|
||||
in
|
||||
let e = Gen.persistent gen in
|
||||
OUnit.assert_equal [0;1;2;3;4;5] (GR.to_list e);
|
||||
|
|
@ -86,7 +86,7 @@ let test_big_rr () =
|
|||
()
|
||||
|
||||
let test_merge_sorted () =
|
||||
Gen.of_list [Gen.of_list [1;3;5]; Gen.of_list [0;1;1;3;4;6;10]; Gen.of_list [2;2;11]]
|
||||
[Gen.of_list [1;3;5]; Gen.of_list [0;1;1;3;4;6;10]; Gen.of_list [2;2;11]]
|
||||
|> Gen.sorted_merge_n ?cmp:None
|
||||
|> Gen.to_list
|
||||
|> OUnit.assert_equal ~printer:Helpers.print_int_list [0;1;1;1;2;2;3;3;4;5;6;10;11]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue