quickcheck-monoid-subclasses-0.3.0.2: src/public/Test/QuickCheck/Classes/Semigroup/Cancellative.hs
{- HLINT ignore "Use camelCase" -}
{- HLINT ignore "Use infix" -}
{- HLINT ignore "Redundant bracket" -}
-- |
-- Copyright: © 2022–2024 Jonathan Knowles
-- License: Apache-2.0
--
-- This module provides 'Laws' definitions for classes exported by
-- "Data.Semigroup.Cancellative".
--
module Test.QuickCheck.Classes.Semigroup.Cancellative
(
-- * Commutative
commutativeLaws
-- * Reductive
, reductiveLaws
, leftReductiveLaws
, rightReductiveLaws
-- * Cancellative
, cancellativeLaws
, leftCancellativeLaws
, rightCancellativeLaws
)
where
import Data.Function
( (&) )
import Data.Maybe
( isJust )
import Data.Proxy
( Proxy (..) )
import Data.Semigroup.Cancellative
( Cancellative
, Commutative
, LeftCancellative
, LeftReductive (..)
, Reductive (..)
, RightCancellative
, RightReductive (..)
)
import Internal
( cover, makeLaw2, makeProperty, report )
import Test.QuickCheck
( Arbitrary (..), Property )
import Test.QuickCheck.Classes
( Laws (..) )
--------------------------------------------------------------------------------
-- Cancellative
--------------------------------------------------------------------------------
-- | 'Laws' for instances of 'Cancellative'.
--
-- Includes the following laws:
--
-- @
-- (a '<>' b) '</>' a '==' 'Just' b
-- @
--
-- @
-- (a '<>' b) '</>' b '==' 'Just' a
-- @
--
-- Note that the following superclass laws are __not__ included:
--
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.leftCancellativeLaws'
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.rightCancellativeLaws'
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.reductiveLaws'
--
cancellativeLaws
:: forall a. (Arbitrary a, Show a, Eq a, Cancellative a)
=> Proxy a
-> Laws
cancellativeLaws _ = Laws "Cancellative"
[ makeLaw2 @a
"cancellativeLaw_cancellation_prefix"
(cancellativeLaw_cancellation_prefix)
, makeLaw2 @a
"cancellativeLaw_cancellation_suffix"
(cancellativeLaw_cancellation_suffix)
]
cancellativeLaw_cancellation_prefix
:: (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_prefix a b =
makeProperty
"(a <> b) </> a == Just b"
((a <> b) </> a == Just b)
& report
"a <> b"
(a <> b)
& report
"(a <> b) </> a"
((a <> b) </> a)
cancellativeLaw_cancellation_suffix
:: (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_suffix a b =
makeProperty
"(a <> b) </> b == Just a"
((a <> b) </> b == Just a)
& report
"a <> b"
(a <> b)
& report
"(a <> b) </> b"
((a <> b) </> b)
--------------------------------------------------------------------------------
-- Commutative
--------------------------------------------------------------------------------
-- | 'Laws' for instances of 'Commutative'.
--
-- Includes the following law:
--
-- @
-- a '<>' b '==' b '<>' a
-- @
--
-- Note that the following superclass laws are __not__ included:
--
-- * 'Test.QuickCheck.Classes.semigroupLaws'
--
commutativeLaws
:: forall a. (Arbitrary a, Show a, Eq a, Commutative a)
=> Proxy a
-> Laws
commutativeLaws _ = Laws "Commutative"
[ makeLaw2 @a
"commutativeLaw_basic"
(commutativeLaw_basic)
]
commutativeLaw_basic
:: (Eq a, Show a, Commutative a) => a -> a -> Property
commutativeLaw_basic a b =
makeProperty
"a <> b == b <> a"
(a <> b == b <> a)
& report
"a <> b"
(a <> b)
& report
"b <> a"
(b <> a)
& cover
"(a /= b) && (a <> b /= a) && (b <> a /= b)"
((a /= b) && (a <> b /= a) && (b <> a /= b))
--------------------------------------------------------------------------------
-- LeftCancellative
--------------------------------------------------------------------------------
-- | 'Laws' for instances of 'LeftCancellative'.
--
-- Includes the following law:
--
-- @
-- 'stripPrefix' a (a '<>' b) '==' 'Just' b
-- @
--
-- Note that the following superclass laws are __not__ included:
--
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.leftReductiveLaws'
--
leftCancellativeLaws
:: forall a. (Arbitrary a, Show a, Eq a, LeftCancellative a)
=> Proxy a
-> Laws
leftCancellativeLaws _ = Laws "LeftCancellative"
[ makeLaw2 @a
"leftCancellativeLaw_cancellation"
(leftCancellativeLaw_cancellation)
]
leftCancellativeLaw_cancellation
:: (Eq a, Show a, LeftCancellative a) => a -> a -> Property
leftCancellativeLaw_cancellation a b =
makeProperty
"stripPrefix a (a <> b) == Just b"
(stripPrefix a (a <> b) == Just b)
& report
"a <> b"
(a <> b)
& report
"stripPrefix a (a <> b)"
(stripPrefix a (a <> b))
--------------------------------------------------------------------------------
-- LeftReductive
--------------------------------------------------------------------------------
-- | 'Laws' for instances of 'LeftReductive'.
--
-- Includes the following laws:
--
-- @
-- a '`isPrefixOf`' (a '<>' b)
-- @
--
-- @
-- 'isPrefixOf' a b '==' 'isJust' ('stripPrefix' a b)
-- @
--
-- @
-- 'maybe' b (a '<>') ('stripPrefix' a b) '==' b
-- @
--
-- Note that the following superclass laws are __not__ included:
--
-- * 'Test.QuickCheck.Classes.semigroupLaws'
--
leftReductiveLaws
:: forall a. (Arbitrary a, Show a, Eq a, LeftReductive a)
=> Proxy a
-> Laws
leftReductiveLaws _ = Laws "LeftReductive"
[ makeLaw2 @a
"leftReductiveLaw_isPrefixOf_mappend"
(leftReductiveLaw_isPrefixOf_mappend)
, makeLaw2 @a
"leftReductiveLaw_isPrefixOf_stripPrefix"
(leftReductiveLaw_isPrefixOf_stripPrefix)
, makeLaw2 @a
"leftReductiveLaw_stripPrefix"
(leftReductiveLaw_stripPrefix)
]
leftReductiveLaw_isPrefixOf_mappend
:: (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_mappend a b =
makeProperty
"a `isPrefixOf` (a <> b)"
(a `isPrefixOf` (a <> b))
& report
"a <> b"
(a <> b)
leftReductiveLaw_isPrefixOf_stripPrefix
:: (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_stripPrefix a b =
makeProperty
"isPrefixOf a b == isJust (stripPrefix a b)"
(isPrefixOf a b == isJust (stripPrefix a b))
& report
"isPrefixOf a b"
(isPrefixOf a b)
& report
"stripPrefix a b"
(stripPrefix a b)
leftReductiveLaw_stripPrefix
:: (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_stripPrefix a b =
makeProperty
"maybe b (a <>) (stripPrefix a b) == b"
(maybe b (a <>) (stripPrefix a b) == b)
& report
"stripPrefix a b"
(stripPrefix a b)
& report
"maybe b (a <>) (stripPrefix a b)"
(maybe b (a <>) (stripPrefix a b))
--------------------------------------------------------------------------------
-- Reductive
--------------------------------------------------------------------------------
-- | 'Laws' for instances of 'Reductive'.
--
-- Includes the following laws:
--
-- @
-- a '</>' b '==' 'stripPrefix' b a
-- @
--
-- @
-- a '</>' b '==' 'stripSuffix' b a
-- @
--
-- @
-- 'maybe' a (b '<>') (a '</>' b) '==' a
-- @
--
-- @
-- 'maybe' a ('<>' b) (a '</>' b) '==' a
-- @
--
-- Note that the following superclass laws are __not__ included:
--
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.commutativeLaws'
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.leftReductiveLaws'
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.rightReductiveLaws'
--
reductiveLaws
:: forall a. (Arbitrary a, Show a, Eq a, Reductive a)
=> Proxy a
-> Laws
reductiveLaws _ = Laws "Reductive"
[ makeLaw2 @a
"reductiveLaw_equivalence_prefix"
(reductiveLaw_equivalence_prefix)
, makeLaw2 @a
"reductiveLaw_equivalence_suffix"
(reductiveLaw_equivalence_suffix)
, makeLaw2 @a
"reductiveLaw_inversion_prefix"
(reductiveLaw_inversion_prefix)
, makeLaw2 @a
"reductiveLaw_inversion_suffix"
(reductiveLaw_inversion_suffix)
]
reductiveLaw_equivalence_prefix
:: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_prefix a b =
makeProperty
"a </> b == stripPrefix b a"
(a </> b == stripPrefix b a)
& report
"a </> b"
(a </> b)
& report
"stripPrefix b a"
(stripPrefix b a)
reductiveLaw_equivalence_suffix
:: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_suffix a b =
makeProperty
"a </> b == stripSuffix b a"
(a </> b == stripSuffix b a)
& report
"a </> b"
(a </> b)
& report
"stripSuffix b a"
(stripSuffix b a)
reductiveLaw_inversion_prefix
:: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_prefix a b =
makeProperty
"maybe a (b <>) (a </> b) == a"
(maybe a (b <>) (a </> b) == a)
& report
"a </> b"
(a </> b)
& report
"maybe a (b <>) (a </> b)"
(maybe a (b <>) (a </> b))
reductiveLaw_inversion_suffix
:: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_suffix a b =
makeProperty
"maybe a (<> b) (a </> b) == a"
(maybe a (<> b) (a </> b) == a)
& report
"a </> b"
(a </> b)
& report
"maybe a (<> b) (a </> b)"
(maybe a (<> b) (a </> b))
--------------------------------------------------------------------------------
-- RightCancellative
--------------------------------------------------------------------------------
-- | 'Laws' for instances of 'RightCancellative'.
--
-- Includes the following law:
--
-- @
-- 'stripSuffix' b (a '<>' b) '==' 'Just' a
-- @
--
-- Note that the following superclass laws are __not__ included:
--
-- * 'Test.QuickCheck.Classes.Semigroup.Cancellative.rightReductiveLaws'
--
rightCancellativeLaws
:: forall a. (Arbitrary a, Show a, Eq a, RightCancellative a)
=> Proxy a
-> Laws
rightCancellativeLaws _ = Laws "RightCancellative"
[ makeLaw2 @a
"rightCancellativeLaw_cancellation"
(rightCancellativeLaw_cancellation)
]
rightCancellativeLaw_cancellation
:: (Eq a, Show a, RightCancellative a) => a -> a -> Property
rightCancellativeLaw_cancellation a b =
makeProperty
"stripSuffix b (a <> b) == Just a"
(stripSuffix b (a <> b) == Just a)
& report
"a <> b"
(a <> b)
& report
"stripSuffix b (a <> b)"
(stripSuffix b (a <> b))
--------------------------------------------------------------------------------
-- RightReductive
--------------------------------------------------------------------------------
-- | 'Laws' for instances of 'RightReductive'.
--
-- Includes the following laws:
--
-- @
-- b '`isSuffixOf`' (a '<>' b)
-- @
--
-- @
-- 'isSuffixOf' a b '==' 'isJust' ('stripSuffix' a b)
-- @
--
-- @
-- 'maybe' b ('<>' a) ('stripSuffix' a b) '==' b
-- @
--
-- Note that the following superclass laws are __not__ included:
--
-- * 'Test.QuickCheck.Classes.semigroupLaws'
--
rightReductiveLaws
:: forall a. (Arbitrary a, Show a, Eq a, RightReductive a)
=> Proxy a
-> Laws
rightReductiveLaws _ = Laws "RightReductive"
[ makeLaw2 @a
"rightReductiveLaw_isSuffixOf_mappend"
(rightReductiveLaw_isSuffixOf_mappend)
, makeLaw2 @a
"rightReductiveLaw_isSuffixOf_stripSuffix"
(rightReductiveLaw_isSuffixOf_stripSuffix)
, makeLaw2 @a
"rightReductiveLaw_stripSuffix"
(rightReductiveLaw_stripSuffix)
]
rightReductiveLaw_isSuffixOf_mappend
:: (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_mappend a b =
makeProperty
"b `isSuffixOf` (a <> b)"
(b `isSuffixOf` (a <> b))
& report
"a <> b"
(a <> b)
rightReductiveLaw_isSuffixOf_stripSuffix
:: (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_stripSuffix a b =
makeProperty
"isSuffixOf a b == isJust (stripSuffix a b)"
(isSuffixOf a b == isJust (stripSuffix a b))
& report
"isSuffixOf a b"
(isSuffixOf a b)
& report
"stripSuffix a b"
(stripSuffix a b)
rightReductiveLaw_stripSuffix
:: (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_stripSuffix a b =
makeProperty
"maybe b (<> a) (stripSuffix a b) == b"
(maybe b (<> a) (stripSuffix a b) == b)
& report
"stripSuffix a b"
(stripSuffix a b)
& report
"maybe b (<> a) (stripSuffix a b)"
(maybe b (<> a) (stripSuffix a b))