HORIZON HASKELLDocslts/ghc-9.10.xc74966e2026-09-27Search names, modules, packages, or :: a typeCtrl K

GHC 9.10.3 · lts/ghc-9.10.x · c74966e · 2026-09-27

Modulequickcheck-classes-0.6.5.0Haskell2010

Test.QuickCheck.Classes

This library provides sets of properties that should hold for common typeclasses.

Note: on GHC < 8.6, this library uses the higher-kinded typeclasses (Show1, Eq1, Ord1, etc.), but on GHC >= 8.6, it uses -XQuantifiedConstraints to express these constraints more cleanly.

  • 3 types
  • 53 values

Running

3 declarations
valuelawsCheck :: Laws -> IO ()
#

A convenience function for testing properties in GHCi. For example, at GHCi:

Example1 expression
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.

valuelawsCheckMany
  1. :: [(String, [Laws])]

    Element is type name paired with typeclass laws

  2. -> IO ()
#

A convenience function for checking multiple typeclass instances of multiple types. Consider the following Haskell source file:

import Data.Proxy (Proxy(..))
import Data.Map (Map)
import Data.Set (Set)

-- A Proxy for Set Int.
setInt :: Proxy (Set Int)
setInt = Proxy

-- A Proxy for Map Int Int.
mapInt :: Proxy (Map Int Int)
mapInt = Proxy

myLaws :: Proxy a -> [Laws]
myLaws p = [eqLaws p, monoidLaws p]

namedTests :: [(String, [Laws])]
namedTests =
  [ ("Set Int", myLaws setInt)
  , ("Map Int Int", myLaws mapInt)
  ]

Now, in GHCi:

Example1 expression
lawsCheckMany namedTests
Testing properties for common typeclasses
-------------
-- Set Int --
-------------

Eq: Transitive +++ OK, passed 100 tests.
Eq: Symmetric +++ OK, passed 100 tests.
Eq: Reflexive +++ OK, passed 100 tests.
Monoid: Associative +++ OK, passed 100 tests.
Monoid: Left Identity +++ OK, passed 100 tests.
Monoid: Right Identity +++ OK, passed 100 tests.
Monoid: Concatenation +++ OK, passed 100 tests.

-----------------
-- Map Int Int --
-----------------

Eq: Transitive +++ OK, passed 100 tests.
Eq: Symmetric +++ OK, passed 100 tests.
Eq: Reflexive +++ OK, passed 100 tests.
Monoid: Associative +++ OK, passed 100 tests.
Monoid: Left Identity +++ OK, passed 100 tests.
Monoid: Right Identity +++ OK, passed 100 tests.
Monoid: Concatenation +++ OK, passed 100 tests.

In the case of a failing test, the program terminates with exit code 1.

valuelawsCheckOne :: Proxy a -> [Proxy a -> Laws] -> IO ()
#

A convenience function that allows one to check many typeclass instances of the same type.

