```-- | The representation of the ring structure.
module Algebra.Structures.Ring
( Ring(..)
, propRing
, (<->), (<^>), (*>), (<*)
, sumRing, productRing
) where

import Test.QuickCheck

infixl 8 <^>
infixl 7 <*>
infixl 7 *>
infixl 7 <*
infixl 6 <+>
infixl 6 <->

-------------------------------------------------------------------------------
-- | Definition of rings.

class Ring a where
(<+>) :: a -> a -> a

-- | Multiplication
(<*>) :: a -> a -> a

neg   :: a -> a

zero  :: a

-- | The multiplicative identity
one   :: a

-------------------------------------------------------------------------------
-- Properties

-- Addition satisfy the same properties as a commutative group
propAddAssoc :: (Ring a, Eq a) => a -> a -> a -> (Bool,String)
propAddAssoc a b c = ((a <+> b) <+> c == a <+> (b <+> c), "propAddAssoc")

-- Zero is the additive identity
propAddIdentity :: (Ring a, Eq a) => a -> (Bool,String)
propAddIdentity a = (a <+> zero == a && zero <+> a == a, "propAddIdentity")

-- Negation is the additive inverse
propAddInv :: (Ring a, Eq a) => a -> (Bool,String)
propAddInv a = (neg a <+> a == zero && a <+> neg a == zero, "propAddInv")

propAddComm :: (Ring a, Eq a) => a -> a -> (Bool,String)
propAddComm x y = (x <+> y == y <+> x, "propAddComm")

-- Multiplication is associative
propMulAssoc :: (Ring a, Eq a) => a -> a -> a -> (Bool,String)
propMulAssoc a b c = ((a <*> b) <*> c == a <*> (b <*> c), "propMulAssoc")

-- Multiplication is right-distributive over addition
propRightDist :: (Ring a, Eq a) => a -> a -> a -> (Bool,String)
propRightDist a b c =
((a <+> b) <*> c == (a <*> c) <+> (b <*> c), "propRightDist")

-- Multiplication is left-ditributive over addition
propLeftDist :: (Ring a, Eq a) => a -> a -> a -> (Bool,String)
propLeftDist a b c =
(a <*> (b <+> c) == (a <*> b) <+> (a <*> c), "propLeftDist")

-- One is multiplicative identity
propMulIdentity :: (Ring a, Eq a) => a -> (Bool,String)
propMulIdentity a = (one <*> a == a && a <*> one == a, "propMulIdentity")

-- | Specification of rings. Test that the arguments satisfy the ring axioms.
propRing :: (Ring a, Eq a) => a -> a -> a -> Property
propRing a b c = whenFail (print errorMsg) cond
where
(cond,errorMsg) =
propAddComm a b    &&& propMulAssoc a b c &&& propRightDist a b c &&&
propLeftDist a b c &&& propMulIdentity a

(False,x) &&& _         = (False,x)
_         &&& (False,x) = (False,x)
_         &&& _         = (True,"")

-------------------------------------------------------------------------------
-- Operations

-- | Subtraction
(<->) :: Ring a => a -> a -> a
a <-> b = a <+> neg b

-- | Summation
sumRing :: Ring a => [a] -> a
sumRing = foldr (<+>) zero

-- | Product
productRing :: Ring a => [a] -> a
productRing = foldr (<*>) one

-- | Exponentiation
(<^>) :: Ring a => a -> Integer -> a
x <^> 0 = one
x <^> y = if y < 0
then error "<^>: Input should be positive"
else x <*> x <^> (y-1)

-- | Multiply from left with an integer; n *> x means x + x + ... + x, n times.
(*>) :: Ring a => Integer -> a -> a
0 *> _ = zero
n *> x | n > 0     = x <+> x <* (n-1)
| otherwise = neg (abs n *> x) -- error "<*: Negative input"

-- Multiply from right with an integer.
(<*) :: Ring a => a -> Integer -> a
_ <* 0 = zero
x <* n | n > 0     = x <+> x <* (n-1)
| otherwise = neg (x <* abs n) -- error "<*: Negative input"
```