HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulegeneric-random-1.5.0.1Haskell2010

Generic.Random.Internal.Generic

Core implementation.

Warning

This is an internal module: it is not subject to any versioning policy, breaking changes can happen at any time.

If something here seems useful, please report it or create a pull request to export it from an external module.

  • 24 types
  • 12 classes
  • 29 values

Random generators

9 declarations
valuegenericArbitrary
  1. :: GArbitrary UnsizedOpts a
  2. => Weights a

    List of weights for every constructor

  3. -> Gen a
#

Pick a constructor with a given distribution, and fill its fields with recursive calls to arbitrary.

Example
genericArbitrary (2 % 3 % 5 % ()) :: Gen a

Picks the first constructor with probability 2/10, the second with probability 3/10, the third with probability 5/10.

valuegenericArbitraryRec
  1. :: GArbitrary SizedOptsDef a
  2. => Weights a

    List of weights for every constructor

  3. -> Gen a
#

Decrease size at every recursive call, but don't do anything different at size 0.

genericArbitraryRec (7 % 11 % 13 % ()) :: Gen a

N.B.: This replaces the generator for fields of type [t] with listOf' arbitrary instead of Test.QuickCheck.listOf arbitrary (i.e., arbitrary for lists).

valuegenericArbitraryG
  1. :: GArbitrary (SetGens genList UnsizedOpts) a
  2. => genList
  3. -> Weights a
  4. -> Gen a
#

genericArbitrary with explicit generators.

Example
genericArbitraryG customGens (17 % 19 % ())

where, the generators for String and Int fields are overridden as follows, for example:

customGens :: Gen String :+ Gen Int
customGens =
  (filter (/= 'NUL') <$> arbitrary) :+
  (getNonNegative <$> arbitrary)
Note on multiple matches

Multiple generators may match a given field: the first will be chosen.

Internal

73 declarations
datadata (:|) a b
#

Constructors

