{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeAbstractions #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Circuit.Bimonoid
(
Copy (..),
Discard (..),
Merge (..),
Zero (..),
CopyDiscard,
MergeZero,
Bimonoid,
SigCopy (..),
SigDiscard (..),
SigCopyDiscard,
SigPlus (..),
SigZero (..),
SigMergeZero,
Affine,
Relevant,
Cartesian,
CoAffine,
CoRelevant,
CopyT (..),
DiscardT (..),
MergeT (..),
ZeroT (..),
BimonoidT,
)
where
import Circuit.Category (Category (..))
import Circuit.Syntax (Algebra (..), Sig, SigCompose (..), Syntax (..), (:+:) (..))
import Circuit.Tensor (Tensor (..), Unit)
import Data.Kind (Type)
import Prelude hiding (id, (.))
class Merge arr a where
plus :: arr (a, a) a
class Zero arr a where
zero :: arr () a
type MergeZero arr a = (Merge arr a, Zero arr a)
instance Merge (->) () where
plus :: ((), ()) -> ()
plus ((), ())
_ = ()
{-# INLINE plus #-}
instance Zero (->) () where
zero :: () -> ()
zero ()
_ = ()
{-# INLINE zero #-}
instance Merge (->) Int where
plus :: (Int, Int) -> Int
plus = (Int -> Int -> Int) -> (Int, Int) -> Int
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Int
forall a. Num a => a -> a -> a
(+)
{-# INLINE plus #-}
instance Zero (->) Int where
zero :: () -> Int
zero ()
_ = Int
0
{-# INLINE zero #-}
instance Merge (->) Integer where
plus :: (Integer, Integer) -> Integer
plus = (Integer -> Integer -> Integer) -> (Integer, Integer) -> Integer
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+)
{-# INLINE plus #-}
instance Zero (->) Integer where
zero :: () -> Integer
zero ()
_ = Integer
0
{-# INLINE zero #-}
instance Merge (->) Double where
plus :: (Double, Double) -> Double
plus = (Double -> Double -> Double) -> (Double, Double) -> Double
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Double -> Double -> Double
forall a. Num a => a -> a -> a
(+)
{-# INLINE plus #-}
instance Zero (->) Double where
zero :: () -> Double
zero ()
_ = Double
0
{-# INLINE zero #-}
instance Merge (->) Float where
plus :: (Float, Float) -> Float
plus = (Float -> Float -> Float) -> (Float, Float) -> Float
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Float -> Float -> Float
forall a. Num a => a -> a -> a
(+)
{-# INLINE plus #-}
instance Zero (->) Float where
zero :: () -> Float
zero ()
_ = Float
0
{-# INLINE zero #-}
instance Merge (->) Bool where
plus :: (Bool, Bool) -> Bool
plus = (Bool -> Bool -> Bool) -> (Bool, Bool) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Bool -> Bool -> Bool
(||)
{-# INLINE plus #-}
instance Zero (->) Bool where
zero :: () -> Bool
zero ()
_ = Bool
False
{-# INLINE zero #-}
instance (Merge (->) a, Merge (->) b) => Merge (->) (a, b) where
plus :: ((a, b), (a, b)) -> (a, b)
plus ((a
a, b
b), (a
a', b
b')) = ((a, a) -> a
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
plus (a
a, a
a'), (b, b) -> b
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
plus (b
b, b
b'))
{-# INLINE plus #-}
instance (Zero (->) a, Zero (->) b) => Zero (->) (a, b) where
zero :: () -> (a, b)
zero ()
u = (() -> a
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
zero ()
u, () -> b
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
zero ()
u)
{-# INLINE zero #-}
instance (Merge (->) a, Zero (->) a) => Merge (->) [a] where
plus :: ([a], [a]) -> [a]
plus ([a]
xs, [a]
ys) = [a] -> [a] -> [a]
forall {b}. (Merge (->) b, Zero (->) b) => [b] -> [b] -> [b]
go [a]
xs [a]
ys
where
go :: [b] -> [b] -> [b]
go [] [] = []
go [] (b
y : [b]
ys') = (b, b) -> b
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
plus (() -> b
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
zero (), b
y) b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b] -> [b] -> [b]
go [] [b]
ys'
go (b
x : [b]
xs') [] = (b, b) -> b
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
plus (b
x, () -> b
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
zero ()) b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b] -> [b] -> [b]
go [b]
xs' []
go (b
x : [b]
xs') (b
y : [b]
ys') = (b, b) -> b
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
plus (b
x, b
y) b -> [b] -> [b]
forall a. a -> [a] -> [a]
: [b] -> [b] -> [b]
go [b]
xs' [b]
ys'
{-# INLINE plus #-}
instance Zero (->) [a] where
zero :: () -> [a]
zero ()
_ = []
{-# INLINE zero #-}
class Copy arr a where
copy :: arr a (a, a)
class Discard arr a where
discard :: arr a ()
type CopyDiscard arr a = (Copy arr a, Discard arr a)
type Bimonoid arr a = (Copy arr a, Discard arr a, Merge arr a, Zero arr a)
class (CopyT t arr a, DiscardT t arr a, MergeT t arr a, ZeroT t arr a) => BimonoidT t arr a
instance (CopyT t arr a, DiscardT t arr a, MergeT t arr a, ZeroT t arr a) => BimonoidT t arr a
class (Tensor t arr) => CopyT t arr a where
copyT :: arr a (t a a)
class (Tensor t arr) => DiscardT t arr a where
discardT :: arr a (Unit t)
class (Tensor t arr) => MergeT t arr a where
plusT :: arr (t a a) a
class (Tensor t arr) => ZeroT t arr a where
zeroT :: arr (Unit t) a
type Affine arr a = Discard arr a
type Relevant arr a = Copy arr a
type Cartesian arr a = (Copy arr a, Discard arr a)
type CoAffine arr a = Zero arr a
type CoRelevant arr a = Merge arr a
instance Copy (->) () where
copy :: () -> ((), ())
copy ()
u = (()
u, ()
u)
{-# INLINE copy #-}
instance Discard (->) () where
discard :: () -> ()
discard ()
_ = ()
{-# INLINE discard #-}
instance Copy (->) Int where
copy :: Int -> (Int, Int)
copy Int
a = (Int
a, Int
a)
{-# INLINE copy #-}
instance Discard (->) Int where
discard :: Int -> ()
discard Int
_ = ()
{-# INLINE discard #-}
instance Copy (->) Integer where
copy :: Integer -> (Integer, Integer)
copy Integer
a = (Integer
a, Integer
a)
{-# INLINE copy #-}
instance Discard (->) Integer where
discard :: Integer -> ()
discard Integer
_ = ()
{-# INLINE discard #-}
instance Copy (->) Double where
copy :: Double -> (Double, Double)
copy Double
a = (Double
a, Double
a)
{-# INLINE copy #-}
instance Discard (->) Double where
discard :: Double -> ()
discard Double
_ = ()
{-# INLINE discard #-}
instance Copy (->) Float where
copy :: Float -> (Float, Float)
copy Float
a = (Float
a, Float
a)
{-# INLINE copy #-}
instance Discard (->) Float where
discard :: Float -> ()
discard Float
_ = ()
{-# INLINE discard #-}
instance Copy (->) Bool where
copy :: Bool -> (Bool, Bool)
copy Bool
a = (Bool
a, Bool
a)
{-# INLINE copy #-}
instance Discard (->) Bool where
discard :: Bool -> ()
discard Bool
_ = ()
{-# INLINE discard #-}
instance Copy (->) (a, b) where
copy :: (a, b) -> ((a, b), (a, b))
copy (a, b)
ab = ((a, b)
ab, (a, b)
ab)
{-# INLINE copy #-}
instance Discard (->) (a, b) where
discard :: (a, b) -> ()
discard (a, b)
_ = ()
{-# INLINE discard #-}
instance Copy (->) [a] where
copy :: [a] -> ([a], [a])
copy [a]
as = ([a]
as, [a]
as)
{-# INLINE copy #-}
instance Discard (->) [a] where
discard :: [a] -> ()
discard [a]
_ = ()
{-# INLINE discard #-}
instance Copy (->) (Maybe a) where
copy :: Maybe a -> (Maybe a, Maybe a)
copy Maybe a
m = (Maybe a
m, Maybe a
m)
{-# INLINE copy #-}
instance Discard (->) (Maybe a) where
discard :: Maybe a -> ()
discard Maybe a
_ = ()
{-# INLINE discard #-}
data SigCopy (w :: Type -> Type -> Type) arr rec a b where
SigCopy ::
(CopyT w arr a) =>
SigCopy w arr rec a (w a a)
instance Algebra (SigCopy w) arr arr' where
type Ctx (SigCopy w) arr arr' = ()
alg :: forall (rec :: * -> * -> *) a b.
Ctx (SigCopy w) arr arr' =>
(forall x y. arr x y -> arr' x y)
-> (forall x y. rec x y -> arr' x y)
-> SigCopy w arr rec a b
-> arr' a b
alg forall x y. arr x y -> arr' x y
emb forall x y. rec x y -> arr' x y
_ SigCopy w arr rec a b
SigCopy = arr a b -> arr' a b
forall x y. arr x y -> arr' x y
emb (forall {k} (t :: k -> k -> k) (arr :: k -> k -> *) (a :: k).
CopyT t arr a =>
arr a (t a a)
forall (t :: * -> * -> *) (arr :: * -> * -> *) a.
CopyT t arr a =>
arr a (t a a)
copyT @w)
data SigDiscard (w :: Type -> Type -> Type) arr rec a b where
SigDiscard ::
(DiscardT w arr a) =>
SigDiscard w arr rec a (Unit w)
instance Algebra (SigDiscard w) arr arr' where
type Ctx (SigDiscard w) arr arr' = ()
alg :: forall (rec :: * -> * -> *) a b.
Ctx (SigDiscard w) arr arr' =>
(forall x y. arr x y -> arr' x y)
-> (forall x y. rec x y -> arr' x y)
-> SigDiscard w arr rec a b
-> arr' a b
alg forall x y. arr x y -> arr' x y
emb forall x y. rec x y -> arr' x y
_ SigDiscard w arr rec a b
SigDiscard = arr a b -> arr' a b
forall x y. arr x y -> arr' x y
emb (forall {k} (t :: k -> k -> k) (arr :: k -> k -> *) (a :: k).
DiscardT t arr a =>
arr a (Unit t)
forall (t :: * -> * -> *) (arr :: * -> * -> *) a.
DiscardT t arr a =>
arr a (Unit t)
discardT @w)
type SigCopyDiscard w = SigCopy w :+: SigDiscard w
data SigPlus (w :: Type -> Type -> Type) arr rec a b where
SigPlus ::
(MergeT w arr a) =>
SigPlus w arr rec (w a a) a
instance Algebra (SigPlus w) arr arr' where
type Ctx (SigPlus w) arr arr' = ()
alg :: forall (rec :: * -> * -> *) a b.
Ctx (SigPlus w) arr arr' =>
(forall x y. arr x y -> arr' x y)
-> (forall x y. rec x y -> arr' x y)
-> SigPlus w arr rec a b
-> arr' a b
alg forall x y. arr x y -> arr' x y
emb forall x y. rec x y -> arr' x y
_ SigPlus w arr rec a b
SigPlus = arr a b -> arr' a b
forall x y. arr x y -> arr' x y
emb (forall {k} (t :: k -> k -> k) (arr :: k -> k -> *) (a :: k).
MergeT t arr a =>
arr (t a a) a
forall (t :: * -> * -> *) (arr :: * -> * -> *) a.
MergeT t arr a =>
arr (t a a) a
plusT @w)
data SigZero (w :: Type -> Type -> Type) arr rec a b where
SigZero ::
(ZeroT w arr a) =>
SigZero w arr rec (Unit w) a
instance Algebra (SigZero w) arr arr' where
type Ctx (SigZero w) arr arr' = ()
alg :: forall (rec :: * -> * -> *) a b.
Ctx (SigZero w) arr arr' =>
(forall x y. arr x y -> arr' x y)
-> (forall x y. rec x y -> arr' x y)
-> SigZero w arr rec a b
-> arr' a b
alg forall x y. arr x y -> arr' x y
emb forall x y. rec x y -> arr' x y
_ SigZero w arr rec a b
SigZero = arr a b -> arr' a b
forall x y. arr x y -> arr' x y
emb (forall {k} (t :: k -> k -> k) (arr :: k -> k -> *) (a :: k).
ZeroT t arr a =>
arr (Unit t) a
forall (t :: * -> * -> *) (arr :: * -> * -> *) a.
ZeroT t arr a =>
arr (Unit t) a
zeroT @w)
type SigMergeZero w = SigPlus w :+: SigZero w
instance {-# OVERLAPPABLE #-} (Copy arr a, Tensor (,) arr) => CopyT (,) arr a where
copyT :: arr a (a, a)
copyT = arr a (a, a)
forall (arr :: * -> * -> *) a. Copy arr a => arr a (a, a)
copy
{-# INLINE copyT #-}
instance {-# OVERLAPPABLE #-} (Discard arr a, Tensor (,) arr) => DiscardT (,) arr a where
discardT :: arr a (Unit (,))
discardT = arr a ()
arr a (Unit (,))
forall {k} (arr :: k -> * -> *) (a :: k). Discard arr a => arr a ()
discard
{-# INLINE discardT #-}
instance {-# OVERLAPPABLE #-} (Merge arr a, Tensor (,) arr) => MergeT (,) arr a where
plusT :: arr (a, a) a
plusT = arr (a, a) a
forall (arr :: * -> * -> *) a. Merge arr a => arr (a, a) a
plus
{-# INLINE plusT #-}
instance {-# OVERLAPPABLE #-} (Zero arr a, Tensor (,) arr) => ZeroT (,) arr a where
zeroT :: arr (Unit (,)) a
zeroT = arr () a
arr (Unit (,)) a
forall {k} (arr :: * -> k -> *) (a :: k). Zero arr a => arr () a
zero
{-# INLINE zeroT #-}