leancheck-0.9.2: src/Test/LeanCheck/Utils/Operators.hs
-- |
-- Module : Test.LeanCheck.Utils.Operators
-- Copyright : (c) 2015-2020 Rudy Matela
-- License : 3-Clause BSD (see the file LICENSE)
-- Maintainer : Rudy Matela <rudy@matela.com.br>
--
-- This module is part of LeanCheck,
-- a simple enumerative property-based testing library.
--
-- Some operators for property-based testing.
module Test.LeanCheck.Utils.Operators
(
-- * Combining properties
(==>)
, (===), (====)
, (&&&), (&&&&), (&&&&&)
, (|||), (||||)
-- * Properties of unary functions
, isIdempotent
, isIdentity
, isNeverIdentity
-- * Properties of operators (binary functions)
, isCommutative
, isAssociative
, isDistributiveOver
, isLeftDistributiveOver
, isRightDistributiveOver
, isFlipped
-- * Properties of relations (binary functions returning truth values)
, isTransitive
, isReflexive
, isIrreflexive
, isSymmetric
, isAsymmetric
, isAntisymmetric
-- * Properties of order relations
, isEquivalence
, isPartialOrder
, isStrictPartialOrder
, isTotalOrder
, isStrictTotalOrder
, isComparison
-- * Ternary comparison operators
, (=$), ($=)
, (=|), (|=)
-- * Properties for typeclass instances
, okEq
, okOrd
, okEqOrd
, okNum
, okNumNonNegative
-- * Deprecated functions
, idempotent
, identity
, neverIdentity
, commutative
, associative
, distributive
, symmetric2
, transitive
, reflexive
, irreflexive
, symmetric
, asymmetric
, antisymmetric
, equivalence
, partialOrder
, strictPartialOrder
, totalOrder
, strictTotalOrder
, comparison
)
where
import Test.LeanCheck ((==>))
combine :: (b -> c -> d) -> (a -> b) -> (a -> c) -> (a -> d)
combine (?) f g = \x -> f x ? g x
-- Uneeded, just food for thought:
-- > combine2 :: (c -> d -> e) -> (a -> b -> c) -> (a -> b -> d) -> (a -> b -> e)
-- Two possible implementations:
-- > combine2 op f g = \x y -> f x y `op` g x y
-- > combine2 = combine . combine
-- | Allows building equality properties between functions.
--
-- > prop_id_idempotent = id === id . id
--
-- > > check $ id === (+0)
-- > +++ OK, passed 200 tests.
--
-- > > check $ id === id . id
-- > +++ OK, passed 1 tests (exhausted).
--
-- > > check $ id === (+1)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0
(===) :: Eq b => (a -> b) -> (a -> b) -> a -> Bool
(===) = combine (==)
infix 4 ===
-- | Allows building equality properties between two-argument functions.
--
-- > > holds 100 $ const ==== asTypeOf
-- > True
--
-- > > holds 100 $ (+) ==== flip (+)
-- > True
--
-- > > holds 100 $ (+) ==== (*)
-- > False
(====) :: Eq c => (a -> b -> c) -> (a -> b -> c) -> a -> b -> Bool
(====) = combine (===)
infix 4 ====
-- | And ('&&') operator over one-argument properties.
--
-- Allows building conjuntions between one-argument properties:
--
-- > > holds 100 $ id === (+0) &&& id === (id . id)
-- > True
(&&&) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
(&&&) = combine (&&)
infixr 3 &&&
-- | And ('&&') operator over two-argument properties.
--
-- Allows building conjuntions between two-argument properties:
--
-- > > holds 100 $ (+) ==== flip (+) &&&& (+) ==== (*)
-- > False
(&&&&) :: (a -> b -> Bool) -> (a -> b -> Bool) -> a -> b -> Bool
(&&&&) = combine (&&&)
infixr 3 &&&&
-- | And operator over three-argument properties.
(&&&&&) :: (a -> b -> c -> Bool) -> (a -> b -> c -> Bool) -> a -> b -> c -> Bool
(&&&&&) = combine (&&&&)
infixr 3 &&&&&
-- | Or ('||') operator over one-argument properties.
--
-- Allows building disjunctions between one-argument properties:
--
-- > > holds 100 $ id === (+0) ||| id === (id . id)
-- > True
(|||) :: (a -> Bool) -> (a -> Bool) -> a -> Bool
(|||) = combine (||)
infixr 2 |||
-- | Or ('||') operator over two-argument properties.
--
-- Allows building conjuntions between two-argument properties:
--
-- > > holds 100 $ (+) ==== flip (+) |||| (+) ==== (*)
-- > True
(||||) :: (a -> b -> Bool) -> (a -> b -> Bool) -> a -> b -> Bool
(||||) = combine (|||)
infixr 2 ||||
-- | Is a given operator commutative? @x + y = y + x@
--
-- > > check $ isCommutative (+)
-- > +++ OK, passed 200 tests.
--
-- > > import Data.List
-- > > check $ isCommutative (union :: [Int]->[Int]->[Int])
-- > *** Failed! Falsifiable (after 4 tests):
-- > [] [0,0]
isCommutative :: Eq b => (a -> a -> b) -> a -> a -> Bool
isCommutative (?) = \x y -> x ? y == y ? x
-- | Is a given operator associative? @x + (y + z) = (x + y) + z@
--
-- > > check $ isAssociative (+)
-- > +++ OK, passed 200 tests.
--
-- > > check $ isAssociative (-)
-- > *** Failed! Falsifiable (after 2 tests):
-- > 0 0 1
isAssociative :: Eq a => (a -> a -> a) -> a -> a -> a -> Bool
isAssociative (?) = \x y z -> x ? (y ? z) == (x ? y) ? z
-- | Does the first operator, left-distributes over the second?
--
-- This is an alias to 'isLeftDistributiveOver'.
isDistributiveOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool
isDistributiveOver = isLeftDistributiveOver
-- | Does the first operator, left-distributes over the second?
-- @x * (y + z) = (x * y) + (x * z)@
--
-- > > check $ (*) `isLeftDistributiveOver` (+)
-- > +++ OK, passed 200 tests.
--
-- > > check $ (+) `isLeftDistributiveOver` (*)
-- > *** Failed! Falsifiable (after 8 tests):
-- > 1 0 1
isLeftDistributiveOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool
(?) `isLeftDistributiveOver` (#) = \x y z -> x ? (y # z) == (x ? y) # (x ? z)
-- | Does the first operator, right-distributes over the second?
-- @(y + z) * x = (y * x) + (z * x)@
--
-- > > check $ (*) `isRightDistributiveOver` (+)
-- > +++ OK, passed 200 tests.
--
-- > > check $ (+) `isRightDistributiveOver` (*)
-- > *** Failed! Falsifiable (after 8 tests):
-- > 1 0 1
isRightDistributiveOver :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool
(?) `isRightDistributiveOver` (#) = \x y z -> (y # z) ? x == (y ? x) # (z ? x)
-- | Are two operators 'flip'ped versions of each other?
--
-- > > check $ ((<) `isFlipped` (>) :: Int -> Int -> Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ ((<=) `isFlipped` (>=) :: Int -> Int -> Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ ((<) `isFlipped` (>=) :: Int -> Int -> Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0 0
--
-- > > check $ ((<=) `isFlipped` (>) :: Int -> Int -> Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0 0
isFlipped :: Eq c => (a -> b -> c) -> (b -> a -> c) -> a -> b -> Bool
(+-) `isFlipped` (-+) = \x y -> x +- y == y -+ x
-- | Is a given relation transitive?
--
-- A relation is transitive when
-- if a is related to b then b is related to c.
--
-- > > check $ isTransitive ((==) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ isTransitive ((/=) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 3 tests):
-- > 0 1 0
isTransitive :: (a -> a -> Bool) -> a -> a -> a -> Bool
isTransitive (?) = \x y z -> x ? y && y ? z ==> x ? z
-- | Is a given relation reflexive?
--
-- A relation is reflexive when
-- an element is always related to itself.
--
-- > > check $ isReflexive ((==) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ isReflexive ((/=) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0
isReflexive :: (a -> a -> Bool) -> a -> Bool
isReflexive (?) = \x -> x ? x
-- | Is a given relation irreflexive?
--
-- A given relation is irreflexive or anti-reflexive
-- when an element is _never_ related to itself.
--
-- This is /not/ the negation of 'isReflexive'.
--
-- > > check $ isIrreflexive ((==) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0
--
-- > > check $ isIrreflexive ((/=) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
isIrreflexive :: (a -> a -> Bool) -> a -> Bool
isIrreflexive (?) = \x -> not $ x ? x
-- | Is a given relation symmetric?
--
-- A relation is symmetric when
-- if a is related to b, then b is related to a.
--
-- > > check $ isSymmetric (&&)
-- > +++ OK, passed 4 tests (exhausted).
--
-- > > check $ isSymmetric (==>)
-- > *** Failed! Falsifiable (after 2 tests):
-- > False True
--
-- This is a type-restricted version of 'isCommutative'.
isSymmetric :: (a -> a -> Bool) -> a -> a -> Bool
isSymmetric = isCommutative
-- | Is a given relation antisymmetric?
--
-- Not to be confused with 'isAsymmetric'.
-- Not to be confused with the negation of 'isSymmetric'.
--
-- > > check $ isAntisymmetric ((<=) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ isAntisymmetric ((/=) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 2 tests):
-- > 0 1
isAntisymmetric :: Eq a => (a -> a -> Bool) -> a -> a -> Bool
isAntisymmetric (?) = \x y -> x ? y && y ? x ==> x == y
-- | Is a given relation asymmetric?
--
-- Not to be confused with not 'isSymmetric' and 'isAntisymmetric'.
--
-- > > check $ isAsymmetric ((<=) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0 0
--
-- > > check $ isAsymmetric ((<) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
isAsymmetric :: (a -> a -> Bool) -> a -> a -> Bool
isAsymmetric (?) = \x y -> x ? y ==> not (y ? x)
-- | Is the given binary relation an equivalence?
--
-- In other words,
-- is the given relation reflexive, symmetric and transitive?
--
-- > > check (isEquivalence (==) :: Int -> Int -> Int -> Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check (isEquivalence (<=) :: Int -> Int -> Int -> Bool)
-- > *** Failed! Falsifiable (after 3 tests):
-- > 0 1 0
--
-- Or, using "Test.LeanCheck.Utils.TypeBinding":
--
-- > > check $ isEquivalence (<=) -:> int
-- > *** Failed! Falsifiable (after 3 tests):
-- > 0 1 0
isEquivalence :: (a -> a -> Bool) -> a -> a -> a -> Bool
isEquivalence (==) = \x y z -> isReflexive (==) x
&& isSymmetric (==) x y
&& isTransitive (==) x y z
-- | Is the given binary relation a partial order?
--
-- In other words,
-- is the given relation reflexive, antisymmetric and transitive?
--
-- > > check $ isPartialOrder ((<) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0 0 0
--
-- > > check $ isPartialOrder ((<=) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ isPartialOrder isSubsetOf
-- > +++ OK, passed 200 tests.
isPartialOrder :: Eq a => (a -> a -> Bool) -> a -> a -> a -> Bool
isPartialOrder (<=) = \x y z -> isReflexive (<=) x
&& isAntisymmetric (<=) x y
&& isTransitive (<=) x y z
-- | Is the given binary relation a strict partial order?
--
-- In other words,
-- is the given relation irreflexive, asymmetric and transitive?
--
-- > > check $ isStrictPartialOrder ((<) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ isStrictPartialOrder ((<=) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0 0 0
isStrictPartialOrder :: (a -> a -> Bool) -> a -> a -> a -> Bool
isStrictPartialOrder (<) = \x y z -> isIrreflexive (<) x
&& isAsymmetric (<) x y -- implied?
&& isTransitive (<) x y z
-- | Is the given binary relation a total order?
--
-- > > check $ isTotalOrder ((<) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0 0 0
-- > > check $ isTotalOrder ((<=) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
isTotalOrder :: Eq a => (a -> a -> Bool) -> a -> a -> a -> Bool
isTotalOrder (<=) = \x y z -> (x <= y || y <= x)
&& isAntisymmetric (<=) x y
&& isTransitive (<=) x y z
-- | Is the given binary relation a strict total order?
--
-- > > check $ isStrictTotalOrder ((<=) :: Int->Int->Bool)
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0 0 0
--
-- > > check $ isStrictTotalOrder ((<) :: Int->Int->Bool)
-- > +++ OK, passed 200 tests.
isStrictTotalOrder :: Eq a => (a -> a -> Bool) -> a -> a -> a -> Bool
isStrictTotalOrder (<) = \x y z -> (x /= y ==> x < y || y < x)
&& isIrreflexive (<) x
&& isAsymmetric (<) x y -- implied?
&& isTransitive (<) x y z
-- | Does the given 'compare' function follow the required properties?
--
-- This is useful for testing custom 'Ord' instances.
--
-- > > check $ isComparison (compare :: Int->Int->Ordering)
-- > +++ OK, passed 200 tests.
isComparison :: (a -> a -> Ordering) -> a -> a -> a -> Bool
isComparison compare = \x y z -> isEquivalence (===) x y z
&& isIrreflexive (<) x
&& isTransitive (<) x y z
&& ((<) `isFlipped` (>)) x y
where
x === y = x `compare` y == EQ
x < y = x `compare` y == LT
x > y = x `compare` y == GT
-- | Is the given function idempotent? @f (f x) == x@
--
-- > > check $ isIdempotent abs
-- > +++ OK, passed 200 tests.
--
-- > > check $ isIdempotent sort
-- > +++ OK, passed 200 tests.
--
-- > > check $ isIdempotent negate
-- > *** Failed! Falsifiable (after 2 tests):
-- > 1
isIdempotent :: Eq a => (a -> a) -> a -> Bool
isIdempotent f = f . f === f
-- | Is the given function an identity? @f x == x@
--
-- > > check $ isIdentity (+0)
-- > +++ OK, passed 200 tests.
--
-- > > check $ isIdentity (sort :: [()]->[()])
-- > +++ OK, passed 200 tests.
--
-- > > check $ isIdentity (not . not)
-- > +++ OK, passed 2 tests (exhausted).
isIdentity :: Eq a => (a -> a) -> a -> Bool
isIdentity f = f === id
-- | Is the given function never an identity? @f x /= x@
--
-- > > check $ neverIdentity not
-- > +++ OK, passed 2 tests (exhausted).
--
-- > > check $ neverIdentity negate
-- > *** Failed! Falsifiable (after 1 tests):
-- > 0
--
-- Note: this is not the same as not being an 'identity'.
isNeverIdentity :: Eq a => (a -> a) -> a -> Bool
isNeverIdentity = (not .) . isIdentity
-- | Is this 'Eq' instance valid?
--
-- This is useful for testing your custom 'Eq' instances
-- against required properties.
--
-- In particular,
-- this function tests that '==' is an equivalence
-- and that '/=' is the negation of '=='.
--
-- > > check $ (okEq :: Int -> Int -> Int -> Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ (okEq :: Bool -> Bool -> Bool -> Bool)
-- > +++ OK, passed 8 tests (exhausted).
okEq :: Eq a => a -> a -> a -> Bool
okEq x y z = isEquivalence (==) x y z
&& (x /= y) == not (x == y)
-- | Is this 'Ord' instance valid?
--
-- This is useful for testing your custom 'Ord' instances
-- against required properties.
--
-- > > check $ (okOrd :: Int -> Int -> Int -> Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ (okOrd :: Bool -> Bool -> Bool -> Bool)
-- > +++ OK, passed 8 tests (exhausted).
okOrd :: Ord a => a -> a -> a -> Bool
okOrd x y z = isTotalOrder (<=) x y z
&& isComparison compare x y z
&& (x <= y) == ((x `compare` y) `elem` [LT,EQ])
-- | Is this 'Eq' and 'Ord' instance valid and consistent?
--
-- This is useful for testing your custom 'Eq' and 'Ord' instances
-- against required properties.
--
-- > > check $ (okEqOrd :: Int -> Int -> Int -> Bool)
-- > +++ OK, passed 200 tests.
--
-- > > check $ (okEqOrd :: Bool -> Bool -> Bool -> Bool)
-- > +++ OK, passed 8 tests (exhausted).
okEqOrd :: (Eq a, Ord a) => a -> a -> a -> Bool
okEqOrd x y z = okEq x y z
&& okOrd x y z
&& (x == y) == (x `compare` y == EQ) -- consistent instances
-- | Like 'okNum' but restricted to zero and positives.
--
-- > > check (okNumNonNegative :: Natural -> Natural -> Natural -> Bool)
-- > +++ OK, passed 200 tests.
okNumNonNegative :: (Eq a, Num a) => a -> a -> a -> Bool
okNumNonNegative x y z = isCommutative (+) x y
&& isCommutative (*) x y
&& isAssociative (+) x y z
&& isAssociative (*) x y z
&& ((*) `isDistributiveOver` (+)) x y z
&& isIdempotent (+0) x
&& isIdempotent (*1) x
&& isIdempotent abs x
&& isIdempotent signum x
&& abs x * signum x == x
-- | Is this 'Num' instance valid?
--
-- This is useful for testing your custom 'Num' instances
-- against required properties.
--
-- > > check (okNum :: Int -> Int -> Int -> Bool)
-- > +++ OK, passed 200 tests.
--
-- Double is /mostly/ valid, but not /entirely/ valid:
--
-- > > check (okNum :: Double -> Double -> Double -> Bool)
-- > *** Failed! Falsifiable (after 6 tests):
-- 0.0 0.0 Infinity
okNum :: (Eq a, Num a) => a -> a -> a -> Bool
okNum x y z = okNumNonNegative x y z
&& negate (negate x) == x
&& x - x == 0
-- | Equal under, a ternary operator with the same fixity as '=='.
--
-- > x =$ f $= y = f x == f y
--
-- > > [1,2,3,4,5] =$ take 2 $= [1,2,4,8,16]
-- > True
--
-- > > [1,2,3,4,5] =$ take 3 $= [1,2,4,8,16]
-- > False
--
-- > > [1,2,3] =$ sort $= [3,2,1]
-- > True
--
-- > > 42 =$ (`mod` 10) $= 16842
-- > True
--
-- > > 42 =$ (`mod` 9) $= 16842
-- > False
--
-- > > 'a' =$ isLetter $= 'b'
-- > True
--
-- > > 'a' =$ isLetter $= '1'
-- > False
(=$) :: Eq b => a -> (a -> b) -> a -> Bool
(x =$ f) y = f x == f y
infixl 4 =$
-- | See '=$'
($=) :: (a -> Bool) -> a -> Bool
($=) = ($)
infixl 4 $=
-- | Check if two lists are equal for @n@ values.
-- This operator has the same fixity of '=='.
--
-- > xs =| n |= ys = take n xs == take n ys
--
-- > [1,2,3,4,5] =| 2 |= [1,2,4,8,16] -- > True
-- > [1,2,3,4,5] =| 3 |= [1,2,4,8,16] -- > False
(=|) :: Eq a => [a] -> Int -> [a] -> Bool
xs =| n = xs =$ take n
infixl 4 =|
-- | See '=|'
(|=) :: (a -> Bool) -> a -> Bool
(|=) = ($)
infixl 4 |=
-- | Deprecated: use 'isCommutative'.
{-# DEPRECATED commutative "Use isCommutative." #-}
commutative :: Eq b => (a -> a -> b) -> a -> a -> Bool
commutative = isCommutative
-- | Deprecated: use 'isAssociative'.
{-# DEPRECATED associative "Use isAssociative." #-}
associative :: Eq a => (a -> a -> a) -> a -> a -> a -> Bool
associative = isAssociative
-- | Deprecated: use 'isDistributiveOver'.
{-# DEPRECATED distributive "Use isDistributiveOver." #-}
distributive :: Eq a => (a -> a -> a) -> (a -> a -> a) -> a -> a -> a -> Bool
distributive = isDistributiveOver
-- | Deprecated: use 'isFlipped'.
{-# DEPRECATED symmetric2 "Use isFlipped." #-}
symmetric2 :: Eq c => (a -> b -> c) -> (b -> a -> c) -> a -> b -> Bool
symmetric2 = isFlipped
-- | Deprecated: use 'isTransitive'.
{-# DEPRECATED transitive "Use isTransitive." #-}
transitive :: (a -> a -> Bool) -> a -> a -> a -> Bool
transitive = isTransitive
-- | Deprecated: use 'isReflexive'.
{-# DEPRECATED reflexive "Use isReflexive." #-}
reflexive :: (a -> a -> Bool) -> a -> Bool
reflexive = isReflexive
-- | Deprecated: use 'isIrreflexive'.
{-# DEPRECATED irreflexive "Use isIrreflexive." #-}
irreflexive :: (a -> a -> Bool) -> a -> Bool
irreflexive = isIrreflexive
-- | Deprecated: use 'isSymmetric'.
{-# DEPRECATED symmetric "Use isSymmetric." #-}
symmetric :: (a -> a -> Bool) -> a -> a -> Bool
symmetric = isSymmetric
-- | Deprecated: use 'isAntisymmetric'.
{-# DEPRECATED antisymmetric "Use isAntisymmetric." #-}
antisymmetric :: Eq a => (a -> a -> Bool) -> a -> a -> Bool
antisymmetric = isAntisymmetric
-- | Deprecated: use 'isAsymmetric'.
{-# DEPRECATED asymmetric "Use isAsymmetric." #-}
asymmetric :: (a -> a -> Bool) -> a -> a -> Bool
asymmetric = isAsymmetric
-- | Deprecated: use 'isEquivalence'.
{-# DEPRECATED equivalence "Use isEquivalence." #-}
equivalence :: (a -> a -> Bool) -> a -> a -> a -> Bool
equivalence = isEquivalence
-- | Deprecated: use 'isPartialOrder'.
{-# DEPRECATED partialOrder "Use isPartialOrder." #-}
partialOrder :: Eq a => (a -> a -> Bool) -> a -> a -> a -> Bool
partialOrder = isPartialOrder
-- | Deprecated: use 'isStrictPartialOrder'.
{-# DEPRECATED strictPartialOrder "Use isStrictPartialOrder." #-}
strictPartialOrder :: (a -> a -> Bool) -> a -> a -> a -> Bool
strictPartialOrder = isStrictPartialOrder
-- | Deprecated: use 'isTotalOrder'.
{-# DEPRECATED totalOrder "Use isTotalOrder." #-}
totalOrder :: Eq a => (a -> a -> Bool) -> a -> a -> a -> Bool
totalOrder = isTotalOrder
-- | Deprecated: use 'isStrictTotalOrder'.
{-# DEPRECATED strictTotalOrder "Use isStrictTotalOrder." #-}
strictTotalOrder :: Eq a => (a -> a -> Bool) -> a -> a -> a -> Bool
strictTotalOrder = isStrictTotalOrder
-- | Deprecated: use 'isComparison'.
{-# DEPRECATED comparison "Use isComparison." #-}
comparison :: (a -> a -> Ordering) -> a -> a -> a -> Bool
comparison = isComparison
-- | Deprecated: use 'isIdempotent'.
{-# DEPRECATED idempotent "Use isIdempotent." #-}
idempotent :: Eq a => (a -> a) -> a -> Bool
idempotent = isIdempotent
-- | Deprecated: use 'isIdentity'.
{-# DEPRECATED identity "Use isIdentity." #-}
identity :: Eq a => (a -> a) -> a -> Bool
identity = isIdentity
-- | Deprecated: use 'isNeverIdentity'.
{-# DEPRECATED neverIdentity "Use isNeverIdentity." #-}
neverIdentity :: Eq a => (a -> a) -> a -> Bool
neverIdentity = isNeverIdentity