{-# 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