{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeAbstractions #-}
{-# LANGUAGE TypeFamilyDependencies #-}
module Circuit.Linear
(
Lolli (..),
Exponential (..),
BangCopy (..),
BangWeaken (..),
WhyNotIntro (..),
WhyNotMonoid (..),
LinearBang,
AffineBang,
RelevantBang,
)
where
import Circuit.Category (Category (..))
import Circuit.Par (Bot, Par (..))
import Circuit.Tensor (Tensor (..), Unit)
import Data.Kind (Type)
import Data.Void (Void, absurd)
import Prelude hiding (curry, id, uncurry, (.))
class (Category arr) => Lolli (t :: Type -> Type -> Type) (arr :: Type -> Type -> Type) where
type LolliT t arr a b :: Type
lolli ::
arr a b ->
arr (LolliT t arr a b) (LolliT t arr a b)
eval ::
arr (t a (LolliT t arr a b)) b
curry ::
arr (t a b) c ->
arr a (LolliT t arr b c)
uncurry ::
arr a (LolliT t arr b c) ->
arr (t a b) c
instance Lolli (,) (->) where
type LolliT (,) (->) a b = a -> b
lolli :: forall a b. (a -> b) -> LolliT (,) (->) a b -> LolliT (,) (->) a b
lolli a -> b
_ = LolliT (,) (->) a b -> LolliT (,) (->) a b
(a -> b) -> a -> b
forall a. a -> a
forall k (arr :: k -> k -> *) (a :: k). Category arr => arr a a
id
{-# INLINE lolli #-}
eval :: forall a b. (a, LolliT (,) (->) a b) -> b
eval (a
a, LolliT (,) (->) a b
f) = LolliT (,) (->) a b
a -> b
f a
a
{-# INLINE eval #-}
curry :: forall a b c. ((a, b) -> c) -> a -> LolliT (,) (->) b c
curry (a, b) -> c
f a
a b
b = (a, b) -> c
f (a
a, b
b)
{-# INLINE curry #-}
uncurry :: forall a b c. (a -> LolliT (,) (->) b c) -> (a, b) -> c
uncurry a -> LolliT (,) (->) b c
g (a
a, b
b) = a -> LolliT (,) (->) b c
g a
a b
b
{-# INLINE uncurry #-}
class (Tensor t arr) => Exponential t arr where
type Bang t arr a :: Type
type WhyNot t arr a = result | result -> a
class (Exponential t arr) => BangCopy t arr where
copyE ::
arr (Bang t arr a) (t (Bang t arr a) (Bang t arr a))
class (Exponential t arr) => BangWeaken t arr where
discardE ::
arr (Bang t arr a) (Unit t)
derelict ::
arr (Bang t arr a) a
class (Exponential t arr) => WhyNotIntro t arr where
introduce ::
arr a (WhyNot t arr a)
class (Exponential t arr, Par p arr) => WhyNotMonoid t p arr where
mergeE ::
arr (p (WhyNot t arr a) (WhyNot t arr a)) (WhyNot t arr a)
zeroE ::
arr (Bot p) (WhyNot t arr a)
type LinearBang t arr = (Exponential t arr, BangCopy t arr, BangWeaken t arr)
type AffineBang t arr = (Exponential t arr, BangWeaken t arr)
type RelevantBang t arr = (Exponential t arr, BangCopy t arr)
instance Exponential (,) (->) where
type Bang (,) (->) a = a
type WhyNot (,) (->) a = [a]
instance BangCopy (,) (->) where
copyE :: forall a. Bang (,) (->) a -> (Bang (,) (->) a, Bang (,) (->) a)
copyE Bang (,) (->) a
x = (Bang (,) (->) a
x, Bang (,) (->) a
x)
{-# INLINE copyE #-}
instance BangWeaken (,) (->) where
discardE :: forall a. Bang (,) (->) a -> Unit (,)
discardE Bang (,) (->) a
_ = ()
{-# INLINE discardE #-}
derelict :: forall a. Bang (,) (->) a -> a
derelict = a -> a
Bang (,) (->) a -> a
forall a. a -> a
forall k (arr :: k -> k -> *) (a :: k). Category arr => arr a a
id
{-# INLINE derelict #-}
instance WhyNotIntro (,) (->) where
introduce :: forall a. a -> WhyNot (,) (->) a
introduce a
x = [a
x]
{-# INLINE introduce #-}
instance WhyNotMonoid (,) Either (->) where
mergeE :: forall a.
Either (WhyNot (,) (->) a) (WhyNot (,) (->) a) -> WhyNot (,) (->) a
mergeE = ([a] -> [a]) -> ([a] -> [a]) -> Either [a] [a] -> [a]
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either [a] -> [a]
forall a. a -> a
forall k (arr :: k -> k -> *) (a :: k). Category arr => arr a a
id [a] -> [a]
forall a. a -> a
forall k (arr :: k -> k -> *) (a :: k). Category arr => arr a a
id
{-# INLINE mergeE #-}
zeroE :: forall a. Bot Either -> WhyNot (,) (->) a
zeroE = Void -> [a]
Bot Either -> WhyNot (,) (->) a
forall a. Void -> a
absurd
{-# INLINE zeroE #-}