{-# LANGUAGE RebindableSyntax #-}
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
a = a
forall a. C a => a
one a -> a -> a
forall a. C a => a -> a -> a
/ a
a
{-# INLINE (/) #-}
a
a / a
b = a
a a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
recip a
b
{-# INLINE fromRational' #-}
fromRational' Rational
r = Integer -> a
forall a. C a => Integer -> a
fromInteger (Rational -> Integer
forall a. T a -> a
numerator Rational
r) a -> a -> a
forall a. C a => a -> a -> a
/ Integer -> a
forall a. C a => Integer -> a
fromInteger (Rational -> Integer
forall a. T a -> a
denominator Rational
r)
{-# INLINE (^-) #-}
a
a ^- Integer
n = if Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
< Integer
forall a. C a => a
zero
then a -> a
forall a. C a => a -> a
recip (a
aa -> Integer -> a
forall a. C a => a -> Integer -> a
^(-Integer
n))
else a
aa -> Integer -> a
forall a. C a => a -> Integer -> a
^Integer
n
{-# INLINE fromRational #-}
fromRational :: (C a) => P.Rational -> a
fromRational :: Rational -> a
fromRational Rational
x = Rational -> a
forall a. C a => Rational -> a
fromRational' (Rational -> Integer
forall a. Ratio a -> a
Ratio98.numerator Rational
x Integer -> Integer -> Rational
forall a. a -> a -> T a
:% Rational -> Integer
forall a. Ratio a -> a
Ratio98.denominator Rational
x)
instance C Float where
{-# INLINE (/) #-}
{-# INLINE recip #-}
/ :: Float -> Float -> Float
(/) = Float -> Float -> Float
forall a. Fractional a => a -> a -> a
(P./)
recip :: Float -> Float
recip = (Float -> Float
forall a. Fractional a => a -> a
P.recip)
fromRational' :: Rational -> Float
fromRational' Rational
x =
Rational -> Float
forall a. Fractional a => Rational -> a
P.fromRational (Rational -> Integer
forall a. T a -> a
numerator Rational
x Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
Ratio98.% Rational -> Integer
forall a. T a -> a
denominator Rational
x)
instance C Double where
{-# INLINE (/) #-}
{-# INLINE recip #-}
/ :: Double -> Double -> Double
(/) = Double -> Double -> Double
forall a. Fractional a => a -> a -> a
(P./)
recip :: Double -> Double
recip = (Double -> Double
forall a. Fractional a => a -> a
P.recip)
fromRational' :: Rational -> Double
fromRational' Rational
x =
Rational -> Double
forall a. Fractional a => Rational -> a
P.fromRational (Rational -> Integer
forall a. T a -> a
numerator Rational
x Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
Ratio98.% Rational -> Integer
forall a. T a -> a
denominator Rational
x)
instance (PID.C a) => C (Ratio.T a) where
{-# INLINE (/) #-}
{-# INLINE recip #-}
{-# INLINE fromRational' #-}
T a
x / :: T a -> T a -> T a
/ T a
y = T a
x T a -> T a -> T a
forall a. C a => a -> a -> a
* T a -> T a
forall a. C a => a -> a
recip T a
y
recip :: T a -> T a
recip = T a -> T a
forall a. (C a, C a) => T a -> T a
Ratio.recip
fromRational' :: Rational -> T a
fromRational' (Integer
x:%Integer
y) = Integer -> a
forall a. C a => Integer -> a
fromInteger Integer
x a -> a -> T a
forall a. C a => a -> a -> T a
% Integer -> a
forall a. C a => Integer -> a
fromInteger Integer
y
propDivision :: (Eq a, ZeroTestable.C a, C a) => a -> a -> Property
propReciprocal :: (Eq a, ZeroTestable.C a, C a) => a -> Property
propDivision :: a -> a -> Property
propDivision a
a a
b = Bool -> Bool
not (a -> Bool
forall a. C a => a -> Bool
isZero a
b) Bool -> Bool -> Property
forall prop. Testable prop => Bool -> prop -> Property
==> (a
a a -> a -> a
forall a. C a => a -> a -> a
* a
b) a -> a -> a
forall a. C a => a -> a -> a
/ a
b a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
a
propReciprocal :: a -> Property
propReciprocal a
a = Bool -> Bool
not (a -> Bool
forall a. C a => a -> Bool
isZero a
a) Bool -> Bool -> Property
forall prop. Testable prop => Bool -> prop -> Property
==> a
a a -> a -> a
forall a. C a => a -> a -> a
* a -> a
forall a. C a => a -> a
recip a
a a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
forall a. C a => a
one
instance (P.Integral a) => C (Ratio98.Ratio a) where
{-# INLINE (/) #-}
{-# INLINE recip #-}
/ :: Ratio a -> Ratio a -> Ratio a
(/) = Ratio a -> Ratio a -> Ratio a
forall a. Fractional a => a -> a -> a
(P./)
recip :: Ratio a -> Ratio a
recip = (Ratio a -> Ratio a
forall a. Fractional a => a -> a
P.recip)
instance (P.RealFloat a) => C (Complex98.Complex a) where
{-# INLINE (/) #-}
{-# INLINE recip #-}
/ :: Complex a -> Complex a -> Complex a
(/) = Complex a -> Complex a -> Complex a
forall a. Fractional a => a -> a -> a
(P./)
recip :: Complex a -> Complex a
recip = (Complex a -> Complex a
forall a. Fractional a => a -> a
P.recip)