{-# LANGUAGE RebindableSyntax #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}

{-
Rationale for -fno-warn-orphans:
 * The orphan instances can't be put into Numeric.NonNegative.Wrapper
   since that's in another package.
 * We had to spread the instance declarations
   over the modules defining the typeclasses instantiated.
   Do we want that?
-}

{- |
Copyright   :  (c) Henning Thielemann 2007

Maintainer  :  haskell@henning-thielemann.de
Stability   :  stable
Portability :  Haskell 98

A type for non-negative numbers.
It performs a run-time check at construction time (i.e. at run-time)
and is a member of the non-negative number type class
'Numeric.NonNegative.Class.C'.
-}
module Number.NonNegative
   (T, fromNumber, fromNumberMsg, fromNumberClip, fromNumberUnsafe, toNumber,
    NonNegW.Int, NonNegW.Integer, NonNegW.Float, NonNegW.Double,
    Ratio, Rational) where

import Numeric.NonNegative.Wrapper
   (T, fromNumberUnsafe, toNumber, )
import qualified Numeric.NonNegative.Wrapper as NonNegW

import qualified Algebra.NonNegative        as NonNeg
import qualified Algebra.Transcendental     as Trans
import qualified Algebra.Algebraic          as Algebraic
import qualified Algebra.RealRing          as RealRing
import qualified Algebra.Field              as Field
import qualified Algebra.RealIntegral       as RealIntegral
import qualified Algebra.IntegralDomain     as Integral
import qualified Algebra.Absolute               as Absolute
import qualified Algebra.Ring               as Ring
import qualified Algebra.Additive           as Additive
import qualified Algebra.Monoid             as Monoid
import qualified Algebra.ZeroTestable       as ZeroTestable

import qualified Algebra.ToInteger          as ToInteger
import qualified Algebra.ToRational         as ToRational

import qualified Number.Ratio as R

import NumericPrelude.Base
import Data.Tuple.HT (mapSnd, mapPair, )
import NumericPrelude.Numeric hiding (Int, Integer, Float, Double, Rational, )


{- |
Convert a number to a non-negative number.
If a negative number is given, an error is raised.
-}
fromNumber :: (Ord a, Additive.C a) =>
      a
   -> T a
fromNumber :: a -> T a
fromNumber = String -> a -> T a
forall a. (Ord a, C a) => String -> a -> T a
fromNumberMsg String
"fromNumber"

fromNumberMsg :: (Ord a, Additive.C a) =>
      String  {- ^ name of the calling function to be used in the error message -}
   -> a
   -> T a
fromNumberMsg :: String -> a -> T a
fromNumberMsg String
funcName a
x =
   if a
xa -> a -> Bool
forall a. Ord a => a -> a -> Bool
>=a
forall a. C a => a
zero
     then a -> T a
forall a. a -> T a
fromNumberUnsafe a
x
     else String -> T a
forall a. HasCallStack => String -> a
error (String
funcNameString -> String -> String
forall a. [a] -> [a] -> [a]
++String
": negative number")

fromNumberWrap :: (Ord a, Additive.C a) =>
      String
   -> a
   -> T a
fromNumberWrap :: String -> a -> T a
fromNumberWrap String
funcName =
   String -> a -> T a
forall a. (Ord a, C a) => String -> a -> T a
fromNumberMsg (String
"Number.NonNegative."String -> String -> String
forall a. [a] -> [a] -> [a]
++String
funcName)

{- |
Convert a number to a non-negative number.
A negative number will be replaced by zero.
Use this function with care since it may hide bugs.
-}
fromNumberClip :: (Ord a, Additive.C a) =>
      a
   -> T a
fromNumberClip :: a -> T a
fromNumberClip = a -> T a
forall a. a -> T a
fromNumberUnsafe (a -> T a) -> (a -> a) -> a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. Ord a => a -> a -> a
max a
forall a. C a => a
zero



{- |
Results are not checked for positivity.
-}
lift :: (a -> a) -> (T a -> T a)
lift :: (a -> a) -> T a -> T a
lift a -> a
f = a -> T a
forall a. a -> T a
fromNumberUnsafe (a -> T a) -> (T a -> a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (T a -> a) -> T a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber

liftWrap :: (Ord a, Additive.C a) => String -> (a -> a) -> (T a -> T a)
liftWrap :: String -> (a -> a) -> T a -> T a
liftWrap String
msg a -> a
f = String -> a -> T a
forall a. (Ord a, C a) => String -> a -> T a
fromNumberWrap String
msg (a -> T a) -> (T a -> a) -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
f (a -> a) -> (T a -> a) -> T a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber


{- |
Results are not checked for positivity.
-}
lift2 :: (a -> a -> a) -> (T a -> T a -> T a)
lift2 :: (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
f T a
x T a
y =
   a -> T a
forall a. a -> T a
fromNumberUnsafe (a -> T a) -> a -> T a
forall a b. (a -> b) -> a -> b
$ a -> a -> a
f (T a -> a
forall a. T a -> a
toNumber T a
x) (T a -> a
forall a. T a -> a
toNumber T a
y)



instance ZeroTestable.C a => ZeroTestable.C (T a) where
   isZero :: T a -> Bool
isZero = a -> Bool
forall a. C a => a -> Bool
isZero (a -> Bool) -> (T a -> a) -> T a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber

instance (Additive.C a) => Monoid.C (T a) where
   idt :: T a
idt = a -> T a
forall a. a -> T a
fromNumberUnsafe a
forall a. C a => a
Additive.zero
   T a
x <*> :: T a -> T a -> T a
<*> T a
y = a -> T a
forall a. a -> T a
fromNumberUnsafe (T a -> a
forall a. T a -> a
toNumber T a
x a -> a -> a
forall a. C a => a -> a -> a
+ T a -> a
forall a. T a -> a
toNumber T a
y)
--   mconcat = fromNumberUnsafe . sum . map toNumber

instance (Ord a, Additive.C a) => NonNeg.C (T a) where
   split :: T a -> T a -> (T a, (Bool, T a))
split = (T a -> a) -> (a -> T a) -> T a -> T a -> (T a, (Bool, T a))
forall b a.
(Ord b, C b) =>
(a -> b) -> (b -> a) -> a -> a -> (a, (Bool, a))
NonNeg.splitDefault T a -> a
forall a. T a -> a
toNumber a -> T a
forall a. a -> T a
fromNumberUnsafe

instance (Ord a, Additive.C a) => Additive.C (T a) where
   zero :: T a
zero   = a -> T a
forall a. a -> T a
fromNumberUnsafe a
forall a. C a => a
zero
   + :: T a -> T a -> T a
(+)    = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
(+)
   (-)    = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"-" ((a -> a) -> T a -> T a) -> (T a -> a -> a) -> T a -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (-) (a -> a -> a) -> (T a -> a) -> T a -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber
   negate :: T a -> T a
negate = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"negate" a -> a
forall a. C a => a -> a
negate

instance (Ord a, Ring.C a) => Ring.C (T a) where
   * :: T a -> T a -> T a
(*)    = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
(*)
   fromInteger :: Integer -> T a
fromInteger = String -> a -> T a
forall a. (Ord a, C a) => String -> a -> T a
fromNumberWrap String
"fromInteger" (a -> T a) -> (Integer -> a) -> Integer -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. C a => Integer -> a
fromInteger

instance (Ord a, ToRational.C a) => ToRational.C (T a) where
   toRational :: T a -> Rational
toRational = a -> Rational
forall a. C a => a -> Rational
ToRational.toRational (a -> Rational) -> (T a -> a) -> T a -> Rational
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber

instance ToInteger.C a => ToInteger.C (T a) where
   toInteger :: T a -> Integer
toInteger = a -> Integer
forall a. C a => a -> Integer
toInteger (a -> Integer) -> (T a -> a) -> T a -> Integer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber

{- already defined in the imported module
instance (Ord a, Additive.C a, Enum a) => Enum (T a) where
   toEnum   = fromNumberWrap "toEnum" . toEnum
   fromEnum = fromEnum . toNumber

instance (Ord a, Additive.C a, Bounded a) => Bounded (T a) where
   minBound = fromNumberClip minBound
   maxBound = fromNumberWrap "maxBound" maxBound

instance (Additive.C a, Arbitrary a) => Arbitrary (T a) where
   arbitrary = liftM (fromNumberUnsafe . abs) arbitrary
-}

instance RealIntegral.C a => RealIntegral.C (T a) where
   quot :: T a -> T a -> T a
quot = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
quot
   rem :: T a -> T a -> T a
rem  = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
rem
   quotRem :: T a -> T a -> (T a, T a)
quotRem T a
x T a
y =
      (a -> T a, a -> T a) -> (a, a) -> (T a, T a)
forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair
         (a -> T a
forall a. a -> T a
fromNumberUnsafe, a -> T a
forall a. a -> T a
fromNumberUnsafe)
         (a -> a -> (a, a)
forall a. C a => a -> a -> (a, a)
quotRem (T a -> a
forall a. T a -> a
toNumber T a
x) (T a -> a
forall a. T a -> a
toNumber T a
y))

instance (Ord a, Integral.C a) => Integral.C (T a) where
   div :: T a -> T a -> T a
div  = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
div
   mod :: T a -> T a -> T a
mod  = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
mod
   divMod :: T a -> T a -> (T a, T a)
divMod T a
x T a
y =
      (a -> T a, a -> T a) -> (a, a) -> (T a, T a)
forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair
         (a -> T a
forall a. a -> T a
fromNumberUnsafe, a -> T a
forall a. a -> T a
fromNumberUnsafe)
         (a -> a -> (a, a)
forall a. C a => a -> a -> (a, a)
divMod (T a -> a
forall a. T a -> a
toNumber T a
x) (T a -> a
forall a. T a -> a
toNumber T a
y))

instance (Ord a, Field.C a) => Field.C (T a) where
   fromRational' :: Rational -> T a
fromRational' = String -> a -> T a
forall a. (Ord a, C a) => String -> a -> T a
fromNumberWrap String
"fromRational" (a -> T a) -> (Rational -> a) -> Rational -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. C a => Rational -> a
fromRational'
   / :: T a -> T a -> T a
(/) = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
(/)


instance (ZeroTestable.C a, Ord a, Absolute.C a) => Absolute.C (T a) where
   abs :: T a -> T a
abs    = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift a -> a
forall a. C a => a -> a
abs
   signum :: T a -> T a
signum = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift a -> a
forall a. C a => a -> a
signum

instance (ZeroTestable.C a, RealRing.C a) => RealRing.C (T a) where
   splitFraction :: T a -> (b, T a)
splitFraction = (a -> T a) -> (b, a) -> (b, T a)
forall b c a. (b -> c) -> (a, b) -> (a, c)
mapSnd a -> T a
forall a. a -> T a
fromNumberUnsafe ((b, a) -> (b, T a)) -> (T a -> (b, a)) -> T a -> (b, T a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b, a)
forall a b. (C a, C b) => a -> (b, a)
splitFraction (a -> (b, a)) -> (T a -> a) -> T a -> (b, a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber
   truncate :: T a -> b
truncate = a -> b
forall a b. (C a, C b) => a -> b
truncate (a -> b) -> (T a -> a) -> T a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber
   round :: T a -> b
round    = a -> b
forall a b. (C a, C b) => a -> b
round    (a -> b) -> (T a -> a) -> T a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber
   ceiling :: T a -> b
ceiling  = a -> b
forall a b. (C a, C b) => a -> b
ceiling  (a -> b) -> (T a -> a) -> T a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber
   floor :: T a -> b
floor    = a -> b
forall a b. (C a, C b) => a -> b
floor    (a -> b) -> (T a -> a) -> T a -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber

instance (Ord a, Algebraic.C a) => Algebraic.C (T a) where
   sqrt :: T a -> T a
sqrt = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift a -> a
forall a. C a => a -> a
sqrt
   ^/ :: T a -> Rational -> T a
(^/) T a
x Rational
r = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift (a -> Rational -> a
forall a. C a => a -> Rational -> a
^/ Rational
r) T a
x

instance (Ord a, Trans.C a) => Trans.C (T a) where
   pi :: T a
pi = a -> T a
forall a. (Ord a, C a) => a -> T a
fromNumber a
forall a. C a => a
pi
   exp :: T a -> T a
exp  = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift a -> a
forall a. C a => a -> a
exp
   log :: T a -> T a
log  = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"log" a -> a
forall a. C a => a -> a
log
   ** :: T a -> T a -> T a
(**) = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 a -> a -> a
forall a. C a => a -> a -> a
(**)
   logBase :: T a -> T a -> T a
logBase = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"logBase" ((a -> a) -> T a -> T a) -> (T a -> a -> a) -> T a -> T a -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> a
forall a. C a => a -> a -> a
logBase (a -> a -> a) -> (T a -> a) -> T a -> a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T a -> a
forall a. T a -> a
toNumber
   sin :: T a -> T a
sin = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"sin" a -> a
forall a. C a => a -> a
sin
   tan :: T a -> T a
tan = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"tan" a -> a
forall a. C a => a -> a
tan
   cos :: T a -> T a
cos = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"cos" a -> a
forall a. C a => a -> a
cos
   asin :: T a -> T a
asin = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"asin" a -> a
forall a. C a => a -> a
asin
   atan :: T a -> T a
atan = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"atan" a -> a
forall a. C a => a -> a
atan
   acos :: T a -> T a
acos = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"acos" a -> a
forall a. C a => a -> a
acos
   sinh :: T a -> T a
sinh = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"sinh" a -> a
forall a. C a => a -> a
sinh
   tanh :: T a -> T a
tanh = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"tanh" a -> a
forall a. C a => a -> a
tanh
   cosh :: T a -> T a
cosh = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"cosh" a -> a
forall a. C a => a -> a
cosh
   asinh :: T a -> T a
asinh = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"asinh" a -> a
forall a. C a => a -> a
asinh
   atanh :: T a -> T a
atanh = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"atanh" a -> a
forall a. C a => a -> a
atanh
   acosh :: T a -> T a
acosh = String -> (a -> a) -> T a -> T a
forall a. (Ord a, C a) => String -> (a -> a) -> T a -> T a
liftWrap String
"acosh" a -> a
forall a. C a => a -> a
acosh


type Ratio a  = T (R.T a)
type Rational = T R.Rational


{- legacy instances already defined in non-negative package -}