{-# LANGUAGE CPP #-} {-# LANGUAGE Safe #-} module Data.Ring ( (<<) , (><) , (<>) , negate , Ring(..) ) where import safe Data.Complex import safe Data.Fixed import safe Data.Int import safe Data.Group import safe Data.Semiring import safe GHC.Real import safe Prelude hiding (Num(..)) import safe qualified Prelude as N -- | Rings. -- -- A ring /R/ is a commutative group with a second monoidal operation /></ that distributes over /<>/. -- -- The basic properties of a ring follow immediately from the axioms: -- -- @ r '><' 'mempty' ≡ 'mempty' ≡ 'mempty' '><' r @ -- -- @ 'negate' 'sunit' '><' r ≡ 'negate' r @ -- -- Furthermore, the binomial formula holds for any commuting pair of elements (that is, any /a/ and /b/ such that /a >< b = b >< a/). -- -- If /mempty = sunit/ in a ring /R/, then /R/ has only one element, and is called the zero ring. -- Otherwise the additive identity, the additive inverse of each element, and the multiplicative identity are unique. -- -- See < https://en.wikipedia.org/wiki/Ring_(mathematics) >. -- -- If the ring is < https://en.wikipedia.org/wiki/Ordered_ring ordered > (i.e. has an 'Ord' instance), then the following additional properties must hold: -- -- @ a <= b ==> a <> c <= b <> c @ -- -- @ mempty <= a && mempty <= b ==> mempty <= a >< b @ -- -- See the properties module for a detailed specification of the laws. -- class (Group a, Semiring a) => Ring a where -- | A ring homomorphism from the integers to /a/. fromInteger :: Integer -> a -- | Absolute value of an element. -- -- @ abs r ≡ r >< signum r @ -- abs :: Ord a => a -> a abs x = if mempty <= x then x else negate x -- satisfies trichotomy law: -- Exactly one of the following is true: a is positive, -a is positive, or a = 0. -- This property follows from the fact that ordered rings are abelian, linearly ordered groups with respect to addition. signum :: Ord a => a -> a signum x = if mempty <= x then sunit else negate sunit instance Ring Rational where fromInteger x = fromInteger x :% sunit {-# INLINE fromInteger #-} instance Ring a => Ring (Complex a) where fromInteger x = fromInteger x :+ mempty {-# INLINE fromInteger #-} #define deriveRing(ty) \ instance Ring (ty) where { \ fromInteger = N.fromInteger \ ; abs = N.abs \ ; signum = N.signum \ ; {-# INLINE abs #-} \ ; {-# INLINE signum #-} \ } deriveRing(Int) deriveRing(Int8) deriveRing(Int16) deriveRing(Int32) deriveRing(Int64) deriveRing(Integer) deriveRing(Uni) deriveRing(Deci) deriveRing(Centi) deriveRing(Milli) deriveRing(Micro) deriveRing(Nano) deriveRing(Pico)