module Control.Effect.Coroutine ( Coroutine(..) , yield , Status(..) , runCoroutine ) where import Control.Effect.Base data Coroutine a b :: Effect where Yield :: a -> Coroutine a b m b yield :: Coroutine a b :< effs => a -> Eff effs b yield :: a -> Eff effs b yield = Coroutine a b (Eff effs) b -> Eff effs b forall (eff :: Effect) a (effs :: [Effect]). (eff :< effs) => eff (Eff effs) a -> Eff effs a send (Coroutine a b (Eff effs) b -> Eff effs b) -> (a -> Coroutine a b (Eff effs) b) -> a -> Eff effs b forall b c a. (b -> c) -> (a -> b) -> a -> c . a -> Coroutine a b (Eff effs) b forall a b (m :: * -> *). a -> Coroutine a b m b Yield data Status effs a b c = Done c | Yielded a !(b -> Eff (Coroutine a b ': effs) c) runCoroutine :: Eff (Coroutine a b ': effs) c -> Eff effs (Status effs a b c) runCoroutine :: Eff (Coroutine a b : effs) c -> Eff effs (Status effs a b c) runCoroutine = (c -> Eff effs (Status effs a b c)) -> (forall (effs' :: [Effect]) b. (Coroutine a b :< effs') => Coroutine a b (Eff effs') b -> Handle (Coroutine a b) effs c (Status effs a b c) effs' b) -> Eff (Coroutine a b : effs) c -> Eff effs (Status effs a b c) forall (eff :: Effect) a r (effs :: [Effect]). (a -> Eff effs r) -> (forall (effs' :: [Effect]) b. (eff :< effs') => eff (Eff effs') b -> Handle eff effs a r effs' b) -> Eff (eff : effs) a -> Eff effs r handle (Status effs a b c -> Eff effs (Status effs a b c) forall (f :: * -> *) a. Applicative f => a -> f a pure (Status effs a b c -> Eff effs (Status effs a b c)) -> (c -> Status effs a b c) -> c -> Eff effs (Status effs a b c) forall b c a. (b -> c) -> (a -> b) -> a -> c . c -> Status effs a b c forall (effs :: [Effect]) a b c. c -> Status effs a b c Done) \case Yield a -> ((b -> Eff (Coroutine a b : effs) c) -> Eff effs (Status effs a b c)) -> Handle (Coroutine a b) effs c (Status effs a b c) effs' b forall a (eff :: Effect) (effs :: [Effect]) i r (effs' :: [Effect]). ((a -> Eff (eff : effs) i) -> Eff effs r) -> Handle eff effs i r effs' a control0 \b -> Eff (Coroutine a b : effs) c k -> Status effs a b c -> Eff effs (Status effs a b c) forall (f :: * -> *) a. Applicative f => a -> f a pure (Status effs a b c -> Eff effs (Status effs a b c)) -> Status effs a b c -> Eff effs (Status effs a b c) forall a b. (a -> b) -> a -> b $! a -> (b -> Eff (Coroutine a b : effs) c) -> Status effs a b c forall (effs :: [Effect]) a b c. a -> (b -> Eff (Coroutine a b : effs) c) -> Status effs a b c Yielded a a b -> Eff (Coroutine a b : effs) c k