-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Generic random generators for QuickCheck -- -- Derive instances of Arbitrary for QuickCheck, with various -- options to customize implementations. -- -- For more information -- -- @package generic-random @version 1.5.0.1 -- | 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. module Generic.Random.Internal.Generic -- | 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. genericArbitrary :: GArbitrary UnsizedOpts a => Weights a -> Gen a -- | Pick every constructor with equal probability. Equivalent to -- genericArbitrary uniform. -- --
--   genericArbitraryU :: Gen a
--   
genericArbitraryU :: (GArbitrary UnsizedOpts a, GUniformWeight a) => Gen a -- | arbitrary for types with one constructor. Equivalent to -- genericArbitraryU, with a stricter type. -- --
--   genericArbitrarySingle :: Gen a
--   
genericArbitrarySingle :: (GArbitrary UnsizedOpts a, Weights_ (Rep a) ~ L c0) => 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). genericArbitraryRec :: GArbitrary SizedOptsDef a => Weights a -> 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. genericArbitraryG :: GArbitrary (SetGens genList UnsizedOpts) a => genList -> Weights a -> Gen a -- | genericArbitraryU with explicit generators. See also -- genericArbitraryG. genericArbitraryUG :: (GArbitrary (SetGens genList UnsizedOpts) a, GUniformWeight a) => genList -> Gen a -- | genericArbitrarySingle with explicit generators. See also -- genericArbitraryG. genericArbitrarySingleG :: (GArbitrary (SetGens genList UnsizedOpts) a, Weights_ (Rep a) ~ L c0) => genList -> Gen a -- | genericArbitraryRec with explicit generators. See also -- genericArbitraryG. genericArbitraryRecG :: GArbitrary (SetGens genList SizedOpts) a => genList -> Weights a -> Gen a -- | General generic generator with custom options. genericArbitraryWith :: GArbitrary opts a => opts -> Weights a -> Gen a type family Weights_ (f :: Type -> Type) :: Type data a :| b N :: a -> Int -> b -> (:|) a b data L (c :: Symbol) L :: L (c :: Symbol) -- | 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). data Weights a Weights :: Weights_ (Rep a) -> Int -> Weights a -- | Type of a single weight, tagged with the name of the associated -- constructor for additional compile-time checking. -- --
--   ((9 :: W "Leaf") % (8 :: W "Node") % ())
--   
newtype W (c :: Symbol) W :: Int -> W (c :: Symbol) -- | A smart constructor to specify a custom distribution. It can be -- omitted for the % operator is overloaded to insert it. weights :: (Weights_ (Rep a), Int, ()) -> Weights a -- | Uniform distribution. uniform :: UniformWeight_ (Rep a) => Weights a type family First a :: Symbol type family First' w type family Prec' w class WeightBuilder' w -- | A binary constructor for building up trees of weights. (%) :: (WeightBuilder' w, c ~ First' w) => W c -> Prec' w -> w infixr 1 % class WeightBuilder a where { type family Prec a r; } (%.) :: (WeightBuilder a, c ~ First a) => W c -> Prec a r -> (a, Int, r) class UniformWeight a uniformWeight :: UniformWeight a => (a, Int) class UniformWeight (Weights_ f) => UniformWeight_ f -- | Derived uniform distribution of constructors for a. class UniformWeight_ (Rep a) => GUniformWeight a -- | 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 (<+)). newtype Options (c :: Coherence) (s :: Sizing) (genList :: Type) Options :: genList -> Options (c :: Coherence) (s :: Sizing) (genList :: Type) [_generators] :: Options (c :: Coherence) (s :: Sizing) (genList :: Type) -> genList -- | Setter for Options. -- -- This subsumes the other setters: SetSized, SetUnsized, -- SetGens. type family SetOptions (x :: k) (o :: Type) :: Type -- | Infix flipped synonym for Options. type (<+) o x = SetOptions x o infixl 1 <+ type UnsizedOpts = Options 'INCOHERENT 'Unsized () type SizedOpts = Options 'INCOHERENT 'Sized () type SizedOptsDef = Options 'INCOHERENT 'Sized (Gen1 [] :+ ()) -- | Like UnsizedOpts, but using coherent instances by default. type CohUnsizedOpts = Options 'COHERENT 'Unsized () -- | Like SizedOpts, but using coherent instances by default. type CohSizedOpts = Options 'COHERENT 'Sized () -- | Coerce an Options value between types with the same -- representation. setOpts :: forall x o. Coercible o (SetOptions x o) => o -> SetOptions x o -- | Default options for unsized generators. unsizedOpts :: UnsizedOpts -- | Default options for sized generators. sizedOpts :: SizedOpts -- | Default options overriding the list generator using listOf'. sizedOptsDef :: SizedOptsDef -- | Like unsizedOpts, but using coherent instances by default. cohUnsizedOpts :: CohUnsizedOpts -- | Like sizedOpts but using coherent instances by default. cohSizedOpts :: CohSizedOpts -- | 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. data Sizing -- | Decrease the size parameter when running generators for fields Sized :: Sizing -- | Don't touch the size parameter Unsized :: Sizing type family SizingOf opts :: Sizing type family SetSized (o :: Type) :: Type type family SetUnsized (o :: Type) :: Type setSized :: Options c s g -> Options c 'Sized g setUnsized :: Options c s g -> Options c 'Unsized g -- | 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.) data Coherence -- | Match custom generators incoherently. INCOHERENT :: Coherence -- | Match custom generators coherently by default (can be manually -- bypassed with Incoherent). COHERENT :: Coherence type family CoherenceOf (o :: Type) :: Coherence -- | Match this generator incoherently when the COHERENT option is -- set. newtype Incoherent g Incoherent :: g -> Incoherent g -- | Heterogeneous list of generators. data a :+ b (:+) :: a -> b -> (:+) a b infixr 1 :+ infixr 1 :+ type family GeneratorsOf opts :: Type class HasGenerators opts generators :: HasGenerators opts => opts -> GeneratorsOf opts -- | 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. setGenerators :: genList -> Options c s g0 -> Options c s genList type family SetGens (g :: Type) opts -- | 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. newtype FieldGen (s :: Symbol) a FieldGen :: Gen a -> FieldGen (s :: Symbol) a [unFieldGen] :: FieldGen (s :: Symbol) a -> Gen a -- | FieldGen constructor with the field name given via a proxy. fieldGen :: proxy s -> Gen a -> FieldGen s a -- | Custom generator for the i-th field of the constructor named -- c. Fields are 0-indexed. newtype ConstrGen (c :: Symbol) (i :: Nat) a ConstrGen :: Gen a -> ConstrGen (c :: Symbol) (i :: Nat) a [unConstrGen] :: ConstrGen (c :: Symbol) (i :: Nat) a -> Gen a -- | ConstrGen constructor with the constructor name given via a -- proxy. constrGen :: proxy '(c, i) -> Gen a -> ConstrGen c i a -- | 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. newtype Gen1 f Gen1 :: (forall a. Gen a -> Gen (f a)) -> Gen1 f [unGen1] :: Gen1 f -> forall a. Gen a -> Gen (f a) -- | 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. newtype Gen1_ f Gen1_ :: (forall a. Gen (f a)) -> Gen1_ f [unGen1_] :: Gen1_ f -> forall a. Gen (f a) -- | An alternative to vectorOf that divides the size parameter by -- the length of the list. vectorOf' :: Int -> Gen a -> Gen [a] -- | 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). listOf' :: Gen a -> Gen [a] -- | 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). listOf1' :: Gen a -> Gen [a] -- | Geometric distribution of parameter 1/(sqrt n + 1) (n -- >= 0). geom :: Int -> Gen Int -- | Generic Arbitrary class GA opts f ga :: GA opts f => opts -> Weights_ f -> Int -> Gen (f p) -- | Generic Arbitrary class (Generic a, GA opts (Rep a)) => GArbitrary opts a gaSum' :: GASum opts f => opts -> Weights_ f -> Int -> Gen (f p) class GASum opts f gaSum :: GASum opts f => opts -> Int -> Weights_ f -> Gen (f p) class GAProduct (s :: Sizing) (c :: Maybe Symbol) opts f gaProduct :: GAProduct s c opts f => proxys '(s, c) -> opts -> Gen (f p) class GAProduct' (c :: Maybe Symbol) (i :: Nat) opts f gaProduct' :: GAProduct' c i opts f => proxy '(c, i) -> opts -> Gen (f p) type family Arity f :: Nat -- | 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
--   
class FindGen (i :: AInstr) (s :: AStore) (g :: Type) (gs :: Type) (a :: Type) findGen :: FindGen i s g gs a => (Proxy i, Proxy s, FullGenListOf s) -> g -> gs -> Gen a data AInstr Shift :: AInstr Match :: Coherence -> AInstr MatchCoh :: Bool -> AInstr data AStore S :: Type -> Coherence -> ASel -> AStore type ASel = (Maybe Symbol, Nat, Maybe Symbol) iShift :: Proxy 'Shift type family FullGenListOf (s :: AStore) :: Type type family ACoherenceOf (s :: AStore) :: Coherence type family ASelOf (s :: AStore) :: ASel type DummySel = '( 'Nothing, 0, 'Nothing) -- | Get the name contained in a Meta tag. type family Name (d :: Meta) :: Maybe Symbol type family Matches (s :: ASel) (g :: Type) (a :: Type) :: Bool newtype Weighted a Weighted :: Maybe (Int -> Gen a, Int) -> Weighted a liftGen :: Gen a -> Weighted a instance GHC.Num.Num (Generic.Random.Internal.Generic.W c) instance GHC.Base.Functor Generic.Random.Internal.Generic.Weighted instance GHC.Base.Applicative Generic.Random.Internal.Generic.Weighted instance GHC.Base.Alternative Generic.Random.Internal.Generic.Weighted instance Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.MatchCoh (Generic.Random.Internal.Generic.Matches (Generic.Random.Internal.Generic.ASelOf s) g a)) s g gs a => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.COHERENT) s g gs a instance Generic.Random.Internal.Generic.GAProduct (Generic.Random.Internal.Generic.SizingOf opts) (Generic.Random.Internal.Generic.Name c) opts f => Generic.Random.Internal.Generic.GA opts (GHC.Generics.M1 GHC.Generics.C c f) instance Generic.Random.Internal.Generic.GAProduct (Generic.Random.Internal.Generic.SizingOf opts) (Generic.Random.Internal.Generic.Name c) opts f => Generic.Random.Internal.Generic.GASum opts (GHC.Generics.M1 GHC.Generics.C c f) instance (Generic.Random.Internal.Generic.HasGenerators opts, Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift ('Generic.Random.Internal.Generic.S gs coh '(c, i, Generic.Random.Internal.Generic.Name d)) () gs a, gs GHC.Types.~ Generic.Random.Internal.Generic.GeneratorsOf opts, coh GHC.Types.~ Generic.Random.Internal.Generic.CoherenceOf opts) => Generic.Random.Internal.Generic.GAProduct' c i opts (GHC.Generics.S1 d (GHC.Generics.K1 _k a)) instance Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift ('Generic.Random.Internal.Generic.S fg coh Generic.Random.Internal.Generic.DummySel) () fg a => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.INCOHERENT) ('Generic.Random.Internal.Generic.S fg coh _sel) (Generic.Random.Internal.Generic.Gen1 f) gs (f a) instance (f x GHC.Types.~ a', Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift ('Generic.Random.Internal.Generic.S fg coh Generic.Random.Internal.Generic.DummySel) () fg x) => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.MatchCoh 'GHC.Types.True) ('Generic.Random.Internal.Generic.S fg coh _sel) (Generic.Random.Internal.Generic.Gen1 f) gs a' instance Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match (Generic.Random.Internal.Generic.ACoherenceOf s)) s g gs a => Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s g gs a instance Test.QuickCheck.Arbitrary.Arbitrary a => Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s () () a instance Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s b g a => Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s () (b Generic.Random.Internal.Generic.:+ g) a instance Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s g () a => Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s () g a instance Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s g (h Generic.Random.Internal.Generic.:+ gs) a => Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s (g Generic.Random.Internal.Generic.:+ h) gs a instance Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.INCOHERENT) s g gs a => Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s (Generic.Random.Internal.Generic.Incoherent g) gs a instance Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s () gs a => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.INCOHERENT) s _g gs a instance Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.INCOHERENT) s (Test.QuickCheck.Gen.Gen a) gs a instance forall k (s :: Generic.Random.Internal.Generic.AStore) (f :: k -> *) gs (a :: k). Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.INCOHERENT) s (Generic.Random.Internal.Generic.Gen1_ f) gs (f a) instance (a GHC.Types.~ a') => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.INCOHERENT) ('Generic.Random.Internal.Generic.S _fg _coh '(con, i, 'GHC.Maybe.Just s)) (Generic.Random.Internal.Generic.FieldGen s a) gs a' instance (a GHC.Types.~ a') => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.Match 'Generic.Random.Internal.Generic.INCOHERENT) ('Generic.Random.Internal.Generic.S _fg _coh '( 'GHC.Maybe.Just c, i, s)) (Generic.Random.Internal.Generic.ConstrGen c i a) gs a' instance Generic.Random.Internal.Generic.FindGen 'Generic.Random.Internal.Generic.Shift s () gs a => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.MatchCoh 'GHC.Types.False) s _g gs a instance (a GHC.Types.~ a') => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.MatchCoh 'GHC.Types.True) s (Test.QuickCheck.Gen.Gen a) gs a' instance forall k (f :: k -> *) (x :: k) a' (s :: Generic.Random.Internal.Generic.AStore) gs. (f x GHC.Types.~ a') => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.MatchCoh 'GHC.Types.True) s (Generic.Random.Internal.Generic.Gen1_ f) gs a' instance (a GHC.Types.~ a') => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.MatchCoh 'GHC.Types.True) s (Generic.Random.Internal.Generic.FieldGen sn a) gs a' instance (a GHC.Types.~ a') => Generic.Random.Internal.Generic.FindGen ('Generic.Random.Internal.Generic.MatchCoh 'GHC.Types.True) s (Generic.Random.Internal.Generic.ConstrGen c i a) gs a' instance forall k (c :: GHC.Maybe.Maybe GHC.Types.Symbol) opts (f :: k -> *). (Generic.Random.Internal.Generic.GAProduct' c 0 opts f, GHC.TypeNats.KnownNat (Generic.Random.Internal.Generic.Arity f)) => Generic.Random.Internal.Generic.GAProduct 'Generic.Random.Internal.Generic.Sized c opts f instance forall k (c :: GHC.Maybe.Maybe GHC.Types.Symbol) (i :: GHC.Types.Nat) opts (f :: k -> *) (g :: k -> *). (Generic.Random.Internal.Generic.GAProduct' c i opts f, Generic.Random.Internal.Generic.GAProduct' c (i GHC.TypeNats.+ Generic.Random.Internal.Generic.Arity f) opts g) => Generic.Random.Internal.Generic.GAProduct' c i opts (f GHC.Generics.:*: g) instance forall k (c :: GHC.Maybe.Maybe GHC.Types.Symbol) opts (f :: k -> *). Generic.Random.Internal.Generic.GAProduct' c 0 opts f => Generic.Random.Internal.Generic.GAProduct 'Generic.Random.Internal.Generic.Unsized c opts f instance forall k (c :: GHC.Maybe.Maybe GHC.Types.Symbol) opts (d :: GHC.Generics.Meta) (f :: k -> *). Generic.Random.Internal.Generic.GAProduct' c 0 opts (GHC.Generics.S1 d f) => Generic.Random.Internal.Generic.GAProduct 'Generic.Random.Internal.Generic.Sized c opts (GHC.Generics.S1 d f) instance Generic.Random.Internal.Generic.GAProduct' c i opts GHC.Generics.U1 instance Generic.Random.Internal.Generic.GAProduct 'Generic.Random.Internal.Generic.Sized c opts GHC.Generics.U1 instance (Generic.Random.Internal.Generic.GASum opts f, Generic.Random.Internal.Generic.GASum opts g) => Generic.Random.Internal.Generic.GA opts (f GHC.Generics.:+: g) instance (Generic.Random.Internal.Generic.GASum opts f, Generic.Random.Internal.Generic.GASum opts g) => Generic.Random.Internal.Generic.GASum opts (f GHC.Generics.:+: g) instance (GHC.Generics.Generic a, Generic.Random.Internal.Generic.GA opts (GHC.Generics.Rep a)) => Generic.Random.Internal.Generic.GArbitrary opts a instance Generic.Random.Internal.Generic.GA opts f => Generic.Random.Internal.Generic.GA opts (GHC.Generics.M1 GHC.Generics.D c f) instance Generic.Random.Internal.Generic.HasGenerators (Generic.Random.Internal.Generic.Options c s g) instance Generic.Random.Internal.Generic.UniformWeight_ (GHC.Generics.Rep a) => Generic.Random.Internal.Generic.GUniformWeight a instance Generic.Random.Internal.Generic.UniformWeight (Generic.Random.Internal.Generic.Weights_ f) => Generic.Random.Internal.Generic.UniformWeight_ f instance (Generic.Random.Internal.Generic.UniformWeight a, Generic.Random.Internal.Generic.UniformWeight b) => Generic.Random.Internal.Generic.UniformWeight (a Generic.Random.Internal.Generic.:| b) instance Generic.Random.Internal.Generic.UniformWeight (Generic.Random.Internal.Generic.L c) instance Generic.Random.Internal.Generic.UniformWeight () instance Generic.Random.Internal.Generic.WeightBuilder (Generic.Random.Internal.Generic.Weights_ (GHC.Generics.Rep a)) => Generic.Random.Internal.Generic.WeightBuilder' (Generic.Random.Internal.Generic.Weights a) instance Generic.Random.Internal.Generic.WeightBuilder a => Generic.Random.Internal.Generic.WeightBuilder' (a, GHC.Types.Int, r) instance Generic.Random.Internal.Generic.WeightBuilder a => Generic.Random.Internal.Generic.WeightBuilder (a Generic.Random.Internal.Generic.:| b) instance Generic.Random.Internal.Generic.WeightBuilder (Generic.Random.Internal.Generic.L c) instance Generic.Random.Internal.Generic.WeightBuilder () -- | Base case discovery. -- --

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. module Generic.Random.Internal.BaseCase -- | 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). genericArbitrary' :: (GArbitrary SizedOptsDef a, BaseCase a) => Weights a -> Gen a -- | 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). genericArbitraryU' :: (GArbitrary SizedOptsDef a, BaseCase a, GUniformWeight a) => Gen a -- | Run the first generator if the size is positive. Run the second if the -- size is zero. -- --
--   defaultGen `withBaseCase` baseCaseGen
--   
withBaseCase :: Gen a -> Gen a -> Gen a -- | Find a base case of type a with maximum depth z, -- recursively using BaseCaseSearch instances to search deeper -- levels. -- -- y is the depth of a base case, if found. -- -- e is the original type the search started with, that -- a appears in. It is used for error reporting. class BaseCaseSearch (a :: Type) (z :: Nat) (y :: Maybe Nat) (e :: Type) baseCaseSearch :: BaseCaseSearch a z y e => prox y -> proxy '(z, e) -> IfM y Gen Proxy a class BaseCaseSearching_ a z y baseCaseSearching_ :: BaseCaseSearching_ a z y => proxy y -> proxy2 '(z, a) -> IfM y Gen Proxy a -> Gen a -- | Progressively increase the depth bound for BaseCaseSearch. class BaseCaseSearching a z baseCaseSearching :: BaseCaseSearching a z => proxy '(z, a) -> Gen a -- | Custom instances can override the default behavior. class BaseCase a -- | Generator of base cases. baseCase :: BaseCase a => Gen a type family IfM (b :: Maybe t) (c :: k) (d :: k) :: k type (==) m n = IsEQ (CmpNat m n) type family IsEQ (e :: Ordering) :: Bool type family (||?) (b :: Maybe Nat) (c :: Maybe Nat) :: Maybe Nat type family (&&?) (b :: Maybe Nat) (c :: Maybe Nat) :: Maybe Nat type Max m n = MaxOf (CmpNat m n) m n type family MaxOf (e :: Ordering) (m :: k) (n :: k) :: k type Min m n = MinOf (CmpNat m n) m n type family MinOf (e :: Ordering) (m :: k) (n :: k) :: k class Alternative (IfM y Weighted Proxy) => GBCS (f :: k -> Type) (z :: Nat) (y :: Maybe Nat) (e :: Type) gbcs :: GBCS f z y e => prox y -> proxy '(z, e) -> IfM y Weighted Proxy (f p) class Alternative (IfM (yf ||? yg) Weighted Proxy) => GBCSSum f g z e yf yg gbcsSum :: GBCSSum f g z e yf yg => prox '(yf, yg) -> proxy '(z, e) -> IfM yf Weighted Proxy (f p) -> IfM yg Weighted Proxy (g p) -> IfM (yf ||? yg) Weighted Proxy ((f :+: g) p) class GBCSSumCompare f g z e o gbcsSumCompare :: GBCSSumCompare f g z e o => proxy0 o -> proxy '(z, e) -> Weighted (f p) -> Weighted (g p) -> Weighted ((f :+: g) p) class Alternative (IfM (yf &&? yg) Weighted Proxy) => GBCSProduct f g z e yf yg gbcsProduct :: GBCSProduct f g z e yf yg => prox '(yf, yg) -> proxy '(z, e) -> IfM yf Weighted Proxy (f p) -> IfM yg Weighted Proxy (g p) -> IfM (yf &&? yg) Weighted Proxy ((f :*: g) p) class IsMaybe b ifMmap :: IsMaybe b => proxy b -> (c a -> c' a') -> (d a -> d' a') -> IfM b c d a -> IfM b c' d' a' ifM :: IsMaybe b => proxy b -> c a -> d a -> IfM b c d a class GBaseCaseSearch a z y e gBaseCaseSearch :: GBaseCaseSearch a z y e => prox y -> proxy '(z, e) -> IfM y Gen Proxy a instance Generic.Random.Internal.BaseCase.GBaseCaseSearch a z y e => Generic.Random.Internal.BaseCase.BaseCaseSearch a z y e instance (GHC.Generics.Generic a, Generic.Random.Internal.BaseCase.GBCS (GHC.Generics.Rep a) z y e, Generic.Random.Internal.BaseCase.IsMaybe y) => Generic.Random.Internal.BaseCase.GBaseCaseSearch a z y e instance forall t1 (t2 :: t1). Generic.Random.Internal.BaseCase.IsMaybe ('GHC.Maybe.Just t2) instance Generic.Random.Internal.BaseCase.IsMaybe 'GHC.Maybe.Nothing instance (Generic.Random.Internal.BaseCase.BaseCaseSearch c (z GHC.TypeNats.- 1) y e, (z Generic.Random.Internal.BaseCase.== 0) GHC.Types.~ 'GHC.Types.False, GHC.Base.Alternative (Generic.Random.Internal.BaseCase.IfM y Generic.Random.Internal.Generic.Weighted Data.Proxy.Proxy), Generic.Random.Internal.BaseCase.IsMaybe y) => Generic.Random.Internal.BaseCase.GBCS (GHC.Generics.K1 i c) z y e instance forall k (y :: GHC.Maybe.Maybe GHC.Types.Nat) (f :: k -> *) (g :: k -> *) (z :: GHC.Types.Nat) e (yf :: GHC.Maybe.Maybe GHC.Types.Nat) (yg :: GHC.Maybe.Maybe GHC.Types.Nat). (GHC.Base.Alternative (Generic.Random.Internal.BaseCase.IfM y Generic.Random.Internal.Generic.Weighted Data.Proxy.Proxy), Generic.Random.Internal.BaseCase.GBCSProduct f g z e yf yg, Generic.Random.Internal.BaseCase.GBCS f z yf e, Generic.Random.Internal.BaseCase.GBCS g z yg e, y GHC.Types.~ (yf Generic.Random.Internal.BaseCase.&&? yg)) => Generic.Random.Internal.BaseCase.GBCS (f GHC.Generics.:*: g) z y e instance forall k1 k2 k3 (yf :: GHC.Maybe.Maybe GHC.Types.Nat) (yg :: GHC.Maybe.Maybe GHC.Types.Nat) (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3). ((yf Generic.Random.Internal.BaseCase.&&? yg) GHC.Types.~ 'GHC.Maybe.Nothing) => Generic.Random.Internal.BaseCase.GBCSProduct f g z e yf yg instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3) (m :: GHC.Types.Nat) (n :: GHC.Types.Nat). Generic.Random.Internal.BaseCase.GBCSProduct f g z e ('GHC.Maybe.Just m) ('GHC.Maybe.Just n) instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3) (m :: GHC.Types.Nat) (n :: GHC.Types.Nat). Generic.Random.Internal.BaseCase.GBCSSumCompare f g z e (GHC.TypeNats.CmpNat m n) => Generic.Random.Internal.BaseCase.GBCSSum f g z e ('GHC.Maybe.Just m) ('GHC.Maybe.Just n) instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3). Generic.Random.Internal.BaseCase.GBCSSumCompare f g z e 'GHC.Types.EQ instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3). Generic.Random.Internal.BaseCase.GBCSSumCompare f g z e 'GHC.Types.LT instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3). Generic.Random.Internal.BaseCase.GBCSSumCompare f g z e 'GHC.Types.GT instance forall k (y :: GHC.Maybe.Maybe GHC.Types.Nat) (f :: k -> *) (g :: k -> *) (z :: GHC.Types.Nat) e (yf :: GHC.Maybe.Maybe GHC.Types.Nat) (yg :: GHC.Maybe.Maybe GHC.Types.Nat). (GHC.Base.Alternative (Generic.Random.Internal.BaseCase.IfM y Generic.Random.Internal.Generic.Weighted Data.Proxy.Proxy), Generic.Random.Internal.BaseCase.GBCSSum f g z e yf yg, Generic.Random.Internal.BaseCase.GBCS f z yf e, Generic.Random.Internal.BaseCase.GBCS g z yg e, y GHC.Types.~ (yf Generic.Random.Internal.BaseCase.||? yg)) => Generic.Random.Internal.BaseCase.GBCS (f GHC.Generics.:+: g) z y e instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3). Generic.Random.Internal.BaseCase.GBCSSum f g z e 'GHC.Maybe.Nothing 'GHC.Maybe.Nothing instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3) (m :: GHC.Types.Nat). Generic.Random.Internal.BaseCase.GBCSSum f g z e ('GHC.Maybe.Just m) 'GHC.Maybe.Nothing instance forall k1 k2 k3 (f :: k1 -> *) (g :: k1 -> *) (z :: k2) (e :: k3) (n :: GHC.Types.Nat). Generic.Random.Internal.BaseCase.GBCSSum f g z e 'GHC.Maybe.Nothing ('GHC.Maybe.Just n) instance forall k (f :: k -> *) (z :: GHC.Types.Nat) (y :: GHC.Maybe.Maybe GHC.Types.Nat) e i (c :: GHC.Generics.Meta). Generic.Random.Internal.BaseCase.GBCS f z y e => Generic.Random.Internal.BaseCase.GBCS (GHC.Generics.M1 i c f) z y e instance (y GHC.Types.~ 'GHC.Maybe.Nothing) => Generic.Random.Internal.BaseCase.GBCS (GHC.Generics.K1 i c) 0 y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.GBCS GHC.Generics.U1 z y e instance forall k (f :: k -> *) e (y :: GHC.Maybe.Maybe GHC.Types.Nat) (z :: GHC.Types.Nat). ((TypeError ...), GHC.Base.Alternative (Generic.Random.Internal.BaseCase.IfM y Generic.Random.Internal.Generic.Weighted Data.Proxy.Proxy)) => Generic.Random.Internal.BaseCase.GBCS f z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Types.Char z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Types.Int z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Integer.Type.Integer z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Types.Float z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Types.Double z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Types.Word z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch () z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Types.Bool z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch [a] z y e instance (y GHC.Types.~ 'GHC.Maybe.Just 0) => Generic.Random.Internal.BaseCase.BaseCaseSearch GHC.Types.Ordering z y e instance (Generic.Random.Internal.BaseCase.BaseCaseSearch a z y a, Generic.Random.Internal.BaseCase.BaseCaseSearching_ a z y) => Generic.Random.Internal.BaseCase.BaseCaseSearching a z instance forall k t a (z :: k) (m :: t). Generic.Random.Internal.BaseCase.BaseCaseSearching_ a z ('GHC.Maybe.Just m) instance Generic.Random.Internal.BaseCase.BaseCaseSearching a (z GHC.TypeNats.+ 1) => Generic.Random.Internal.BaseCase.BaseCaseSearching_ a z 'GHC.Maybe.Nothing instance Generic.Random.Internal.BaseCase.BaseCaseSearching a 0 => Generic.Random.Internal.BaseCase.BaseCase a module Generic.Random.DerivingVia -- | 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. newtype GenericArbitrary weights a GenericArbitrary :: a -> GenericArbitrary weights a [unGenericArbitrary] :: GenericArbitrary weights a -> a -- | Pick every constructor with equal probability. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryU. newtype GenericArbitraryU a GenericArbitraryU :: a -> GenericArbitraryU a [unGenericArbitraryU] :: GenericArbitraryU a -> a -- | 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. newtype GenericArbitrarySingle a GenericArbitrarySingle :: a -> GenericArbitrarySingle a [unGenericArbitrarySingle] :: GenericArbitrarySingle a -> a -- | 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. newtype GenericArbitraryRec weights a GenericArbitraryRec :: a -> GenericArbitraryRec weights a [unGenericArbitraryRec] :: GenericArbitraryRec weights a -> a -- | 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. newtype GenericArbitraryG genList weights a GenericArbitraryG :: a -> GenericArbitraryG genList weights a [unGenericArbitraryG] :: GenericArbitraryG genList weights a -> a -- | GenericArbitraryU with explicit generators. See also -- GenericArbitraryG. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryUG. newtype GenericArbitraryUG genList a GenericArbitraryUG :: a -> GenericArbitraryUG genList a [unGenericArbitraryUG] :: GenericArbitraryUG genList a -> a -- | genericArbitrarySingle with explicit generators. See also -- GenericArbitraryG. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitrarySingleG. newtype GenericArbitrarySingleG genList a GenericArbitrarySingleG :: a -> GenericArbitrarySingleG genList a [unGenericArbitrarySingleG] :: GenericArbitrarySingleG genList a -> a -- | genericArbitraryRec with explicit generators. See also -- genericArbitraryG. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryRecG. newtype GenericArbitraryRecG genList weights a GenericArbitraryRecG :: a -> GenericArbitraryRecG genList weights a [unGenericArbitraryRecG] :: GenericArbitraryRecG genList weights a -> a -- | General generic generator with custom options. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryWith. newtype GenericArbitraryWith opts weights a GenericArbitraryWith :: a -> GenericArbitraryWith opts weights a [unGenericArbitraryWith] :: GenericArbitraryWith opts weights a -> a -- | 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
--   
newtype AndShrinking f a AndShrinking :: a -> AndShrinking f a class TypeLevelGenList a where { type family TypeLevelGenList' a :: Type; } toGenList :: TypeLevelGenList a => Proxy a -> TypeLevelGenList' a class TypeLevelOpts a where { type family TypeLevelOpts' a :: Type; } toOpts :: TypeLevelOpts a => Proxy a -> TypeLevelOpts' a instance forall k (weights :: k) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitrary weights a) instance forall k (weights :: k) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitrary weights a) instance GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitraryU a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitraryU a) instance GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitrarySingle a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitrarySingle a) instance forall k (weights :: k) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitraryRec weights a) instance forall k (weights :: k) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitraryRec weights a) instance forall k1 (genList :: k1) k2 (weights :: k2) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitraryG genList weights a) instance forall k1 (genList :: k1) k2 (weights :: k2) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitraryG genList weights a) instance forall k (genList :: k) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitraryUG genList a) instance forall k (genList :: k) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitraryUG genList a) instance forall k (genList :: k) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitrarySingleG genList a) instance forall k (genList :: k) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitrarySingleG genList a) instance forall k1 (genList :: k1) k2 (weights :: k2) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitraryRecG genList weights a) instance forall k1 (genList :: k1) k2 (weights :: k2) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitraryRecG genList weights a) instance forall k1 (opts :: k1) k2 (weights :: k2) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.GenericArbitraryWith opts weights a) instance forall k1 (opts :: k1) k2 (weights :: k2) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.GenericArbitraryWith opts weights a) instance forall k (f :: k) a. GHC.Show.Show a => GHC.Show.Show (Generic.Random.DerivingVia.AndShrinking f a) instance forall k (f :: k) a. GHC.Classes.Eq a => GHC.Classes.Eq (Generic.Random.DerivingVia.AndShrinking f a) instance forall k1 k2 opts a (weights :: k1) (opts' :: k2). (Generic.Random.Internal.Generic.GArbitrary opts a, Generic.Random.DerivingVia.TypeLevelWeights' weights a, Generic.Random.DerivingVia.TypeLevelOpts opts', opts GHC.Types.~ Generic.Random.DerivingVia.TypeLevelOpts' opts') => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitraryWith opts' weights a) instance forall k1 k2 genList a (weights :: k1) (genList' :: k2). (Generic.Random.Internal.Generic.GArbitrary (Generic.Random.Internal.Generic.SetGens genList Generic.Random.Internal.Generic.UnsizedOpts) a, Generic.Random.Internal.Generic.GUniformWeight a, Generic.Random.DerivingVia.TypeLevelWeights' weights a, Generic.Random.DerivingVia.TypeLevelGenList genList', genList GHC.Types.~ Generic.Random.DerivingVia.TypeLevelGenList' genList') => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitraryG genList' weights a) instance forall k genList a (genList' :: k). (Generic.Random.Internal.Generic.GArbitrary (Generic.Random.Internal.Generic.SetGens genList Generic.Random.Internal.Generic.UnsizedOpts) a, Generic.Random.Internal.Generic.GUniformWeight a, Generic.Random.DerivingVia.TypeLevelGenList genList', genList GHC.Types.~ Generic.Random.DerivingVia.TypeLevelGenList' genList') => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitraryUG genList' a) instance forall k genList a (c0 :: GHC.Types.Symbol) (genList' :: k). (Generic.Random.Internal.Generic.GArbitrary (Generic.Random.Internal.Generic.SetGens genList Generic.Random.Internal.Generic.UnsizedOpts) a, Generic.Random.Internal.Generic.Weights_ (GHC.Generics.Rep a) GHC.Types.~ Generic.Random.Internal.Generic.L c0, Generic.Random.DerivingVia.TypeLevelGenList genList', genList GHC.Types.~ Generic.Random.DerivingVia.TypeLevelGenList' genList') => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitrarySingleG genList' a) instance forall k1 k2 genList a (weights :: k1) (genList' :: k2). (Generic.Random.Internal.Generic.GArbitrary (Generic.Random.Internal.Generic.SetGens genList Generic.Random.Internal.Generic.SizedOpts) a, Generic.Random.DerivingVia.TypeLevelWeights' weights a, Generic.Random.DerivingVia.TypeLevelGenList genList', genList GHC.Types.~ Generic.Random.DerivingVia.TypeLevelGenList' genList') => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitraryRecG genList' weights a) instance Test.QuickCheck.Arbitrary.Arbitrary a => Generic.Random.DerivingVia.TypeLevelGenList (Test.QuickCheck.Gen.Gen a) instance (Generic.Random.DerivingVia.TypeLevelGenList a, Generic.Random.DerivingVia.TypeLevelGenList b) => Generic.Random.DerivingVia.TypeLevelGenList (a Generic.Random.Internal.Generic.:+ b) instance forall k a (weights :: k). (Generic.Random.Internal.Generic.GArbitrary Generic.Random.Internal.Generic.UnsizedOpts a, Generic.Random.DerivingVia.TypeLevelWeights' weights a) => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitrary weights a) instance forall k a (weights :: k). (Generic.Random.Internal.Generic.GArbitrary Generic.Random.Internal.Generic.SizedOptsDef a, Generic.Random.DerivingVia.TypeLevelWeights' weights a) => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitraryRec weights a) instance (GHC.TypeNats.KnownNat weight, Generic.Random.DerivingVia.TypeLevelWeights weights a) => Generic.Random.DerivingVia.TypeLevelWeights (weight : weights) (Generic.Random.Internal.Generic.L x Generic.Random.Internal.Generic.:| a) instance GHC.TypeNats.KnownNat weight => Generic.Random.DerivingVia.TypeLevelWeights '[weight] (Generic.Random.Internal.Generic.L x) instance forall a (w :: a) (ws :: [a]) t u v. Generic.Random.DerivingVia.TypeLevelWeights (w : ws) (t Generic.Random.Internal.Generic.:| (u Generic.Random.Internal.Generic.:| v)) => Generic.Random.DerivingVia.TypeLevelWeights (w : ws) ((t Generic.Random.Internal.Generic.:| u) Generic.Random.Internal.Generic.:| v) instance Generic.Random.DerivingVia.TypeLevelWeights '[] () instance (Test.QuickCheck.Arbitrary.Arbitrary (f a), GHC.Types.Coercible (f a) a, GHC.Generics.Generic a, Test.QuickCheck.Arbitrary.RecursivelyShrink (GHC.Generics.Rep a), Test.QuickCheck.Arbitrary.GSubterms (GHC.Generics.Rep a) a) => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.AndShrinking f a) instance (Generic.Random.Internal.Generic.GArbitrary Generic.Random.Internal.Generic.UnsizedOpts a, Generic.Random.Internal.Generic.Weights_ (GHC.Generics.Rep a) GHC.Types.~ Generic.Random.Internal.Generic.L c0) => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitrarySingle a) instance (Generic.Random.Internal.Generic.GArbitrary Generic.Random.Internal.Generic.UnsizedOpts a, Generic.Random.Internal.Generic.GUniformWeight a) => Test.QuickCheck.Arbitrary.Arbitrary (Generic.Random.DerivingVia.GenericArbitraryU a) -- | 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: -- -- module Generic.Random -- | 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. genericArbitrary :: GArbitrary UnsizedOpts a => Weights a -> Gen a -- | Pick every constructor with equal probability. Equivalent to -- genericArbitrary uniform. -- --
--   genericArbitraryU :: Gen a
--   
genericArbitraryU :: (GArbitrary UnsizedOpts a, GUniformWeight a) => Gen a -- | arbitrary for types with one constructor. Equivalent to -- genericArbitraryU, with a stricter type. -- --
--   genericArbitrarySingle :: Gen a
--   
genericArbitrarySingle :: (GArbitrary UnsizedOpts a, Weights_ (Rep a) ~ L c0) => 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). genericArbitraryRec :: GArbitrary SizedOptsDef a => Weights a -> 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). genericArbitrary' :: (GArbitrary SizedOptsDef a, BaseCase a) => Weights a -> Gen a -- | 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). genericArbitraryU' :: (GArbitrary SizedOptsDef a, BaseCase a, GUniformWeight a) => 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. genericArbitraryG :: GArbitrary (SetGens genList UnsizedOpts) a => genList -> Weights a -> Gen a -- | genericArbitraryU with explicit generators. See also -- genericArbitraryG. genericArbitraryUG :: (GArbitrary (SetGens genList UnsizedOpts) a, GUniformWeight a) => genList -> Gen a -- | genericArbitrarySingle with explicit generators. See also -- genericArbitraryG. genericArbitrarySingleG :: (GArbitrary (SetGens genList UnsizedOpts) a, Weights_ (Rep a) ~ L c0) => genList -> Gen a -- | genericArbitraryRec with explicit generators. See also -- genericArbitraryG. genericArbitraryRecG :: GArbitrary (SetGens genList SizedOpts) a => genList -> Weights a -> Gen 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). data Weights a -- | Type of a single weight, tagged with the name of the associated -- constructor for additional compile-time checking. -- --
--   ((9 :: W "Leaf") % (8 :: W "Node") % ())
--   
data W (c :: Symbol) -- | A binary constructor for building up trees of weights. (%) :: (WeightBuilder' w, c ~ First' w) => W c -> Prec' w -> w infixr 1 % -- | Uniform distribution. uniform :: UniformWeight_ (Rep a) => Weights a -- | Heterogeneous list of generators. data a :+ b (:+) :: a -> b -> (:+) a b infixr 1 :+ infixr 1 :+ -- | 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. newtype FieldGen (s :: Symbol) a FieldGen :: Gen a -> FieldGen (s :: Symbol) a [unFieldGen] :: FieldGen (s :: Symbol) a -> Gen a -- | FieldGen constructor with the field name given via a proxy. fieldGen :: proxy s -> Gen a -> FieldGen s a -- | Custom generator for the i-th field of the constructor named -- c. Fields are 0-indexed. newtype ConstrGen (c :: Symbol) (i :: Nat) a ConstrGen :: Gen a -> ConstrGen (c :: Symbol) (i :: Nat) a [unConstrGen] :: ConstrGen (c :: Symbol) (i :: Nat) a -> Gen a -- | ConstrGen constructor with the constructor name given via a -- proxy. constrGen :: proxy '(c, i) -> Gen a -> ConstrGen c i a -- | 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. newtype Gen1 f Gen1 :: (forall a. Gen a -> Gen (f a)) -> Gen1 f [unGen1] :: Gen1 f -> forall a. Gen a -> Gen (f a) -- | 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. newtype Gen1_ f Gen1_ :: (forall a. Gen (f a)) -> Gen1_ f [unGen1_] :: Gen1_ f -> forall a. Gen (f a) -- | 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). listOf' :: Gen a -> Gen [a] -- | 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). listOf1' :: Gen a -> Gen [a] -- | An alternative to vectorOf that divides the size parameter by -- the length of the list. vectorOf' :: Int -> Gen a -> Gen [a] -- | Run the first generator if the size is positive. Run the second if the -- size is zero. -- --
--   defaultGen `withBaseCase` baseCaseGen
--   
withBaseCase :: Gen a -> Gen a -> Gen a -- | Custom instances can override the default behavior. class BaseCase a -- | Generator of base cases. baseCase :: BaseCase a => Gen a -- | 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 (<+)). data Options (c :: Coherence) (s :: Sizing) (genList :: Type) -- | General generic generator with custom options. genericArbitraryWith :: GArbitrary opts a => opts -> Weights a -> Gen a -- | Setter for Options. -- -- This subsumes the other setters: SetSized, SetUnsized, -- SetGens. type family SetOptions (x :: k) (o :: Type) :: Type -- | Infix flipped synonym for Options. type (<+) o x = SetOptions x o infixl 1 <+ -- | Coerce an Options value between types with the same -- representation. setOpts :: forall x o. Coercible o (SetOptions x o) => o -> SetOptions x o -- | 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. data Sizing -- | Decrease the size parameter when running generators for fields Sized :: Sizing -- | Don't touch the size parameter Unsized :: Sizing type family SetSized (o :: Type) :: Type type family SetUnsized (o :: Type) :: Type setSized :: Options c s g -> Options c 'Sized g setUnsized :: Options c s g -> Options c 'Unsized g type family SetGens (g :: Type) opts -- | 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. setGenerators :: genList -> Options c s g0 -> Options c s genList -- | 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.) data Coherence -- | Match custom generators incoherently. INCOHERENT :: Coherence -- | Match custom generators coherently by default (can be manually -- bypassed with Incoherent). COHERENT :: Coherence -- | Match this generator incoherently when the COHERENT option is -- set. newtype Incoherent g Incoherent :: g -> Incoherent g type SizedOpts = Options 'INCOHERENT 'Sized () -- | Default options for sized generators. sizedOpts :: SizedOpts type SizedOptsDef = Options 'INCOHERENT 'Sized (Gen1 [] :+ ()) -- | Default options overriding the list generator using listOf'. sizedOptsDef :: SizedOptsDef type UnsizedOpts = Options 'INCOHERENT 'Unsized () -- | Default options for unsized generators. unsizedOpts :: UnsizedOpts -- | Like UnsizedOpts, but using coherent instances by default. type CohUnsizedOpts = Options 'COHERENT 'Unsized () -- | Like unsizedOpts, but using coherent instances by default. cohUnsizedOpts :: CohUnsizedOpts -- | Like SizedOpts, but using coherent instances by default. type CohSizedOpts = Options 'COHERENT 'Sized () -- | Like sizedOpts but using coherent instances by default. cohSizedOpts :: CohSizedOpts -- | Generic Arbitrary class (Generic a, GA opts (Rep a)) => GArbitrary opts a -- | Derived uniform distribution of constructors for a. class UniformWeight_ (Rep a) => GUniformWeight a -- | 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. newtype GenericArbitrary weights a GenericArbitrary :: a -> GenericArbitrary weights a [unGenericArbitrary] :: GenericArbitrary weights a -> a -- | Pick every constructor with equal probability. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryU. newtype GenericArbitraryU a GenericArbitraryU :: a -> GenericArbitraryU a [unGenericArbitraryU] :: GenericArbitraryU a -> a -- | 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. newtype GenericArbitrarySingle a GenericArbitrarySingle :: a -> GenericArbitrarySingle a [unGenericArbitrarySingle] :: GenericArbitrarySingle a -> a -- | 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. newtype GenericArbitraryRec weights a GenericArbitraryRec :: a -> GenericArbitraryRec weights a [unGenericArbitraryRec] :: GenericArbitraryRec weights a -> a -- | 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. newtype GenericArbitraryG genList weights a GenericArbitraryG :: a -> GenericArbitraryG genList weights a [unGenericArbitraryG] :: GenericArbitraryG genList weights a -> a -- | GenericArbitraryU with explicit generators. See also -- GenericArbitraryG. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryUG. newtype GenericArbitraryUG genList a GenericArbitraryUG :: a -> GenericArbitraryUG genList a [unGenericArbitraryUG] :: GenericArbitraryUG genList a -> a -- | genericArbitrarySingle with explicit generators. See also -- GenericArbitraryG. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitrarySingleG. newtype GenericArbitrarySingleG genList a GenericArbitrarySingleG :: a -> GenericArbitrarySingleG genList a [unGenericArbitrarySingleG] :: GenericArbitrarySingleG genList a -> a -- | genericArbitraryRec with explicit generators. See also -- genericArbitraryG. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryRecG. newtype GenericArbitraryRecG genList weights a GenericArbitraryRecG :: a -> GenericArbitraryRecG genList weights a [unGenericArbitraryRecG] :: GenericArbitraryRecG genList weights a -> a -- | General generic generator with custom options. -- -- This newtype does no shrinking. To add generic shrinking, use -- AndShrinking. -- -- Uses genericArbitraryWith. newtype GenericArbitraryWith opts weights a GenericArbitraryWith :: a -> GenericArbitraryWith opts weights a [unGenericArbitraryWith] :: GenericArbitraryWith opts weights a -> a -- | 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
--   
newtype AndShrinking f a AndShrinking :: a -> AndShrinking f a class TypeLevelGenList a where { type family TypeLevelGenList' a :: Type; } toGenList :: TypeLevelGenList a => Proxy a -> TypeLevelGenList' a class TypeLevelOpts a where { type family TypeLevelOpts' a :: Type; } toOpts :: TypeLevelOpts a => Proxy a -> TypeLevelOpts' a -- | Generic implementations of QuickCheck's arbitrary. -- --

Example

-- -- Define your type. -- --
--   data Tree a = Leaf a | Node (Tree a) (Tree a)
--     deriving Generic
--   
-- -- Pick an arbitrary implementation, specifying the required -- distribution of data constructors. -- --
--   instance Arbitrary a => Arbitrary (Tree a) where
--     arbitrary = genericArbitrary (9 % 8 % ())
--   
-- -- That random generator arbitrary :: Gen (Tree a) picks -- a Leaf with probability 9/17, or a Node with -- probability 8/17, and recursively fills their fields with -- arbitrary. -- -- For Tree, the generic implementation genericArbitrary -- is equivalent to the following: -- --
--   genericArbitrary :: Arbitrary a => Weights (Tree a) -> Gen (Tree a)
--   genericArbitrary (x % y % ()) =
--     frequency
--       [ (x, Leaf <$> arbitrary)
--       , (y, Node <$> arbitrary <*> arbitrary)
--       ]
--   
-- --

Distribution of constructors

-- -- The distribution of constructors can be specified as a special list of -- weights in the same order as the data type definition. This -- assigns to each constructor a probability p_C proportional to -- its weight weight_C; in other words, p_C = weight_C / -- sumOfWeights. -- -- The list of weights is built up with the (%) operator -- as a cons, and using the unit () as the empty list, in the -- order corresponding to the data type definition. -- --

Uniform distribution

-- -- You can specify the uniform distribution (all weights equal to 1) with -- uniform. (genericArbitraryU is available as a shorthand -- for genericArbitrary uniform.) -- -- Note that for many recursive types, a uniform distribution tends to -- produce big or even infinite values. -- --

Typed weights

-- -- The weights actually have type W "ConstructorName" -- (just a newtype around Int), so that you can annotate a weight -- with its corresponding constructor. The constructors must appear in -- the same order as in the original type definition. -- -- This will type-check: -- --
--   ((x :: W "Leaf") % (y :: W "Node") % ()) :: Weights (Tree a)
--   ( x              % (y :: W "Node") % ()) :: Weights (Tree a)
--   
-- -- This will not: -- --
--   ((x :: W "Node") % y % ()) :: Weights (Tree a)
--   -- Requires an order of constructors different from the definition of the Tree type.
--   
--   ( x              % y % z % ()) :: Weights (Tree a)
--   -- Doesn't have the right number of weights.
--   
-- --

Ensuring termination

-- -- As mentioned earlier, one must be careful with recursive types to -- avoid producing extremely large values. The alternative generator -- genericArbitraryRec decreases the size parameter at every call -- to keep values at reasonable sizes. It is to be used together with -- withBaseCase. -- -- For example, we may provide a base case consisting of only -- Leaf: -- --
--   instance Arbitrary a => Arbitrary (Tree a) where
--     arbitrary = genericArbitraryRec (1 % 2 % ())
--       `withBaseCase` (Leaf <$> arbitrary)
--   
-- -- That is equivalent to the following definition. Note the resize -- modifier. -- --
--   arbitrary :: Arbitrary a => Gen (Tree a)
--   arbitrary = sized $ \n ->
--     -- "if" condition from withBaseCase
--     if n == 0 then
--       Leaf <$> arbitrary
--     else
--       -- genericArbitraryRec
--       frequency
--         [ (1, resize (max 0 (n - 1)) (Leaf <$> arbitrary))
--         , (2, resize (n `div` 2)     (Node <$> arbitrary <*> arbitrary))
--         ]
--   
-- -- The resizing strategy is as follows: the size parameter of Gen -- is divided among the fields of the chosen constructor, or decreases by -- one if the constructor is unary. withBaseCase defG -- baseG is equal to defG as long as the size parameter is -- nonzero, and it becomes baseG once the size reaches zero. -- This combination generally ensures that the number of constructors -- remains bounded by the initial size parameter passed to Gen. -- --

Automatic base case discovery

-- -- In some situations, generic-random can also construct base cases -- automatically. This works best with fully concrete types (no type -- parameters). -- --
--   {-# LANGUAGE FlexibleInstances #-}
--   
--   instance Arbitrary (Tree ()) where
--     arbitrary = genericArbitrary' (1 % 2 % ())
--   
-- -- The above instance will infer the value Leaf () as a base -- case. -- -- To discover values of type Tree a, we must inspect the type -- argument a, thus we incur some extra constraints if we want -- polymorphism. It is preferrable to apply the type class -- BaseCase to the instance head (Tree a) as follows, as -- it doesn't reduce to something worth seeing. -- --
--   {-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
--   
--   instance (Arbitrary a, BaseCase (Tree a))
--     => Arbitrary (Tree a) where
--     arbitrary = genericArbitrary' (1 % 2 % ())
--   
-- -- The BaseCase type class finds values of minimal depth, where -- the depth of a constructor is defined as 1 + max(0, depths of -- fields), e.g., Leaf () has depth 2. -- --

Note about lists

-- -- The Arbitrary instance for lists can be problematic for this -- way of implementing recursive sized generators, because they make a -- lot of recursive calls to arbitrary without decreasing the size -- parameter. Hence, as a default, genericArbitraryRec also -- detects fields which are lists to replace arbitrary with a -- different generator that divides the size parameter by the length of -- the list before generating each element. This uses the customizable -- mechanism shown in the next section. -- -- If you really want to use arbitrary for lists in the derived -- instances, substitute genericArbitraryRec with -- genericArbitraryRecG (). -- --
--   arbitrary = genericArbitraryRecG ()
--     `withBaseCase` baseGen
--   
-- -- Some combinators are available for further tweaking: listOf', -- listOf1', vectorOf'. -- --

Custom generators for some fields

-- --

Example 1 (Gen, FieldGen)

-- -- Sometimes, a few fields may need custom generators instead of -- arbitrary. For example, imagine here that String is -- meant to represent alphanumerical strings only, and that IDs are meant -- to be nonnegative, whereas balances can have any sign. -- --
--   data User = User {
--     userName :: String,
--     userId :: Int,
--     userBalance :: Int
--     } deriving Generic
--   
-- -- A naive approach has the following problems: -- -- -- -- Using generic-random, we can declare a (heterogeneous) list of -- generators to be used instead of arbitrary when generating -- certain fields. -- --
--   customGens :: FieldGen "userId" Int :+ Gen String
--   customGens =
--     FieldGen (getNonNegative <$> arbitrary) :+
--     listOf (elements (filter isAlphaNum [minBound .. maxBound]))
--   
-- -- Now we use the genericArbitraryG combinator and other -- G-suffixed variants that accept those explicit generators. -- -- -- --
--   instance Arbitrary User where
--     arbitrary = genericArbitrarySingleG customGens
--   
-- --

Example 2 (ConstrGen)

-- -- Here's the Tree type from the beginning again. -- --
--   data Tree a = Leaf a | Node (Tree a) (Tree a)
--     deriving Generic
--   
-- -- We will generate "right-leaning linear trees", which look like this: -- --
--   Node (Leaf 1)
--        (Node (Leaf 2)
--              (Node (Leaf 3)
--                    (Node (Leaf 4)
--                          (Leaf 5))))
--   
-- -- To do so, we force every left child of a Node to be a -- Leaf: -- --
--   {-# LANGUAGE ScopedTypeVariables #-}
--   
--   instance Arbitrary a => Arbitrary (Tree a) where
--     arbitrary = genericArbitraryUG customGens
--       where
--         -- Generator for the left field (i.e., at index 0) of constructor Node,
--         -- which must have type (Tree a).
--         customGens :: ConstrGen "Node" 0 (Tree a)
--         customGens =  ConstrGen (Leaf <$> arbitrary)
--   
-- -- That instance is equivalent to the following: -- --
--   instance Arbitrary a => Arbitrary (Tree a) where
--     arbitrary = oneof
--       [ Leaf <$> arbitrary
--       , Node <$> (Leaf <$> arbitrary) <*> arbitrary
--       --                                  ^ recursive call
--       ]
--   
-- --

Custom generators reference

-- -- The custom generator modifiers that can occur in the list are: -- -- -- -- Suggestions to add more modifiers or otherwise improve this tutorial -- are welcome! The issue tracker is this way. module Generic.Random.Tutorial