module Test.Validity
( module Data.GenValidity
, Proxy(Proxy)
, arbitrarySpec
, arbitraryGeneratesOnlyValid
, shrinkProducesOnlyValids
, genValiditySpec
, genValidityValidGeneratesValid
, genGeneratesValid
, genValidityInvalidGeneratesInvalid
, genGeneratesInvalid
, relativeValiditySpec
, relativeValidityImpliesValidA
, relativeValidityImpliesValidB
, genRelativeValiditySpec
, genRelativeValidityValidGeneratesValid
, genRelativeValidityInvalidGeneratesInvalid
, producesValidsOnGen
, producesValidsOnArbitrary
, alwaysProducesValid
, producesValidsOnValids
, producesValidsOnGens2
, alwaysProducesValid2
, producesValidsOnValids2
, producesValidsOnGens3
, alwaysProducesValid3
, producesValidsOnValids3
, CanFail(..)
, succeedsOnGen
, succeedsOnValidInput
, failsOnGen
, failsOnInvalidInput
, validIfSucceedsOnGen
, validIfSucceedsOnArbitrary
, validIfSucceeds
, succeedsOnGens2
, succeedsOnValidInput2
, failsOnGens2
, failsOnInvalidInput2
, validIfSucceedsOnGens2
, validIfSucceeds2
, equivalentOnGen
, equivalentOnValid
, equivalent
, equivalentOnGens2
, equivalentOnValids2
, equivalent2
, inverseFunctionsOnGen
, inverseFunctionsOnValid
, inverseFunctions
, inverseFunctionsIfFirstSucceedsOnGen
, inverseFunctionsIfFirstSucceedsOnValid
, inverseFunctionsIfFirstSucceeds
, inverseFunctionsIfSecondSucceedsOnGen
, inverseFunctionsIfSecondSucceedsOnValid
, inverseFunctionsIfSecondSucceeds
, inverseFunctionsIfSucceedOnGen
, inverseFunctionsIfSucceedOnValid
, inverseFunctionsIfSucceed
, reflexivityOnGen
, reflexivityOnValid
, reflexivityOnUnchecked
, transitiveOnGens
, transitiveOnValid
, transitiveOnUnchecked
, antisymmetryOnGensWithEquality
, antisymmetryOnGensEq
, antisymmetryOnValid
, leftIdentityOnGen
, leftIdentityOnValid
, leftIdentity
, rightIdentityOnGen
, rightIdentityOnValid
, rightIdentity
, identityOnGen
, identityOnValid
, identity
, associativeOnGens
, associativeOnValids
, associative
, commutativeOnGens
, commutativeOnValids
, commutative
) where
import Data.Proxy
import Data.Data
import Data.GenValidity
import Data.GenRelativeValidity
import Test.Hspec
import Test.QuickCheck
arbitrarySpec
:: (Typeable a, Show a, Validity a, Arbitrary a)
=> Proxy a
-> Spec
arbitrarySpec proxy = do
let name = nameOf proxy
describe ("Arbitrary " ++ name) $ do
it ("is instantiated such that 'arbitrary' only generates valid \'"
++ name
++ "\'s") $
arbitraryGeneratesOnlyValid proxy
it ("is instantiated such that 'shrink' only produces valid \'"
++ name
++ "\'s") $ do
forAll arbitrary $ \a ->
shrink (a `asProxyTypeOf` proxy) `shouldSatisfy` all isValid
arbitraryGeneratesOnlyValid
:: forall a. (Show a, Validity a, Arbitrary a)
=> Proxy a
-> Property
arbitraryGeneratesOnlyValid _ =
genGeneratesValid (arbitrary :: Gen a)
shrinkProducesOnlyValids
:: forall a. (Show a, Validity a, Arbitrary a)
=> Proxy a
-> Property
shrinkProducesOnlyValids _ =
genGeneratesValid (shrink <$> arbitrary :: Gen [a])
genValiditySpec
:: (Typeable a, Show a, GenValidity a)
=> Proxy a
-> Spec
genValiditySpec proxy = do
let name = nameOf proxy
describe ("GenValidity " ++ name) $ do
describe ("genValid :: Gen " ++ name) $
it ("only generates valid \'" ++ name ++ "\'s") $
genValidityValidGeneratesValid proxy
describe ("genInvalid :: Gen " ++ name) $
it ("only generates invalid \'" ++ name ++ "\'s") $
genValidityInvalidGeneratesInvalid proxy
genValidityValidGeneratesValid
:: forall a. (Show a, GenValidity a)
=> Proxy a
-> Property
genValidityValidGeneratesValid _ =
genGeneratesValid (genValid :: Gen a)
genGeneratesValid
:: (Show a, Validity a)
=> Gen a
-> Property
genGeneratesValid gen =
forAll gen (`shouldSatisfy` isValid)
genValidityInvalidGeneratesInvalid
:: forall a. (Show a, GenValidity a)
=> Proxy a
-> Property
genValidityInvalidGeneratesInvalid _ =
genGeneratesInvalid (genInvalid :: Gen a)
genGeneratesInvalid
:: (Show a, Validity a)
=> Gen a
-> Property
genGeneratesInvalid gen =
forAll gen (`shouldNotSatisfy` isValid)
relativeValiditySpec
:: (Typeable a, Typeable b,
Data a, Data b,
Show a, Show b,
GenValidity a, GenValidity b, GenRelativeValidity a b)
=> Proxy a
-> Proxy b
-> Spec
relativeValiditySpec one two = do
let nameOne = nameOf one
nameTwo = nameOf two
describe ("RelativeValidity " ++ nameOne ++ " " ++ nameTwo) $ do
describe ("isValidFor :: "
++ nameOne
++ " -> "
++ nameTwo
++ " -> Bool") $ do
it ("implies isValid " ++ nameOne ++ " for any " ++ nameTwo) $
relativeValidityImpliesValidA one two
it ("implies isValid " ++ nameTwo ++ " for any " ++ nameOne) $
relativeValidityImpliesValidB one two
relativeValidityImpliesValidA
:: (Show a, Show b,
GenValidity a, GenValidity b, RelativeValidity a b)
=> Proxy a
-> Proxy b
-> Property
relativeValidityImpliesValidA one two =
forAll genUnchecked $ \a ->
forAll genUnchecked $ \b ->
not ((a `asProxyTypeOf` one) `isValidFor` (b `asProxyTypeOf` two))
|| isValid a
relativeValidityImpliesValidB
:: (Show a, Show b,
GenValidity a, GenValidity b, RelativeValidity a b)
=> Proxy a
-> Proxy b
-> Property
relativeValidityImpliesValidB one two =
forAll genUnchecked $ \a ->
forAll genUnchecked $ \b ->
not ((a `asProxyTypeOf` one) `isValidFor` (b `asProxyTypeOf` two))
|| isValid b
genRelativeValiditySpec
:: (Typeable a, Typeable b,
Show a, Show b,
GenValidity a, GenValidity b,
RelativeValidity a b,
GenRelativeValidity a b)
=> Proxy a
-> Proxy b
-> Spec
genRelativeValiditySpec one two = do
let nameOne = nameOf one
let nameTwo = nameOf two
describe ("GenRelativeValidity " ++ nameOne ++ " " ++ nameTwo) $ do
describe ("genValidFor :: " ++ nameTwo ++ " -> Gen " ++ nameOne) $
it ("only generates valid \'"
++ nameOne
++ "\'s for the "
++ nameTwo) $
genRelativeValidityValidGeneratesValid one two
describe ("genInvalidFor :: " ++ nameTwo ++ " -> Gen " ++ nameOne) $
it ("only generates invalid \'"
++ nameOne
++ "\'s for the "
++ nameTwo) $
genRelativeValidityInvalidGeneratesInvalid one two
genRelativeValidityValidGeneratesValid
:: (Show a, Show b,
GenValidity a, GenValidity b,
RelativeValidity a b,
GenRelativeValidity a b)
=> Proxy a
-> Proxy b
-> Property
genRelativeValidityValidGeneratesValid one two =
forAll genValid $ \b ->
forAll (genValidFor b) $ \a ->
(a `asProxyTypeOf` one)
`shouldSatisfy` (`isValidFor` (b `asProxyTypeOf` two))
genRelativeValidityInvalidGeneratesInvalid
:: (Show a, Show b,
GenValidity a, GenValidity b,
RelativeValidity a b,
GenRelativeValidity a b)
=> Proxy a
-> Proxy b
-> Property
genRelativeValidityInvalidGeneratesInvalid one two =
forAll genUnchecked $ \b ->
forAll (genInvalidFor b) $ \a ->
(a `asProxyTypeOf` one)
`shouldNotSatisfy` (`isValidFor` (b `asProxyTypeOf` two))
class CanFail f where
hasFailed :: f a -> Bool
resultIfSucceeded :: f a -> Maybe a
instance CanFail Maybe where
hasFailed Nothing = True
hasFailed _ = False
resultIfSucceeded Nothing = Nothing
resultIfSucceeded (Just r) = Just r
instance CanFail (Either e) where
hasFailed (Left _) = True
hasFailed _ = False
resultIfSucceeded (Left _) = Nothing
resultIfSucceeded (Right r) = Just r
producesValidsOnGen
:: (Show a, Show b, Validity b)
=> (a -> b)
-> Gen a
-> Property
producesValidsOnGen func gen
= forAll gen $ \a -> func a `shouldSatisfy` isValid
producesValidsOnArbitrary
:: (Show a, Show b, Arbitrary a, Validity b)
=> (a -> b)
-> Property
producesValidsOnArbitrary = (`producesValidsOnGen` arbitrary)
alwaysProducesValid
:: (Show a, Show b, GenValidity a, Validity b)
=> (a -> b)
-> Property
alwaysProducesValid = (`producesValidsOnGen` genUnchecked)
producesValidsOnValids
:: (Show a, Show b, GenValidity a, Validity b)
=> (a -> b)
-> Property
producesValidsOnValids = (`producesValidsOnGen` genValid)
producesValidsOnGens2
:: (Show a, Show b, Show c, Validity c)
=> (a -> b -> c)
-> Gen a -> Gen b
-> Property
producesValidsOnGens2 func gen1 gen2
= forAll gen1 $ \a ->
forAll gen2 $ \b ->
func a b `shouldSatisfy` isValid
alwaysProducesValid2
:: (Show a, Show b, Show c, GenValidity a, GenValidity b, Validity c)
=> (a -> b -> c)
-> Property
alwaysProducesValid2 func
= producesValidsOnGens2 func genUnchecked genUnchecked
producesValidsOnValids2
:: (Show a, Show b, Show c, GenValidity a, GenValidity b, Validity c)
=> (a -> b -> c)
-> Property
producesValidsOnValids2 func
= producesValidsOnGens2 func genValid genValid
producesValidsOnGens3
:: (Show a, Show b, Show c, Show d, Validity d)
=> (a -> b -> c -> d)
-> Gen a -> Gen b -> Gen c
-> Property
producesValidsOnGens3 func gen1 gen2 gen3
= forAll gen1 $ \a ->
forAll gen2 $ \b ->
forAll gen3 $ \c ->
func a b c `shouldSatisfy` isValid
alwaysProducesValid3
:: (Show a, Show b, Show c, Show d,
GenValidity a, GenValidity b, GenValidity c,
Validity d)
=> (a -> b -> c -> d)
-> Property
alwaysProducesValid3 func
= producesValidsOnGens3 func genUnchecked genUnchecked genUnchecked
producesValidsOnValids3
:: (Show a, Show b, Show c, Show d,
GenValidity a, GenValidity b, GenValidity c,
Validity d)
=> (a -> b -> c -> d)
-> Property
producesValidsOnValids3 func
= producesValidsOnGens3 func genValid genValid genValid
succeedsOnGen
:: (Show a, Show b, Show (f b), CanFail f)
=> (a -> f b)
-> Gen a
-> Property
succeedsOnGen func gen
= forAll gen $ \a -> func a `shouldNotSatisfy` hasFailed
succeedsOnValidInput
:: (Show a, Show b, Show (f b), GenValidity a, CanFail f)
=> (a -> f b)
-> Property
succeedsOnValidInput = (`succeedsOnGen` genValid)
failsOnGen
:: (Show a, Show b, Show (f b), CanFail f)
=> (a -> f b)
-> Gen a
-> Property
failsOnGen func gen
= forAll gen $ \a -> func a `shouldSatisfy` hasFailed
failsOnInvalidInput
:: (Show a, Show b, Show (f b), GenValidity a, CanFail f)
=> (a -> f b)
-> Property
failsOnInvalidInput = (`failsOnGen` genInvalid)
validIfSucceedsOnGen
:: (Show a, Show b, Show (f b), Validity b, CanFail f)
=> (a -> f b)
-> Gen a
-> Property
validIfSucceedsOnGen func gen
= forAll gen $ \a ->
case resultIfSucceeded (func a) of
Nothing -> return ()
Just res -> res `shouldSatisfy` isValid
validIfSucceedsOnArbitrary
:: (Show a, Show b, Show (f b), Arbitrary a, Validity b, CanFail f)
=> (a -> f b)
-> Property
validIfSucceedsOnArbitrary = (`validIfSucceedsOnGen` arbitrary)
validIfSucceeds
:: (Show a, Show b, Show (f b), GenValidity a, Validity b, CanFail f)
=> (a -> f b)
-> Property
validIfSucceeds = (`validIfSucceedsOnGen` genUnchecked)
succeedsOnGens2
:: (Show a, Show b, Show c, Show (f c),
CanFail f)
=> (a -> b -> f c)
-> Gen a -> Gen b
-> Property
succeedsOnGens2 func genA genB =
forAll genA $ \a ->
forAll genB $ \b ->
func a b `shouldNotSatisfy` hasFailed
succeedsOnValidInput2
:: (Show a, Show b, Show c, Show (f c),
GenValidity a, GenValidity b,
CanFail f)
=> (a -> b -> f c)
-> Property
succeedsOnValidInput2 func
= succeedsOnGens2 func genValid genValid
failsOnGens2
:: (Show a, Show b, Show c, Show (f c),
CanFail f)
=> (a -> b -> f c)
-> Gen a -> Gen b
-> Property
failsOnGens2 func genA genB =
forAll genA $ \a ->
forAll genB $ \b ->
func a b `shouldSatisfy` hasFailed
failsOnInvalidInput2
:: (Show a, Show b, Show c, Show (f c),
GenValidity a, GenValidity b,
CanFail f)
=> (a -> b -> f c)
-> Property
failsOnInvalidInput2 func
= failsOnGens2 func genInvalid genUnchecked
.&&. failsOnGens2 func genUnchecked genInvalid
validIfSucceedsOnGens2
:: (Show a, Show b, Show c, Show (f c),
Validity c, CanFail f)
=> (a -> b -> f c)
-> Gen a -> Gen b
-> Property
validIfSucceedsOnGens2 func genA genB =
forAll genA $ \a ->
forAll genB $ \b ->
case resultIfSucceeded (func a b) of
Nothing -> return ()
Just res -> res `shouldSatisfy` isValid
validIfSucceeds2
:: (Show a, Show b, Show c, Show (f c),
GenValidity a, GenValidity b,
Validity c, CanFail f)
=> (a -> b -> f c)
-> Property
validIfSucceeds2 func
= validIfSucceedsOnGens2 func genUnchecked genUnchecked
equivalentOnGen
:: (Show a, Eq a, Show b, Eq b)
=> (a -> b)
-> (a -> b)
-> Gen a
-> Property
equivalentOnGen f g gen =
forAll gen $ \a ->
f a `shouldBe` g a
equivalentOnValid
:: (Show a, Eq a, GenValidity a, Show b, Eq b)
=> (a -> b)
-> (a -> b)
-> Property
equivalentOnValid f g
= equivalentOnGen f g genValid
equivalent
:: (Show a, Eq a, GenValidity a, Show b, Eq b)
=> (a -> b)
-> (a -> b)
-> Property
equivalent f g
= equivalentOnGen f g genUnchecked
equivalentOnGens2
:: (Show a, Eq a,
Show b, Eq b,
Show c, Eq c)
=> (a -> b -> c)
-> (a -> b -> c)
-> Gen (a, b)
-> Property
equivalentOnGens2 f g gen =
forAll gen $ \(a, b) ->
f a b `shouldBe` g a b
equivalentOnValids2
:: (Show a, Eq a, GenValidity a,
Show b, Eq b, GenValidity b,
Show c, Eq c)
=> (a -> b -> c)
-> (a -> b -> c)
-> Property
equivalentOnValids2 f g
= equivalentOnGens2 f g genValid
equivalent2
:: (Show a, Eq a, GenValidity a,
Show b, Eq b, GenValidity b,
Show c, Eq c)
=> (a -> b -> c)
-> (a -> b -> c)
-> Property
equivalent2 f g
= equivalentOnGens2 f g genUnchecked
inverseFunctionsOnGen
:: (Show a, Eq a)
=> (a -> b)
-> (b -> a)
-> Gen a
-> Property
inverseFunctionsOnGen f g gen =
forAll gen $ \a ->
g (f a) `shouldBe` a
inverseFunctionsOnValid
:: (Show a, Eq a, GenValidity a)
=> (a -> b)
-> (b -> a)
-> Property
inverseFunctionsOnValid f g
= inverseFunctionsOnGen f g genValid
inverseFunctions
:: (Show a, Eq a, GenValidity a)
=> (a -> b)
-> (b -> a)
-> Property
inverseFunctions f g
= inverseFunctionsOnGen f g genUnchecked
inverseFunctionsIfFirstSucceedsOnGen
:: (Show a, Eq a, CanFail f)
=> (a -> f b)
-> (b -> a)
-> Gen a
-> Property
inverseFunctionsIfFirstSucceedsOnGen f g gen =
forAll gen $ \a ->
case resultIfSucceeded (f a) of
Nothing -> return ()
Just b -> g b `shouldBe` a
inverseFunctionsIfFirstSucceedsOnValid
:: (Show a, Eq a, GenValidity a, CanFail f)
=> (a -> f b)
-> (b -> a)
-> Property
inverseFunctionsIfFirstSucceedsOnValid f g
= inverseFunctionsIfFirstSucceedsOnGen f g genValid
inverseFunctionsIfFirstSucceeds
:: (Show a, Eq a, GenValidity a, CanFail f)
=> (a -> f b)
-> (b -> a)
-> Property
inverseFunctionsIfFirstSucceeds f g
= inverseFunctionsIfFirstSucceedsOnGen f g genUnchecked
inverseFunctionsIfSecondSucceedsOnGen
:: (Show a, Eq a, CanFail f)
=> (a -> b)
-> (b -> f a)
-> Gen a
-> Property
inverseFunctionsIfSecondSucceedsOnGen f g gen =
forAll gen $ \a ->
case resultIfSucceeded (g (f a)) of
Nothing -> return ()
Just r -> r `shouldBe` a
inverseFunctionsIfSecondSucceedsOnValid
:: (Show a, Eq a, GenValidity a, CanFail f)
=> (a -> b)
-> (b -> f a)
-> Property
inverseFunctionsIfSecondSucceedsOnValid f g
= inverseFunctionsIfSecondSucceedsOnGen f g genValid
inverseFunctionsIfSecondSucceeds
:: (Show a, Eq a, GenValidity a, CanFail f)
=> (a -> b)
-> (b -> f a)
-> Property
inverseFunctionsIfSecondSucceeds f g
= inverseFunctionsIfSecondSucceedsOnGen f g genUnchecked
inverseFunctionsIfSucceedOnGen
:: (Show a, Eq a, CanFail f, CanFail g)
=> (a -> f b)
-> (b -> g a)
-> Gen a
-> Property
inverseFunctionsIfSucceedOnGen f g gen =
forAll gen $ \a ->
case do fa <- resultIfSucceeded $ f a
resultIfSucceeded $ g fa
of
Nothing -> return ()
Just r -> r `shouldBe` a
inverseFunctionsIfSucceedOnValid
:: (Show a, Eq a, GenValidity a, CanFail f, CanFail g)
=> (a -> f b)
-> (b -> g a)
-> Property
inverseFunctionsIfSucceedOnValid f g
= inverseFunctionsIfSucceedOnGen f g genValid
inverseFunctionsIfSucceed
:: (Show a, Eq a, GenValidity a, CanFail f, CanFail g)
=> (a -> f b)
-> (b -> g a)
-> Property
inverseFunctionsIfSucceed f g
= inverseFunctionsIfSucceedOnGen f g genUnchecked
(===>) :: Bool -> Bool -> Bool
(===>) a b = not a || b
reflexivityOnGen
:: Show a
=> (a -> a -> Bool)
-> Gen a
-> Property
reflexivityOnGen func gen =
forAll gen $ \a ->
func a a
reflexivityOnValid
:: (Show a, GenValidity a)
=> (a -> a -> Bool)
-> Property
reflexivityOnValid func
= reflexivityOnGen func genValid
reflexivityOnUnchecked
:: (Show a, GenValidity a)
=> (a -> a -> Bool)
-> Property
reflexivityOnUnchecked func
= reflexivityOnGen func genUnchecked
transitiveOnGens
:: Show a
=> (a -> a -> Bool)
-> Gen (a, a, a)
-> Property
transitiveOnGens func gen =
forAll gen $ \(a, b, c) ->
(func a b && func b c)
===> (func a c)
transitiveOnValid
:: (Show a, GenValidity a)
=> (a -> a -> Bool)
-> Property
transitiveOnValid func
= transitiveOnGens func genValid
transitiveOnUnchecked
:: (Show a, GenValidity a)
=> (a -> a -> Bool)
-> Property
transitiveOnUnchecked func
= transitiveOnGens func genUnchecked
antisymmetryOnGensWithEquality
:: Show a
=> (a -> a -> Bool)
-> Gen (a, a)
-> (a -> a -> Bool)
-> Property
antisymmetryOnGensWithEquality func gen eq =
forAll gen $ \(a, b) ->
(func a b && func b a)
===> (a `eq` b)
antisymmetryOnGensEq
:: (Show a, Eq a)
=> (a -> a -> Bool)
-> Gen (a, a)
-> Property
antisymmetryOnGensEq func gen
= antisymmetryOnGensWithEquality func gen (==)
antisymmetryOnValid
:: (Show a, Eq a, GenValidity a)
=> (a -> a -> Bool)
-> Property
antisymmetryOnValid func =
antisymmetryOnGensEq func genValid
leftIdentityOnGen
:: (Show a, Eq a)
=> (b -> a -> a)
-> b
-> Gen a
-> Property
leftIdentityOnGen op b gen =
forAll gen $ \a ->
b `op` a `shouldBe` a
leftIdentityOnValid
:: (Show a, Eq a, GenValidity a)
=> (b -> a -> a)
-> b
-> Property
leftIdentityOnValid op b
= leftIdentityOnGen op b genValid
leftIdentity
:: (Show a, Eq a, GenValidity a)
=> (b -> a -> a)
-> b
-> Property
leftIdentity op b
= leftIdentityOnGen op b genUnchecked
rightIdentityOnGen
:: (Show a, Eq a)
=> (a -> b -> a)
-> b
-> Gen a
-> Property
rightIdentityOnGen op b gen =
forAll gen $ \a ->
a `op` b `shouldBe` a
rightIdentityOnValid
:: (Show a, Eq a, GenValidity a)
=> (a -> b -> a)
-> b
-> Property
rightIdentityOnValid op b
= rightIdentityOnGen op b genValid
rightIdentity
:: (Show a, Eq a, GenValidity a)
=> (a -> b -> a)
-> b
-> Property
rightIdentity op b
= rightIdentityOnGen op b genUnchecked
identityOnGen
:: (Show a, Eq a)
=> (a -> a -> a)
-> a
-> Gen a
-> Property
identityOnGen op e gen =
leftIdentityOnGen op e gen .&&. rightIdentityOnGen op e gen
identityOnValid
:: (Show a, Eq a, GenValidity a)
=> (a -> a -> a)
-> a
-> Property
identityOnValid op a
= identityOnGen op a genValid
identity
:: (Show a, Eq a, GenValidity a)
=> (a -> a -> a)
-> a
-> Property
identity op e
= identityOnGen op e genUnchecked
associativeOnGens
:: (Show a, Eq a)
=> (a -> a -> a)
-> Gen (a, a, a)
-> Property
associativeOnGens op gen =
forAll gen $ \(a, b, c) ->
((a `op` b) `op` c) `shouldBe` (a `op` (b `op` c))
associativeOnValids
:: (Show a, Eq a, GenValidity a)
=> (a -> a -> a)
-> Property
associativeOnValids op
= associativeOnGens op genValid
associative
:: (Show a, Eq a, GenValidity a)
=> (a -> a -> a)
-> Property
associative op
= associativeOnGens op genUnchecked
commutativeOnGens
:: (Show a, Eq a)
=> (a -> a -> a)
-> Gen (a, a)
-> Property
commutativeOnGens op gen =
forAll gen $ \(a, b) ->
(a `op` b) `shouldBe` (b `op` a)
commutativeOnValids
:: (Show a, Eq a, GenValidity a)
=> (a -> a -> a)
-> Property
commutativeOnValids op
= commutativeOnGens op genValid
commutative
:: (Show a, Eq a, GenValidity a)
=> (a -> a -> a)
-> Property
commutative op
= commutativeOnGens op genUnchecked
nameOf :: Typeable a => Proxy a -> String
nameOf proxy =
let (_, [ty]) = splitTyConApp $ typeOf proxy
in show ty