Up

Module type Generator

Signature

type 'a t

An 'a t a generates values of type 'a with a specific probability distribution.

type 'a obs
include Core_kernel.Monad.S with type 'a t := 'a t
type 'a t
include Monad_intf.S_without_syntax with type 'a t := 'a t
type 'a t

A monad is an abstraction of the concept of sequencing of computations. A value of type 'a monad represents a computation that returns a value of type 'a.

include Monad_intf.Infix with type 'a t := 'a t
type 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t

t >>= f returns a computation that sequences the computations represented by two monad elements. The resulting computation first does t to yield a value v, and then runs the computation returned by f v.

val (>>|) : 'a t -> ('a -> 'b) -> 'b t

t >>| f is t >>= (fun a -> return (f a)).

module Monad_infix : Monad_intf.Infix with type 'a t := 'a t
val bind : 'a t -> ('a -> 'b t) -> 'b t

bind t f = t >>= f

val return : 'a -> 'a t

return v returns the (trivial) computation that returns v.

val map : 'a t -> f:('a -> 'b) -> 'b t

map t ~f is t >>| f.

val join : 'a t t -> 'a t

join t is t >>= (fun t' -> t').

val ignore_m : 'a t -> unit t

ignore_m t is map t ~f:(fun _ -> ()). ignore_m used to be called ignore, but we decided that was a bad name, because it shadowed the widely used Pervasives.ignore. Some monads still do let ignore = ignore_m for historical reasons.

val all : 'a t list -> 'a list t
val all_ignore : unit t list -> unit t
include Monad_intf.Syntax with type 'a t := 'a t
type 'a t
module Let_syntax : sig .. end
val singleton : 'a -> 'a t
val doubleton : 'a -> 'a -> 'a t
val of_list : 'a list -> 'a t

Produce any of the given values, weighted equally.

of_list [ v1 ; ... ; vN ] = union [ singleton v1 ; ... ; singleton vN ]

val union : 'a t list -> 'a t

Combine arbitary generators, weighted equally.

union [ g1 ; ... ; gN ] = weighted_union [ (1.0, g1) ; ... ; (1.0, gN) ]

val of_sequence : ?p:float -> 'a Core_kernel.Sequence.t -> 'a t

Generator for the values from a potentially infinite sequence. Chooses each value with probability p, or continues with probability 1-p. Defaults to p=0.25.

val tuple2 : 'a t -> 'b t -> ('a * 'b) t
val tuple3 : 'a t -> 'b t -> 'c t -> ('a * 'b * 'c) t
val tuple4 : 'a t -> 'b t -> 'c t -> 'd t -> ('a * 'b * 'c * 'd) t
val tuple5 : 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> ('a * 'b * 'c * 'd * 'e) t
val tuple6 : 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t -> ('a * 'b * 'c * 'd * 'e * 'f) t
val variant2 : 'a t -> 'b t -> [
| `A of 'a
| `B of 'b
] t
val variant3 : 'a t -> 'b t -> 'c t -> [
| `A of 'a
| `B of 'b
| `C of 'c
] t
val variant4 : 'a t -> 'b t -> 'c t -> 'd t -> [
| `A of 'a
| `B of 'b
| `C of 'c
| `D of 'd
] t
val variant5 : 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> [
| `A of 'a
| `B of 'b
| `C of 'c
| `D of 'd
| `E of 'e
] t
val variant6 : 'a t -> 'b t -> 'c t -> 'd t -> 'e t -> 'f t -> [
| `A of 'a
| `B of 'b
| `C of 'c
| `D of 'd
| `E of 'e
| `F of 'f
] t
val size : int t

size produces a geometric distribution (think "radioactive decay") starting at 0 and increasing with probability 0.75. It produces natural numbers and is weighted toward low values, making it a good default for, e.g., data structure sizes.

val fn : ?branching_factor:int t -> 'a obs -> 'b t -> ('a -> 'b) t

Generators for functions; take observers for inputs and a generator for outputs. The observer splits the space of possible inputs into a number of "buckets"; each randomly generated function applies the observer to an input, and produces a different output value for each bucket.

The ?branching_factor argument determines how many branches the function's decision tree has, and thus how many categories of inputs it can distinguish. If absent, branching_factor defaults to a geometric distribution similar to size but capped by the maximum branching factor of the domain observers.

val fn2 : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c t -> ('a -> 'b -> 'c) t
val fn3 : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd t -> ('a -> 'b -> 'c -> 'd) t
val fn4 : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd obs -> 'e t -> ('a -> 'b -> 'c -> 'd -> 'e) t
val fn5 : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd obs -> 'e obs -> 'f t -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f) t
val fn6 : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd obs -> 'e obs -> 'f obs -> 'g t -> ('a -> 'b -> 'c -> 'd -> 'e -> 'f -> 'g) t
val compare_fn : ?branching_factor:int t -> 'a obs -> ('a -> 'a -> int) t

