{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Circuit.Poly.Channel
(
Channel (..),
emitChannel,
commitChannel,
idChannel,
constChannel,
mapChannel,
)
where
import Circuit.Poly
( Dir,
Eval (..),
Mono,
Morphism (..),
Poly (..),
applyLens,
lens,
runMorphism,
)
import Circuit.System
( System,
SystemEval (..),
evalToSystem,
fromEvalSystem,
lensAsSystem,
system,
toEvalSystem,
)
import Control.Category (id, (.))
import Data.Functor (void)
import Prelude hiding (id, (.))
data Channel arr (p :: Poly) where
Ch ::
(SystemEval p) =>
s ->
System arr s p ->
Channel arr p
emitChannel :: Channel (->) p -> Eval p ()
emitChannel :: forall (p :: Poly). Channel (->) p -> Eval p ()
emitChannel (Ch s
s System (->) s p
sys) = Eval p s -> Eval p ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (System (->) s p -> s -> Eval p s
forall (p :: Poly) s.
SystemEval p =>
System (->) s p -> s -> Eval p s
toEvalSystem System (->) s p
sys s
s)
commitChannel :: Channel (->) p -> Dir p -> Channel (->) p
commitChannel :: forall (p :: Poly). Channel (->) p -> Dir p -> Channel (->) p
commitChannel (Ch s
s System (->) s p
sys) Dir p
d =
let (Pos p
_pos, Dir p -> s
next) = Eval p s -> (Pos p, Dir p -> s)
forall x. Eval p x -> (Pos p, Dir p -> x)
forall (p :: Poly) x.
SystemEval p =>
Eval p x -> (Pos p, Dir p -> x)
evalToSystem (System (->) s p -> s -> Eval p s
forall (p :: Poly) s.
SystemEval p =>
System (->) s p -> s -> Eval p s
toEvalSystem System (->) s p
sys s
s)
in s -> System (->) s p -> Channel (->) p
forall (p :: Poly) s (arr :: * -> * -> *).
SystemEval p =>
s -> System arr s p -> Channel arr p
Ch (Dir p -> s
next Dir p
d) System (->) s p
sys
idChannel :: a -> Channel (->) (Mono a a)
idChannel :: forall a. a -> Channel (->) (Mono a a)
idChannel a
s0 = a -> System (->) a (Mono a a) -> Channel (->) (Mono a a)
forall (p :: Poly) s (arr :: * -> * -> *).
SystemEval p =>
s -> System arr s p -> Channel arr p
Ch a
s0 (Morphism (Mono a a) (Mono a a) -> System (->) a (Mono a a)
forall s i o.
Morphism (Mono s s) (Mono i o) -> System (->) s (Mono i o)
lensAsSystem ((a -> a) -> (a -> a -> a) -> Morphism (Mono a a) (Mono a a)
forall a b db da.
(a -> b) -> (a -> db -> da) -> Morphism (Mono da a) (Mono db b)
lens a -> a
forall a. a -> a
forall {k} (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id (\a
_ a
d -> a
d)))
constChannel :: b -> Channel (->) (Mono a b)
constChannel :: forall b a. b -> Channel (->) (Mono a b)
constChannel b
b = b -> System (->) b (Mono a b) -> Channel (->) (Mono a b)
forall (p :: Poly) s (arr :: * -> * -> *).
SystemEval p =>
s -> System arr s p -> Channel arr p
Ch b
b (Morphism (Mono b b) (Mono a b) -> System (->) b (Mono a b)
forall s i o.
Morphism (Mono s s) (Mono i o) -> System (->) s (Mono i o)
lensAsSystem ((b -> b) -> (b -> a -> b) -> Morphism (Mono b b) (Mono a b)
forall a b db da.
(a -> b) -> (a -> db -> da) -> Morphism (Mono da a) (Mono db b)
lens (b -> b -> b
forall a b. a -> b -> a
const b
b) b -> a -> b
forall a b. a -> b -> a
const))
mapChannel ::
(SystemEval p, SystemEval q) =>
Morphism p q ->
Channel (->) p ->
Channel (->) q
mapChannel :: forall (p :: Poly) (q :: Poly).
(SystemEval p, SystemEval q) =>
Morphism p q -> Channel (->) p -> Channel (->) q
mapChannel Morphism p q
m (Ch s
s System (->) s p
sys) =
s -> System (->) s q -> Channel (->) q
forall (p :: Poly) s (arr :: * -> * -> *).
SystemEval p =>
s -> System arr s p -> Channel arr p
Ch s
s (((s, Dir q) -> (s, Pos q)) -> System (->) s q
forall (arr :: * -> * -> *) s (p :: Poly).
arr (s, Dir p) (s, Pos p) -> System arr s p
system (s, Dir q) -> (s, Pos q)
step)
where
step :: (s, Dir q) -> (s, Pos q)
step (s
s', Dir q
d') =
let tgtEval :: Eval q s
tgtEval = Morphism p q -> forall x. Eval p x -> Eval q x
forall (p :: Poly) (q :: Poly).
Morphism p q -> forall x. Eval p x -> Eval q x
runMorphism Morphism p q
m (System (->) s p -> s -> Eval p s
forall (p :: Poly) s.
SystemEval p =>
System (->) s p -> s -> Eval p s
toEvalSystem System (->) s p
sys s
s')
(Pos q
pos, Dir q -> s
next) = Eval q s -> (Pos q, Dir q -> s)
forall x. Eval q x -> (Pos q, Dir q -> x)
forall (p :: Poly) x.
SystemEval p =>
Eval p x -> (Pos p, Dir p -> x)
evalToSystem Eval q s
tgtEval
in (Dir q -> s
next Dir q
d', Pos q
pos)