- class C a => C a where
- isUnit :: a -> Bool
- stdAssociate :: a -> a
- stdUnitInv :: a -> a
- stdUnit :: a -> a

- intQuery :: (Integral a, C a) => a -> Bool
- intAssociate :: (Integral a, C a, C a) => a -> a
- intStandard :: (Integral a, C a, C a) => a -> a
- intStandardInverse :: (Integral a, C a, C a) => a -> a
- propComposition :: (Eq a, C a) => a -> Bool
- propInverseUnit :: (Eq a, C a) => a -> Bool
- propUniqueAssociate :: (Eq a, C a) => a -> a -> Property
- propAssociateProduct :: (Eq a, C a) => a -> a -> Bool

# Class

This class lets us deal with the units in a ring.
`isUnit`

tells whether an element is a unit.
The other operations let us canonically
write an element as a unit times another element.
Two elements a, b of a ring R are _associates_ if a=b*u for a unit u.
For an element a, we want to write it as a=b*u where b is an associate of a.
The map (a->b) is called
StandardAssociate by Gap,
unitCanonical by Axiom,
and canAssoc by DoCon.
The map (a->u) is called
canInv by DoCon and
unitNormal(x).unit by Axiom.

The laws are

stdAssociate x * stdUnit x === x stdUnit x * stdUnitInv x === 1 isUnit u ==> stdAssociate x === stdAssociate (x*u)

Currently some algorithms assume

stdAssociate(x*y) === stdAssociate x * stdAssociate y

Minimal definition:
`isUnit`

and (`stdUnit`

or `stdUnitInv`

) and optionally `stdAssociate`

stdAssociate :: a -> aSource

stdUnitInv :: a -> aSource

# Standard implementations for instances

intAssociate :: (Integral a, C a, C a) => a -> aSource

intStandard :: (Integral a, C a, C a) => a -> aSource

intStandardInverse :: (Integral a, C a, C a) => a -> aSource

# Properties

propComposition :: (Eq a, C a) => a -> BoolSource

propInverseUnit :: (Eq a, C a) => a -> BoolSource

propUniqueAssociate :: (Eq a, C a) => a -> a -> PropertySource

propAssociateProduct :: (Eq a, C a) => a -> a -> BoolSource