Generator for comparison functions; result is guaranteed to be a partial order.

val equal_fn : ?branching_factor:int t -> 'a obs -> ('a -> 'a -> bool) t

Generator for equality functions; result is guaranteed to be an equivalence relation.

type ('a, 'b) fn_with_sexp = ('a -> 'b) * (unit -> Sexp.t)

Generators for functions, annotated with sexps that describe the functions. Intended for debugging purposes. These generators each produce a fn_with_sexp, whose description can be extracted using fn_sexp.

val sexp_of_fn_with_sexp : ('a -> Sexplib.Sexp.t) -> ('b -> Sexplib.Sexp.t) -> ('a, 'b) fn_with_sexp -> Sexplib.Sexp.t
val fn_sexp : (_, _) fn_with_sexp -> Sexp.t
val compare_fn_with_sexp : ?branching_factor:int t -> 'a obs -> ('a, 'a -> int) fn_with_sexp t
val equal_fn_with_sexp : ?branching_factor:int t -> 'a obs -> ('a, 'a -> bool) fn_with_sexp t
val fn_with_sexp : ?branching_factor:int t -> 'a obs -> 'b t -> sexp_of_rng:('b -> Sexp.t) -> ('a, 'b) fn_with_sexp t
val fn2_with_sexp : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c t -> sexp_of_rng:('c -> Sexp.t) -> ('a, 'b -> 'c) fn_with_sexp t
val fn3_with_sexp : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd t -> sexp_of_rng:('d -> Sexp.t) -> ('a, 'b -> 'c -> 'd) fn_with_sexp t
val fn4_with_sexp : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd obs -> 'e t -> sexp_of_rng:('e -> Sexp.t) -> ('a, 'b -> 'c -> 'd -> 'e) fn_with_sexp t
val fn5_with_sexp : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd obs -> 'e obs -> 'f t -> sexp_of_rng:('f -> Sexp.t) -> ('a, 'b -> 'c -> 'd -> 'e -> 'f) fn_with_sexp t
val fn6_with_sexp : ?branching_factor:int t -> 'a obs -> 'b obs -> 'c obs -> 'd obs -> 'e obs -> 'f obs -> 'g t -> sexp_of_rng:('g -> Sexp.t) -> ('a, 'b -> 'c -> 'd -> 'e -> 'f -> 'g) fn_with_sexp t
val filter_map : 'a t -> f:('a -> 'b option) -> 'b t

filter_map t ~f produces y for every x in t such that f x = Some y. filter t ~f produces every x in t such that f x = true.

Caveat: Use filter and filter_map sparingly. Every time f rejects a value, it counts as a failed attempt to produce a value. Too many failures can cause Quickcheck to take a long time to generate values, or fail a test if it fails more times than the maximum configured number of attempts.

val filter : 'a t -> f:('a -> bool) -> 'a t
val recursive : ('a t -> 'a t) -> 'a t

Fixed-point generator. For example, the following produces a naive generator for natural numbers:


        recursive (fun t ->
          union [ singleton 0 ; t >>| Int.succ ])
      
module Choice : sig .. end
'a Choice.t represents the choice of a value from a generator.
val bind_choice : 'a t -> ('a Choice.t -> 'b t) -> 'b t

bind_choice t f is like bind t f, except f is passed an 'a Choice.t and can thus use subsets of t by using Choice.gen with the ~keep option.

bind t f is equal to bind_choice t (fun c -> f (Choice.value c)), although bind is cheaper than bind_choice.

val failure : _ t

Empty generator that is guaranteed to fail to produce a value.

val weighted_union : (float * 'a t) list -> 'a t

weighted_union alist produces a generator that combines the distributions of each t in alist with the associated weights, which must be finite positive floating point values.

val of_fun : (unit -> 'a t) -> 'a t

of_fun f produces a generator that lazily applies f.

f *MUST* be deterministic or else random value generation will fail. However, it is recommended that f not be memoized. Instead, spread out the work of generating a whole distribution over many of_fun calls combined with weighted_union. This allows lazily generated generators to be garbage collected after each test and the relevant portions cheaply recomputed in subsequent tests, rather than accumulating without bound over time.

val choose : 'a t -> random_float_between_zero_and_one:(unit -> float) -> max_attempts:int -> [
| `No_choices_remain
| `Ran_out_of_attempts
| `Choice of 'a Choice.t
]

choose t ~random_float_between_zero_and_one makes a choice in t at random, using random_float_between_zero_and_one to produce random floats between 0. (inclusive) and 1. (exclusive) for each weighted choice. If t has been fully explored, it produces `No_choices_remain. Otherwise it produces `Choice c for some choice c in t.

val inspect : 'a t -> [
| `Failure
| `Singleton of 'a
| `Weighted_union of (float * 'a t) list
]

inspect t produces a concrete representation of the outermost constructor of t. It is possible to explore t further with recursive calls to inspect; however, be aware that t may be infinite.