| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Test.QuickCheck.Classes
Description
This library provides sets of properties that should hold for common typeclasses.
All of these take a Proxy argument that is used to nail down the type for which
the typeclass dictionaries should be tested. For example, at GHCi:
>>> lawsCheck (monoidLaws (Proxy :: Proxy Ordering))
Monoid: Associative +++ OK, passed 100 tests.
Monoid: Left Identity +++ OK, passed 100 tests.
Monoid: Right Identity +++ OK, passed 100 tests.
Assuming that the Arbitrary instance for Ordering is good, we now
have confidence that the Monoid instance for Ordering satisfies
the monoid laws. We can check multiple typeclasses with:
>>> foldMap (lawsCheck . ($ (Proxy :: Proxy Word))) [jsonLaws,showReadLaws]
ToJSON/FromJSON: Encoding Equals Value +++ OK, passed 100 tests.
ToJSON/FromJSON: Partial Isomorphism +++ OK, passed 100 tests.
Show/Read: Partial Isomorphism +++ OK, passed 100 tests.
- lawsCheck :: Laws -> IO ()
- lawsCheckMany :: [(String, [Laws])] -> IO ()
- bitsLaws :: (FiniteBits a, Arbitrary a, Show a) => Proxy a -> Laws
- commutativeMonoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- eqLaws :: (Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- integralLaws :: (Integral a, Arbitrary a, Show a) => Proxy a -> Laws
- isListLaws :: (IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a), Eq a) => Proxy a -> Laws
- jsonLaws :: (ToJSON a, FromJSON a, Show a, Arbitrary a, Eq a) => Proxy a -> Laws
- monoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- ordLaws :: (Ord a, Arbitrary a, Show a) => Proxy a -> Laws
- primLaws :: (Prim a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- semigroupLaws :: (Semigroup a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- showReadLaws :: (Show a, Read a, Eq a, Arbitrary a) => Proxy a -> Laws
- storableLaws :: (Storable a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
- alternativeLaws :: (Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- altLaws :: (Alt f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- applicativeLaws :: (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- bifunctorLaws :: (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f) => proxy f -> Laws
- foldableLaws :: (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- functorLaws :: (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- monadLaws :: (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- monadPlusLaws :: (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- monadZipLaws :: (MonadZip f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- traversableLaws :: (Traversable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws
- data Laws = Laws {
- lawsTypeclass :: String
- lawsProperties :: [(String, Property)]
Running
lawsCheck :: Laws -> IO () Source #
A convenience function for testing properties in GHCi. See the test suite of this library for an example of how to integrate multiple properties into larger test suite.
A convenience function for checking multiple typeclass instances of multiple types.
Properties
Ground types
bitsLaws :: (FiniteBits a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Conjunction Idempotence
n .&. n ≡ n- Disjunction Idempotence
n .|. n ≡ n- Double Complement
complement (complement n) ≡ n- Set Bit
setBit n i ≡ n .|. bit i- Clear Bit
clearBit n i ≡ n .&. complement (bit i)- Complement Bit
complementBit n i ≡ xor n (bit i)- Clear Zero
clearBit zeroBits i ≡ zeroBits- Set Zero
setBit zeroBits i ≡ bit i- Test Zero
testBit zeroBits i ≡ False- Pop Zero
popCount zeroBits ≡ 0- Count Leading Zeros of Zero
countLeadingZeros zeroBits ≡ finiteBitSize ⊥- Count Trailing Zeros of Zero
countTrailingZeros zeroBits ≡ finiteBitSize ⊥
All of the useful instances of the Bits typeclass
also have FiniteBits instances, so these property
tests actually require that instance as well.
Note: This property test is only available when
using base-4.7 or newer.
commutativeMonoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests everything from monoidProps plus the following:
- Commutative
mappend a b ≡ mappend b a
eqLaws :: (Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Transitive
a == b ∧ b == c ⇒ a == c- Symmetric
a == b ⇒ b == a- Reflexive
a == a
Some of these properties involve implication. In the case that the left hand side of the implication arrow does not hold, we do not retry. Consequently, these properties only end up being useful when the data type has a small number of inhabitants.
integralLaws :: (Integral a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Quotient Remainder
(quot x y) * y + (rem x y) ≡ x- Division Modulus
(div x y) * y + (mod x y) ≡ x- Integer Roundtrip
fromInteger (toInteger x) ≡ x
isListLaws :: (IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a), Eq a) => Proxy a -> Laws Source #
Tests the following properties:
- Partial Isomorphism
fromList . toList ≡ id- Length Preservation
fromList xs ≡ fromListN (length xs) xs
Note: This property test is only available when
using base-4.7 or newer.
jsonLaws :: (ToJSON a, FromJSON a, Show a, Arbitrary a, Eq a) => Proxy a -> Laws Source #
Tests the following properties:
- Partial Isomorphism
decode . encode ≡ Just- Encoding Equals Value
decode . encode ≡ Just . toJSON
Note that in the second property, the type of decode is ByteString -> Value,
not ByteString -> a
monoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Associative
mappend a (mappend b c) ≡ mappend (mappend a b) c- Left Identity
mappend mempty a ≡ a- Right Identity
mappend a mempty ≡ a
ordLaws :: (Ord a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Antisymmetry
- @a ≤ b ∧ b ≤ a ⇒ a = b
- Transitivity
a ≤ b ∧ b ≤ c ⇒ a ≤ c- Totality
a ≤ b ∨ a > b
primLaws :: (Prim a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Test that a Prim instance obey the several laws.
semigroupLaws :: (Semigroup a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws Source #
Tests the following properties:
- Associative
a <> (b <> c) ≡ (a <> b) <> c
Higher-Kinded Types
alternativeLaws :: (Alternative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
applicativeLaws :: (Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
bifunctorLaws :: (Bifunctor f, Eq2 f, Show2 f, Arbitrary2 f) => proxy f -> Laws Source #
foldableLaws :: (Foldable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
Tests the following Foldable properties:
- fold
fold≡foldMapid- foldMap
foldMapf ≡foldr(mappend. f)mempty- foldr
foldrf z t ≡appEndo(foldMap(Endo. f) t ) z- foldr'
foldr'f z0 xs = let f' k x z = k$!f x z infoldlf'idxs z0- foldr1
foldr1f t ≡ let Just (xs,x) = unsnoc (toListt) infoldrf x xs- foldl
foldlf z t ≡appEndo(getDual(foldMap(Dual.Endo.flipf) t)) z- foldl'
foldl'f z0 xs ≡ let f' x k z = k$!f z x infoldrf'idxs z0- foldl1
foldl1f t ≡ let x : xs =toListt infoldlf x xs- toList
toList≡foldr(:) []- null
null≡foldr(const(constFalse))True- length
length≡ getSum . foldMap (const(Sum1))
Note that this checks to ensure that foldl' and foldr'
are suitably strict.
functorLaws :: (Functor f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
monadLaws :: (Monad f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
monadPlusLaws :: (MonadPlus f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
monadZipLaws :: (MonadZip f, Applicative f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
Tests the following monadic zipping properties:
- Naturality
liftM (f *** g) (mzip ma mb) = mzip (liftM f ma) (liftM g mb)
In the laws above, the infix function *** refers to a typeclass
method of Arrow.
traversableLaws :: (Traversable f, Eq1 f, Show1 f, Arbitrary1 f) => proxy f -> Laws Source #
Tests the following Traversable properties:
- Naturality
t .for every applicative transformationtraversef =traverse(t . f)t- Identity
traverseIdentity = Identity- Composition
traverse(Compose .fmapg . f) = Compose .fmap(traverseg) .traversef- Sequence Naturality
t .for every applicative transformationsequenceA=sequenceA.fmaptt- Sequence Identity
sequenceA.fmapIdentity = Identity- Sequence Composition
sequenceA.fmapCompose = Compose .fmapsequenceA.sequenceA- foldMap
foldMap=foldMapDefault- fmap
fmap=fmapDefault
Where an applicative transformation is a function
t :: (Applicative f, Applicative g) => f a -> g a
preserving the Applicative operations, i.e.
Types
A set of laws associated with a typeclass.
Constructors
| Laws | |
Fields
| |