-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Provide common invariants to be checked with QuickCheck
--   
--   test-invariant is a library for providing common invariants of
--   functions as higher order polymorphic functions. This reduces for a
--   lot of cases the need for writing prop_ functions for QuickCheck.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ idempotent (abs :: Int -&gt; Int)
--   
--   &gt;&gt;&gt; quickCheck $ involutory not
--   
--   &gt;&gt;&gt; quickCheck $ not . involutory (+ (2 :: Int))
--   </pre>
@package test-invariant
@version 0.4.5.0

module Test.Invariant

-- | Defines extensional equality. This allows concise, point-free,
--   definitions of laws.
--   
--   <pre>
--   f(x) == g(x)
--   f &lt;=&gt; g
--   </pre>
(<=>) :: Eq b => (a -> b) -> (a -> b) -> a -> Bool
infix 2 <=>

-- | Pointfree version of QuickChecks ==&gt;. This notation reduces a lot
--   of lambdas, for example:
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (/=0) &amp;&gt; not . idempotent (*(2::Int))
--   +++ OK, passed 100 tests.
--   </pre>
(&>) :: Testable b => (a -> Bool) -> (a -> b) -> a -> Property
infix 1 &>

-- | Checks whether a function is idempotent.
--   
--   <pre>
--   f(f(x)) == f(x)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ idempotent (abs :: Int -&gt; Int)
--   +++ OK, passed 100 tests.
--   </pre>
idempotent :: Eq a => (a -> a) -> a -> Bool

-- | Checks whether a function is pointSymmetric.
--   
--   <pre>
--   f(-x) == -f(x)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ pointSymmetric (^3)
--   +++ OK, passed 100 tests.
--   </pre>
pointSymmetric :: (Num a, Num b, Eq b) => (a -> b) -> a -> Bool

-- | Checks whether a function is reflectionSymmetric.
--   
--   <pre>
--   f(x) == f(-x)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ pointSymmetric (^2)
--   +++ OK, passed 100 tests.
--   </pre>
reflectionSymmetric :: (Num a, Eq b) => (a -> b) -> a -> Bool

-- | Checks whether a function is monotonicIncreasing.
--   
--   <pre>
--   x &gt;= y,  f(x) &gt;= f(y)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ monotonicIncreasing ceiling
--   +++ OK, passed 100 tests.
--   </pre>
monotonicIncreasing :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool

-- | Checks whether a function is strictly monotonicIncreasing'.
--   
--   <pre>
--   x &gt; y,  f(x) &gt; f(y)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ monotonicIncreasing' (+1)
--   +++ OK, passed 100 tests.
--   </pre>
monotonicIncreasing' :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool

-- | Checks whether a function is monotonicDecreasing.
--   
--   <pre>
--   x &gt;= y,  f(x) &lt;= f(y)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ monotonicDecreasing (\x -&gt; floor $ negate x)
--   +++ OK, passed 100 tests.
--   </pre>
monotonicDecreasing :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool

-- | Checks whether a function is strictly monotonicDecreasing'.
--   
--   <pre>
--   x &gt; y,  f(x) &lt; f(y)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ monotonicDecreasing' (-1)
--   +++ OK, passed 100 tests.
--   </pre>
monotonicDecreasing' :: (Ord a, Ord b) => (a -> b) -> a -> a -> Bool

-- | Checks whether a function is involutory.
--   
--   <pre>
--   f(f(x)) = x
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ involutory negate
--   +++ OK, passed 100 tests.
--   </pre>
involutory :: Eq a => (a -> a) -> a -> Bool

-- | Checks whether a function is the inverse of another function.
--   
--   <pre>
--   f(g(x)) = x
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (`div` 2) `inverts` (*2)
--   +++ OK, passed 100 tests.
--   </pre>
inverts :: Eq a => (b -> a) -> (a -> b) -> a -> Bool

-- | Checks whether an binary operator is commutative.
--   
--   <pre>
--   a * b = b * a
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ commutative (+)
--   +++ OK, passed 100 tests.
--   </pre>
commutative :: Eq b => (a -> a -> b) -> a -> a -> Bool

