metamon/generator
Generators: deterministic, size-aware samplers that produce values alongside their lazy shrink alternatives.
A Generator(a) is a pair of:
run: takes a seed and a size and returns aTree(a)edges: a finite list of must-try boundary values
Combinators (map, bind, map2, tuple2, one_of, …) preserve
integrated shrinking via the underlying Tree(a) and propagate edges
in a way appropriate for each combinator (see § 4.4 of the spec).
Types
Values
pub fn add_edges(g: Generator(a), more: List(a)) -> Generator(a)
Append more edges to an existing generator. Symmetric to
with_examples but reads better for library authors.
pub fn ascii_alphanumeric() -> Generator(String)
A single ASCII alphanumeric character.
pub fn ascii_letter() -> Generator(String)
A single ASCII letter generator (a-zA-Z).
pub fn ascii_lower() -> Generator(String)
A single ASCII lowercase letter generator (a-z).
pub fn ascii_printable() -> Generator(String)
A single ASCII printable character (space..~).
pub fn ascii_upper() -> Generator(String)
A single ASCII uppercase letter generator (A-Z).
pub fn bind(
g: Generator(a),
k: fn(a) -> Generator(b),
) -> Generator(b)
Monadic bind. Edges are taken from the outer generator only (the inner edges depend on the value, which is not safe to enumerate at composition time without running the inner generator with a fixed seed).
pub fn bit_array(len: range.Range) -> Generator(BitArray)
Bit array of byte-length within len. Each byte is generated
uniformly.
pub fn dict_of(
key: Generator(k),
value: Generator(v),
len: range.Range,
) -> Generator(dict.Dict(k, v))
Generate a dict.Dict(k, v) of size in len. Duplicate keys are
resolved by last-write-wins (the standard dict.from_list
semantics).
pub fn edges_of(g: Generator(a)) -> List(a)
Inspect the must-try edge values associated with a generator.
pub fn filter(
g: Generator(a),
predicate: fn(a) -> Bool,
) -> Generator(a)
Reject values that fail predicate. The implementation retries
internally up to filter_retry_limit times before panicking; this
is the canonical “filter is too strict” failure and is preferable
to silently misreporting the property.
Edges are filtered by predicate so user-supplied edges that fail
the predicate are silently dropped (they would never be tried
anyway).
pub fn float(lo: Float, hi: Float) -> Generator(Float)
Float in the closed interval [lo, hi]. Shrinking moves toward the
closest endpoint (no fancy mantissa shrinking yet).
pub fn frequency(
weighted: List(#(Int, Generator(a))),
) -> Generator(a)
Weighted choice over a non-empty list of (weight, generator) pairs.
Weights must be positive integers; non-positive weights are treated
as 1.
pub fn generate(
g: Generator(a),
s: seed.Seed,
size: Int,
) -> tree.Tree(a)
Run the generator at the given seed and size. Used by the runner; most user code should not call this directly.
pub fn int(range_value: range.Range) -> Generator(Int)
Integer in the given range, with binary shrinking toward the range
origin. Standard edges (0, 1, -1, bounds) are populated within
the constant interval.
pub fn list_of(
element: Generator(a),
len: range.Range,
) -> Generator(List(a))
A list of values whose length is drawn from len. Shrinking removes
elements via shrink/list_drops and shrinks each remaining element.
pub fn map(g: Generator(a), f: fn(a) -> b) -> Generator(b)
Functor map. Edges are mapped element-wise.
pub fn map2(
g1: Generator(a),
g2: Generator(b),
f: fn(a, b) -> c,
) -> Generator(c)
Applicative map over two independent generators. Shrinking holds one
component fixed while shrinking the other (via tree.zip).
pub fn map3(
g1: Generator(a),
g2: Generator(b),
g3: Generator(c),
f: fn(a, b, c) -> d,
) -> Generator(d)
Three-way applicative map.
pub fn map4(
g1: Generator(a),
g2: Generator(b),
g3: Generator(c),
g4: Generator(d),
f: fn(a, b, c, d) -> e,
) -> Generator(e)
Four-way applicative map.
pub fn map5(
g1: Generator(a),
g2: Generator(b),
g3: Generator(c),
g4: Generator(d),
g5: Generator(e),
f: fn(a, b, c, d, e) -> g,
) -> Generator(g)
Five-way applicative map.
pub fn map6(
g1: Generator(a),
g2: Generator(b),
g3: Generator(c),
g4: Generator(d),
g5: Generator(e),
g6: Generator(g),
f: fn(a, b, c, d, e, g) -> h,
) -> Generator(h)
Six-way applicative map.
pub fn negative_int() -> Generator(Int)
Integer in [-1_000_000, -1]. Shrinks toward -1.
pub fn no_edges(g: Generator(a)) -> Generator(a)
Strip the edges from a generator. Useful when composing into a product type that has its own edge story.
pub fn non_empty_list_of(
element: Generator(a),
len: range.Range,
) -> Generator(List(a))
Non-empty list. Wraps list_of and rejects empty lists from edges.
pub fn non_negative_int() -> Generator(Int)
Integer in [0, 1_000_000]. Linear scaling so small values come
first; shrinks toward 0.
pub fn one_of(generators: List(Generator(a))) -> Generator(a)
Pick uniformly from a non-empty list of generators. Edges are the concatenation of all branch edges.
pub fn option_of(g: Generator(a)) -> Generator(option.Option(a))
Some / None of an inner generator.
pub fn positive_int() -> Generator(Int)
Integer in [1, 1_000_000]. Shrinks toward 1.
pub fn recursive(
base: Generator(a),
step: fn(Generator(a)) -> Generator(a),
) -> Generator(a)
Recursive generator. At size = 0 only base is used; at higher
sizes the recursive call is the result of step applied to a copy
of itself with halved size.
pub fn resize(g: Generator(a), new_size: Int) -> Generator(a)
Override the size used by a generator.
pub fn result_of(
ok: Generator(a),
err: Generator(e),
) -> Generator(Result(a, e))
Ok / Error of two inner generators.
pub fn return(value: a) -> Generator(a)
A constant generator that always returns value and has no shrinks.
pub fn sample(g: Generator(a), n: Int) -> List(a)
Pull n plain sample values, ignoring shrink trees. Useful at the
REPL or in test diagnostics.
pub fn scale(g: Generator(a), f: fn(Int) -> Int) -> Generator(a)
Transform the size given to a generator.
pub fn set_of(
element: Generator(a),
len: range.Range,
) -> Generator(set.Set(a))
Generate a set.Set(a) of size in len.
pub fn sized(builder: fn(Int) -> Generator(a)) -> Generator(a)
Construct a generator whose strategy depends on the current size.
pub fn statistics(
g: Generator(a),
n: Int,
classify: fn(a) -> String,
) -> dict.Dict(String, Int)
Bucket n generated values via classify for distribution sanity
checks.
pub fn string(
char_gen: Generator(String),
len: range.Range,
) -> Generator(String)
A string built from char_gen characters with length in len.
pub fn string_ascii(len: range.Range) -> Generator(String)
An ASCII string with length in len.
pub fn string_unicode(len: range.Range) -> Generator(String)
A Unicode-aware string (includes BiDi/emoji/NUL via edges).
pub fn tuple2(
g1: Generator(a),
g2: Generator(b),
) -> Generator(#(a, b))
Pair two independent generators.
pub fn tuple3(
g1: Generator(a),
g2: Generator(b),
g3: Generator(c),
) -> Generator(#(a, b, c))
Triple of independent generators.
pub fn tuple4(
g1: Generator(a),
g2: Generator(b),
g3: Generator(c),
g4: Generator(d),
) -> Generator(#(a, b, c, d))
Quadruple of independent generators.
pub fn tuple5(
g1: Generator(a),
g2: Generator(b),
g3: Generator(c),
g4: Generator(d),
g5: Generator(e),
) -> Generator(#(a, b, c, d, e))
Quintuple of independent generators.
pub fn unicode_codepoint() -> Generator(Int)
A Unicode scalar value (excluding surrogates).