-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Generic implementation for QuickCheck's Arbitrary -- -- Generic implementations of methods of the Arbitrary class from -- the QuickCheck library. The approach taken here can lead to diverging -- instances for mutually recursive types but is safe for simply -- recursive ones and guarantees flat distribution for constructors of -- sum-types. @package generic-arbitrary @version 1.0.0 -- | This module is a generic implementation of the arbitrary -- method. Example usage: -- --
--   data Foo = Foo
--     { _fooX :: X
--     , _fooY :: Y
--     } deriving (Generic)
--   
--   instance Arbitrary Foo where
--     arbitrary = genericArbitrary
--     shrink = genericShrink
--   
-- -- This instance can also be derived using DerivingVia language extension -- --
--   data Foo = Foo
--     { _fooX :: X
--     , _fooY :: Y
--     } deriving (Generic)
--       deriving (Arbitrary) via GenericArbitrary Foo
--   
-- -- The generated arbitrary method is equivalent to -- --
--   Foo <$> arbitrary <*> arbitrary
--   
-- -- . -- -- It can also handle a recursive types problem. Assuming a type -- --
--   data R = R R
--     deriving Generic
--   
-- -- there is no instance -- --
--   instance Arbitrary R where
--     arbitrary = genericArbitrary
--     shrink = genericShrink
--   
-- -- If you try to compile this you will get a type level error -- --
--   • R refers to itself in all constructors
--   
-- -- Which means that there is no finite term for R because it is -- recursive. But, if you correct the definition of R like this. -- --
--   data R = R R | F
--     deriving Generic
--   
-- -- Then it will compile. And the arbitrary generated will not -- hang forever, because it respects the size parameter. -- -- There is a limitation of recursion detection: -- --
--   data R1 = R1 R2
--     deriving (Eq, Ord, Show, Generic)
--     deriving anyclass NFData
--     deriving Arbitrary via (GenericArbitrary R1)
--   
--   data R2 = R2 R1
--     deriving (Eq, Ord, Show, Generic)
--     deriving anyclass NFData
--     deriving Arbitrary via (GenericArbitrary R2)
--   
-- -- This code will compile and the arbitrary generated will -- always hang. Yes, there is a problem with mutually recursive types. -- -- Now lets see an example of datatype with parameters -- --
--   data A a = A a
--     deriving (Eq, Ord, Show)
--     deriving anyclass NFData
--     deriving (Generic)
--   
--   instance (Arbitrary a) => Arbitrary (A a) where
--     arbitrary = genericArbitrary
--     shrink = genericShrink
--   
-- -- It should work from first glance, but when compile it will throw an -- error: -- --
--   • Could not deduce (Test.QuickCheck.Arbitrary.Generic.GArbitrary
--                         (A a)
--                         (GHC.Generics.D1
--                            ('GHC.Generics.MetaData A ParametersTest "main" 'False)
--                            (GHC.Generics.C1
--                               ('GHC.Generics.MetaCons A 'GHC.Generics.PrefixI 'False)
--                               (GHC.Generics.S1
--                                  ('GHC.Generics.MetaSel
--                                     'Nothing
--                                     'GHC.Generics.NoSourceUnpackedness
--                                     'GHC.Generics.NoSourceStrictness
--                                     'GHC.Generics.DecidedLazy)
--                                  (GHC.Generics.Rec0 a))))
--                         (TypesDiffer (A a) a))
--       arising from a use of ‘genericArbitrary’
--   
-- -- Here the TypesDiffer is a type familty dealing with recursive -- types and helping us to eliminate inproper instances. To convince the -- compiller, that the a parameter is not an A a we -- must fix the instance with additional constraint -- --
--   instance (Arg (A a) a, Arbitrary a) => Arbitrary (A a) where
--     arbitrary = genericArbitrary
--     shrink = genericShrink
--   
-- -- Now everything compiles and works as expected. module Test.QuickCheck.Arbitrary.Generic genericArbitrary :: forall a ga some. (Generic a, GArbitrary a ga some, ga ~ Rep a) => Gen a -- | Newtype for DerivingVia -- -- Usage: -- --
--   data Foo = Foo
--     { _fooX :: X
--     , _fooY :: Y
--     } deriving (Generic)
--       deriving (Arbitrary) via GenericArbitrary Foo
--   
newtype GenericArbitrary a GenericArbitrary :: a -> GenericArbitrary a [unGenericArbitrary] :: GenericArbitrary a -> a -- | Constraint helper for types with parameters -- -- Usage: -- --
--   data A a = A a
--     deriving (Generic)
--   instance (Arg (A a) a, Arbitrary a) => Arbitrary (A a) where
--     arbitrary = genericArbitrary
--     shrink = genericShrink
--   
type Arg self field = (TypesDiffer self field ~ 'True) -- | Generic arbitrary. -- -- Parameters are: * self: the ADT we generating instance for * a: some -- part of the `Rep self` * finite: Is a finite? Infinite type -- has no finite values (like Stream) class (Finite self a ~ finite) => GArbitrary self a (finite :: Bool) class (Finite self a ~ af, Finite self b ~ bf) => FiniteSum self (a :: * -> *) (b :: * -> *) af bf class FiniteSumElem self a type family Finite self (a :: * -> *) :: Bool type family AllFieldsFinal self (a :: * -> *) :: Bool type family TypesDiffer a b type family ArgumentsCount (a :: * -> *) :: Nat -- | Calculates count of constructors encoded by particular :+:. -- Internal use only. type family SumLen a :: Nat -- | Random generation and shrinking of values. -- -- QuickCheck provides Arbitrary instances for most types in -- base, except those which incur extra dependencies. For a -- wider range of Arbitrary instances see the -- quickcheck-instances package. class Arbitrary a -- | A generator for values of the given type. -- -- It is worth spending time thinking about what sort of test data you -- want - good generators are often the difference between finding bugs -- and not finding them. You can use sample, label and -- classify to check the quality of your test data. -- -- There is no generic arbitrary implementation included because -- we don't know how to make a high-quality one. If you want one, -- consider using the testing-feat or generic-random -- packages. -- -- The QuickCheck manual goes into detail on how to write good -- generators. Make sure to look at it, especially if your type is -- recursive! arbitrary :: Arbitrary a => Gen a -- | Produces a (possibly) empty list of all the possible immediate shrinks -- of the given value. -- -- The default implementation returns the empty list, so will not try to -- shrink the value. If your data type has no special invariants, you can -- enable shrinking by defining shrink = genericShrink, -- but by customising the behaviour of shrink you can often get -- simpler counterexamples. -- -- Most implementations of shrink should try at least three -- things: -- --
    --
  1. Shrink a term to any of its immediate subterms. You can use -- subterms to do this.
  2. --
  3. Recursively apply shrink to all immediate subterms. You can -- use recursivelyShrink to do this.
  4. --
  5. Type-specific shrinkings such as replacing a constructor by a -- simpler constructor.
  6. --
-- -- For example, suppose we have the following implementation of binary -- trees: -- --
--   data Tree a = Nil | Branch a (Tree a) (Tree a)
--   
-- -- We can then define shrink as follows: -- --
--   shrink Nil = []
--   shrink (Branch x l r) =
--     -- shrink Branch to Nil
--     [Nil] ++
--     -- shrink to subterms
--     [l, r] ++
--     -- recursively shrink subterms
--     [Branch x' l' r' | (x', l', r') <- shrink (x, l, r)]
--   
-- -- There are a couple of subtleties here: -- -- -- -- There is a fair bit of boilerplate in the code above. We can avoid it -- with the help of some generic functions. The function -- genericShrink tries shrinking a term to all of its subterms -- and, failing that, recursively shrinks the subterms. Using it, we can -- define shrink as: -- --
--   shrink x = shrinkToNil x ++ genericShrink x
--     where
--       shrinkToNil Nil = []
--       shrinkToNil (Branch _ l r) = [Nil]
--   
-- -- genericShrink is a combination of subterms, which -- shrinks a term to any of its subterms, and recursivelyShrink, -- which shrinks all subterms of a term. These may be useful if you need -- a bit more control over shrinking than genericShrink gives you. -- -- A final gotcha: we cannot define shrink as simply -- shrink x = Nil:genericShrink x as this shrinks -- Nil to Nil, and shrinking will go into an infinite -- loop. -- -- If all this leaves you bewildered, you might try shrink = -- genericShrink to begin with, after deriving -- Generic for your type. However, if your data type has any -- special invariants, you will need to check that genericShrink -- can't break those invariants. shrink :: Arbitrary a => a -> [a] -- | Shrink a term to any of its immediate subterms, and also recursively -- shrink all subterms. genericShrink :: (Generic a, RecursivelyShrink (Rep a), GSubterms (Rep a) a) => a -> [a] instance GHC.Classes.Eq a => GHC.Classes.Eq (Test.QuickCheck.Arbitrary.Generic.GenericArbitrary a) instance GHC.Show.Show a => GHC.Show.Show (Test.QuickCheck.Arbitrary.Generic.GenericArbitrary a) instance (Test.QuickCheck.Arbitrary.Generic.FiniteSumElem self a, Test.QuickCheck.Arbitrary.Generic.FiniteSumElem self b, Test.QuickCheck.Arbitrary.Generic.Finite self a GHC.Types.~ 'GHC.Types.True, Test.QuickCheck.Arbitrary.Generic.Finite self b GHC.Types.~ 'GHC.Types.True) => Test.QuickCheck.Arbitrary.Generic.FiniteSum self a b 'GHC.Types.True 'GHC.Types.True instance (Test.QuickCheck.Arbitrary.Generic.FiniteSumElem self a, Test.QuickCheck.Arbitrary.Generic.Finite self a GHC.Types.~ 'GHC.Types.True, Test.QuickCheck.Arbitrary.Generic.Finite self b GHC.Types.~ 'GHC.Types.False) => Test.QuickCheck.Arbitrary.Generic.FiniteSum self a b 'GHC.Types.True 'GHC.Types.False instance (Test.QuickCheck.Arbitrary.Generic.FiniteSumElem self b, Test.QuickCheck.Arbitrary.Generic.Finite self a GHC.Types.~ 'GHC.Types.False, Test.QuickCheck.Arbitrary.Generic.Finite self b GHC.Types.~ 'GHC.Types.True) => Test.QuickCheck.Arbitrary.Generic.FiniteSum self a b 'GHC.Types.False 'GHC.Types.True instance Test.QuickCheck.Arbitrary.Generic.FiniteSum self a b af bf => Test.QuickCheck.Arbitrary.Generic.FiniteSumElem self (a GHC.Generics.:+: b) instance Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.C c f) 'GHC.Types.True => Test.QuickCheck.Arbitrary.Generic.FiniteSumElem self (GHC.Generics.M1 GHC.Generics.C c f) instance (Test.QuickCheck.Arbitrary.Generic.FiniteSum self a b af bf, Test.QuickCheck.Arbitrary.Generic.GArbitrary self (a GHC.Generics.:+: b) 'GHC.Types.True) => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.D t (a GHC.Generics.:+: b)) 'GHC.Types.True instance (GHC.Generics.Generic a, Test.QuickCheck.Arbitrary.Generic.GArbitrary a (GHC.Generics.Rep a) some, Test.QuickCheck.Arbitrary.RecursivelyShrink (GHC.Generics.Rep a), Test.QuickCheck.Arbitrary.GSubterms (GHC.Generics.Rep a) a) => Test.QuickCheck.Arbitrary.Arbitrary (Test.QuickCheck.Arbitrary.Generic.GenericArbitrary a) instance Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.C c f) 'GHC.Types.True => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.D t (GHC.Generics.M1 GHC.Generics.C c f)) 'GHC.Types.True instance (Test.QuickCheck.Arbitrary.Generic.GArbitrary self f some, GHC.TypeNats.KnownNat (Test.QuickCheck.Arbitrary.Generic.ArgumentsCount f), Test.QuickCheck.Arbitrary.Generic.AllFieldsFinal self f GHC.Types.~ some) => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.C c f) some instance Test.QuickCheck.Arbitrary.Generic.GArbitrary self GHC.Generics.U1 'GHC.Types.True instance Test.QuickCheck.Arbitrary.Generic.GArbitrary self f some => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.S t f) some instance (Test.QuickCheck.Arbitrary.Arbitrary t, Test.QuickCheck.Arbitrary.Generic.Finite self (GHC.Generics.K1 GHC.Generics.R t) GHC.Types.~ some) => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.K1 GHC.Generics.R t) some instance (Test.QuickCheck.Arbitrary.Generic.GArbitrary self a af, Test.QuickCheck.Arbitrary.Generic.GArbitrary self b bf, (af Data.Type.Bool.&& bf) GHC.Types.~ some) => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (a GHC.Generics.:*: b) some instance ((TypeError ...), Test.QuickCheck.Arbitrary.Generic.AllFieldsFinal self f GHC.Types.~ 'GHC.Types.False) => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.D t (GHC.Generics.M1 GHC.Generics.C c f)) 'GHC.Types.False instance (Test.QuickCheck.Arbitrary.Generic.GArbitrary self a af, Test.QuickCheck.Arbitrary.Generic.GArbitrary self b bf, GHC.TypeNats.KnownNat (Test.QuickCheck.Arbitrary.Generic.SumLen a), GHC.TypeNats.KnownNat (Test.QuickCheck.Arbitrary.Generic.SumLen b), (af Data.Type.Bool.|| bf) GHC.Types.~ some) => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (a GHC.Generics.:+: b) some instance ((TypeError ...), (Test.QuickCheck.Arbitrary.Generic.Finite self a Data.Type.Bool.|| Test.QuickCheck.Arbitrary.Generic.Finite self b) GHC.Types.~ 'GHC.Types.False) => Test.QuickCheck.Arbitrary.Generic.GArbitrary self (GHC.Generics.M1 GHC.Generics.D t (a GHC.Generics.:+: b)) 'GHC.Types.False