-- | Checks whether an binary operator is associative.
--   
--   <pre>
--   a + (b + c) = (a + b) + c
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ associative (+)
--   +++ OK, passed 100 tests.
--   </pre>
associative :: Eq a => (a -> a -> a) -> a -> a -> a -> Bool

-- | Checks whether an operator is left-distributive over an other
--   operator.
--   
--   <pre>
--   a * (b + c) = (a * b) + (a * c)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (*) `distributesLeftOver` (+)
--   +++ OK, passed 100 tests.
--   </pre>
distributesLeftOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool

-- | Checks whether an operator is right-distributive over an other
--   operator.
--   
--   <pre>
--   (b + c) / a = (b / a) + (c / a)
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (/) `distributesRightOver` (+)
--   +++ OK, passed 100 tests.
--   </pre>
distributesRightOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool

-- | Checks whether an operator is distributive over an other operator.
--   
--   <pre>
--   a * (b + c) = (a * b) + (a * c) = (b + c) * a
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (*) `distributesOver` (+)
--   +++ OK, passed 100 tests.
--   </pre>
distributesOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool

-- | Checks whether a function increases the size of a list.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ inflating (1:)
--   +++ OK, passed 100 tests.
--   </pre>
inflating :: ([a] -> [b]) -> [a] -> Bool

-- | Checks whether a function increases strictly the size of a list.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ inflating (1:)
--   +++ OK, passed 100 tests.
--   </pre>
inflating' :: ([a] -> [b]) -> [a] -> Bool

-- | Checks whether a function decreases the size of a list.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ deflating tail
--   +++ OK, passed 100 tests.
--   </pre>
deflating :: ([a] -> [b]) -> [a] -> Bool

-- | Checks whether a function decreases strictly the size of a list.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ deflating tail
--   +++ OK, passed 100 tests.
--   </pre>
deflating' :: ([a] -> [b]) -> [a] -> Bool

-- | Checks whether a function is cyclic by applying its result to itself
--   within n applications.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (`div` 10) `cyclesWithin` 100
--   +++ OK, passed 100 tests.
--   </pre>
cyclesWithin :: Eq a => (a -> a) -> Int -> a -> Bool

-- | Checks whether a function is invariant over an other function.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ length `invariatesOver` reverse
--   +++ OK, passed 100 tests.
--   </pre>
invariatesOver :: Eq b => (a -> b) -> (a -> a) -> a -> Bool

-- | Checks whether a binary function is fixed by an argument.
--   
--   f x y == const a y
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (*) `fixedBy` 0
--   +++ OK, passed 100 tests.
--   </pre>
fixedBy :: Eq c => (a -> b -> c) -> a -> b -> b -> Bool

-- | Checks whether a function is invariant over an other function.
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ length &lt;~~ reverse
--   +++ OK, passed 100 tests.
--   </pre>
(<~~) :: Eq b => (a -> b) -> (a -> a) -> a -> Bool
infix 2 <~~

-- | Checks whether a function is the inverse of another function.
--   
--   <pre>
--   f(g(x)) = x
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (`div` 2) @~&gt; (*2)
--   +++ OK, passed 100 tests.
--   </pre>
(@~>) :: Eq a => (b -> a) -> (a -> b) -> a -> Bool
infix 2 @~>

-- | Checks whether a function is an endomorphism in relation to a unary
--   operator.
--   
--   <pre>
--   f(g(x)) = g(f(x))
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (*7) &lt;?&gt; abs
--   +++ OK, passed 100 tests.
--   </pre>
(<?>) :: Eq a => (a -> a) -> (a -> a) -> a -> Bool
infix 2 <?>

-- | Checks whether a function is an endomorphism in relation to a binary
--   operator.
--   
--   <pre>
--   f(g(x,y)) = g(f(x),f(y))
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; quickCheck $ (^2) &lt;??&gt; (*)
--   +++ OK, passed 100 tests.
--   </pre>
(<??>) :: Eq a => (a -> a) -> (a -> a -> a) -> a -> a -> Bool

-- | Checks whether a function is an endomorphism in relation to a ternary
--   operator.
--   
--   <pre>
--   f(g(x,y,z)) = g(f(x),f(y),f(z))
--   </pre>
(<???>) :: Eq a => (a -> a) -> (a -> a -> a -> a) -> a -> a -> a -> Bool
