    {-# LANGUAGE CPP #-}
    {-# LANGUAGE ScopedTypeVariables #-}

    {-# OPTIONS_GHC -Wall #-}

    module Test.QuickCheck.Classes.Ring
      (
    #if HAVE_SEMIRINGS
        ringLaws
    #endif
      ) where

    #if HAVE_SEMIRINGS
    import Data.Semiring
    import Prelude hiding (Num(..))
    #endif

    import Data.Proxy (Proxy)
    import Test.QuickCheck hiding ((.&.))
    import Test.QuickCheck.Property (Property)

    import Test.QuickCheck.Classes.Internal (Laws(..), myForAllShrink)

    #if HAVE_SEMIRINGS
    -- | Tests the following properties:
    --
    -- [/Additive Inverse/]
    --   @'negate' a '+' a ≡ 0@
    --
    -- Note that this does not test any of the laws tested by 'Test.QuickCheck.Classes.Semiring.semiringLaws'.
    ringLaws :: (Ring a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
    ringLaws :: forall a. (Ring a, Eq a, Arbitrary a, Show a) => Proxy a -> Laws
    ringLaws Proxy a
    p = String -> [(String, Property)] -> Laws
    Laws String
    "Ring"
      [ (String
    "Additive Inverse", Proxy a -> Property
    forall a.
    (Ring a, Eq a, Arbitrary a, Show a) =>
    Proxy a -> Property
    ringAdditiveInverse Proxy a
    p)
      ]

    ringAdditiveInverse :: forall a. (Ring a, Eq a, Arbitrary a, Show a) => Proxy a -> Property
    ringAdditiveInverse :: forall a.
    (Ring a, Eq a, Arbitrary a, Show a) =>
    Proxy a -> Property
    ringAdditiveInverse Proxy a
    _ = Bool
    -> (a -> Bool)
    -> (a -> [String])
    -> String
    -> (a -> a)
    -> String
    -> (a -> a)
    -> Property
    forall a b.
    (Arbitrary a, Show b, Eq b) =>
    Bool
    -> (a -> Bool)
    -> (a -> [String])
    -> String
    -> (a -> b)
    -> String
    -> (a -> b)
    -> Property
    myForAllShrink Bool
    True (Bool -> a -> Bool
    forall a b. a -> b -> a
    const Bool
    True)
      (\(a
    a :: a) -> [String
    "a = " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ a -> String
    forall a. Show a => a -> String
    show a
    a])
      String
    "negate a + a"
      (\a
    a -> a -> a
    forall a. Ring a => a -> a
    negate a
    a a -> a -> a
    forall a. Semiring a => a -> a -> a
    + a
    a)
      String
    "0"
      (a -> a -> a
    forall a b. a -> b -> a
    const a
    forall a. Semiring a => a
    zero)
    #endif