    {-|
    The <http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html QuickCheck manual>
    gives detailed information about using QuickCheck effectively.
    You can also try <https://begriffs.com/posts/2017-01-14-design-use-quickcheck.html>,
    a tutorial written by a user of QuickCheck.

    To start using QuickCheck, write down your property as a function returning @Bool@.
    For example, to check that reversing a list twice gives back the same list you can write:

    @
    import Test.QuickCheck

    prop_reverse :: [Int] -> Bool
    prop_reverse xs = reverse (reverse xs) == xs
    @

    You can then use QuickCheck to test @prop_reverse@ on 100 random lists:

    >>> quickCheck prop_reverse
    +++ OK, passed 100 tests.

    To run more tests you can use the 'withMaxSuccess' combinator:

    >>> quickCheck (withMaxSuccess 10000 prop_reverse)
    +++ OK, passed 10000 tests.

    To use QuickCheck on your own data types you will need to write 'Arbitrary'
    instances for those types. See the
    <http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html QuickCheck manual> for
    details about how to do that.

    When testing fails @quickCheck@ will try to give you a minimal counterexample to
    your property:
    @
    import Test.QuickCheck

    prop_reverse_bad :: [Int] -> Bool
    prop_reverse_bad xs = reverse xs == xs

    >>> quickCheck prop_reverse_bad
    *** Failed! Falsified (after 3 tests and 3 shrinks):
    [0,1]
    @

    However, beware because not all properties that ought to fail will fail when you expect
    them to:

    @
    >>> quickCheck $ \ x y -> x == y
    +++ Ok, passed 100 tests.
    @

    That's because GHCi will default any type variables in your property to '()', so in the example
    above @quickCheck@ was really testing that '()' is equal to itself. To avoid this behaviour it
    is best practise to monomorphise your polymorphic properties when testing:

    @
    >>> quickCheck $ \ x y -> (x :: Int) == y
    *** Failed! Falsified (after 4 tests and 3 shrinks):
    0
    1
    @

    -}
    {-# LANGUAGE CPP #-}
    #ifndef NO_SAFE_HASKELL
    {-# LANGUAGE Safe #-}
    #endif
    #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
    {-# LANGUAGE PatternSynonyms #-}
    #endif
    module Test.QuickCheck
      (
        -- * Running tests
        quickCheck
      , Args(..), Result(..)
      , stdArgs
      , quickCheckWith
      , quickCheckWithResult
      , quickCheckResult
      , recheck
      , isSuccess
        -- ** Running tests verbosely
      , verboseCheck
      , verboseCheckWith
      , verboseCheckWithResult
      , verboseCheckResult
    #ifndef NO_TEMPLATE_HASKELL
        -- ** Testing all properties in a module

        -- | These functions test all properties in the current module, using
        -- Template Haskell. You need to have a @{-\# LANGUAGE TemplateHaskell \#-}@
        -- pragma in your module for any of these to work.
      , quickCheckAll
      , verboseCheckAll
      , forAllProperties
      , allProperties
        -- ** Testing polymorphic properties
      , polyQuickCheck
      , polyVerboseCheck
      , monomorphic
    #endif

        -- * The 'Arbitrary' typeclass: generation of random values
      , Arbitrary(..)
        -- ** Helper functions for implementing 'shrink'
    #ifndef NO_GENERICS
      , genericShrink
      , subterms
      , recursivelyShrink
    #endif
      , shrinkNothing
      , shrinkList
      , shrinkMap
      , shrinkMapBy
      , shrinkIntegral
      , shrinkRealFrac
      , shrinkBoundedEnum
      , shrinkDecimal

        -- ** Lifting of 'Arbitrary' to unary and binary type constructors
      , Arbitrary1(..)
      , arbitrary1
      , shrink1
      , Arbitrary2(..)
      , arbitrary2
      , shrink2

        -- * The 'Gen' monad: combinators for building random generators
      , Gen
        -- ** Generator combinators
      , choose
      , chooseInt
      , chooseInteger
      , chooseBoundedIntegral
      , chooseEnum
      , chooseAny
      , oneof
      , frequency
      , elements
      , growingElements
      , sized
      , getSize
      , resize
      , scale
      , suchThat
      , suchThatMap
      , suchThatMaybe
      , applyArbitrary2
      , applyArbitrary3
      , applyArbitrary4
        -- ** Generators for lists
      , listOf
      , listOf1
      , vectorOf
      , vector
      , infiniteListOf
      , infiniteList
      , shuffle
      , sublistOf
      , orderedList
        -- ** Generators for particular types
      , arbitrarySizedIntegral
      , arbitrarySizedNatural
      , arbitrarySizedFractional
      , arbitrarySizedBoundedIntegral
      , arbitraryBoundedIntegral
      , arbitraryBoundedRandom
      , arbitraryBoundedEnum
      , arbitraryUnicodeChar
      , arbitraryASCIIChar
      , arbitraryPrintableChar
        -- ** Running generators
      , generate
        -- ** Debugging generators
      , sample
      , sample'

    #ifndef NO_GADTS
        -- * The 'Function' typeclass: generation of random shrinkable, showable functions

        -- | Example of use:
        --
        -- >>> :{
        -- >>> let prop :: Fun String Integer -> Bool
        -- >>>     prop (Fun _ f) = f "monkey" == f "banana" || f "banana" == f "elephant"
        -- >>> :}
        -- >>> quickCheck prop
        -- *** Failed! Falsified (after 3 tests and 134 shrinks):
        -- {"elephant"->1, "monkey"->1, _->0}
        --
        -- To generate random values of type @'Fun' a b@,
        -- you must have an instance @'Function' a@.
        -- If your type has a 'Show' instance, you can use 'functionShow' to write the instance; otherwise,
        -- use 'functionMap' to give a bijection between your type and a type that is already an instance of 'Function'.
        -- See the @'Function' [a]@ instance for an example of the latter.
        --
        -- For more information, see the paper \"Shrinking and showing functions\" by Koen Claessen.
      , Fun (..)
      , applyFun
      , applyFun2
      , applyFun3
    #if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 708
      , pattern Fn
      , pattern Fn2
      , pattern Fn3
    #endif
      , Function (..)
      , functionMap
      , functionShow
      , functionIntegral
      , functionRealFrac
      , functionBoundedEnum
      , functionVoid
    #endif

        -- * The 'CoArbitrary' typeclass: generation of functions the old-fashioned way
      , CoArbitrary(..)
    #ifndef NO_GENERICS
      , genericCoarbitrary
    #endif
      , variant
      , coarbitraryIntegral
      , coarbitraryReal
      , coarbitraryShow
      , coarbitraryEnum
      , (><)

        -- * Type-level modifiers for changing generator behavior

        -- | These types do things such as restricting the kind of test data that can be generated.
        -- They can be pattern-matched on in properties as a stylistic
        -- alternative to using explicit quantification.
        --
        -- Examples:
        --
        -- @
        -- -- Functions cannot be shown (but see 'Function')
        -- prop_TakeDropWhile ('Blind' p) (xs :: ['A']) =
        --   takeWhile p xs ++ dropWhile p xs == xs
        -- @
        --
        -- @
        -- prop_TakeDrop ('NonNegative' n) (xs :: ['A']) =
        --   take n xs ++ drop n xs == xs
        -- @
        --
        -- @
        -- -- cycle does not work for empty lists
        -- prop_Cycle ('NonNegative' n) ('NonEmpty' (xs :: ['A'])) =
        --   take n (cycle xs) == take n (xs ++ cycle xs)
        -- @
        --
        -- @
        -- -- Instead of 'forAll' 'orderedList'
        -- prop_Sort ('Ordered' (xs :: ['OrdA'])) =
        --   sort xs == xs
        -- @
      , Blind(..)
      , Fixed(..)
      , OrderedList(..)
      , NonEmptyList(..)
      , InfiniteList(..)
      , SortedList(..)
      , Positive(..)
      , Negative(..)
      , NonZero(..)
      , NonNegative(..)
      , NonPositive(..)
      , Large(..)
      , Small(..)
      , Smart(..)
      , Shrink2(..)
    #ifndef NO_MULTI_PARAM_TYPE_CLASSES
      , Shrinking(..)
      , ShrinkState(..)
    #endif
      , ASCIIString(..)
      , UnicodeString(..)
      , PrintableString(..)

        -- * Property combinators
      , Property, Testable(..)
      , forAll
      , forAllShrink
      , forAllShow
      , forAllShrinkShow
      , forAllBlind
      , forAllShrinkBlind
      , shrinking
      , (==>)
      , Discard(..)
      , discard
      , (===)
      , (=/=)
    #ifndef NO_DEEPSEQ
      , total
    #endif
      , ioProperty
      , idempotentIOProperty
        -- ** Controlling property execution
      , verbose
      , verboseShrinking
      , noShrinking
      , withMaxSuccess
      , within
      , discardAfter
      , withDiscardRatio
      , withMaxSize
      , withMaxShrinks
      , once
      , again
      , mapSize
        -- ** Conjunction and disjunction
      , (.&.)
      , (.&&.)
      , conjoin
      , (.||.)
      , disjoin
        -- ** What to do on failure
    #ifndef NO_TYPEABLE
      , Witness(..)
      , witness
      , coerceWitness
      , castWitness
    #endif
      , counterexample
      , printTestCase
      , whenFail
      , whenFail'
      , expectFailure
        -- * Analysing test case distribution
      , label
      , collect
      , classify
      , tabulate
        -- ** Checking test case distribution
      , cover
      , coverTable
      , checkCoverage
      , checkCoverageWith
      , Confidence(..)
      , stdConfidence
        -- ** Generating example test cases
      , labelledExamples
      , labelledExamplesWith
      , labelledExamplesWithResult
      , labelledExamplesResult
      )
     where

    --------------------------------------------------------------------------
    -- imports

    import Test.QuickCheck.Gen
    import Test.QuickCheck.Arbitrary
    import Test.QuickCheck.Modifiers
    import Test.QuickCheck.Property hiding ( Result(..) )
    import Test.QuickCheck.Test
    import Test.QuickCheck.Exception
    #ifndef NO_GADTS
    import Test.QuickCheck.Function
    #endif
    import Test.QuickCheck.Features
    import Test.QuickCheck.State
    #ifndef NO_TEMPLATE_HASKELL
    import Test.QuickCheck.All
    #endif

    --------------------------------------------------------------------------
    -- the end.