Example1 expression
specialisedLawsCheckMany (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.

Properties

0 declarations

Ground types

valuebitsLaws :: (FiniteBits a, Arbitrary a, Show a) => Proxy a -> Laws
#

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

Right Rotation

no sign extension → (rotateR n i ≡ (shiftR n i) .|. (shiftL n (finiteBitSize ⊥ - i)))

Left Rotation

no sign extension → (rotateL n i ≡ (shiftL n i) .|. (shiftR n (finiteBitSize ⊥ - i)))

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.

valueeqLaws :: (Eq a, Arbitrary a, Show a) => Proxy a -> Laws
#

Tests the following properties:

Transitive

a == b ∧ b == c ⇒ a == c

Symmetric

a == b ⇒ b == a

Reflexive

a == a

Negation

x /= y == not (x == y)

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.

valuenumLaws :: (Num a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
#

Tests the following properties:

Additive Commutativity

a + b ≡ b + a

Additive Left Identity

0 + a ≡ a

Additive Right Identity

a + 0 ≡ a

Multiplicative Associativity

a * (b * c) ≡ (a * b) * c

Multiplicative Left Identity

1 * a ≡ a

Multiplicative Right Identity

a * 1 ≡ a

Multiplication Left Distributes Over Addition

a * (b + c) ≡ (a * b) + (a * c)

Multiplication Right Distributes Over Addition

(a + b) * c ≡ (a * c) + (b * c)

Multiplicative Left Annihilation

0 * a ≡ 0

Multiplicative Right Annihilation

a * 0 ≡ 0

Additive Inverse

negate a + a ≡ 0

Subtraction

a + negate b ≡ a - b

Abs Is Idempotent

@

abs

(

abs

a) ≡

abs

a

Signum Is Idempotent

@

signum

(

signum

a) ≡

signum

a

Product Of Abs And Signum Is Id

abs a * signum a ≡ a

valueintegralLaws :: (Integral a, Arbitrary a, Show a) => Proxy a -> Laws
#

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

QuotRem is (Quot, Rem)

quotRem x y ≡ (quot x y, rem x y)

DivMod is (Div, Mod)

divMod x y ≡ (div x y, mod x y)

valueisListLaws
  1. :: (IsList a, Show a, Show (Item a), Arbitrary a, Arbitrary (Item a), Eq a)
  2. => Proxy a
  3. -> Laws
#

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.

valuejsonLaws
  1. :: (ToJSON a, FromJSON a, Show a, Arbitrary a, Eq a)
  2. => Proxy a
  3. -> Laws
#

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

valuemonoidLaws :: (Monoid a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
#

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

Concatenation

mconcat as ≡ foldr mappend mempty as

valueordLaws :: (Ord a, Arbitrary a, Show a) => Proxy a -> Laws
#

Tests the following properties:

Antisymmetry

a ≤ b ∧ b ≤ a ⇒ a = b

Transitivity

a ≤ b ∧ b ≤ c ⇒ a ≤ c

Totality

a ≤ b ∨ a > b

valueenumLaws :: (Enum a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
#

Tests the following properties:

Succ Pred Identity

succ (pred x) ≡ x

Pred Succ Identity

pred (succ x) ≡ x

This only works for Enum types that are not bounded, meaning that succ and pred must be total. This means that these property tests work correctly for types like Integer but not for Int.

Sadly, there is not a good way to test fromEnum and toEnum, since many types that have reasonable implementations for succ and pred have more inhabitants than Int does.

valuesemiringLaws :: (Semiring a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
#

Tests the following properties:

Additive Commutativity

a + b ≡ b + a

Additive Left Identity

0 + a ≡ a

Additive Right Identity

a + 0 ≡ a

Multiplicative Associativity

a * (b * c) ≡ (a * b) * c

Multiplicative Left Identity

1 * a ≡ a

Multiplicative Right Identity

a * 1 ≡ a

Multiplication Left Distributes Over Addition

a * (b + c) ≡ (a * b) + (a * c)

Multiplication Right Distributes Over Addition

(a + b) * c ≡ (a * c) + (b * c)

Multiplicative Left Annihilation

0 * a ≡ 0

Multiplicative Right Annihilation

a * 0 ≡ 0

Also tests that fromNatural is a homomorphism of semirings:

FromNatural Maps Zero

fromNatural

0 =

zero

FromNatural Maps One

fromNatural

1 =

one

FromNatural Maps Plus

fromNatural

(

a

+

b

) =

fromNatural

a

+

fromNatural

b

FromNatural Maps Times

fromNatural

(

a

*

b

) =

fromNatural

a

*

fromNatural

b

valuegcdDomainLaws :: (Eq a, GcdDomain a, Arbitrary a, Show a) => Proxy a -> Laws
#

Test that a GcdDomain instance obey several laws.

Check that divide is an inverse of times:

  • y /= 0 => (x * y) `divide` y == Just x,

  • y /= 0, x `divide` y == Just z => x == z * y.

Check that gcd is a common divisor and is a multiple of any common divisor:

  • x /= 0, y /= 0 => isJust (x `divide` gcd x y) && isJust (y `divide` gcd x y),

  • z /= 0 => isJust (gcd (x * z) (y * z) `divide` z).

Check that lcm is a common multiple and is a factor of any common multiple:

  • x /= 0, y /= 0 => isJust (lcm x y `divide` x) && isJust (lcm x y `divide` y),

  • x /= 0, y /= 0, isJust (z `divide` x), isJust (z `divide` y) => isJust (z `divide` lcm x y).

Check that gcd of coprime numbers is a unit of the semiring (has an inverse):

  • y /= 0, coprime x y => isJust (1 `divide` gcd x y).

valueeuclideanLaws :: (Eq a, Euclidean a, Arbitrary a, Show a) => Proxy a -> Laws
#

Test that a Euclidean instance obey laws of a Euclidean domain.

  • y /= 0, r == x `rem` y => r == 0 || degree r < degree y,

  • y /= 0, (q, r) == x `quotRem` y => x == q * y + r,

  • y /= 0 => x `quot` x y == fst (x `quotRem` y),

  • y /= 0 => x `rem` x y == snd (x `quotRem` y).

valueshowReadLaws :: (Show a, Read a, Eq a, Arbitrary a) => Proxy a -> Laws
#

Tests the following properties:

Partial Isomorphism: show / read

readMaybe (show a) ≡ Just a

Partial Isomorphism: show / read with initial space

readMaybe (" " ++ show a) ≡ Just a

Partial Isomorphism: showsPrec / readsPrec

(a,"") `elem` readsPrec p (showsPrec p a "")

Partial Isomorphism: showList / readList

(as,"") `elem` readList (showList as "")

Partial Isomorphism: showListWith shows / readListDefault

(as,"") `elem` readListDefault (showListWith shows as "")

Note: When using base-4.5 or older, a shim implementation of readMaybe is used.

valuegenericLaws
  1. :: (Generic a, Eq a, Arbitrary a, Show a, Show (Rep a ()), Arbitrary (Rep a ()), Eq (Rep a ()))
  2. => Proxy a
  3. -> Laws
#

Tests the following properties:

From-To Inverse

from . to ≡ id

To-From Inverse

to . from ≡ id

Note: This property test is only available when using base-4.5 or newer.

Note: from and to don't actually care about the type variable x in Rep a x, so here we instantiate it to () by default. If you would like to instantiate x as something else, please file a bug report.

Unary type constructors

valuefoldableLaws
  1. :: (Foldable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
  2. => proxy f
  3. -> Laws
#

Tests the following Foldable properties:

fold

fold ≡ foldMap id

foldMap

foldMap f ≡ foldr (mappend . f) mempty

foldr

foldr f z t ≡ appEndo (foldMap (Endo . f) t ) z

foldr'

foldr' f z0 xs ≡ let f' k x z = k $! f x z in foldl f' id xs z0

foldr1

foldr1 f t ≡ let Just (xs,x) = unsnoc (toList t) in foldr f x xs

foldl

foldl f z t ≡ appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z

foldl'

foldl' f z0 xs ≡ let f' x k z = k $! f z x in foldr f' id xs z0

foldl1

foldl1 f t ≡ let x : xs = toList t in foldl f x xs

toList

toList ≡ foldr (:) []

null

null ≡ foldr (const (const False)) True

length

length ≡ getSum . foldMap (const (Sum 1))

Note that this checks to ensure that foldl' and foldr' are suitably strict.

valuetraversableLaws
  1. :: (Traversable f, forall a. Eq a => Eq (f a), forall a. Show a => Show (f a), forall a. Arbitrary a => Arbitrary (f a))
  2. => proxy f
  3. -> Laws
#

Tests the following Traversable properties:

Naturality

t . traverse f ≡ traverse (t . f)

for every applicative transformation

t

Identity

traverse Identity ≡ Identity

Composition

traverse (Compose . fmap g . f) ≡ Compose . fmap (traverse g) . traverse f

Sequence Naturality

t . sequenceA ≡ sequenceA . fmap t

for every applicative transformation

t

Sequence Identity

sequenceA . fmap Identity ≡ Identity

Sequence Composition

sequenceA . fmap Compose ≡ Compose . fmap sequenceA . 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.

  • Identity: t (pure x) ≡ pure x

  • Distributivity: t (x <*> y) ≡ t x <*> t y

Binary type constructors

valuebifoldableLaws
  1. :: (Bifoldable f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
  2. => proxy f
  3. -> Laws
#

Tests the following Bifunctor properties:

Bifold Identity

bifold ≡ bifoldMap id id

BifoldMap Identity

bifoldMap f g ≡ bifoldr (mappend . f) (mappend . g) mempty

Bifoldr Identity

bifoldr f g z t ≡ appEndo (bifoldMap (Endo . f) (Endo . g) t) z

Note: This property test is only available when this package is built with base-4.10+ or transformers-0.5+.

valuebitraversableLaws
  1. :: (Bitraversable f, forall a b. (Eq a, Eq b) => Eq (f a b), forall a b. (Show a, Show b) => Show (f a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (f a b))
  2. => proxy f
  3. -> Laws
#

Tests the following Bitraversable properties:

Naturality

bitraverse (t . f) (t . g) ≡ t . bitraverse f g

for every applicative transformation

t

Identity

bitraverse Identity Identity ≡ Identity

Composition

Compose . fmap (bitraverse g1 g2) . bitraverse f1 f2 ≡ bitraverse (Compose . fmap g1 g2 . f1) (Compose . fmap g2 . f2)

Note: This property test is only available when this package is built with base-4.9+ or transformers-0.5+.

valuecategoryLaws
  1. :: (Category c, forall a b. (Eq a, Eq b) => Eq (c a b), forall a b. (Show a, Show b) => Show (c a b), forall a b. (Arbitrary a, Arbitrary b) => Arbitrary (c a b))
  2. => proxy c
  3. -> Laws
#

Tests the following Category properties:

Right Identity

f . id ≡ f

Left Identity

id . f ≡ f

Associativity

f . (g . h) ≡ (f . g) . h

Note: This property test is only available when this package is built with base-4.9+ or transformers-0.5+.

Types

3 declarations
datadata Laws
#

A set of laws associated with a typeclass.

Note: Most of the top-level functions provided by this library have the shape `forall a. (Ctx a) => Proxy a -> Laws`. You can just as easily provide your own Laws in libraries/test suites using regular QuickCheck machinery.

Constructors

datadata Proxy1 (f :: Type -> Type)
#

In older versions of GHC, Proxy is not poly-kinded, so we provide Proxy1.

datadata Proxy2 (f :: Type -> Type -> Type)
#

In older versions of GHC, Proxy is not poly-kinded, so we provide Proxy2.