Instances5TypeLevelWeights, UniformWeight, WeightBuilder, Prec
  • TypeLevelWeights (w ': ws) (t :| (u :| v)) => TypeLevelWeights (w ': ws) ((t :| u) :| v)Defined in generic-random-1.5.0.1 · Generic.Random.DerivingVia
  • (KnownNat weight, TypeLevelWeights weights a) => TypeLevelWeights (weight ': weights) (L x :| a)Defined in generic-random-1.5.0.1 · Generic.Random.DerivingVia
  • (UniformWeight a, UniformWeight b) => UniformWeight (a :| b)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • WeightBuilder a => WeightBuilder (a :| b)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type Prec (a :| b) r = Prec a (b, Int, r)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
datadata L (c :: Symbol)
#
Instances5UniformWeight, WeightBuilder, TypeLevelWeights, Prec
  • UniformWeight (L c)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • WeightBuilder (L c)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • KnownNat weight => TypeLevelWeights '[weight] (L x)Defined in generic-random-1.5.0.1 · Generic.Random.DerivingVia
  • (KnownNat weight, TypeLevelWeights weights a) => TypeLevelWeights (weight ': weights) (L x :| a)Defined in generic-random-1.5.0.1 · Generic.Random.DerivingVia
  • type Prec (L c) r = rDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
datadata Weights a
#

Trees of weights assigned to constructors of type a, rescaled to obtain a probability distribution.

Two ways of constructing them.

(x1 % x2 % ... % xn % ()) :: Weights a
uniform :: Weights a

Using (%), there must be exactly as many weights as there are constructors.

uniform is equivalent to (1 % ... % 1 % ()) (automatically fills out the right number of 1s).

Constructors

Instances1WeightBuilder'
newtypenewtype W (c :: Symbol)
#

Type of a single weight, tagged with the name of the associated constructor for additional compile-time checking.

((9 :: W "Leaf") % (8 :: W "Node") % ())

Constructors

Instances1Num
  • Num (W c)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
valueweights :: (Weights_ (Rep a), Int, ()) -> Weights a
#

A smart constructor to specify a custom distribution. It can be omitted for the % operator is overloaded to insert it.

newtypenewtype Options (c :: Coherence) (s :: Sizing) genList
#

Type-level options for GArbitrary.

Note: it is recommended to avoid referring to the Options type explicitly in code, as the set of options may change in the future. Instead, use the provided synonyms (UnsizedOpts, SizedOpts, SizedOptsDef) and the setter SetOptions (abbreviated as (<+)).

Constructors

Instances10HasGenerators, SetGens, SetOptions, SetSized, SetUnsized, CoherenceOf, …
  • HasGenerators (Options c s g)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type SetGens g (Options c s _g) = Options c s gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type SetOptions c (Options _c s g) = Options c s gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type SetOptions g (Options c s _g) = Options c s gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type SetOptions s (Options c _s g) = Options c s gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type SetSized (Options c s g) = Options c 'Sized gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type SetUnsized (Options c s g) = Options c 'Unsized gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type CoherenceOf (Options c _s _g) = cDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type GeneratorsOf (Options _c _s g) = gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type SizingOf (Options _c s _g) = sDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
familytype family SetOptions (x :: k) o
#

Setter for Options.

This subsumes the other setters: SetSized, SetUnsized, SetGens.

Instances3SetOptions
datadata Sizing
#

Whether to decrease the size parameter before generating fields.

The Sized option makes the size parameter decrease in the following way: - Constructors with one field decrease the size parameter by 1 to generate that field. - Constructors with more than one field split the size parameter among all fields; the size parameter is rounded down to then be divided equally.

Constructors

  • Sized

    Decrease the size parameter when running generators for fields

  • Unsized

    Don't touch the size parameter

Instances1SetOptions
familytype family SizingOf opts :: Sizing
#
Instances1SizingOf
  • type SizingOf (Options _c s _g) = sDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
datadata Coherence
#

For custom generators to work with parameterized types, incoherent instances must be used internally. In practice, the resulting behavior is what users want 100% of the time, so you should forget this option even exists.

Details

The default configuration of generic-random does a decent job if we trust GHC implements precisely the instance resolution algorithm as described in the GHC manual:

While that assumption holds in practice, it is overly context-dependent (to know the context leading to a particular choice, we must replay the whole resolution algorithm). In particular, this algorithm may find one solution, but it is not guaranteed to be unique: the behavior of the program is dependent on implementation details.

An notable property to consider of an implicit type system (such as type classes) is coherence: the behavior of the program is stable under specialization.

This sounds nice on paper, but actually leads to surprising behavior for generic implementations with parameterized types, such as generic-random.

To address that, the coherence property can be relaxd by users, by explicitly allowing some custom generators to be chosen incoherently. With appropriate precautions, it is possible to ensure a weaker property which nevertheless helps keep type inference predictable: when a solution is found, it is unique. (This is assuredly weaker, i.e., is not stable under specialization.)

Constructors

  • INCOHERENT

    Match custom generators incoherently.

  • COHERENT

    Match custom generators coherently by default (can be manually bypassed with Incoherent).

Instances1SetOptions
datadata (:+) a b
#

Heterogeneous list of generators.

Constructors

  • a :+ binfixr 1
Instances4FindGen, TypeLevelGenList, TypeLevelGenList'
familytype family GeneratorsOf opts
#
Instances1GeneratorsOf
  • type GeneratorsOf (Options _c _s g) = gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
valuesetGenerators :: genList -> Options c s g0 -> Options c s genList
#

Define the set of custom generators.

Note: for recursive types which can recursively appear inside lists or other containers, you may want to include a custom generator to decrease the size when generating such containers.

See also the Note about lists in Generic.Random.Tutorial#notelists.

familytype family SetGens g opts
#
Instances1SetGens
  • type SetGens g (Options c s _g) = Options c s gDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
newtypenewtype FieldGen (s :: Symbol) a
#

Custom generator for record fields named s.

If there is a field named s with a different type, this will result in a type error.

Constructors

Instances2FindGen
  • a ~ a' => FindGen ('MatchCoh 'True) s (FieldGen sn a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for field s.

  • a ~ a' => FindGen ('Match 'INCOHERENT) ('S _fg _coh '(con, i, 'Just s)) (FieldGen s a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for field s.

newtypenewtype ConstrGen (c :: Symbol) (i :: Nat) a
#

Custom generator for the i-th field of the constructor named c. Fields are 0-indexed.

Constructors

Instances2FindGen
  • a ~ a' => FindGen ('MatchCoh 'True) s (ConstrGen c i a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for i-th field of constructor c.

  • a ~ a' => FindGen ('Match 'INCOHERENT) ('S _fg _coh '('Just c, i, s)) (ConstrGen c i a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for i-th field of constructor c.

newtypenewtype Gen1 (f :: Type -> Type)
#

Custom generators for "containers" of kind Type -> Type, parameterized by the generator for "contained elements".

A custom generator Gen1 f will be used for any field whose type has the form f x, requiring a generator of x. The generator for x will be constructed using the list of custom generators if possible, otherwise an instance Arbitrary x will be required.

Constructors

Instances2FindGen
newtypenewtype Gen1_ (f :: k -> Type)
#

Custom generators for unary type constructors that are not "containers", i.e., which don't require a generator of a to generate an f a.

A custom generator Gen1_ f will be used for any field whose type has the form f x.

Constructors

Instances2FindGen
  • f x ~ a' => FindGen ('MatchCoh 'True) s (Gen1_ f) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • FindGen ('Match 'INCOHERENT) s (Gen1_ f) gs (f a)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for non-container f.

valuelistOf' :: Gen a -> Gen [a]
#

An alternative to Test.QuickCheck.listOf that divides the size parameter by the length of the list. The length follows a geometric distribution of parameter 1/(sqrt size + 1).

valuelistOf1' :: Gen a -> Gen [a]
#

An alternative to Test.QuickCheck.listOf1 (nonempty lists) that divides the size parameter by the length of the list. The length (minus one) follows a geometric distribution of parameter 1/(sqrt size + 1).

valuegeom :: Int -> Gen Int
#

Geometric distribution of parameter 1/(sqrt n + 1) (n >= 0).

classclass GA opts (f :: Type -> Type) where
#

Generic Arbitrary

Methods

Instances3GA
  • (GASum opts f, GASum opts g) => GA opts (f :+: g)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • GA opts f => GA opts (M1 D c f)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • GAProduct (SizingOf opts) (Name c) opts f => GA opts (M1 C c f)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
classclass GAProduct (s :: Sizing) (c :: Maybe Symbol) opts (f :: k -> Type) where
#

Methods

Instances4GAProduct
classclass GAProduct' (c :: Maybe Symbol) (i :: Nat) opts (f :: k -> Type) where
#

Methods

Instances3GAProduct'
classclass FindGen (i :: AInstr) (s :: AStore) g gs a where
#

Given a list of custom generators g :+ gs, find one that applies, or use Arbitrary a by default.

g and gs follow this little state machine:

          g,      gs | result
---------------------+-----------------------------
         (),      () | END
         (), g :+ gs | g, gs
         (),      g  | g, () when g is not (_ :+ _)
     g :+ h,      gs | g, h :+ gs
      Gen a,      gs | END if g matches, else ((), gs)
 FieldGen a,      gs | idem
ConstrGen a,      gs | idem
     Gen1 a,      gs | idem
    Gen1_ a,      gs | idem

Methods

Instances19FindGen, …
  • Arbitrary a => FindGen 'Shift s () () aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    All candidates have been exhausted

  • FindGen 'Shift s g () a => FindGen 'Shift s () g aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Examine the last candidate (g is not of the form _ :+ _)

  • FindGen ('Match (ACoherenceOf s)) s g gs a => FindGen 'Shift s g gs aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    If none of the above matches, then g should be a simple generator, and we test whether it matches the type a.

  • FindGen 'Shift s b g a => FindGen 'Shift s () (b :+ g) aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Examine the next candidate

  • FindGen ('Match 'INCOHERENT) s g gs a => FindGen 'Shift s (Incoherent g) gs aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • FindGen 'Shift s g (h :+ gs) a => FindGen 'Shift s (g :+ h) gs aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    This can happen if the generators form a tree rather than a list, for whatever reason.

  • FindGen 'Shift s () gs a => FindGen ('Match 'INCOHERENT) s _g gs aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    None of the INCOHERENT instances match, discard the candidate g and look at the rest of the list gs.

  • FindGen 'Shift s () gs a => FindGen ('MatchCoh 'False) s _g gs aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • FindGen ('MatchCoh (Matches (ASelOf s) g a)) s g gs a => FindGen ('Match 'COHERENT) s g gs aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • FindGen ('Match 'INCOHERENT) s (Gen a) gs aDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for a.

  • a ~ a' => FindGen ('MatchCoh 'True) s (Gen a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • a ~ a' => FindGen ('MatchCoh 'True) s (FieldGen sn a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for field s.

  • f x ~ a' => FindGen ('MatchCoh 'True) s (Gen1_ f) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • FindGen ('Match 'INCOHERENT) s (Gen1_ f) gs (f a)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for non-container f.

  • a ~ a' => FindGen ('MatchCoh 'True) s (ConstrGen c i a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for i-th field of constructor c.

  • (f x ~ a', FindGen 'Shift ('S fg coh DummySel) () fg x) => FindGen ('MatchCoh 'True) ('S fg coh _sel) (Gen1 f) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • FindGen 'Shift ('S fg coh DummySel) () fg a => FindGen ('Match 'INCOHERENT) ('S fg coh _sel) (Gen1 f) gs (f a)Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for container f. Start the search for containee a, discarding field information.

  • a ~ a' => FindGen ('Match 'INCOHERENT) ('S _fg _coh '(con, i, 'Just s)) (FieldGen s a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for field s.

  • a ~ a' => FindGen ('Match 'INCOHERENT) ('S _fg _coh '('Just c, i, s)) (ConstrGen c i a) gs a'Defined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic

    Matching custom generator for i-th field of constructor c.

familytype family Name (d :: Meta) :: Maybe Symbol
#

Get the name contained in a Meta tag.

Instances2Name
  • type Name ('MetaCons n _f _s) = 'Just nDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic
  • type Name ('MetaSel mn su ss ds) = mnDefined in generic-random-1.5.0.1 · Generic.Random.Internal.Generic