    {-# LANGUAGE MultiParamTypeClasses #-}
    {-# LANGUAGE KindSignatures #-}
    {-# LANGUAGE TypeApplications #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE AllowAmbiguousTypes #-}

    -- | Monad properties
    --
    -- You will need @TypeApplications@ to use these.
    module Test.Validity.Monad
        ( monadSpecOnValid
        , monadSpec
        , monadSpecOnArbitrary
        , monadSpecOnGens
        ) where

    import Data.Data

    import Control.Monad (ap)
    import Data.GenValidity
    import Test.QuickCheck.Gen (unGen)
    import Test.QuickCheck.Random (mkQCGen)

    import Test.Hspec
    import Test.QuickCheck

    import Test.Validity.Functions
    import Test.Validity.Utils

    {-# ANN module "HLint: ignore Use fmap" #-}

    {-# ANN module "HLint: ignore Use <$>" #-}

    {-# ANN module "HLint: ignore Use >=>" #-}

    {-# ANN module "HLint: ignore Use id" #-}

    {-# ANN module "HLint: ignore Monad law, left identity" #-}

    {-# ANN module "HLint: ignore Monad law, right identity" #-}

    {-# ANN module "HLint: ignore Avoid lambda" #-}

    {-# ANN module "HLint: ignore Reduce duplication" #-}

    returnTypeStr ::
           forall (m :: * -> *). (Typeable m)
        => String
    returnTypeStr :: String
    returnTypeStr = [String] -> String
    unwords ["return", "::", "a", "->", Typeable m => String
    forall k (a :: k). Typeable a => String
    nameOf @m, "a"]

    bindTypeStr ::
           forall (m :: * -> *). (Typeable m)
        => String
    bindTypeStr :: String
    bindTypeStr =
        [String] -> String
    unwords
            [ "(>>=)"
            , "::"
            , Typeable m => String
    forall k (a :: k). Typeable a => String
    nameOf @m
            , "a"
            , "->"
            , "(b"
            , "->"
            , Typeable m => String
    forall k (a :: k). Typeable a => String
    nameOf @m
            , "a)"
            , "->"
            , Typeable m => String
    forall k (a :: k). Typeable a => String
    nameOf @m
            , "b"
            ]

    -- | Standard test spec for properties of Monad instances for values generated with GenValid instances
    --
    -- Example usage:
    --
    -- > monadSpecOnValid @[]
    monadSpecOnValid ::
           forall (f :: * -> *).
           (Eq (f Int), Show (f Int), Monad f, Typeable f, GenValid (f Int))
        => Spec
    monadSpecOnValid :: Spec
    monadSpecOnValid = Gen (f Int) -> Spec
    forall (f :: * -> *).
    (Eq (f Int), Show (f Int), Monad f, Typeable f) =>
    Gen (f Int) -> Spec
    monadSpecWithInts @f Gen (f Int)
    forall a. GenValid a => Gen a
    genValid

    -- | Standard test spec for properties of Monad instances for values generated with GenUnchecked instances
    --
    -- Example usage:
    --
    -- > monadSpec @[]
    monadSpec ::
           forall (f :: * -> *).
           (Eq (f Int), Show (f Int), Monad f, Typeable f, GenUnchecked (f Int))
        => Spec
    monadSpec :: Spec
    monadSpec = Gen (f Int) -> Spec
    forall (f :: * -> *).
    (Eq (f Int), Show (f Int), Monad f, Typeable f) =>
    Gen (f Int) -> Spec
    monadSpecWithInts @f Gen (f Int)
    forall a. GenUnchecked a => Gen a
    genUnchecked

    -- | Standard test spec for properties of Monad instances for values generated with Arbitrary instances
    --
    -- Example usage:
    --
    -- > monadSpecOnArbitrary @[]
    monadSpecOnArbitrary ::
           forall (f :: * -> *).
           (Eq (f Int), Show (f Int), Monad f, Typeable f, Arbitrary (f Int))
        => Spec
    monadSpecOnArbitrary :: Spec
    monadSpecOnArbitrary = Gen (f Int) -> Spec
    forall (f :: * -> *).
    (Eq (f Int), Show (f Int), Monad f, Typeable f) =>
    Gen (f Int) -> Spec
    monadSpecWithInts @f Gen (f Int)
    forall a. Arbitrary a => Gen a
    arbitrary

    monadSpecWithInts ::
           forall (f :: * -> *). (Eq (f Int), Show (f Int), Monad f, Typeable f)
        => Gen (f Int)
        -> Spec
    monadSpecWithInts :: Gen (f Int) -> Spec
    monadSpecWithInts gen :: Gen (f Int)
    gen =
        Gen Int
    -> String
    -> Gen (f Int)
    -> String
    -> Gen (f Int)
    -> String
    -> Gen (Int -> Int)
    -> String
    -> Gen (Int -> f Int)
    -> String
    -> Gen (Int -> f Int)
    -> String
    -> Gen (f (Int -> Int))
    -> String
    -> Spec
    forall (f :: * -> *) a b c.
    (Show a, Eq a, Show (f a), Show (f b), Show (f c), Eq (f a),
     Eq (f b), Eq (f c), Monad f, Typeable f, Typeable a, Typeable b,
     Typeable c) =>
    Gen a
    -> String
    -> Gen (f a)
    -> String
    -> Gen (f b)
    -> String
    -> Gen (a -> b)
    -> String
    -> Gen (a -> f b)
    -> String
    -> Gen (b -> f c)
    -> String
    -> Gen (f (a -> b))
    -> String
    -> Spec
    monadSpecOnGens
            @f
            @Int
            Gen Int
    forall a. GenUnchecked a => Gen a
    genUnchecked
            "int"
            Gen (f Int)
    gen
            ([String] -> String
    unwords [Typeable f => String
    forall k (a :: k). Typeable a => String
    nameOf @f, "of ints"])
            Gen (f Int)
    gen
            ([String] -> String
    unwords [Typeable f => String
    forall k (a :: k). Typeable a => String
    nameOf @f, "of ints"])
            (Int -> Int -> Int
    forall a. Num a => a -> a -> a
    (+) (Int -> Int -> Int) -> Gen Int -> Gen (Int -> Int)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen Int
    forall a. GenUnchecked a => Gen a
    genUnchecked)
            "increments"
            (do Int
    s <- Gen Int
    genListLength
                (Int -> f Int) -> Gen (Int -> f Int)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ((Int -> f Int) -> Gen (Int -> f Int))
    -> (Int -> f Int) -> Gen (Int -> f Int)
    forall a b. (a -> b) -> a -> b
    $ \b :: Int
    b -> Gen (f Int) -> QCGen -> Int -> f Int
    forall a. Gen a -> QCGen -> Int -> a
    unGen Gen (f Int)
    gen (Int -> QCGen
    mkQCGen Int
    b) Int
    s)
            "perturbations using the int"
            (do Int
    s <- Gen Int
    genListLength
                (Int -> f Int) -> Gen (Int -> f Int)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ((Int -> f Int) -> Gen (Int -> f Int))
    -> (Int -> f Int) -> Gen (Int -> f Int)
    forall a b. (a -> b) -> a -> b
    $ \b :: Int
    b -> Gen (f Int) -> QCGen -> Int -> f Int
    forall a. Gen a -> QCGen -> Int -> a
    unGen Gen (f Int)
    gen (Int -> QCGen
    mkQCGen (Int -> QCGen) -> Int -> QCGen
    forall a b. (a -> b) -> a -> b
    $ 2 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    * Int
    b) Int
    s)
            "perturbations using the double the int"
            ((Int -> Int) -> f (Int -> Int)
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ((Int -> Int) -> f (Int -> Int))
    -> Gen (Int -> Int) -> Gen (f (Int -> Int))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Int -> Int -> Int
    forall a. Num a => a -> a -> a
    (+) (Int -> Int -> Int) -> Gen Int -> Gen (Int -> Int)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen Int
    forall a. GenUnchecked a => Gen a
    genUnchecked))
            ([String] -> String
    unwords [Typeable f => String
    forall k (a :: k). Typeable a => String
    nameOf @f, "of additions"])

    -- | Standard test spec for properties of Monad instances for values generated by given generators (and names for those generator).
    --
    -- Example usage:
    --
    -- > monadSpecOnGens
    -- >     @[]
    -- >     @Int
    -- >     (pure 4)
    -- >     "four"
    -- >     (genListOf $ pure 5)
    -- >     "list of fives"
    -- >     (genListOf $ pure 6)
    -- >     "list of sixes"
    -- >     ((*) <$> genValid)
    -- >     "factorisations"
    -- >     (pure $ \a -> [a])
    -- >     "singletonisation"
    -- >     (pure $ \a -> [a])
    -- >     "singletonisation"
    -- >     (pure $ pure (+ 1))
    -- >     "increment in list"
    monadSpecOnGens ::
           forall (f :: * -> *) (a :: *) (b :: *) (c :: *).
           ( Show a
           , Eq a
           , Show (f a)
           , Show (f b)
           , Show (f c)
           , Eq (f a)
           , Eq (f b)
           , Eq (f c)
           , Monad f
           , Typeable f
           , Typeable a
           , Typeable b
           , Typeable c
           )
        => Gen a
        -> String
        -> Gen (f a)
        -> String
        -> Gen (f b)
        -> String
        -> Gen (a -> b)
        -> String
        -> Gen (a -> f b)
        -> String
        -> Gen (b -> f c)
        -> String
        -> Gen (f (a -> b))
        -> String
        -> Spec
    monadSpecOnGens :: Gen a
    -> String
    -> Gen (f a)
    -> String
    -> Gen (f b)
    -> String
    -> Gen (a -> b)
    -> String
    -> Gen (a -> f b)
    -> String
    -> Gen (b -> f c)
    -> String
    -> Gen (f (a -> b))
    -> String
    -> Spec
    monadSpecOnGens gena :: Gen a
    gena genaname :: String
    genaname gen :: Gen (f a)
    gen genname :: String
    genname genb :: Gen (f b)
    genb genbname :: String
    genbname geng :: Gen (a -> b)
    geng gengname :: String
    gengname genbf :: Gen (a -> f b)
    genbf genbfname :: String
    genbfname gencf :: Gen (b -> f c)
    gencf gencfname :: String
    gencfname genfab :: Gen (f (a -> b))
    genfab genfabname :: String
    genfabname =
        Spec -> Spec
    forall a. SpecWith a -> SpecWith a
    parallel (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $
        String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe ("Monad " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Typeable f => String
    forall k (a :: k). Typeable a => String
    nameOf @f) (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
            String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe ([String] -> String
    unwords [Typeable f => String
    forall (m :: * -> *). Typeable m => String
    returnTypeStr @f, "and", Typeable f => String
    forall (m :: * -> *). Typeable m => String
    bindTypeStr @f]) (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                String -> Property -> SpecWith (Arg Property)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it
                    ([String] -> String
    unwords
                         [ "satisfy the first Monad law: 'return a >>= k = k a' for"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @a String
    genaname
                         , "and"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(a -> f b) String
    genbfname
                         ]) (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                    (a -> Anon (a -> f b) -> f b)
    -> (a -> Anon (a -> f b) -> f b)
    -> Gen (a, Anon (a -> f b))
    -> ((a, Anon (a -> f b)) -> [(a, Anon (a -> f b))])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2
                        (\a :: a
    a (Anon k :: a -> f b
    k) -> a -> f a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    a f a -> (a -> f b) -> f b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> f b
    k)
                        (\a :: a
    a (Anon k :: a -> f b
    k) -> a -> f b
    k a
    a)
                        ((,) (a -> Anon (a -> f b) -> (a, Anon (a -> f b)))
    -> Gen a -> Gen (Anon (a -> f b) -> (a, Anon (a -> f b)))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen a
    gena Gen (Anon (a -> f b) -> (a, Anon (a -> f b)))
    -> Gen (Anon (a -> f b)) -> Gen (a, Anon (a -> f b))
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ((a -> f b) -> Anon (a -> f b)
    forall a. a -> Anon a
    Anon ((a -> f b) -> Anon (a -> f b))
    -> Gen (a -> f b) -> Gen (Anon (a -> f b))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen (a -> f b)
    genbf))
                        (a, Anon (a -> f b)) -> [(a, Anon (a -> f b))]
    forall a. a -> [a]
    shrinkNothing
                String -> Property -> SpecWith (Arg Property)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it
                    ([String] -> String
    unwords
                         [ "satisfy the second Monad law: 'm >>= return = m' for"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f a) String
    genname
                         ]) (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                    (f a -> f a)
    -> (f a -> f a) -> Gen (f a) -> (f a -> [f a]) -> Property
    forall a b.
    (Show a, Eq a, Show b, Eq b) =>
    (a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
    equivalentOnGen (\m :: f a
    m -> f a
    m f a -> (a -> f a) -> f a
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> f a
    forall (m :: * -> *) a. Monad m => a -> m a
    return) (\m :: f a
    m -> f a
    m) Gen (f a)
    gen f a -> [f a]
    forall a. a -> [a]
    shrinkNothing
            String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe (Typeable f => String
    forall (m :: * -> *). Typeable m => String
    bindTypeStr @f) (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $
                String -> Property -> SpecWith (Arg Property)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it
                    ([String] -> String
    unwords
                         [ "satisfies the third Monad law: 'm >>= (x -> k x >>= h) = (m >>= k) >>= h' for"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f a) String
    genname
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(a -> f b) String
    genbfname
                         , "and"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(b -> f c) String
    gencfname
                         ]) (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                (f a -> Anon (a -> f b) -> Anon (b -> f c) -> f c)
    -> (f a -> Anon (a -> f b) -> Anon (b -> f c) -> f c)
    -> Gen (f a, Anon (a -> f b), Anon (b -> f c))
    -> ((f a, Anon (a -> f b), Anon (b -> f c))
        -> [(f a, Anon (a -> f b), Anon (b -> f c))])
    -> Property
    forall a b c d.
    (Show a, Show b, Show c, Show d, Eq d) =>
    (a -> b -> c -> d)
    -> (a -> b -> c -> d)
    -> Gen (a, b, c)
    -> ((a, b, c) -> [(a, b, c)])
    -> Property
    equivalentOnGens3
                    (\m :: f a
    m (Anon k :: a -> f b
    k) (Anon h :: b -> f c
    h) -> f a
    m f a -> (a -> f c) -> f c
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (\x :: a
    x -> a -> f b
    k a
    x f b -> (b -> f c) -> f c
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= b -> f c
    h))
                    (\m :: f a
    m (Anon k :: a -> f b
    k) (Anon h :: b -> f c
    h) -> (f a
    m f a -> (a -> f b) -> f b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= a -> f b
    k) f b -> (b -> f c) -> f c
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= b -> f c
    h)
                    ((,,) (f a
     -> Anon (a -> f b)
     -> Anon (b -> f c)
     -> (f a, Anon (a -> f b), Anon (b -> f c)))
    -> Gen (f a)
    -> Gen
         (Anon (a -> f b)
          -> Anon (b -> f c) -> (f a, Anon (a -> f b), Anon (b -> f c)))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen (f a)
    gen Gen
      (Anon (a -> f b)
       -> Anon (b -> f c) -> (f a, Anon (a -> f b), Anon (b -> f c)))
    -> Gen (Anon (a -> f b))
    -> Gen (Anon (b -> f c) -> (f a, Anon (a -> f b), Anon (b -> f c)))
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ((a -> f b) -> Anon (a -> f b)
    forall a. a -> Anon a
    Anon ((a -> f b) -> Anon (a -> f b))
    -> Gen (a -> f b) -> Gen (Anon (a -> f b))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen (a -> f b)
    genbf) Gen (Anon (b -> f c) -> (f a, Anon (a -> f b), Anon (b -> f c)))
    -> Gen (Anon (b -> f c))
    -> Gen (f a, Anon (a -> f b), Anon (b -> f c))
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> ((b -> f c) -> Anon (b -> f c)
    forall a. a -> Anon a
    Anon ((b -> f c) -> Anon (b -> f c))
    -> Gen (b -> f c) -> Gen (Anon (b -> f c))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen (b -> f c)
    gencf))
                    (f a, Anon (a -> f b), Anon (b -> f c))
    -> [(f a, Anon (a -> f b), Anon (b -> f c))]
    forall a. a -> [a]
    shrinkNothing
            String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe ([String] -> String
    unwords ["relation with Applicative", Typeable f => String
    forall k (a :: k). Typeable a => String
    nameOf @f]) (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $ do
                String -> Property -> SpecWith (Arg Property)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it
                    ([String] -> String
    unwords
                         ["satisfies 'pure = return' for", String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f a) String
    genname]) (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                    (a -> f a) -> (a -> f a) -> Gen a -> (a -> [a]) -> Property
    forall a b.
    (Show a, Eq a, Show b, Eq b) =>
    (a -> b) -> (a -> b) -> Gen a -> (a -> [a]) -> Property
    equivalentOnGen (forall a. Applicative f => a -> f a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure @f) (forall a. Monad f => a -> f a
    forall (m :: * -> *) a. Monad m => a -> m a
    return @f) Gen a
    gena a -> [a]
    forall a. a -> [a]
    shrinkNothing
                String -> Property -> SpecWith (Arg Property)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it
                    ([String] -> String
    unwords
                         [ "satisfies '(<*>) = ap' for"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f (a -> b)) String
    genfabname
                         , "and"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f a) String
    genname
                         ]) (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                    (Anon (f (a -> b)) -> f a -> f b)
    -> (Anon (f (a -> b)) -> f a -> f b)
    -> Gen (Anon (f (a -> b)), f a)
    -> ((Anon (f (a -> b)), f a) -> [(Anon (f (a -> b)), f a)])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2
                        (\(Anon a :: f (a -> b)
    a) b :: f a
    b -> f (a -> b)
    a f (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> f a
    b)
                        (\(Anon a :: f (a -> b)
    a) b :: f a
    b -> f (a -> b) -> f a -> f b
    forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
    ap f (a -> b)
    a f a
    b)
                        ((,) (Anon (f (a -> b)) -> f a -> (Anon (f (a -> b)), f a))
    -> Gen (Anon (f (a -> b))) -> Gen (f a -> (Anon (f (a -> b)), f a))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (f (a -> b) -> Anon (f (a -> b))
    forall a. a -> Anon a
    Anon (f (a -> b) -> Anon (f (a -> b)))
    -> Gen (f (a -> b)) -> Gen (Anon (f (a -> b)))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen (f (a -> b))
    genfab) Gen (f a -> (Anon (f (a -> b)), f a))
    -> Gen (f a) -> Gen (Anon (f (a -> b)), f a)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Gen (f a)
    gen)
                        (Anon (f (a -> b)), f a) -> [(Anon (f (a -> b)), f a)]
    forall a. a -> [a]
    shrinkNothing
                String -> Property -> SpecWith (Arg Property)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it
                    ([String] -> String
    unwords
                         [ "satisfies '(>>) = (*>)' for"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f a) String
    genname
                         , "and"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f b) String
    genbname
                         ]) (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                    (f a -> f b -> f b)
    -> (f a -> f b -> f b)
    -> Gen (f a, f b)
    -> ((f a, f b) -> [(f a, f b)])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2 f a -> f b -> f b
    forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
    (>>) f a -> f b -> f b
    forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
    (*>) ((,) (f a -> f b -> (f a, f b)) -> Gen (f a) -> Gen (f b -> (f a, f b))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen (f a)
    gen Gen (f b -> (f a, f b)) -> Gen (f b) -> Gen (f a, f b)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Gen (f b)
    genb) (f a, f b) -> [(f a, f b)]
    forall a. a -> [a]
    shrinkNothing
            String -> Spec -> Spec
    forall a. HasCallStack => String -> SpecWith a -> SpecWith a
    describe ([String] -> String
    unwords ["relation with Functor", Typeable f => String
    forall k (a :: k). Typeable a => String
    nameOf @f]) (Spec -> Spec) -> Spec -> Spec
    forall a b. (a -> b) -> a -> b
    $
                String -> Property -> SpecWith (Arg Property)
    forall a.
    (HasCallStack, Example a) =>
    String -> a -> SpecWith (Arg a)
    it
                    ([String] -> String
    unwords
                         [ "satisfies 'fmap f xs = xs >>= return . f' for"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(a -> b) String
    gengname
                         , "and"
                         , String -> String
    forall k (a :: k). Typeable a => String -> String
    genDescr @(f a) String
    genname
                         ]) (Property -> Spec) -> Property -> Spec
    forall a b. (a -> b) -> a -> b
    $
                (Anon (a -> b) -> f a -> f b)
    -> (Anon (a -> b) -> f a -> f b)
    -> Gen (Anon (a -> b), f a)
    -> ((Anon (a -> b), f a) -> [(Anon (a -> b), f a)])
    -> Property
    forall a b c.
    (Show a, Show b, Show c, Eq c) =>
    (a -> b -> c)
    -> (a -> b -> c) -> Gen (a, b) -> ((a, b) -> [(a, b)]) -> Property
    equivalentOnGens2
                    (\(Anon f :: a -> b
    f) xs :: f a
    xs -> (a -> b) -> f a -> f b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> b
    f f a
    xs)
                    (\(Anon f :: a -> b
    f) xs :: f a
    xs -> f a
    xs f a -> (a -> f b) -> f b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (b -> f b
    forall (m :: * -> *) a. Monad m => a -> m a
    return (b -> f b) -> (a -> b) -> a -> f b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> b
    f))
                    ((,) (Anon (a -> b) -> f a -> (Anon (a -> b), f a))
    -> Gen (Anon (a -> b)) -> Gen (f a -> (Anon (a -> b), f a))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ((a -> b) -> Anon (a -> b)
    forall a. a -> Anon a
    Anon ((a -> b) -> Anon (a -> b)) -> Gen (a -> b) -> Gen (Anon (a -> b))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Gen (a -> b)
    geng) Gen (f a -> (Anon (a -> b), f a))
    -> Gen (f a) -> Gen (Anon (a -> b), f a)
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Gen (f a)
    gen)
                    (Anon (a -> b), f a) -> [(Anon (a -> b), f a)]
    forall a. a -> [a]
    shrinkNothing