module TheatreDev.Terminal.StatefulActorSpec where import TheatreDev.Prelude data StatefulActorSpec message = forall state. StatefulActorSpec { () enter :: Concurrently state, () step :: state -> NonEmpty message -> Concurrently state, () exit :: state -> Concurrently () } instance Semigroup (StatefulActorSpec message) where StatefulActorSpec Concurrently state leftEnter state -> NonEmpty message -> Concurrently state leftStep state -> Concurrently () leftExit <> :: StatefulActorSpec message -> StatefulActorSpec message -> StatefulActorSpec message <> StatefulActorSpec Concurrently state rightEnter state -> NonEmpty message -> Concurrently state rightStep state -> Concurrently () rightExit = StatefulActorSpec { enter :: Concurrently (state, state) enter = (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Concurrently state leftEnter forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> Concurrently state rightEnter, step :: (state, state) -> NonEmpty message -> Concurrently (state, state) step = \(state leftState, state rightState) NonEmpty message messages -> (,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> state -> NonEmpty message -> Concurrently state leftStep state leftState NonEmpty message messages forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b <*> state -> NonEmpty message -> Concurrently state rightStep state rightState NonEmpty message messages, exit :: (state, state) -> Concurrently () exit = \(state leftState, state rightState) -> state -> Concurrently () leftExit state leftState forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b *> state -> Concurrently () rightExit state rightState } instance Monoid (StatefulActorSpec message) where mempty :: StatefulActorSpec message mempty = StatefulActorSpec { enter :: Concurrently () enter = forall (f :: * -> *) a. Applicative f => a -> f a pure (), step :: () -> NonEmpty message -> Concurrently () step = forall a b. a -> b -> a const forall a b. (a -> b) -> a -> b $ forall a b. a -> b -> a const forall a b. (a -> b) -> a -> b $ forall (f :: * -> *) a. Applicative f => a -> f a pure (), exit :: () -> Concurrently () exit = forall a b. a -> b -> a const forall a b. (a -> b) -> a -> b $ forall (f :: * -> *) a. Applicative f => a -> f a pure () } individual :: IO state -> (state -> message -> IO state) -> (state -> IO ()) -> StatefulActorSpec message individual :: forall state message. IO state -> (state -> message -> IO state) -> (state -> IO ()) -> StatefulActorSpec message individual IO state enter state -> message -> IO state step state -> IO () exit = StatefulActorSpec { enter :: Concurrently state enter = forall a. IO a -> Concurrently a Concurrently IO state enter, step :: state -> NonEmpty message -> Concurrently state step = \state state NonEmpty message messages -> forall a. IO a -> Concurrently a Concurrently (forall (t :: * -> *) (m :: * -> *) b a. (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b foldM state -> message -> IO state step state state NonEmpty message messages), exit :: state -> Concurrently () exit = \state state -> forall a. IO a -> Concurrently a Concurrently (state -> IO () exit state state) }