{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ExistentialQuantification #-}
module LLVM.DSL.Parameter (
   T,
   ($#),
   get,
   valueTuple,
   multiValue,

   with,
   withValue,
   withMulti,

   Tunnel(..),
   tunnel,

   Tuple(..),
   withTuple,
   withTuple1,
   withTuple2,

   -- * for implementation of new processes
   wordInt,
   ) where

import qualified LLVM.Extra.Multi.Value.Marshal as MarshalMV
import qualified LLVM.Extra.Multi.Value as MultiValue
import qualified LLVM.Extra.Tuple as Tuple
import qualified LLVM.Extra.Marshal as Marshal

import qualified Algebra.Transcendental as Trans
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 qualified Control.Category as Cat
import qualified Control.Arrow as Arr
import qualified Control.Applicative as App
import qualified Control.Functor.HT as FuncHT
import Control.Applicative (pure, liftA2)

import Data.Tuple.HT (mapFst, mapPair, mapTriple)
import Data.Word (Word)

import Prelude2010
import Prelude ()


{- |
This data type is for parameters of parameterized LLVM code.
It is better than using plain functions of type @p -> a@
since it allows for numeric instances
and we can make explicit,
whether a parameter is constant.

We recommend to use parameters for atomic types.
Although a parameter of type @T p (a,b)@ is possible,
it means that the whole parameter is variable
if only one of the pair elements is variable.
This way you may miss opportunities for constant folding.
-}
data T p a =
   Constant a |
   Variable (p -> a)


get :: T p a -> (p -> a)
get :: forall p a. T p a -> p -> a
get (Constant a
a) = a -> p -> a
forall a b. a -> b -> a
const a
a
get (Variable p -> a
f) = p -> a
f


{- |
The call @value param v@ requires
that @v@ represents the same value as @valueTupleOf (get param p)@ for some @p@.
However @v@ might be the result of a load operation
and @param@ might be a constant.
In this case it is more efficient to use @valueTupleOf (get param undefined)@
since the constant is translated to an LLVM constant
that allows for certain optimizations.

This is the main function for taking advantage of a constant parameter
in low-level implementations.
For simplicity we do not omit constant parameters in the parameter struct
since this would mean to construct types at runtime and might become ugly.
Instead we just check using 'value' at the according places in LLVM code
whether a parameter is constant
and ignore the parameter from the struct in this case.
In many cases there will be no speed benefit
because the parameter will be loaded to a register anyway.
It can only lead to speed-up if subsequent optimizations
can precompute constant expressions.
Another example is 'drop' where a loop with constant loop count can be generated.
For small loop counts and simple loop bodies the loop might get unrolled.
-}
valueTuple ::
   (Tuple.Value tuple, Tuple.ValueOf tuple ~ value) =>
   T p tuple -> value -> value
valueTuple :: forall tuple value p.
(Value tuple, ValueOf tuple ~ value) =>
T p tuple -> value -> value
valueTuple = (tuple -> value) -> T p tuple -> value -> value
forall a value p. (a -> value) -> T p a -> value -> value
genericValue tuple -> value
tuple -> ValueOf tuple
forall a. Value a => a -> ValueOf a
Tuple.valueOf

multiValue ::
   (MultiValue.C a) =>
   T p a -> MultiValue.T a -> MultiValue.T a
multiValue :: forall a p. C a => T p a -> T a -> T a
multiValue = (a -> T a) -> T p a -> T a -> T a
forall a value p. (a -> value) -> T p a -> value -> value
genericValue a -> T a
forall a. C a => a -> T a
MultiValue.cons

genericValue ::
   (a -> value) ->
   T p a -> value -> value
genericValue :: forall a value p. (a -> value) -> T p a -> value -> value
genericValue a -> value
cons T p a
p value
v =
   case T p a
p of
      Constant a
a -> a -> value
cons a
a
      Variable p -> a
_ -> value
v


{- |
This function provides specialised variants of 'get' and 'value',
that use the unit type for constants
and thus save space in parameter structures.
-}
{-# INLINE withValue #-}
withValue ::
   (Marshal.C tuple, Tuple.ValueOf tuple ~ value) =>
   T p tuple ->
   (forall parameters.
    (Marshal.C parameters) =>
    (p -> parameters) ->
    (Tuple.ValueOf parameters -> value) ->
    a) ->
   a
withValue :: forall tuple value p a.
(C tuple, ValueOf tuple ~ value) =>
T p tuple
-> (forall parameters.
    C parameters =>
    (p -> parameters) -> (ValueOf parameters -> value) -> a)
-> a
withValue (Constant tuple
a) forall parameters.
C parameters =>
(p -> parameters) -> (ValueOf parameters -> value) -> a
f = (p -> ()) -> (ValueOf () -> value) -> a
forall parameters.
C parameters =>
(p -> parameters) -> (ValueOf parameters -> value) -> a
f (() -> p -> ()
forall a b. a -> b -> a
const ()) (\() -> tuple -> ValueOf tuple
forall a. Value a => a -> ValueOf a
Tuple.valueOf tuple
a)
withValue (Variable p -> tuple
v) forall parameters.
C parameters =>
(p -> parameters) -> (ValueOf parameters -> value) -> a
f = (p -> tuple) -> (ValueOf tuple -> value) -> a
forall parameters.
C parameters =>
(p -> parameters) -> (ValueOf parameters -> value) -> a
f p -> tuple
v value -> value
ValueOf tuple -> value
forall a. a -> a
id

{-# INLINE withMulti #-}
withMulti ::
   (MarshalMV.C b) =>
   T p b ->
   (forall parameters.
    (MarshalMV.C parameters) =>
    (p -> parameters) ->
    (MultiValue.T parameters -> MultiValue.T b) ->
    a) ->
   a
withMulti :: forall b p a.
C b =>
T p b
-> (forall parameters.
    C parameters =>
    (p -> parameters) -> (T parameters -> T b) -> a)
-> a
withMulti = (b -> T b)
-> T p b
-> (forall parameters.
    C parameters =>
    (p -> parameters) -> (T parameters -> T b) -> a)
-> a
forall b p a.
C b =>
(b -> T b)
-> T p b
-> (forall parameters.
    C parameters =>
    (p -> parameters) -> (T parameters -> T b) -> a)
-> a
with b -> T b
forall a. C a => a -> T a
MultiValue.cons

{-# INLINE with #-}
with ::
   (MarshalMV.C b) =>
   (b -> MultiValue.T b) ->
   T p b ->
   (forall parameters.
    (MarshalMV.C parameters) =>
    (p -> parameters) ->
    (MultiValue.T parameters -> MultiValue.T b) ->
    a) ->
   a
with :: forall b p a.
C b =>
(b -> T b)
-> T p b
-> (forall parameters.
    C parameters =>
    (p -> parameters) -> (T parameters -> T b) -> a)
-> a
with b -> T b
cons T p b
p forall parameters.
C parameters =>
(p -> parameters) -> (T parameters -> T b) -> a
f =
   case T p b
p of
      Constant b
b -> (p -> ()) -> (T () -> T b) -> a
forall parameters.
C parameters =>
(p -> parameters) -> (T parameters -> T b) -> a
f (() -> p -> ()
forall a b. a -> b -> a
const ()) (\T ()
_ -> b -> T b
cons b
b)
      Variable p -> b
v -> (p -> b) -> (T b -> T b) -> a
forall parameters.
C parameters =>
(p -> parameters) -> (T parameters -> T b) -> a
f p -> b
v T b -> T b
forall a. a -> a
id


data Tunnel p a =
   forall t.
   (MarshalMV.C t) => Tunnel (p -> t) (MultiValue.T t -> MultiValue.T a)

tunnel :: (MarshalMV.C a) => (a -> MultiValue.T a) -> T p a -> Tunnel p a
tunnel :: forall a p. C a => (a -> T a) -> T p a -> Tunnel p a
tunnel a -> T a
cons T p a
p =
   case T p a
p of
      Constant a
b -> (p -> ()) -> (T () -> T a) -> Tunnel p a
forall p a t. C t => (p -> t) -> (T t -> T a) -> Tunnel p a
Tunnel (() -> p -> ()
forall a b. a -> b -> a
const ()) (\T ()
_ -> a -> T a
cons a
b)
      Variable p -> a
v -> (p -> a) -> (T a -> T a) -> Tunnel p a
forall p a t. C t => (p -> t) -> (T t -> T a) -> Tunnel p a
Tunnel p -> a
v T a -> T a
forall a. a -> a
id


wordInt :: T p Int -> T p Word
wordInt :: forall p. T p Int -> T p Word
wordInt = (Int -> Word) -> T p Int -> T p Word
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral


infixl 0 $#

($#) :: (T p a -> b) -> (a -> b)
$# :: forall p a b. (T p a -> b) -> a -> b
($#) T p a -> b
f a
a = T p a -> b
f (a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
a)



class Tuple tuple where
   type Composed tuple
   type Source tuple
   decompose :: T (Source tuple) (Composed tuple) -> tuple

instance Tuple (T p a) where
   type Composed (T p a) = a
   type Source (T p a) = p
   decompose :: T (Source (T p a)) (Composed (T p a)) -> T p a
decompose = T p a -> T p a
T (Source (T p a)) (Composed (T p a)) -> T p a
forall a. a -> a
id

instance (Tuple a, Tuple b, Source a ~ Source b) => Tuple (a,b) where
   type Composed (a,b) = (Composed a, Composed b)
   type Source (a,b) = Source a
   decompose :: T (Source (a, b)) (Composed (a, b)) -> (a, b)
decompose = (T (Source b) (Composed a) -> a, T (Source b) (Composed b) -> b)
-> (T (Source b) (Composed a), T (Source b) (Composed b)) -> (a, b)
forall a c b d. (a -> c, b -> d) -> (a, b) -> (c, d)
mapPair (T (Source a) (Composed a) -> a
T (Source b) (Composed a) -> a
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose, T (Source b) (Composed b) -> b
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose) ((T (Source b) (Composed a), T (Source b) (Composed b)) -> (a, b))
-> (T (Source b) (Composed a, Composed b)
    -> (T (Source b) (Composed a), T (Source b) (Composed b)))
-> T (Source b) (Composed a, Composed b)
-> (a, b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Source b) (Composed a, Composed b)
-> (T (Source b) (Composed a), T (Source b) (Composed b))
forall (f :: * -> *) a b. Functor f => f (a, b) -> (f a, f b)
FuncHT.unzip

instance
   (Tuple a, Tuple b, Tuple c, Source a ~ Source b, Source b ~ Source c) =>
      Tuple (a,b,c) where
   type Composed (a,b,c) = (Composed a, Composed b, Composed c)
   type Source (a,b,c) = Source a
   decompose :: T (Source (a, b, c)) (Composed (a, b, c)) -> (a, b, c)
decompose = (T (Source c) (Composed a) -> a, T (Source c) (Composed b) -> b,
 T (Source c) (Composed c) -> c)
-> (T (Source c) (Composed a), T (Source c) (Composed b),
    T (Source c) (Composed c))
-> (a, b, c)
forall a d b e c f.
(a -> d, b -> e, c -> f) -> (a, b, c) -> (d, e, f)
mapTriple (T (Source a) (Composed a) -> a
T (Source c) (Composed a) -> a
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose, T (Source b) (Composed b) -> b
T (Source c) (Composed b) -> b
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose, T (Source c) (Composed c) -> c
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose) ((T (Source c) (Composed a), T (Source c) (Composed b),
  T (Source c) (Composed c))
 -> (a, b, c))
-> (T (Source c) (Composed a, Composed b, Composed c)
    -> (T (Source c) (Composed a), T (Source c) (Composed b),
        T (Source c) (Composed c)))
-> T (Source c) (Composed a, Composed b, Composed c)
-> (a, b, c)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T (Source c) (Composed a, Composed b, Composed c)
-> (T (Source c) (Composed a), T (Source c) (Composed b),
    T (Source c) (Composed c))
forall (f :: * -> *) a b c.
Functor f =>
f (a, b, c) -> (f a, f b, f c)
FuncHT.unzip3

{- |
Provide all elements of a nested tuple as separate parameters.

If you do not use one of the tuple elements,
you will get a type error like
@Couldn't match type `Param.Composed t0' with `Int'@.
The problem is that the type checker cannot infer
that an element is a @Parameter.T@ if it remains unused.
-}
withTuple ::
   (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) =>
   (tuple -> f p) -> f p
withTuple :: forall tuple p (f :: * -> *).
(Tuple tuple, Source tuple ~ p, Composed tuple ~ p) =>
(tuple -> f p) -> f p
withTuple tuple -> f p
f = (T p p -> f p) -> f p
forall p (f :: * -> *). (T p p -> f p) -> f p
idFromFunctor ((T p p -> f p) -> f p) -> (T p p -> f p) -> f p
forall a b. (a -> b) -> a -> b
$ tuple -> f p
f (tuple -> f p) -> (T p p -> tuple) -> T p p -> f p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T p p -> tuple
T (Source tuple) (Composed tuple) -> tuple
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose

idFromFunctor :: (T p p -> f p) -> f p
idFromFunctor :: forall p (f :: * -> *). (T p p -> f p) -> f p
idFromFunctor T p p -> f p
f = T p p -> f p
f T p p
forall a. T a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Cat.id

withTuple1 ::
   (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) =>
   (tuple -> f p a) -> f p a
withTuple1 :: forall tuple p (f :: * -> * -> *) a.
(Tuple tuple, Source tuple ~ p, Composed tuple ~ p) =>
(tuple -> f p a) -> f p a
withTuple1 tuple -> f p a
f = (T p p -> f p a) -> f p a
forall p (f :: * -> * -> *) a. (T p p -> f p a) -> f p a
idFromFunctor1 ((T p p -> f p a) -> f p a) -> (T p p -> f p a) -> f p a
forall a b. (a -> b) -> a -> b
$ tuple -> f p a
f (tuple -> f p a) -> (T p p -> tuple) -> T p p -> f p a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T p p -> tuple
T (Source tuple) (Composed tuple) -> tuple
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose

idFromFunctor1 :: (T p p -> f p a) -> f p a
idFromFunctor1 :: forall p (f :: * -> * -> *) a. (T p p -> f p a) -> f p a
idFromFunctor1 T p p -> f p a
f = T p p -> f p a
f T p p
forall a. T a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Cat.id

withTuple2 ::
   (Tuple tuple, Source tuple ~ p, Composed tuple ~ p) =>
   (tuple -> f p a b) -> f p a b
withTuple2 :: forall tuple p (f :: * -> * -> * -> *) a b.
(Tuple tuple, Source tuple ~ p, Composed tuple ~ p) =>
(tuple -> f p a b) -> f p a b
withTuple2 tuple -> f p a b
f = (T p p -> f p a b) -> f p a b
forall p (f :: * -> * -> * -> *) a b. (T p p -> f p a b) -> f p a b
idFromFunctor2 ((T p p -> f p a b) -> f p a b) -> (T p p -> f p a b) -> f p a b
forall a b. (a -> b) -> a -> b
$ tuple -> f p a b
f (tuple -> f p a b) -> (T p p -> tuple) -> T p p -> f p a b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. T p p -> tuple
T (Source tuple) (Composed tuple) -> tuple
forall tuple.
Tuple tuple =>
T (Source tuple) (Composed tuple) -> tuple
decompose

idFromFunctor2 :: (T p p -> f p a b) -> f p a b
idFromFunctor2 :: forall p (f :: * -> * -> * -> *) a b. (T p p -> f p a b) -> f p a b
idFromFunctor2 T p p -> f p a b
f = T p p -> f p a b
f T p p
forall a. T a a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
Cat.id



{- |
@.@ can be used for fetching a parameter from a super-parameter.
-}
instance Cat.Category T where
   id :: forall a. T a a
id = (a -> a) -> T a a
forall p a. (p -> a) -> T p a
Variable a -> a
forall a. a -> a
id
   Constant c
f . :: forall b c a. T b c -> T a b -> T a c
. T a b
_ = c -> T a c
forall p a. a -> T p a
Constant c
f
   Variable b -> c
f . Constant b
a = c -> T a c
forall p a. a -> T p a
Constant (b -> c
f b
a)
   Variable b -> c
f . Variable a -> b
g = (a -> c) -> T a c
forall p a. (p -> a) -> T p a
Variable (b -> c
f (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
g)

{- |
@arr@ is useful for lifting parameter selectors to our parameter type
without relying on the constructor.
-}
instance Arr.Arrow T where
   arr :: forall p a. (p -> a) -> T p a
arr = (b -> c) -> T b c
forall p a. (p -> a) -> T p a
Variable
   first :: forall b c d. T b c -> T (b, d) (c, d)
first T b c
f = ((b, d) -> (c, d)) -> T (b, d) (c, d)
forall p a. (p -> a) -> T p a
Variable ((b -> c) -> (b, d) -> (c, d)
forall a c b. (a -> c) -> (a, b) -> (c, b)
mapFst (T b c -> b -> c
forall p a. T p a -> p -> a
get T b c
f))



{- |
Useful for splitting @T p (a,b)@ into @T p a@ and @T p b@
using @fmap fst@ and @fmap snd@.
-}
instance Functor (T p) where
   fmap :: forall a b. (a -> b) -> T p a -> T p b
fmap a -> b
f (Constant a
a) = b -> T p b
forall p a. a -> T p a
Constant (a -> b
f a
a)
   fmap a -> b
f (Variable p -> a
g) = (p -> b) -> T p b
forall p a. (p -> a) -> T p a
Variable (a -> b
f (a -> b) -> (p -> a) -> p -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. p -> a
g)

{- |
Useful for combining @T p a@ and @T p b@ to @T p (a,b)@
using @liftA2 (,)@.
However, we do not recommend to do so
because the result parameter can only be constant
if both operands are constant.
-}
instance App.Applicative (T p) where
   pure :: forall a. a -> T p a
pure a
a = a -> T p a
forall p a. a -> T p a
Constant a
a
   Constant a -> b
f <*> :: forall a b. T p (a -> b) -> T p a -> T p b
<*> Constant a
a = b -> T p b
forall p a. a -> T p a
Constant (a -> b
f a
a)
   T p (a -> b)
f <*> T p a
a = (p -> b) -> T p b
forall p a. (p -> a) -> T p a
Variable (\p
p -> T p (a -> b) -> p -> a -> b
forall p a. T p a -> p -> a
get T p (a -> b)
f p
p (T p a -> p -> a
forall p a. T p a -> p -> a
get T p a
a p
p))

instance Monad (T p) where
   return :: forall a. a -> T p a
return = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
   Constant a
x >>= :: forall a b. T p a -> (a -> T p b) -> T p b
>>= a -> T p b
f = a -> T p b
f a
x
   Variable p -> a
x >>= a -> T p b
f =
      (p -> b) -> T p b
forall p a. (p -> a) -> T p a
Variable (\p
p -> T p b -> p -> b
forall p a. T p a -> p -> a
get (a -> T p b
f (p -> a
x p
p)) p
p)


instance Num a => Num (T p a) where
   + :: T p a -> T p a -> T p a
(+) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(+)
   (-) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 (-)
   * :: T p a -> T p a -> T p a
(*) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Num a => a -> a -> a
(*)
   negate :: T p a -> T p a
negate = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
negate
   abs :: T p a -> T p a
abs = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
abs
   signum :: T p a -> T p a
signum = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Num a => a -> a
signum
   fromInteger :: Integer -> T p a
fromInteger = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> T p a) -> (Integer -> a) -> Integer -> T p a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. Num a => Integer -> a
fromInteger

instance Fractional a => Fractional (T p a) where
   / :: T p a -> T p a -> T p a
(/) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Fractional a => a -> a -> a
(/)
   fromRational :: Rational -> T p a
fromRational = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> T p a) -> (Rational -> a) -> Rational -> T p a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. Fractional a => Rational -> a
fromRational

instance Floating a => Floating (T p a) where
   pi :: T p a
pi = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. Floating a => a
pi
   sqrt :: T p a -> T p a
sqrt = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sqrt
   ** :: T p a -> T p a -> T p a
(**) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Floating a => a -> a -> a
(**)
   exp :: T p a -> T p a
exp = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
exp
   log :: T p a -> T p a
log = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
log
   logBase :: T p a -> T p a -> T p a
logBase = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. Floating a => a -> a -> a
logBase
   sin :: T p a -> T p a
sin = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sin
   tan :: T p a -> T p a
tan = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
tan
   cos :: T p a -> T p a
cos = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
cos
   asin :: T p a -> T p a
asin = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
asin
   atan :: T p a -> T p a
atan = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
atan
   acos :: T p a -> T p a
acos = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
acos
   sinh :: T p a -> T p a
sinh = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
sinh
   tanh :: T p a -> T p a
tanh = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
tanh
   cosh :: T p a -> T p a
cosh = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
cosh
   asinh :: T p a -> T p a
asinh = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
asinh
   atanh :: T p a -> T p a
atanh = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
atanh
   acosh :: T p a -> T p a
acosh = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. Floating a => a -> a
acosh


instance Additive.C a => Additive.C (T p a) where
   zero :: T p a
zero = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. C a => a
Additive.zero
   negate :: T p a -> T p a
negate = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. C a => a -> a
Additive.negate
   + :: T p a -> T p a -> T p a
(+) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. C a => a -> a -> a
(Additive.+)
   (-) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. C a => a -> a -> a
(Additive.-)

instance Ring.C a => Ring.C (T p a) where
   one :: T p a
one = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
forall a. C a => a
Ring.one
   * :: T p a -> T p a -> T p a
(*) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. C a => a -> a -> a
(Ring.*)
   T p a
x^ :: T p a -> Integer -> T p a
^Integer
n = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> Integer -> a
forall a. C a => a -> Integer -> a
Ring.^Integer
n) T p a
x
   fromInteger :: Integer -> T p a
fromInteger = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> T p a) -> (Integer -> a) -> Integer -> T p a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> a
forall a. C a => Integer -> a
Ring.fromInteger

instance Field.C a => Field.C (T p a) where
   / :: T p a -> T p a -> T p a
(/) = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. C a => a -> a -> a
(Field./)
   recip :: T p a -> T p a
recip = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. C a => a -> a
Field.recip
   fromRational' :: Rational -> T p a
fromRational' = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (a -> T p a) -> (Rational -> a) -> Rational -> T p a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rational -> a
forall a. C a => Rational -> a
Field.fromRational'

instance Algebraic.C a => Algebraic.C (T p a) where
   T p a
x ^/ :: T p a -> Rational -> T p a
^/ Rational
r = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> Rational -> a
forall a. C a => a -> Rational -> a
Algebraic.^/ Rational
r) T p a
x
   sqrt :: T p a -> T p a
sqrt = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> a
forall a. C a => a -> a
Algebraic.sqrt
   root :: Integer -> T p a -> T p a
root Integer
n = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Integer -> a -> a
forall a. C a => Integer -> a -> a
Algebraic.root Integer
n)

instance Trans.C a => Trans.C (T p a) where
   pi :: T p a
pi      = a -> T p a
forall a. a -> T p a
forall (f :: * -> *) a. Applicative f => a -> f a
pure   a
forall a. C a => a
Trans.pi
   exp :: T p a -> T p a
exp     = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.exp
   log :: T p a -> T p a
log     = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.log
   logBase :: T p a -> T p a -> T p a
logBase = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. C a => a -> a -> a
Trans.logBase
   ** :: T p a -> T p a -> T p a
(**)    = (a -> a -> a) -> T p a -> T p a -> T p a
forall a b c. (a -> b -> c) -> T p a -> T p b -> T p c
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 a -> a -> a
forall a. C a => a -> a -> a
(Trans.**)
   sin :: T p a -> T p a
sin     = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.sin
   tan :: T p a -> T p a
tan     = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.tan
   cos :: T p a -> T p a
cos     = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.cos
   asin :: T p a -> T p a
asin    = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.asin
   atan :: T p a -> T p a
atan    = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.atan
   acos :: T p a -> T p a
acos    = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.acos
   sinh :: T p a -> T p a
sinh    = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.sinh
   tanh :: T p a -> T p a
tanh    = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.tanh
   cosh :: T p a -> T p a
cosh    = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.cosh
   asinh :: T p a -> T p a
asinh   = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.asinh
   atanh :: T p a -> T p a
atanh   = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.atanh
   acosh :: T p a -> T p a
acosh   = (a -> a) -> T p a -> T p a
forall a b. (a -> b) -> T p a -> T p b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap   a -> a
forall a. C a => a -> a
Trans.acosh