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.Ratio as Ratio98
import qualified Algebra.PrincipalIdealDomain as PID
import qualified Algebra.Ring as Ring
import qualified Algebra.Additive as Additive
import qualified Algebra.ZeroTestable as ZeroTestable
import Algebra.Ring ((*), (^), one, fromInteger)
import Algebra.Additive (zero, negate)
import Algebra.ZeroTestable (isZero)
import PreludeBase
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
(/) :: a -> a -> a
recip :: a -> a
fromRational' :: Rational -> a
(^-) :: a -> Integer -> a
recip a = one / a
a / b = a * recip b
fromRational' r = fromInteger (numerator r) / fromInteger (denominator r)
a ^- n = if n < zero
then recip (a^(n))
else a^n
fromRational :: (C a) => P.Rational -> a
fromRational x = fromRational' (Ratio98.numerator x :% Ratio98.denominator x)
instance C Float where
(/) = (P./)
recip = (P.recip)
instance C Double where
(/) = (P./)
recip = (P.recip)
instance (PID.C a) => C (Ratio.T a) where
(x:%y) / (x':%y') = (x*y') % (y*x')
recip (x:%y) = (y:%x)
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
(/) = (P./)