generic-random-1.5.0.1: Generic random generators for QuickCheck

Safe Haskell | None
Language | Haskell2010

Generic.Random

Contents

- Arbitrary implementations
  - With custom generators
- Specifying finite distributions
- Custom generators
- Helpful combinators
- Base cases for recursive types
- Full options
  - Setters
  - Size modifiers
  - Custom generators
  - Coherence options
  - Common options
    - Advanced options
- Generic classes
- Newtypes for DerivingVia
  - Helpers typeclasses

Description

GHC.Generics-based `arbitrary` generators.

# Basic usage

    {-# LANGUAGE DeriveGeneric #-}

    data Foo = A | B | C  -- some generic data type
      deriving Generic

Derive instances of `Arbitrary`.

    instance Arbitrary Foo where
      arbitrary = genericArbitrary uniform  -- Give a distribution of constructors.
      shrink = genericShrink  -- Generic shrinking is provided by the QuickCheck library.

Or derive standalone generators (the fields must still be instances of `Arbitrary`, or use custom generators).

    genFoo :: Gen Foo
    genFoo = genericArbitrary uniform

### Using `DerivingVia`

    {-# LANGUAGE DerivingVia, TypeOperators #-}

    data Foo = A | B | C
      deriving Generic
      deriving Arbitrary via (GenericArbitraryU `AndShrinking' Foo)

For more information:

- Generic.Random.Tutorial
- http://blog.poisson.chat/posts/2018-01-05-generic-random-tour.html

Synopsis

- genericArbitrary :: GArbitrary UnsizedOpts a => Weights a -> Gen a
- genericArbitraryU :: (GArbitrary UnsizedOpts a, GUniformWeight a) => Gen a
- genericArbitrarySingle :: forall a (c0 :: Symbol). (GArbitrary UnsizedOpts a, Weights_ (Rep a) ~ L c0) => Gen a
- genericArbitraryRec :: GArbitrary SizedOptsDef a => Weights a -> Gen a
- genericArbitrary' :: (GArbitrary SizedOptsDef a, BaseCase a) => Weights a -> Gen a
- genericArbitraryU' :: (GArbitrary SizedOptsDef a, BaseCase a, GUniformWeight a) => Gen a
- genericArbitraryG :: GArbitrary (SetGens genList UnsizedOpts) a => genList -> Weights a -> Gen a
- genericArbitraryUG :: (GArbitrary (SetGens genList UnsizedOpts) a, GUniformWeight a) => genList -> Gen a
- genericArbitrarySingleG :: forall genList a (c0 :: Symbol). (GArbitrary (SetGens genList UnsizedOpts) a, Weights_ (Rep a) ~ L c0) => genList -> Gen a
- genericArbitraryRecG :: GArbitrary (SetGens genList SizedOpts) a => genList -> Weights a -> Gen a
- data Weights a
- data W (c :: Symbol)
- (%) :: forall (c :: Symbol). (WeightBuilder' w, c ~ First' w) => W c -> Prec' w -> w
- uniform :: UniformWeight_ (Rep a) => Weights a
- data a :+ b = a :+ b
- newtype FieldGen (s :: Symbol) a = FieldGen {
  - unFieldGen :: Gen a
  }
- fieldGen :: forall proxy (s :: Symbol) a. proxy s -> Gen a -> FieldGen s a
- newtype ConstrGen (c :: Symbol) (i :: Nat) a = ConstrGen {
  - unConstrGen :: Gen a
  }
- constrGen :: forall proxy (c :: Symbol) (i :: Nat) a. proxy '(c, i) -> Gen a -> ConstrGen c i a
- newtype Gen1 (f :: Type -> Type) = Gen1 {
  - unGen1 :: forall a. Gen a -> Gen (f a)
  }
- newtype Gen1_ (f :: k -> Type) = Gen1_ {
  - unGen1_ :: forall (a :: k). Gen (f a)
  }
- listOf' :: Gen a -> Gen [a]
- listOf1' :: Gen a -> Gen [a]
- vectorOf' :: Int -> Gen a -> Gen [a]
- withBaseCase :: Gen a -> Gen a -> Gen a
- class BaseCase a where
  - baseCase :: Gen a
- data Options (c :: Coherence) (s :: Sizing) genList
- genericArbitraryWith :: GArbitrary opts a => opts -> Weights a -> Gen a
- type family SetOptions (x :: k) o
- type (<+) o (x :: k) = SetOptions x o
- setOpts :: forall {k} (x :: k) o. Coercible o (SetOptions x o) => o -> SetOptions x o
- data Sizing
  - = Sized
  - | Unsized
- type family SetSized o
- type family SetUnsized o
- setSized :: forall (c :: Coherence) (s :: Sizing) g. Options c s g -> Options c 'Sized g
- setUnsized :: forall (c :: Coherence) (s :: Sizing) g. Options c s g -> Options c 'Unsized g
- type family SetGens g opts
- setGenerators :: forall genList (c :: Coherence) (s :: Sizing) g0. genList -> Options c s g0 -> Options c s genList
- data Coherence
  - = INCOHERENT
  - | COHERENT
- newtype Incoherent g = Incoherent g
- type SizedOpts = Options 'INCOHERENT 'Sized ()
- sizedOpts :: SizedOpts
- type SizedOptsDef = Options 'INCOHERENT 'Sized (Gen1 [] :+ ())
- sizedOptsDef :: SizedOptsDef
- type UnsizedOpts = Options 'INCOHERENT 'Unsized ()
- unsizedOpts :: UnsizedOpts
- type CohUnsizedOpts = Options 'COHERENT 'Unsized ()
- cohUnsizedOpts :: CohUnsizedOpts
- type CohSizedOpts = Options 'COHERENT 'Sized ()
- cohSizedOpts :: CohSizedOpts
- class (Generic a, GA opts (Rep a)) => GArbitrary opts a
- class UniformWeight_ (Rep a) => GUniformWeight a
- newtype GenericArbitrary (weights :: k) a = GenericArbitrary {
  - unGenericArbitrary :: a
  }
- newtype GenericArbitraryU a = GenericArbitraryU {
  - unGenericArbitraryU :: a
  }
- newtype GenericArbitrarySingle a = GenericArbitrarySingle {
  - unGenericArbitrarySingle :: a
  }
- newtype GenericArbitraryRec (weights :: k) a = GenericArbitraryRec {
  - unGenericArbitraryRec :: a
  }
- newtype GenericArbitraryG (genList :: k) (weights :: k1) a = GenericArbitraryG {
  - unGenericArbitraryG :: a
  }
- newtype GenericArbitraryUG (genList :: k) a = GenericArbitraryUG {
  - unGenericArbitraryUG :: a
  }
- newtype GenericArbitrarySingleG (genList :: k) a = GenericArbitrarySingleG {
  - unGenericArbitrarySingleG :: a
  }
- newtype GenericArbitraryRecG (genList :: k) (weights :: k1) a = GenericArbitraryRecG {
  - unGenericArbitraryRecG :: a
  }
- newtype GenericArbitraryWith (opts :: k) (weights :: k1) a = GenericArbitraryWith {
  - unGenericArbitraryWith :: a
  }
- newtype AndShrinking (f :: k) a = AndShrinking a
- class TypeLevelGenList (a :: k) where
  - type TypeLevelGenList' (a :: k)
  - toGenList :: Proxy a -> TypeLevelGenList' a
- class TypeLevelOpts (a :: k) where
  - type TypeLevelOpts' (a :: k)
  - toOpts :: Proxy a -> TypeLevelOpts' a

# Arbitrary implementations

The suffixes for the variants have the following meanings:

- `U`: pick constructors with uniform distribution (equivalent to passing `uniform` to the non-`U` variant).
- `Single`: restricted to types with a single constructor.
- `G`: with custom generators.
- `Rec`: decrease the size at every recursive call (ensuring termination for (most) recursive types).
- `'`: automatic discovery of "base cases" when size reaches 0.

genericArbitrary Source #

Arguments

:: GArbitrary UnsizedOpts a |
=> Weights a | List of weights for every constructor
-> 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`.

genericArbitraryU :: (GArbitrary UnsizedOpts a, GUniformWeight a) => Gen a Source #

Pick every constructor with equal probability. Equivalent to ``genericArbitrary` `uniform``.

    genericArbitraryU :: Gen a

genericArbitrarySingle :: forall a (c0 :: Symbol). (GArbitrary UnsizedOpts a, Weights_ (Rep a) ~ L c0) => Gen a Source #

`arbitrary` for types with one constructor. Equivalent to `genericArbitraryU`, with a stricter type.

    genericArbitrarySingle :: Gen a

genericArbitraryRec Source #

Arguments

:: GArbitrary SizedOptsDef a |
=> Weights a | List of weights for every constructor
-> 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 ``listOf` arbitrary` (i.e., `arbitrary` for lists).

genericArbitrary' Source #

Arguments

:: (GArbitrary SizedOptsDef a, BaseCase a) |
=> Weights a | List of weights for every constructor
-> Gen a |

Decrease size to ensure termination for recursive types, looking for base cases once the size reaches 0.

    genericArbitrary' (17 % 19 % 23 % ()) :: Gen a

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

genericArbitraryU' :: (GArbitrary SizedOptsDef a, BaseCase a, GUniformWeight a) => Gen a Source #

Equivalent to ``genericArbitrary'` `uniform``.

    genericArbitraryU' :: Gen a

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

## With custom generators

### Note about incoherence

The custom generator feature relies on incoherent instances, which can lead to surprising behaviors for parameterized types.

#### Example

Expand

For example, here is a pair type and a custom generator of `Int` (always generating 0).

    data Pair a b = Pair a b
      deriving (Generic, Show)

    customGen :: Gen Int
    customGen = pure 0

The following two ways of defining a generator of `Pair Int Int` are not equivalent.

The first way is to use `genericArbitrarySingleG` to define a `Gen (Pair a b)` parameterized by types `a` and `b`, and then specialize it to `Gen (Pair Int Int)`.

In this case, the `customGen` will be ignored.

    genPair :: (Arbitrary a, Arbitrary b) => Gen (Pair a b)
    genPair = genericArbitrarySingleG customGen

    genPair' :: Gen (Pair Int Int)
    genPair' = genPair
    -- Will generate nonzero pairs

The second way is to define `Gen (Pair Int Int)` directly using `genericArbitrarySingleG` (as if we inlined `genPair` in `genPair'` above.

Then the `customGen` will actually be used.

    genPair2 :: Gen (Pair Int Int)
    genPair2 = genericArbitrarySingleG customGen
    -- Will only generate (Pair 0 0)

In other words, the decision of whether to use a custom generator is done by comparing the type of the custom generator with the type of the field only in the context where `genericArbitrarySingleG` is being used (or any other variant with a `G` suffix).

In the first case above, those fields have types `a` and `b`, which are not equal to `Int` (or rather, there is no available evidence that they are equal to `Int`, even if they could be instantiated as `Int` later). In the second case, they both actually have type `Int`.

genericArbitraryG :: GArbitrary (SetGens genList UnsizedOpts) a => genList -> Weights a -> Gen a Source #

`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.

genericArbitraryUG :: (GArbitrary (SetGens genList UnsizedOpts) a, GUniformWeight a) => genList -> Gen a Source #

`genericArbitraryU` with explicit generators. See also `genericArbitraryG`.

genericArbitrarySingleG :: forall genList a (c0 :: Symbol). (GArbitrary (SetGens genList UnsizedOpts) a, Weights_ (Rep a) ~ L c0) => genList -> Gen a Source #

`genericArbitrarySingle` with explicit generators. See also `genericArbitraryG`.

genericArbitraryRecG Source #

Arguments

:: GArbitrary (SetGens genList SizedOpts) a |
=> genList |
-> Weights a | List of weights for every constructor
-> Gen a |

`genericArbitraryRec` with explicit generators. See also `genericArbitraryG`.

# Specifying finite distributions

data Weights a Source #

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).

#### Instances

Instances details

WeightBuilder (Weights_ (Rep a)) => WeightBuilder' (Weights a) Source # |
Instance details Defined in Generic.Random.Internal.Generic Methods (%) :: forall (c :: Symbol). c ~ First' (Weights a) => W c -> Prec' (Weights a) -> Weights a Source #

data W (c :: Symbol) Source #

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

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

#### Instances

Instances details

Num (W c) Source # |
Instance details Defined in Generic.Random.Internal.Generic Methods (+) :: W c -> W c -> W c Source # (-) :: W c -> W c -> W c Source # (*) :: W c -> W c -> W c Source # negate :: W c -> W c Source # abs :: W c -> W c Source # signum :: W c -> W c Source # fromInteger :: Integer -> W c Source #

(%) :: forall (c :: Symbol). (WeightBuilder' w, c ~ First' w) => W c -> Prec' w -> w infixr 1 Source #

A binary constructor for building up trees of weights.

uniform :: UniformWeight_ (Rep a) => Weights a Source #

Uniform distribution.

# Custom generators

Custom generators can be specified in a list constructed with `(`:+`)`, and passed to functions such as `genericArbitraryG` to override how certain fields are generated.

Example:

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

There are also different types of generators, other than `Gen`, providing more ways to select the fields the generator than by simply comparing types:

- ``Gen` a`: override fields of type `a`;
- ``Gen1` f`: override fields of type `f x` for some `x`, requiring a generator for `x`;
- ``Gen1_` f`: override fields of type `f x` for some `x`, not requiring a generator for `x`;
- ``FieldGen` s a`: override record fields named `s`, which must have type `a`;
- ``ConstrGen` c i a`: override the field at index `i` of constructor `c`, which must have type `a` (0-indexed);

Multiple generators may match a given field: the first, leftmost generator in the list will be chosen.

data a :+ b infixr 1 Source #

Heterogeneous list of generators.

Constructors

a :+ b infixr 1 |

#### Instances

Instances details

FindGen 'Shift s b g a => FindGen 'Shift s () (b :+ g) a Source # | Examine the next candidate
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy 'Shift, Proxy s, FullGenListOf s) -> () -> (b :+ g) -> Gen a Source #
FindGen 'Shift s g (h :+ gs) a => FindGen 'Shift s (g :+ h) gs a Source # | This can happen if the generators form a tree rather than a list, for whatever reason.
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy 'Shift, Proxy s, FullGenListOf s) -> (g :+ h) -> gs -> Gen a Source #
(TypeLevelGenList a, TypeLevelGenList b) => TypeLevelGenList (a :+ b :: Type) Source # |

Instance details

Defined in Generic.Random.DerivingVia

Associated Types

type TypeLevelGenList' (a :+ b :: Type) |
Instance details Defined in Generic.Random.DerivingVia type TypeLevelGenList' (a :+ b :: Type) = TypeLevelGenList' a :+ TypeLevelGenList' b

Methods

toGenList :: Proxy (a :+ b) -> TypeLevelGenList' (a :+ b) Source #

type TypeLevelGenList' (a :+ b :: Type) Source # |
Instance details Defined in Generic.Random.DerivingVia type TypeLevelGenList' (a :+ b :: Type) = TypeLevelGenList' a :+ TypeLevelGenList' b

newtype FieldGen (s :: Symbol) a Source #

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

FieldGen |

Fields

- unFieldGen :: Gen a

#### Instances

Instances details

a ~ a' => FindGen ('MatchCoh 'True) s (FieldGen sn a) gs a' Source # | Matching custom generator for field `s`.
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('MatchCoh 'True), Proxy s, FullGenListOf s) -> FieldGen sn a -> gs -> Gen a' Source #
a ~ a' => FindGen ('Match 'INCOHERENT) ('S _fg _coh '(con, i, 'Just s)) (FieldGen s a) gs a' Source # | Matching custom generator for field `s`.
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('Match 'INCOHERENT), Proxy ('S _fg _coh '(con, i, 'Just s)), FullGenListOf ('S _fg _coh '(con, i, 'Just s))) -> FieldGen s a -> gs -> Gen a' Source #

fieldGen :: forall proxy (s :: Symbol) a. proxy s -> Gen a -> FieldGen s a Source #

`FieldGen` constructor with the field name given via a proxy.

newtype ConstrGen (c :: Symbol) (i :: Nat) a Source #

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

Constructors

ConstrGen |

Fields

- unConstrGen :: Gen a

#### Instances

Instances details

a ~ a' => FindGen ('MatchCoh 'True) s (ConstrGen c i a) gs a' Source # | Matching custom generator for `i`-th field of constructor `c`.
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('MatchCoh 'True), Proxy s, FullGenListOf s) -> ConstrGen c i a -> gs -> Gen a' Source #
a ~ a' => FindGen ('Match 'INCOHERENT) ('S _fg _coh '('Just c, i, s)) (ConstrGen c i a) gs a' Source # | Matching custom generator for `i`-th field of constructor `c`.
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('Match 'INCOHERENT), Proxy ('S _fg _coh '('Just c, i, s)), FullGenListOf ('S _fg _coh '('Just c, i, s))) -> ConstrGen c i a -> gs -> Gen a' Source #

constrGen :: forall proxy (c :: Symbol) (i :: Nat) a. proxy '(c, i) -> Gen a -> ConstrGen c i a Source #

`ConstrGen` constructor with the constructor name given via a proxy.

newtype Gen1 (f :: Type -> Type) Source #

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

Gen1 |

Fields

- unGen1 :: forall a. Gen a -> Gen (f a)

#### Instances

Instances details

(f x ~ a', FindGen 'Shift ('S fg coh (DummySel :: (Maybe Symbol, Natural, Maybe Symbol))) () fg x) => FindGen ('MatchCoh 'True) ('S fg coh _sel) (Gen1 f) gs a' Source # |
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('MatchCoh 'True), Proxy ('S fg coh _sel), FullGenListOf ('S fg coh _sel)) -> Gen1 f -> gs -> Gen a' Source #
FindGen 'Shift ('S fg coh (DummySel :: (Maybe Symbol, Natural, Maybe Symbol))) () fg a => FindGen ('Match 'INCOHERENT) ('S fg coh _sel) (Gen1 f) gs (f a) Source # | Matching custom generator for container `f`. Start the search for containee `a`, discarding field information.
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('Match 'INCOHERENT), Proxy ('S fg coh _sel), FullGenListOf ('S fg coh _sel)) -> Gen1 f -> gs -> Gen (f a) Source #

newtype Gen1_ (f :: k -> Type) Source #

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

Gen1_ |

Fields

- unGen1_ :: forall (a :: k). Gen (f a)

#### Instances

Instances details

f x ~ a' => FindGen ('MatchCoh 'True) s (Gen1_ f) gs a' Source # |
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('MatchCoh 'True), Proxy s, FullGenListOf s) -> Gen1_ f -> gs -> Gen a' Source #
FindGen ('Match 'INCOHERENT) s (Gen1_ f) gs (f a) Source # | Matching custom generator for non-container `f`.
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy ('Match 'INCOHERENT), Proxy s, FullGenListOf s) -> Gen1_ f -> gs -> Gen (f a) Source #

# Helpful combinators

listOf' :: Gen a -> Gen [a] Source #

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

listOf1' :: Gen a -> Gen [a] Source #

An alternative to `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)`.

vectorOf' :: Int -> Gen a -> Gen [a] Source #

An alternative to `vectorOf` that divides the size parameter by the length of the list.

# Base cases for recursive types

withBaseCase :: Gen a -> Gen a -> Gen a Source #

Run the first generator if the size is positive. Run the second if the size is zero.

    defaultGen `withBaseCase` baseCaseGen

class BaseCase a where Source #

Custom instances can override the default behavior.

Methods

baseCase :: Gen a Source #

Generator of base cases.

#### Instances

Instances details

BaseCaseSearching a 0 => BaseCase a Source # | Overlappable
Instance details Defined in Generic.Random.Internal.BaseCase Methods baseCase :: Gen a Source #

# Full options

data Options (c :: Coherence) (s :: Sizing) genList Source #

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 `(`<+`)`).

#### Instances

Instances details

HasGenerators (Options c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic Methods generators :: Options c s g -> GeneratorsOf (Options c s g) Source #
type SetOptions (c :: Coherence) (Options _c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (c :: Coherence) (Options _c s g) = Options c s g
type SetOptions (s :: Sizing) (Options c _s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (s :: Sizing) (Options c _s g) = Options c s g
type SetOptions (g :: Type) (Options c s _g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (g :: Type) (Options c s _g) = Options c s g
type SetGens g (Options c s _g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetGens g (Options c s _g) = Options c s g
type CoherenceOf (Options c _s _g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type CoherenceOf (Options c _s _g) = c
type GeneratorsOf (Options _c _s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type GeneratorsOf (Options _c _s g) = g
type SetSized (Options c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetSized (Options c s g) = Options c 'Sized g
type SetUnsized (Options c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetUnsized (Options c s g) = Options c 'Unsized g
type SizingOf (Options _c s _g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SizingOf (Options _c s _g) = s

genericArbitraryWith :: GArbitrary opts a => opts -> Weights a -> Gen a Source #

General generic generator with custom options.

## Setters

type family SetOptions (x :: k) o Source #

Setter for `Options`.

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

Since: 1.4.0.0

#### Instances

Instances details

type SetOptions (c :: Coherence) (Options _c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (c :: Coherence) (Options _c s g) = Options c s g
type SetOptions (s :: Sizing) (Options c _s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (s :: Sizing) (Options c _s g) = Options c s g
type SetOptions (g :: Type) (Options c s _g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (g :: Type) (Options c s _g) = Options c s g

type (<+) o (x :: k) = SetOptions x o infixl 1 Source #

Infix flipped synonym for `Options`.

Since: 1.4.0.0

setOpts :: forall {k} (x :: k) o. Coercible o (SetOptions x o) => o -> SetOptions x o Source #

Coerce an `Options` value between types with the same representation.

Since: 1.4.0.0

## Size modifiers

data Sizing Source #

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

#### Instances

Instances details

type SetOptions (s :: Sizing) (Options c _s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (s :: Sizing) (Options c _s g) = Options c s g

type family SetSized o Source #

#### Instances

Instances details

type SetSized (Options c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetSized (Options c s g) = Options c 'Sized g

type family SetUnsized o Source #

#### Instances

Instances details

type SetUnsized (Options c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetUnsized (Options c s g) = Options c 'Unsized g

setSized :: forall (c :: Coherence) (s :: Sizing) g. Options c s g -> Options c 'Sized g Source #

setUnsized :: forall (c :: Coherence) (s :: Sizing) g. Options c s g -> Options c 'Unsized g Source #

## Custom generators

type family SetGens g opts Source #

#### Instances

Instances details

type SetGens g (Options c s _g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetGens g (Options c s _g) = Options c s g

setGenerators :: forall genList (c :: Coherence) (s :: Sizing) g0. genList -> Options c s g0 -> Options c s genList Source #

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.

## Coherence options

data Coherence Source #

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

Expand

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:

- https://downloads.haskell.org/ghc/latest/docs/html/users_guide/glasgow_exts.html#overlapping-instances

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.)

Since: 1.4.0.0

Constructors

INCOHERENT | Match custom generators incoherently.
COHERENT | Match custom generators coherently by default (can be manually bypassed with `Incoherent`).

#### Instances

Instances details

type SetOptions (c :: Coherence) (Options _c s g) Source # |
Instance details Defined in Generic.Random.Internal.Generic type SetOptions (c :: Coherence) (Options _c s g) = Options c s g

newtype Incoherent g Source #

Match this generator incoherently when the `COHERENT` option is set.

Constructors

Incoherent g |

#### Instances

Instances details

FindGen ('Match 'INCOHERENT) s g gs a => FindGen 'Shift s (Incoherent g) gs a Source # |
Instance details Defined in Generic.Random.Internal.Generic Methods findGen :: (Proxy 'Shift, Proxy s, FullGenListOf s) -> Incoherent g -> gs -> Gen a Source #

## Common options

type SizedOpts = Options 'INCOHERENT 'Sized () Source #

sizedOpts :: SizedOpts Source #

Default options for sized generators.

type SizedOptsDef = Options 'INCOHERENT 'Sized (Gen1 [] :+ ()) Source #

sizedOptsDef :: SizedOptsDef Source #

Default options overriding the list generator using `listOf'`.

type UnsizedOpts = Options 'INCOHERENT 'Unsized () Source #

unsizedOpts :: UnsizedOpts Source #

Default options for unsized generators.

### Advanced options

See `Coherence`

type CohUnsizedOpts = Options 'COHERENT 'Unsized () Source #

Like `UnsizedOpts`, but using coherent instances by default.

Since: 1.4.0.0

cohUnsizedOpts :: CohUnsizedOpts Source #

Like `unsizedOpts`, but using coherent instances by default.

type CohSizedOpts = Options 'COHERENT 'Sized () Source #

Like `SizedOpts`, but using coherent instances by default.

Since: 1.4.0.0

cohSizedOpts :: CohSizedOpts Source #

Like `sizedOpts` but using coherent instances by default.

# Generic classes

class (Generic a, GA opts (Rep a)) => GArbitrary opts a Source #

Generic Arbitrary

#### Instances

Instances details

(Generic a, GA opts (Rep a)) => GArbitrary opts a Source # |
Instance details Defined in Generic.Random.Internal.Generic

class UniformWeight_ (Rep a) => GUniformWeight a Source #

Derived uniform distribution of constructors for `a`.

#### Instances

Instances details

UniformWeight_ (Rep a) => GUniformWeight a Source # |
Instance details Defined in Generic.Random.Internal.Generic

# Newtypes for DerivingVia

These newtypes correspond to the variants of `genericArbitrary` above.

newtype GenericArbitrary (weights :: k) a Source #

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

### Example

    data X = ...
      deriving Arbitrary via (GenericArbitrary '[2, 3, 5] X)

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

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitrary`.

Since: 1.5.0.0

Constructors

GenericArbitrary |

Fields

- unGenericArbitrary :: a

#### Instances

Instances details

(GArbitrary UnsizedOpts a, TypeLevelWeights' weights a) => Arbitrary (GenericArbitrary weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitrary weights a) Source # shrink :: GenericArbitrary weights a -> [GenericArbitrary weights a] Source #
Show a => Show (GenericArbitrary weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitrary weights a -> ShowS Source # show :: GenericArbitrary weights a -> String Source # showList :: [GenericArbitrary weights a] -> ShowS Source #
Eq a => Eq (GenericArbitrary weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitrary weights a -> GenericArbitrary weights a -> Bool Source # (/=) :: GenericArbitrary weights a -> GenericArbitrary weights a -> Bool Source #

newtype GenericArbitraryU a Source #

Pick every constructor with equal probability.

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitraryU`.

Since: 1.5.0.0

Constructors

GenericArbitraryU |

Fields

- unGenericArbitraryU :: a

#### Instances

Instances details

(GArbitrary UnsizedOpts a, GUniformWeight a) => Arbitrary (GenericArbitraryU a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitraryU a) Source # shrink :: GenericArbitraryU a -> [GenericArbitraryU a] Source #
Show a => Show (GenericArbitraryU a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitraryU a -> ShowS Source # show :: GenericArbitraryU a -> String Source # showList :: [GenericArbitraryU a] -> ShowS Source #
Eq a => Eq (GenericArbitraryU a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitraryU a -> GenericArbitraryU a -> Bool Source # (/=) :: GenericArbitraryU a -> GenericArbitraryU a -> Bool Source #

newtype GenericArbitrarySingle a Source #

`arbitrary` for types with one constructor. Equivalent to `GenericArbitraryU`, with a stricter type.

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitrarySingle`.

Since: 1.5.0.0

Constructors

GenericArbitrarySingle |

Fields

- unGenericArbitrarySingle :: a

#### Instances

Instances details

(GArbitrary UnsizedOpts a, Weights_ (Rep a) ~ L c0) => Arbitrary (GenericArbitrarySingle a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitrarySingle a) Source # shrink :: GenericArbitrarySingle a -> [GenericArbitrarySingle a] Source #
Show a => Show (GenericArbitrarySingle a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitrarySingle a -> ShowS Source # show :: GenericArbitrarySingle a -> String Source # showList :: [GenericArbitrarySingle a] -> ShowS Source #
Eq a => Eq (GenericArbitrarySingle a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitrarySingle a -> GenericArbitrarySingle a -> Bool Source # (/=) :: GenericArbitrarySingle a -> GenericArbitrarySingle a -> Bool Source #

newtype GenericArbitraryRec (weights :: k) a Source #

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

    data X = ...
      deriving Arbitrary via (GenericArbitraryRec '[2, 3, 5] X)

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

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitraryRec`.

Since: 1.5.0.0

Constructors

GenericArbitraryRec |

Fields

- unGenericArbitraryRec :: a

#### Instances

Instances details

(GArbitrary SizedOptsDef a, TypeLevelWeights' weights a) => Arbitrary (GenericArbitraryRec weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitraryRec weights a) Source # shrink :: GenericArbitraryRec weights a -> [GenericArbitraryRec weights a] Source #
Show a => Show (GenericArbitraryRec weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitraryRec weights a -> ShowS Source # show :: GenericArbitraryRec weights a -> String Source # showList :: [GenericArbitraryRec weights a] -> ShowS Source #
Eq a => Eq (GenericArbitraryRec weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitraryRec weights a -> GenericArbitraryRec weights a -> Bool Source # (/=) :: GenericArbitraryRec weights a -> GenericArbitraryRec weights a -> Bool Source #

newtype GenericArbitraryG (genList :: k) (weights :: k1) a Source #

`GenericArbitrary` with explicit generators.

### Example

    data X = ...
      deriving Arbitrary via (GenericArbitraryG CustomGens '[2, 3, 5] X)

where, for example, custom generators to override `String` and `Int` fields might look as follows:

    type CustomGens = CustomString :+ CustomInt

### Note on multiple matches

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

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitraryG`.

Since: 1.5.0.0

Constructors

GenericArbitraryG |

Fields

- unGenericArbitraryG :: a

#### Instances

Instances details

(GArbitrary (SetGens genList UnsizedOpts) a, GUniformWeight a, TypeLevelWeights' weights a, TypeLevelGenList genList', genList ~ TypeLevelGenList' genList') => Arbitrary (GenericArbitraryG genList' weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitraryG genList' weights a) Source # shrink :: GenericArbitraryG genList' weights a -> [GenericArbitraryG genList' weights a] Source #
Show a => Show (GenericArbitraryG genList weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitraryG genList weights a -> ShowS Source # show :: GenericArbitraryG genList weights a -> String Source # showList :: [GenericArbitraryG genList weights a] -> ShowS Source #
Eq a => Eq (GenericArbitraryG genList weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitraryG genList weights a -> GenericArbitraryG genList weights a -> Bool Source # (/=) :: GenericArbitraryG genList weights a -> GenericArbitraryG genList weights a -> Bool Source #

newtype GenericArbitraryUG (genList :: k) a Source #

`GenericArbitraryU` with explicit generators. See also `GenericArbitraryG`.

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitraryUG`.

Since: 1.5.0.0

Constructors

GenericArbitraryUG |

Fields

- unGenericArbitraryUG :: a

#### Instances

Instances details

(GArbitrary (SetGens genList UnsizedOpts) a, GUniformWeight a, TypeLevelGenList genList', genList ~ TypeLevelGenList' genList') => Arbitrary (GenericArbitraryUG genList' a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitraryUG genList' a) Source # shrink :: GenericArbitraryUG genList' a -> [GenericArbitraryUG genList' a] Source #
Show a => Show (GenericArbitraryUG genList a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitraryUG genList a -> ShowS Source # show :: GenericArbitraryUG genList a -> String Source # showList :: [GenericArbitraryUG genList a] -> ShowS Source #
Eq a => Eq (GenericArbitraryUG genList a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitraryUG genList a -> GenericArbitraryUG genList a -> Bool Source # (/=) :: GenericArbitraryUG genList a -> GenericArbitraryUG genList a -> Bool Source #

newtype GenericArbitrarySingleG (genList :: k) a Source #

`genericArbitrarySingle` with explicit generators. See also `GenericArbitraryG`.

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitrarySingleG`.

Since: 1.5.0.0

Constructors

GenericArbitrarySingleG |

Fields

- unGenericArbitrarySingleG :: a

#### Instances

Instances details

(GArbitrary (SetGens genList UnsizedOpts) a, Weights_ (Rep a) ~ L c0, TypeLevelGenList genList', genList ~ TypeLevelGenList' genList') => Arbitrary (GenericArbitrarySingleG genList' a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitrarySingleG genList' a) Source # shrink :: GenericArbitrarySingleG genList' a -> [GenericArbitrarySingleG genList' a] Source #
Show a => Show (GenericArbitrarySingleG genList a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitrarySingleG genList a -> ShowS Source # show :: GenericArbitrarySingleG genList a -> String Source # showList :: [GenericArbitrarySingleG genList a] -> ShowS Source #
Eq a => Eq (GenericArbitrarySingleG genList a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitrarySingleG genList a -> GenericArbitrarySingleG genList a -> Bool Source # (/=) :: GenericArbitrarySingleG genList a -> GenericArbitrarySingleG genList a -> Bool Source #

newtype GenericArbitraryRecG (genList :: k) (weights :: k1) a Source #

`genericArbitraryRec` with explicit generators. See also `genericArbitraryG`.

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitraryRecG`.

Since: 1.5.0.0

Constructors

GenericArbitraryRecG |

Fields

- unGenericArbitraryRecG :: a

#### Instances

Instances details

(GArbitrary (SetGens genList SizedOpts) a, TypeLevelWeights' weights a, TypeLevelGenList genList', genList ~ TypeLevelGenList' genList') => Arbitrary (GenericArbitraryRecG genList' weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitraryRecG genList' weights a) Source # shrink :: GenericArbitraryRecG genList' weights a -> [GenericArbitraryRecG genList' weights a] Source #
Show a => Show (GenericArbitraryRecG genList weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitraryRecG genList weights a -> ShowS Source # show :: GenericArbitraryRecG genList weights a -> String Source # showList :: [GenericArbitraryRecG genList weights a] -> ShowS Source #
Eq a => Eq (GenericArbitraryRecG genList weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitraryRecG genList weights a -> GenericArbitraryRecG genList weights a -> Bool Source # (/=) :: GenericArbitraryRecG genList weights a -> GenericArbitraryRecG genList weights a -> Bool Source #

newtype GenericArbitraryWith (opts :: k) (weights :: k1) a Source #

General generic generator with custom options.

This newtype does no shrinking. To add generic shrinking, use `AndShrinking`.

Uses `genericArbitraryWith`.

Since: 1.5.0.0

Constructors

GenericArbitraryWith |

Fields

- unGenericArbitraryWith :: a

#### Instances

Instances details

(GArbitrary opts a, TypeLevelWeights' weights a, TypeLevelOpts opts', opts ~ TypeLevelOpts' opts') => Arbitrary (GenericArbitraryWith opts' weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (GenericArbitraryWith opts' weights a) Source # shrink :: GenericArbitraryWith opts' weights a -> [GenericArbitraryWith opts' weights a] Source #
Show a => Show (GenericArbitraryWith opts weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> GenericArbitraryWith opts weights a -> ShowS Source # show :: GenericArbitraryWith opts weights a -> String Source # showList :: [GenericArbitraryWith opts weights a] -> ShowS Source #
Eq a => Eq (GenericArbitraryWith opts weights a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: GenericArbitraryWith opts weights a -> GenericArbitraryWith opts weights a -> Bool Source # (/=) :: GenericArbitraryWith opts weights a -> GenericArbitraryWith opts weights a -> Bool Source #

newtype AndShrinking (f :: k) a Source #

Add generic shrinking to a newtype wrapper for `Arbitrary`, using `genericShrink`.

    data X = ...
      deriving Arbitrary via (GenericArbitrary '[1,2,3] `AndShrinking' X)

Equivalent to:

    instance Arbitrary X where
      arbitrary = genericArbitrary (1 % 2 % 3 % ())
      shrink = genericShrink

Since: 1.5.0.0

Constructors

AndShrinking a |

#### Instances

Instances details

(Arbitrary (f a), Coercible (f a) a, Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) => Arbitrary (AndShrinking f a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods arbitrary :: Gen (AndShrinking f a) Source # shrink :: AndShrinking f a -> [AndShrinking f a] Source #
Show a => Show (AndShrinking f a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods showsPrec :: Int -> AndShrinking f a -> ShowS Source # show :: AndShrinking f a -> String Source # showList :: [AndShrinking f a] -> ShowS Source #
Eq a => Eq (AndShrinking f a) Source # |
Instance details Defined in Generic.Random.DerivingVia Methods (==) :: AndShrinking f a -> AndShrinking f a -> Bool Source # (/=) :: AndShrinking f a -> AndShrinking f a -> Bool Source #

## Helpers typeclasses

class TypeLevelGenList (a :: k) where Source #

Since: 1.5.0.0

Associated Types

type TypeLevelGenList' (a :: k) Source #

Methods

toGenList :: Proxy a -> TypeLevelGenList' a Source #

#### Instances

Instances details

Arbitrary a => TypeLevelGenList (Gen a :: Type) Source # |

Instance details

Defined in Generic.Random.DerivingVia

Associated Types

type TypeLevelGenList' (Gen a :: Type) |
Instance details Defined in Generic.Random.DerivingVia type TypeLevelGenList' (Gen a :: Type) = Gen a

Methods

toGenList :: Proxy (Gen a) -> TypeLevelGenList' (Gen a) Source #

(TypeLevelGenList a, TypeLevelGenList b) => TypeLevelGenList (a :+ b :: Type) Source # |

Instance details

Defined in Generic.Random.DerivingVia

Associated Types

type TypeLevelGenList' (a :+ b :: Type) |
Instance details Defined in Generic.Random.DerivingVia type TypeLevelGenList' (a :+ b :: Type) = TypeLevelGenList' a :+ TypeLevelGenList' b

Methods

toGenList :: Proxy (a :+ b) -> TypeLevelGenList' (a :+ b) Source #

class TypeLevelOpts (a :: k) where Source #

Since: 1.5.0.0

Associated Types

type TypeLevelOpts' (a :: k) Source #

Methods

toOpts :: Proxy a -> TypeLevelOpts' a Source #