{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Circuit.Agent.Machina.Mark
(
spinMark,
markLoop,
)
where
import Circuit (trace)
import Circuit.Category (K (..))
import Circuit.Poles (HasDual (..), Poles (..), emit, polesK)
import Circuit.Trace (Trace (..), base, yank)
import Control.Concurrent.STM (STM)
import Data.Function (fix)
endsU :: Poles (K STM) () ()
endsU :: Poles (K STM) () ()
endsU = (() -> STM ()) -> STM () -> Poles (K STM) () ()
forall (m :: * -> *) a b.
Monad m =>
(a -> m ()) -> m b -> Poles (K m) a b
polesK (STM () -> () -> STM ()
forall a b. a -> b -> a
const (() -> STM ()
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())) (() -> STM ()
forall a. a -> STM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ())
spinMark :: (a -> Bool) -> (s -> a -> s) -> Poles (K STM) a a -> K STM s s
spinMark :: forall a s.
(a -> Bool) -> (s -> a -> s) -> Poles (K STM) a a -> K STM s s
spinMark a -> Bool
isMark s -> a -> s
step Poles (K STM) a a
e = (K STM s s -> K STM s s) -> K STM s s
forall a. (a -> a) -> a
fix ((K STM s s -> K STM s s) -> K STM s s)
-> (K STM s s -> K STM s s) -> K STM s s
forall a b. (a -> b) -> a -> b
$ \K STM s s
go -> (s -> STM s) -> K STM s s
forall {k} (m :: k -> *) a (b :: k). (a -> m b) -> K m a b
K ((s -> STM s) -> K STM s s) -> (s -> STM s) -> K STM s s
forall a b. (a -> b) -> a -> b
$ \s
s -> do
a <- K STM () a -> () -> STM a
forall {k} (m :: k -> *) a (b :: k). K m a b -> a -> m b
runK (Out (K STM) a -> forall x. In (K STM) x -> K STM x a
forall {k1} {k2} (arr :: k1 -> k2 -> *) (a :: k2).
Out arr a -> forall (x :: k1). In arr x -> arr x a
emit (Poles (K STM) a a -> Out (K STM) a
forall {k1} {k2} (arr :: k1 -> k2 -> *) (a :: k1) (b :: k2).
Poles arr a b -> Out arr b
companion Poles (K STM) a a
e) (Poles (K STM) () () -> In (K STM) ()
forall {k1} {k2} (arr :: k1 -> k2 -> *) (a :: k1) (b :: k2).
Poles arr a b -> In arr a
conjoint Poles (K STM) () ()
endsU)) ()
if isMark a
then pure s
else runK go (step s a)
markFrame :: (a -> Bool) -> (s -> a -> s) -> Poles (K STM) a a -> K STM (Either s s) (Either s s)
markFrame :: forall a s.
(a -> Bool)
-> (s -> a -> s)
-> Poles (K STM) a a
-> K STM (Either s s) (Either s s)
markFrame a -> Bool
isMark s -> a -> s
step Poles (K STM) a a
e = (Either s s -> STM (Either s s)) -> K STM (Either s s) (Either s s)
forall {k} (m :: k -> *) a (b :: k). (a -> m b) -> K m a b
K ((Either s s -> STM (Either s s))
-> K STM (Either s s) (Either s s))
-> (Either s s -> STM (Either s s))
-> K STM (Either s s) (Either s s)
forall a b. (a -> b) -> a -> b
$ \Either s s
es -> do
let s :: s
s = (s -> s) -> (s -> s) -> Either s s -> s
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either s -> s
forall a. a -> a
id s -> s
forall a. a -> a
id Either s s
es
a <- K STM () a -> () -> STM a
forall {k} (m :: k -> *) a (b :: k). K m a b -> a -> m b
runK (Out (K STM) a -> forall x. In (K STM) x -> K STM x a
forall {k1} {k2} (arr :: k1 -> k2 -> *) (a :: k2).
Out arr a -> forall (x :: k1). In arr x -> arr x a
emit (Poles (K STM) a a -> Out (K STM) a
forall {k1} {k2} (arr :: k1 -> k2 -> *) (a :: k1) (b :: k2).
Poles arr a b -> Out arr b
companion Poles (K STM) a a
e) (Poles (K STM) () () -> In (K STM) ()
forall {k1} {k2} (arr :: k1 -> k2 -> *) (a :: k1) (b :: k2).
Poles arr a b -> In arr a
conjoint Poles (K STM) () ()
endsU)) ()
pure
( if isMark a
then Right s
else Left (step s a)
)
markLoop :: (a -> Bool) -> (s -> a -> s) -> Poles (K STM) a a -> Trace Either (K STM) s s
markLoop :: forall a s.
(a -> Bool)
-> (s -> a -> s) -> Poles (K STM) a a -> Trace Either (K STM) s s
markLoop a -> Bool
isMark s -> a -> s
step Poles (K STM) a a
e = Trace Either (K STM) (Either s s) (Either s s)
-> Trace Either (K STM) s s
forall (t :: * -> * -> *) (arr :: * -> * -> *) s a b.
Trace t arr (t s a) (t s b) -> Trace t arr a b
yank (K STM (Either s s) (Either s s)
-> Trace Either (K STM) (Either s s) (Either s s)
forall (arr :: * -> * -> *) a b (t :: * -> * -> *).
arr a b -> Trace t arr a b
base ((a -> Bool)
-> (s -> a -> s)
-> Poles (K STM) a a
-> K STM (Either s s) (Either s s)
forall a s.
(a -> Bool)
-> (s -> a -> s)
-> Poles (K STM) a a
-> K STM (Either s s) (Either s s)
markFrame a -> Bool
isMark s -> a -> s
step Poles (K STM) a a
e))