content: -- | "GHC.Generics"-based 'Test.QuickCheck.arbitrary' generators.
  --
  -- = Basic usage
  --
  -- @
  -- {-\# LANGUAGE DeriveGeneric \#-}
  --
  -- data Foo = A | B | C  -- some generic data type
  --   deriving 'GHC.Generics.Generic'
  -- @
  --
  -- Derive instances of 'Test.QuickCheck.Arbitrary'.
  --
  -- @
  -- instance Arbitrary Foo where
  --   arbitrary = 'genericArbitrary' 'uniform'  -- Give a distribution of constructors.
  --   shrink = 'Test.QuickCheck.genericShrink'  -- Generic shrinking is provided by the QuickCheck library.
  -- @
  --
  -- Or derive standalone generators (the fields must still be instances of
  -- 'Test.QuickCheck.Arbitrary', or use custom generators).
  --
  -- @
  -- genFoo :: Gen Foo
  -- genFoo = 'genericArbitrary' 'uniform'
  -- @
  --
  -- === Using @DerivingVia@
  --
  -- @
  -- {-\# LANGUAGE DerivingVia, TypeOperators \#-}
  --
  -- data Foo = A | B | C
  --   deriving 'GHC.Generics.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
  
  {-# LANGUAGE ExplicitNamespaces #-}
  
  module Generic.Random
    (
      -- * 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
    , genericArbitraryU
    , genericArbitrarySingle
    , genericArbitraryRec
    , genericArbitrary'
    , genericArbitraryU'
  
      -- ** With custom generators
  
      -- |
      -- === Note about incoherence
      --
      -- The custom generator feature relies on incoherent instances, which can
      -- lead to surprising behaviors for parameterized types.
      --
      -- ==== __Example__
      --
      -- 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
    , genericArbitraryUG
    , genericArbitrarySingleG
    , genericArbitraryRecG
  
      -- * Specifying finite distributions
    , Weights
    , W
    , (%)
    , uniform
  
      -- * 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 'Test.QuickCheck.Gen', providing
      -- more ways to select the fields the generator than by simply comparing types:
      --
      -- - @'Test.QuickCheck.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.
    , (:+) (..)
    , FieldGen (..)
    , fieldGen
    , ConstrGen (..)
    , constrGen
    , Gen1 (..)
    , Gen1_ (..)
  
      -- * Helpful combinators
    , listOf'
    , listOf1'
    , vectorOf'
  
      -- * Base cases for recursive types
    , withBaseCase
    , BaseCase (..)
  
      -- * Full options
    , Options ()
    , genericArbitraryWith
  
      -- ** Setters
    , SetOptions
    , type (<+)
    , setOpts
  
      -- ** Size modifiers
    , Sizing (..)
    , SetSized
    , SetUnsized
    , setSized
    , setUnsized
  
      -- ** Custom generators
    , SetGens
    , setGenerators
  
      -- ** Coherence options
    , Coherence (..)
    , Incoherent (..)
  
      -- ** Common options
    , SizedOpts
    , sizedOpts
    , SizedOptsDef
    , sizedOptsDef
    , UnsizedOpts
    , unsizedOpts
  
      -- *** Advanced options
      -- | See 'Coherence'
    , CohUnsizedOpts
    , cohUnsizedOpts
    , CohSizedOpts
    , cohSizedOpts
  
      -- * Generic classes
    , GArbitrary
    , GUniformWeight
  
    -- * Newtypes for DerivingVia
  
    -- | These newtypes correspond to the variants of 'genericArbitrary' above.
  
    , GenericArbitrary (..)
    , GenericArbitraryU (..)
    , GenericArbitrarySingle (..)
    , GenericArbitraryRec (..)
    , GenericArbitraryG (..)
    , GenericArbitraryUG (..)
    , GenericArbitrarySingleG (..)
    , GenericArbitraryRecG (..)
    , GenericArbitraryWith (..)
    , AndShrinking (..)
  
    -- ** Helpers typeclasses
    , TypeLevelGenList (..)
    , TypeLevelOpts (..)
    ) where
  
  import Generic.Random.Internal.BaseCase
  import Generic.Random.Internal.Generic
  import Generic.Random.DerivingVia
  