{-# LANGUAGE RebindableSyntax #-}
{- |
Define Transcendental functions on arbitrary fields.
These functions are defined for only a few (in most cases only one) arguments,
that's why we discourage making these types instances of 'Algebra.Transcendental.C'.
But instances of 'Algebra.Transcendental.C' can be useful when working with power series.
If you intend to work with power series with 'Rational' coefficients,
you might consider using @MathObj.PowerSeries.T (Number.PartiallyTranscendental.T Rational)@
instead of @MathObj.PowerSeries.T Rational@.
-}
module Number.PartiallyTranscendental (T, fromValue, toValue) where

import qualified Algebra.Transcendental as Transcendental
import qualified Algebra.Algebraic      as Algebraic
import qualified Algebra.Field          as Field
import qualified Algebra.Ring           as Ring
import qualified Algebra.Additive       as Additive

import NumericPrelude.Numeric
import NumericPrelude.Base

import qualified Prelude as P


newtype T a = Cons {T a -> a
toValue :: a}
   deriving (T a -> T a -> Bool
(T a -> T a -> Bool) -> (T a -> T a -> Bool) -> Eq (T a)
forall a. Eq a => T a -> T a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: T a -> T a -> Bool
$c/= :: forall a. Eq a => T a -> T a -> Bool
== :: T a -> T a -> Bool
$c== :: forall a. Eq a => T a -> T a -> Bool
Eq, Eq (T a)
Eq (T a)
-> (T a -> T a -> Ordering)
-> (T a -> T a -> Bool)
-> (T a -> T a -> Bool)
-> (T a -> T a -> Bool)
-> (T a -> T a -> Bool)
-> (T a -> T a -> T a)
-> (T a -> T a -> T a)
-> Ord (T a)
T a -> T a -> Bool
T a -> T a -> Ordering
T a -> T a -> T a
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (T a)
forall a. Ord a => T a -> T a -> Bool
forall a. Ord a => T a -> T a -> Ordering
forall a. Ord a => T a -> T a -> T a
min :: T a -> T a -> T a
$cmin :: forall a. Ord a => T a -> T a -> T a
max :: T a -> T a -> T a
$cmax :: forall a. Ord a => T a -> T a -> T a
>= :: T a -> T a -> Bool
$c>= :: forall a. Ord a => T a -> T a -> Bool
> :: T a -> T a -> Bool
$c> :: forall a. Ord a => T a -> T a -> Bool
<= :: T a -> T a -> Bool
$c<= :: forall a. Ord a => T a -> T a -> Bool
< :: T a -> T a -> Bool
$c< :: forall a. Ord a => T a -> T a -> Bool
compare :: T a -> T a -> Ordering
$ccompare :: forall a. Ord a => T a -> T a -> Ordering
$cp1Ord :: forall a. Ord a => Eq (T a)
Ord, Int -> T a -> ShowS
[T a] -> ShowS
T a -> String
(Int -> T a -> ShowS)
-> (T a -> String) -> ([T a] -> ShowS) -> Show (T a)
forall a. Show a => Int -> T a -> ShowS
forall a. Show a => [T a] -> ShowS
forall a. Show a => T a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [T a] -> ShowS
$cshowList :: forall a. Show a => [T a] -> ShowS
show :: T a -> String
$cshow :: forall a. Show a => T a -> String
showsPrec :: Int -> T a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> T a -> ShowS
Show)

fromValue :: a -> T a
fromValue :: a -> T a
fromValue = a -> T a
forall a. a -> T a
lift0

lift0 :: a -> T a
lift0 :: a -> T a
lift0 = a -> T a
forall a. a -> T a
Cons

lift1 :: (a -> a) -> (T a -> T a)
lift1 :: (a -> a) -> T a -> T a
lift1 a -> a
f (Cons a
x0) = a -> T a
forall a. a -> T a
Cons (a -> a
f a
x0)

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 (Cons a
x0) (Cons a
x1) = a -> T a
forall a. a -> T a
Cons (a -> a -> a
f a
x0 a
x1)


instance (Additive.C a) => Additive.C (T a) where
    negate :: T a -> T a
negate = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift1 a -> a
forall a. C a => a -> a
negate
    + :: 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
(+)
    (-)    = (a -> a -> a) -> T a -> T a -> T a
forall a. (a -> a -> a) -> T a -> T a -> T a
lift2 (-)
    zero :: T a
zero   = a -> T a
forall a. a -> T a
lift0 a
forall a. C a => a
zero

instance (Ring.C a) => Ring.C (T a) where
    one :: T a
one           = a -> T a
forall a. a -> T a
lift0 a
forall a. C a => a
one
    fromInteger :: Integer -> T a
fromInteger Integer
n = a -> T a
forall a. a -> T a
lift0 (Integer -> a
forall a. C a => Integer -> a
fromInteger Integer
n)
    * :: 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 (Field.C a) => Field.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
(/)

instance (Algebraic.C a) => Algebraic.C (T a) where
    sqrt :: T a -> T a
sqrt T a
x = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift1 a -> a
forall a. C a => a -> a
sqrt T a
x
    root :: Integer -> T a -> T a
root Integer
n = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift1 (Integer -> a -> a
forall a. C a => Integer -> a -> a
Algebraic.root Integer
n)
    ^/ :: T a -> Rational -> T a
(^/) T a
x Rational
y = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift1 (a -> Rational -> a
forall a. C a => a -> Rational -> a
^/Rational
y) T a
x

instance (Algebraic.C a, Eq a) => Transcendental.C (T a) where
    pi :: T a
pi = T a
forall a. HasCallStack => a
undefined
    exp :: T a -> T a
exp = \T a
0 -> T a
1
    sin :: T a -> T a
sin = \T a
0 -> T a
0
    cos :: T a -> T a
cos = \T a
0 -> T a
1
    tan :: T a -> T a
tan = \T a
0 -> T a
0
    T a
x ** :: T a -> T a -> T a
** T a
y = if T a
xT a -> T a -> Bool
forall a. Eq a => a -> a -> Bool
==T a
1 Bool -> Bool -> Bool
|| T a
yT a -> T a -> Bool
forall a. Eq a => a -> a -> Bool
==T a
0
               then T a
1
               else String -> T a
forall a. HasCallStack => String -> a
error String
"partially transcendental power undefined"
    log :: T a -> T a
log  = \T a
1 -> T a
0
    asin :: T a -> T a
asin = \T a
0 -> T a
0
    acos :: T a -> T a
acos = \T a
1 -> T a
0
    atan :: T a -> T a
atan = \T a
0 -> T a
0



instance (P.Num a) => P.Num (T a) where
   fromInteger :: Integer -> T a
fromInteger = a -> T a
forall a. a -> T a
lift0 (a -> T a) -> (Integer -> a) -> Integer -> T a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. Num a => Integer -> a
P.fromInteger
   negate :: T a -> T a
negate = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift1 a -> a
forall a. Num a => a -> a
P.negate
   + :: 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. Num a => a -> a -> a
(P.+)
   (-)    = (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. Num a => a -> a -> a
(P.-)
   * :: 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. Num a => a -> a -> a
(P.*)
   abs :: T a -> T a
abs    = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift1 a -> a
forall a. Num a => a -> a
P.abs
   signum :: T a -> T a
signum = (a -> a) -> T a -> T a
forall a. (a -> a) -> T a -> T a
lift1 a -> a
forall a. Num a => a -> a
P.signum

instance (P.Fractional a) => P.Fractional (T a) where
   fromRational :: Rational -> T a
fromRational = Rational -> T a
forall a. Fractional a => Rational -> a
P.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. Fractional a => a -> a -> a
(P./)