{-# LANGUAGE Rank2Types #-}
module Test.Tasty.QuickCheck.Laws.IdentityMonad (
testIdentityMonadLaws
, testIdentityMonadLawUnwrapReturn
, testIdentityMonadLawReturnUnwrap
, testIdentityMonadLawBind
) where
import Data.Proxy
( Proxy(..) )
import Data.Typeable
( Typeable, typeRep )
import Test.Tasty
( TestTree, testGroup )
import Test.Tasty.QuickCheck
( testProperty, Property, Arbitrary(..), CoArbitrary(..) )
import Text.Show.Functions
()
import Test.Tasty.QuickCheck.Laws.Class
testIdentityMonadLaws
:: ( Monad m
, Eq a, Eq b
, Show t, Show a
, Show (m a)
, Arbitrary t, Arbitrary a, CoArbitrary a
, Arbitrary (m a), Arbitrary (m b)
, Typeable m, Typeable a
)
=> Proxy m
-> Proxy t
-> Proxy a
-> Proxy b
-> (forall u. (Eq u) => t -> m u -> m u -> Bool)
-> (forall a. m a -> a)
-> TestTree
testIdentityMonadLaws pm pt pa pb eq unwrap =
let
label = "Identity Monad Laws for " ++ (show $ typeRep pm) ++ " with " ++
"a :: " ++ (show $ typeRep pa)
in
testGroup label
[ testIdentityMonadLawUnwrapReturn pm pt pa unwrap
, testIdentityMonadLawReturnUnwrap pm pt pa eq unwrap
, testIdentityMonadLawBind pm pt pa pb eq unwrap
]
testIdentityMonadLawUnwrapReturn
:: ( Monad m, Eq a, Show a
, Show t
, Arbitrary t, Arbitrary a, Show (m a)
)
=> Proxy m
-> Proxy t
-> Proxy a
-> (forall a. m a -> a)
-> TestTree
testIdentityMonadLawUnwrapReturn pm pt pa unwrap =
testProperty "unwrap . return === id" $
identityMonadLawUnwrapReturn pm pt pa unwrap
identityMonadLawUnwrapReturn
:: (Monad m, Eq a)
=> Proxy m -> Proxy t -> Proxy a
-> (forall a. m a -> a)
-> t -> a -> Bool
identityMonadLawUnwrapReturn _ _ _ unwrap t x =
(unwrap . return $ x) == x
testIdentityMonadLawReturnUnwrap
:: ( Monad m, Eq a
, Show t
, Arbitrary t, Arbitrary (m a), Show (m a)
)
=> Proxy m
-> Proxy t
-> Proxy a
-> (forall u. (Eq u) => t -> m u -> m u -> Bool)
-> (forall a. m a -> a)
-> TestTree
testIdentityMonadLawReturnUnwrap pm pt pa eq bail =
testProperty "return . unwrap == id" $
identityMonadLawReturnUnwrap pm pt pa eq bail
identityMonadLawReturnUnwrap
:: (Monad m, Eq a)
=> Proxy m -> Proxy t -> Proxy a
-> (forall u. (Eq u) => t -> m u -> m u -> Bool)
-> (forall a. m a -> a)
-> t -> m a -> Bool
identityMonadLawReturnUnwrap _ _ _ eq unwrap t x =
(eq t) (return . unwrap $ x) (x)
testIdentityMonadLawBind
:: ( Monad m, Eq b
, Show t, CoArbitrary a, Arbitrary (m b)
, Arbitrary t, Arbitrary (m a), Show (m a)
)
=> Proxy m
-> Proxy t
-> Proxy a
-> Proxy b
-> (forall u. (Eq u) => t -> m u -> m u -> Bool)
-> (forall a. m a -> a)
-> TestTree
testIdentityMonadLawBind pm pt pa pb eq unwrap =
testProperty "x >>= f === f (unwrap x)" $
identityMonadLawBind pm pt pa pb eq unwrap
identityMonadLawBind
:: (Monad m, Eq b)
=> Proxy m -> Proxy t -> Proxy a -> Proxy b
-> (forall u. (Eq u) => t -> m u -> m u -> Bool)
-> (forall a. m a -> a)
-> t -> m a -> (a -> m b) -> Bool
identityMonadLawBind _ _ _ _ eq unwrap t x f =
(eq t) (x >>= f) (f (unwrap x))