module Data.Array.Knead.Parameter where
import qualified LLVM.Extra.Multi.Value.Memory as MultiValueMemory
import qualified LLVM.Extra.Multi.Value as MultiValue
import qualified LLVM.Extra.Class as Class
import qualified LLVM.Extra.Memory as Memory
import Foreign.Storable.Tuple ()
import Foreign.Storable (Storable, )
import qualified Control.Category as Cat
import qualified Control.Arrow as Arr
import qualified Control.Applicative as App
import Control.Applicative (pure, liftA2, )
import Data.Tuple.HT (mapFst, )
import Data.Word (Word32, )
data T p a =
Constant a |
Variable (p -> a)
get :: T p a -> (p -> a)
get (Constant a) = const a
get (Variable f) = f
valueTuple ::
(Class.MakeValueTuple tuple, Class.ValueTuple tuple ~ value) =>
T p tuple -> value -> value
valueTuple = genericValue Class.valueTupleOf
multiValue ::
(MultiValue.C a) =>
T p a -> MultiValue.T a -> MultiValue.T a
multiValue = genericValue MultiValue.cons
genericValue ::
(a -> value) ->
T p a -> value -> value
genericValue cons p v =
case p of
Constant a -> cons a
Variable _ -> v
withTuple ::
(Storable tuple, Class.MakeValueTuple tuple,
Class.ValueTuple tuple ~ value, Memory.C value) =>
T p tuple ->
(forall parameters.
(Storable parameters,
Class.MakeValueTuple parameters,
Memory.C (Class.ValueTuple parameters)) =>
(p -> parameters) ->
(Class.ValueTuple parameters -> value) ->
a) ->
a
withTuple (Constant a) f = f (const ()) (\() -> Class.valueTupleOf a)
withTuple (Variable v) f = f v id
withMulti ::
(Storable b, MultiValueMemory.C b) =>
T p b ->
(forall parameters.
(Storable parameters,
MultiValueMemory.C parameters) =>
(p -> parameters) ->
(MultiValue.T parameters -> MultiValue.T b) ->
a) ->
a
withMulti = with MultiValue.cons
with ::
(Storable b, MultiValueMemory.C b) =>
(b -> MultiValue.T b) ->
T p b ->
(forall parameters.
(Storable parameters,
MultiValueMemory.C parameters) =>
(p -> parameters) ->
(MultiValue.T parameters -> MultiValue.T b) ->
a) ->
a
with cons p f =
case p of
Constant b -> f (const ()) (\_ -> cons b)
Variable v -> f v id
data Tunnel p a =
forall t.
(Storable t, MultiValueMemory.C t) =>
Tunnel (p -> t) (MultiValue.T t -> MultiValue.T a)
tunnel ::
(Storable a, MultiValueMemory.C a) =>
(a -> MultiValue.T a) -> T p a -> Tunnel p a
tunnel cons p =
case p of
Constant b -> Tunnel (const ()) (\_ -> cons b)
Variable v -> Tunnel v id
word32 :: T p Int -> T p Word32
word32 = fmap fromIntegral
infixl 0 $#
($#) :: (T p a -> b) -> (a -> b)
($#) f a = f (pure a)
instance Cat.Category T where
id = Variable id
Constant f . _ = Constant f
Variable f . Constant a = Constant (f a)
Variable f . Variable g = Variable (f . g)
instance Arr.Arrow T where
arr = Variable
first f = Variable (mapFst (get f))
instance Functor (T p) where
fmap f (Constant a) = Constant (f a)
fmap f (Variable g) = Variable (f . g)
instance App.Applicative (T p) where
pure a = Constant a
Constant f <*> Constant a = Constant (f a)
f <*> a = Variable (\p -> get f p (get a p))
instance Monad (T p) where
return = pure
Constant x >>= f = f x
Variable x >>= f =
Variable (\p -> get (f (x p)) p)
instance Num a => Num (T p a) where
(+) = liftA2 (+)
() = liftA2 ()
(*) = liftA2 (*)
negate = fmap negate
abs = fmap abs
signum = fmap signum
fromInteger = pure . fromInteger
instance Fractional a => Fractional (T p a) where
(/) = liftA2 (/)
fromRational = pure . fromRational