{-# LANGUAGE NoImplicitPrelude #-}
module Algebra.Field (
C,
(/),
recip,
fromRational',
fromRational,
(^-),
propDivision,
propReciprocal,
) where
import Number.Ratio (T((:%)), Rational, (%), numerator, denominator, )
import qualified Number.Ratio as Ratio
import qualified Data.Complex as Complex98
import qualified Data.Ratio as Ratio98
import qualified Algebra.PrincipalIdealDomain as PID
import qualified Algebra.Ring as Ring
import qualified Algebra.ZeroTestable as ZeroTestable
import Algebra.Ring ((*), (^), one, fromInteger)
import Algebra.Additive (zero, negate)
import Algebra.ZeroTestable (isZero)
import NumericPrelude.Base
import Prelude (Integer, Float, Double)
import qualified Prelude as P
import Test.QuickCheck ((==>), Property)
infixr 8 ^-
infixl 7 /
class (Ring.C a) => C a where
{-# MINIMAL recip | (/) #-}
(/) :: a -> a -> a
recip :: a -> a
fromRational' :: Rational -> a
(^-) :: a -> Integer -> a
{-# INLINE recip #-}
recip a = one / a
{-# INLINE (/) #-}
a / b = a * recip b
{-# INLINE fromRational' #-}
fromRational' r = fromInteger (numerator r) / fromInteger (denominator r)
{-# INLINE (^-) #-}
a ^- n = if n < zero
then recip (a^(-n))
else a^n
{-# INLINE fromRational #-}
fromRational :: (C a) => P.Rational -> a
fromRational x = fromRational' (Ratio98.numerator x :% Ratio98.denominator x)
instance C Float where
{-# INLINE (/) #-}
{-# INLINE recip #-}
(/) = (P./)
recip = (P.recip)
fromRational' x =
P.fromRational (numerator x Ratio98.% denominator x)
instance C Double where
{-# INLINE (/) #-}
{-# INLINE recip #-}
(/) = (P./)
recip = (P.recip)
fromRational' x =
P.fromRational (numerator x Ratio98.% denominator x)
instance (PID.C a) => C (Ratio.T a) where
{-# INLINE (/) #-}
{-# INLINE recip #-}
{-# INLINE fromRational' #-}
x / y = x * recip y
recip = Ratio.recip
fromRational' (x:%y) = fromInteger x % fromInteger y
propDivision :: (Eq a, ZeroTestable.C a, C a) => a -> a -> Property
propReciprocal :: (Eq a, ZeroTestable.C a, C a) => a -> Property
propDivision a b = not (isZero b) ==> (a * b) / b == a
propReciprocal a = not (isZero a) ==> a * recip a == one
instance (P.Integral a) => C (Ratio98.Ratio a) where
{-# INLINE (/) #-}
{-# INLINE recip #-}
(/) = (P./)
recip = (P.recip)
instance (P.RealFloat a) => C (Complex98.Complex a) where
{-# INLINE (/) #-}
{-# INLINE recip #-}
(/) = (P./)
recip = (P.recip)