{- 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 Prelude

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 :: forall a.
(Arbitrary a, Show a, Eq a, Cancellative a) =>
Proxy a -> Laws
cancellativeLaws Proxy a
_ = String -> [(String, Property)] -> Laws
Laws String
"Cancellative"
    [ forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"cancellativeLaw_cancellation_prefix"
        (a -> a -> Property
forall a. (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_prefix)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"cancellativeLaw_cancellation_suffix"
        (a -> a -> Property
forall a. (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_suffix)
    ]

cancellativeLaw_cancellation_prefix
    :: (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_prefix :: forall a. (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_prefix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"(a <> b) </> a == Just b"
        ((a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
a Maybe a -> Maybe a -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Maybe a
forall a. a -> Maybe a
Just a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a <> b"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"(a <> b) </> a"
        ((a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
a)

cancellativeLaw_cancellation_suffix
    :: (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_suffix :: forall a. (Eq a, Show a, Cancellative a) => a -> a -> Property
cancellativeLaw_cancellation_suffix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"(a <> b) </> b == Just a"
        ((a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b Maybe a -> Maybe a -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Maybe a
forall a. a -> Maybe a
Just a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a <> b"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"(a <> b) </> b"
        ((a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
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 :: forall a.
(Arbitrary a, Show a, Eq a, Commutative a) =>
Proxy a -> Laws
commutativeLaws Proxy a
_ = String -> [(String, Property)] -> Laws
Laws String
"Commutative"
    [ forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"commutativeLaw_basic"
        (a -> a -> Property
forall a. (Eq a, Show a, Commutative a) => a -> a -> Property
commutativeLaw_basic)
    ]

commutativeLaw_basic
    :: (Eq a, Show a, Commutative a) => a -> a -> Property
commutativeLaw_basic :: forall a. (Eq a, Show a, Commutative a) => a -> a -> Property
commutativeLaw_basic a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"a <> b == b <> a"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a <> b"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"b <> a"
        (a
b a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Bool -> Property -> Property
forall t. Testable t => String -> Bool -> t -> Property
cover
        String
"(a /= b) && (a <> b /= a) && (b <> a /= b)"
        ((a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
b) Bool -> Bool -> Bool
&& (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= a
a) Bool -> Bool -> Bool
&& (a
b a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
/= 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 :: forall a.
(Arbitrary a, Show a, Eq a, LeftCancellative a) =>
Proxy a -> Laws
leftCancellativeLaws Proxy a
_ = String -> [(String, Property)] -> Laws
Laws String
"LeftCancellative"
    [ forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"leftCancellativeLaw_cancellation"
        (a -> a -> Property
forall a. (Eq a, Show a, LeftCancellative a) => a -> a -> Property
leftCancellativeLaw_cancellation)
    ]

leftCancellativeLaw_cancellation
    :: (Eq a, Show a, LeftCancellative a) => a -> a -> Property
leftCancellativeLaw_cancellation :: forall a. (Eq a, Show a, LeftCancellative a) => a -> a -> Property
leftCancellativeLaw_cancellation a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"stripPrefix a (a <> b) == Just b"
        (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
a (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) Maybe a -> Maybe a -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Maybe a
forall a. a -> Maybe a
Just a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a <> b"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripPrefix a (a <> b)"
        (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
a (a
a a -> a -> a
forall a. Semigroup a => a -> a -> 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 :: forall a.
(Arbitrary a, Show a, Eq a, LeftReductive a) =>
Proxy a -> Laws
leftReductiveLaws Proxy a
_ = String -> [(String, Property)] -> Laws
Laws String
"LeftReductive"
    [ forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"leftReductiveLaw_isPrefixOf_mappend"
        (a -> a -> Property
forall a. (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_mappend)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"leftReductiveLaw_isPrefixOf_stripPrefix"
        (a -> a -> Property
forall a. (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_stripPrefix)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"leftReductiveLaw_stripPrefix"
        (a -> a -> Property
forall a. (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_stripPrefix)
    ]

leftReductiveLaw_isPrefixOf_mappend
    :: (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_mappend :: forall a. (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_mappend a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"a `isPrefixOf` (a <> b)"
        (a
a a -> a -> Bool
forall m. LeftReductive m => m -> m -> Bool
`isPrefixOf` (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b))
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a <> b"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)

leftReductiveLaw_isPrefixOf_stripPrefix
    :: (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_stripPrefix :: forall a. (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_isPrefixOf_stripPrefix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"isPrefixOf a b == isJust (stripPrefix a b)"
        (a -> a -> Bool
forall m. LeftReductive m => m -> m -> Bool
isPrefixOf a
a a
b Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe a -> Bool
forall a. Maybe a -> Bool
isJust (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
a a
b))
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Bool -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"isPrefixOf a b"
        (a -> a -> Bool
forall m. LeftReductive m => m -> m -> Bool
isPrefixOf a
a a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripPrefix a b"
        (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
a a
b)

leftReductiveLaw_stripPrefix
    :: (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_stripPrefix :: forall a. (Eq a, Show a, LeftReductive a) => a -> a -> Property
leftReductiveLaw_stripPrefix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"maybe b (a <>) (stripPrefix a b) == b"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
b (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<>) (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
a a
b) a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripPrefix a b"
        (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
a a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"maybe b (a <>) (stripPrefix a b)"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
b (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<>) (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
a 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 :: forall a.
(Arbitrary a, Show a, Eq a, Reductive a) =>
Proxy a -> Laws
reductiveLaws Proxy a
_ = String -> [(String, Property)] -> Laws
Laws String
"Reductive"
    [ forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"reductiveLaw_equivalence_prefix"
        (a -> a -> Property
forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_prefix)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"reductiveLaw_equivalence_suffix"
        (a -> a -> Property
forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_suffix)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"reductiveLaw_inversion_prefix"
        (a -> a -> Property
forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_prefix)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"reductiveLaw_inversion_suffix"
        (a -> a -> Property
forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_suffix)
    ]

reductiveLaw_equivalence_prefix
    :: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_prefix :: forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_prefix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"a </> b == stripPrefix b a"
        (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b Maybe a -> Maybe a -> Bool
forall a. Eq a => a -> a -> Bool
== a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
b a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a </> b"
        (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripPrefix b a"
        (a -> a -> Maybe a
forall m. LeftReductive m => m -> m -> Maybe m
stripPrefix a
b a
a)

reductiveLaw_equivalence_suffix
    :: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_suffix :: forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_equivalence_suffix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"a </> b == stripSuffix b a"
        (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b Maybe a -> Maybe a -> Bool
forall a. Eq a => a -> a -> Bool
== a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
b a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a </> b"
        (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripSuffix b a"
        (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
b a
a)

reductiveLaw_inversion_prefix
    :: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_prefix :: forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_prefix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"maybe a (b <>) (a </> b) == a"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
a (a
b a -> a -> a
forall a. Semigroup a => a -> a -> a
<>) (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b) a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a </> b"
        (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"maybe a (b <>) (a </> b)"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
a (a
b a -> a -> a
forall a. Semigroup a => a -> a -> a
<>) (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b))

reductiveLaw_inversion_suffix
    :: (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_suffix :: forall a. (Eq a, Show a, Reductive a) => a -> a -> Property
reductiveLaw_inversion_suffix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"maybe a (<> b) (a </> b) == a"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
a (a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b) a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a </> b"
        (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"maybe a (<> b) (a </> b)"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
a (a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) (a
a a -> a -> Maybe a
forall m. Reductive m => m -> m -> Maybe m
</> 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 :: forall a.
(Arbitrary a, Show a, Eq a, RightCancellative a) =>
Proxy a -> Laws
rightCancellativeLaws Proxy a
_ = String -> [(String, Property)] -> Laws
Laws String
"RightCancellative"
    [ forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"rightCancellativeLaw_cancellation"
        (a -> a -> Property
forall a. (Eq a, Show a, RightCancellative a) => a -> a -> Property
rightCancellativeLaw_cancellation)
    ]

rightCancellativeLaw_cancellation
    :: (Eq a, Show a, RightCancellative a) => a -> a -> Property
rightCancellativeLaw_cancellation :: forall a. (Eq a, Show a, RightCancellative a) => a -> a -> Property
rightCancellativeLaw_cancellation a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"stripSuffix b (a <> b) == Just a"
        (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
b (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b) Maybe a -> Maybe a -> Bool
forall a. Eq a => a -> a -> Bool
== a -> Maybe a
forall a. a -> Maybe a
Just a
a)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a <> b"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripSuffix b (a <> b)"
        (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
b (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> 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 :: forall a.
(Arbitrary a, Show a, Eq a, RightReductive a) =>
Proxy a -> Laws
rightReductiveLaws Proxy a
_ = String -> [(String, Property)] -> Laws
Laws String
"RightReductive"
    [ forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"rightReductiveLaw_isSuffixOf_mappend"
        (a -> a -> Property
forall a. (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_mappend)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"rightReductiveLaw_isSuffixOf_stripSuffix"
        (a -> a -> Property
forall a. (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_stripSuffix)
    , forall a t.
(Arbitrary a, Show a, Eq a, Semigroup a, Testable t) =>
String -> (a -> a -> t) -> (String, Property)
makeLaw2 @a
        String
"rightReductiveLaw_stripSuffix"
        (a -> a -> Property
forall a. (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_stripSuffix)
    ]

rightReductiveLaw_isSuffixOf_mappend
    :: (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_mappend :: forall a. (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_mappend a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"b `isSuffixOf` (a <> b)"
        (a
b a -> a -> Bool
forall m. RightReductive m => m -> m -> Bool
`isSuffixOf` (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b))
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"a <> b"
        (a
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
b)

rightReductiveLaw_isSuffixOf_stripSuffix
    :: (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_stripSuffix :: forall a. (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_isSuffixOf_stripSuffix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"isSuffixOf a b == isJust (stripSuffix a b)"
        (a -> a -> Bool
forall m. RightReductive m => m -> m -> Bool
isSuffixOf a
a a
b Bool -> Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe a -> Bool
forall a. Maybe a -> Bool
isJust (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
a a
b))
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Bool -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"isSuffixOf a b"
        (a -> a -> Bool
forall m. RightReductive m => m -> m -> Bool
isSuffixOf a
a a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripSuffix a b"
        (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
a a
b)

rightReductiveLaw_stripSuffix
    :: (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_stripSuffix :: forall a. (Eq a, Show a, RightReductive a) => a -> a -> Property
rightReductiveLaw_stripSuffix a
a a
b =
    String -> Bool -> Property
forall t. Testable t => String -> t -> Property
makeProperty
        String
"maybe b (<> a) (stripSuffix a b) == b"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
b (a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a) (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
a a
b) a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> Maybe a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"stripSuffix a b"
        (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
a a
b)
    Property -> (Property -> Property) -> Property
forall a b. a -> (a -> b) -> b
& String -> a -> Property -> Property
forall a prop.
(Show a, Testable prop) =>
String -> a -> prop -> Property
report
        String
"maybe b (<> a) (stripSuffix a b)"
        (a -> (a -> a) -> Maybe a -> a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe a
b (a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
a) (a -> a -> Maybe a
forall m. RightReductive m => m -> m -> Maybe m
stripSuffix a
a a
b))