test-invariant-0.4.0.0: Provide common invariants to be checked with QuickCheck

Safe HaskellSafe-Inferred
LanguageHaskell2010

Test.Invariant

Synopsis

Documentation

(<=>) :: Eq b => (a -> b) -> (a -> b) -> a -> Bool infix 1 Source

Defines extensional equality. This allows concise, point-free, definitions of laws. For example idempotence:

f <=> f . f

(&>) :: Testable b => (a -> Bool) -> (a -> b) -> a -> Property infix 1 Source

Pointfree version of QuickChecks ==>. This notation reduces a lot of lambdas, for example:

>>> quickCheck $ (/=0) &> not . idempotent (*(2::Int))
+++ OK, passed 100 tests.

idempotent :: Eq a => (a -> a) -> a -> Bool Source

Checks whether a function is idempotent.

f(f(x)) == f(x)
>>> quickCheck $ idempotent (abs :: Int -> Int)
+++ OK, passed 100 tests.

pointSymmetric :: (Num a, Num b, Eq b) => (a -> b) -> a -> Bool Source

Checks whether a function is pointSymmetric.

f(-x) == -f(x)
>>> quickCheck $ pointSymmetric (^3)
+++ OK, passed 100 tests.

reflectionSymmetric :: (Num a, Eq b) => (a -> b) -> a -> Bool Source

Checks whether a function is reflectionSymmetric.

f(x) == f(-x)
>>> quickCheck $ pointSymmetric (^2)
+++ OK, passed 100 tests.

monotonicIncreasing :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool Source

Checks whether a function is monotonicIncreasing.

x >= y,  f(x) >= f(y)
>>> quickCheck $ monotonicIncreasing ceiling
+++ OK, passed 100 tests.

monotonicIncreasing' :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool Source

Checks whether a function is strictly monotonicIncreasing'.

x > y,  f(x) > f(y)
>>> quickCheck $ monotonicIncreasing' (+1)
+++ OK, passed 100 tests.

monotonicDecreasing :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool Source

Checks whether a function is monotonicDecreasing.

x >= y,  f(x) <= f(y)
>>> quickCheck $ monotonicDecreasing (\x -> floor $ negate x)
+++ OK, passed 100 tests.

monotonicDecreasing' :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool Source

Checks whether a function is strictly monotonicDecreasing'.

x > y,  f(x) < f(y)
>>> quickCheck $ monotonicDecreasing' (-1)
+++ OK, passed 100 tests.

involutory :: Eq a => (a -> a) -> a -> Bool Source

Checks whether a function is involutory.

f(f(x)) = x
>>> quickCheck $ involutory negate
+++ OK, passed 100 tests.

inverts :: Eq a => (b -> a) -> (a -> b) -> a -> Bool Source

Checks whether a function is the inverse of another function.

f(g(x)) = x
>>> quickCheck $ (`div` 2) `inverts` (*2)
+++ OK, passed 100 tests.

commutative :: Eq b => (a -> a -> b) -> a -> a -> Bool Source

Checks whether an binary operator is commutative.

a * b = b * a
>>> quickCheck $ commutative (+)
+++ OK, passed 100 tests.

associative :: Eq a => (a -> a -> a) -> a -> a -> a -> Bool Source

Checks whether an binary operator is associative.

a + (b + c) = (a + b) + c
>>> quickCheck $ associative (+)
+++ OK, passed 100 tests.

distributesLeftOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool Source

Checks whether an operator is left-distributive over an other operator.

a * (b + c) = (a * b) + (a * c)
>>> quickCheck $ (*) `distributesLeftOver` (+)
+++ OK, passed 100 tests.

distributesRightOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool Source

Checks whether an operator is right-distributive over an other operator.

(b + c) / a = (b / a) + (c / a)
>>> quickCheck $ (/) `distributesRightOver` (+)
+++ OK, passed 100 tests.

distributesOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool Source

Checks whether an operator is distributive over an other operator.

a * (b + c) = (a * b) + (a * c) = (b + c) * a
>>> quickCheck $ (*) `distributesOver` (+)
+++ OK, passed 100 tests.

inflating :: ([a] -> [b]) -> [a] -> Bool Source

Checks whether a function increases the size of a foldable.

>>> quickCheck $ inflating (1:)
+++ OK, passed 100 tests.

deflating :: ([a] -> [b]) -> [a] -> Bool Source

Checks whether a function decreases the size of a foldable.

>>> quickCheck $ deflating tail
+++ OK, passed 100 tests.

cyclesWithin :: Eq a => (a -> a) -> Int -> a -> Bool Source

Checks whether a function is cyclic by applying its result to itself within n applications.

>>> quickCheck $ (`div` 10) `cyclesWithin` 100
+++ OK, passed 100 tests.

invariatesOver :: Eq b => (a -> b) -> (a -> a) -> a -> Bool Source

Checks whether a function is invariant over an other function.

>>> quickCheck $ length `invariatesOver` reverse
+++ OK, passed 100 tests.