{-# OPTIONS_GHC -Wall #-} -- | Field module NumHask.Algebra.Field ( Field , ExpField(..) , QuotientField(..) , BoundedField(..) , infinity , neginfinity ) where import Protolude (Double, Float, Integer, Bool, (||)) import qualified Protolude as P import NumHask.Algebra.Additive import NumHask.Algebra.Multiplicative import NumHask.Algebra.Distribution import NumHask.Algebra.Ring import Data.Complex (Complex(..)) -- | Field class ( AdditiveGroup a , MultiplicativeGroup a , Distribution a , Ring a) => Field a instance Field Double instance Field Float instance {-# Overlapping #-} (Field a) => Field (Complex a) -- | ExpField class (Field a) => ExpField a where exp :: a -> a log :: a -> a logBase :: a -> a -> a logBase a b = log b / log a (**) :: a -> a -> a (**) a b = exp (log a * b) sqrt :: a -> a sqrt a = a**(one/(one+one)) instance ExpField Double where exp = P.exp log = P.log (**) = (P.**) instance ExpField Float where exp = P.exp log = P.log (**) = (P.**) instance {-# Overlapping #-} (ExpField a) => ExpField (Complex a) where exp (rx :+ ix) = exp rx * cos ix :+ exp rx * sin ix where cos = P.undefined sin = P.undefined log (rx :+ ix) = log (sqrt (rx * rx + ix * ix)) :+ atan2 ix rx where atan2 = P.undefined -- | quotient fields explode constraints if they are polymorphed to emit general integrals class (Field a) => QuotientField a where round :: a -> Integer ceiling :: a -> Integer floor :: a -> Integer (^^) :: a -> Integer -> a instance QuotientField Float where round = P.round ceiling = P.ceiling floor = P.floor (^^) = (P.^^) instance QuotientField Double where round = P.round ceiling = P.ceiling floor = P.floor (^^) = (P.^^) -- | providing the concepts of infinity and NaN, thus moving away from error throwing class (Field a) => BoundedField a where maxBound :: a maxBound = one/zero minBound :: a minBound = negate (one/zero) nan :: a nan = zero/zero isNaN :: a -> Bool -- | prints as `Infinity` infinity :: BoundedField a => a infinity = maxBound -- | prints as `-Infinity` neginfinity :: BoundedField a => a neginfinity = minBound instance BoundedField Float where isNaN = P.isNaN instance BoundedField Double where isNaN = P.isNaN instance {-# Overlapping #-} (BoundedField a) => BoundedField (Complex a) where isNaN (rx :+ ix) = isNaN rx || isNaN ix