{-# LANGUAGE AllowAmbiguousTypes #-}
module Data.Effect.Coroutine where
import Control.Monad ((>=>))
import Data.Effect.Input (Input (Input))
import Data.Effect.Output (Output (Output))
data Yield a b :: Effect where
Yield :: a -> Yield a b f b
makeEffectF ''Yield
data Status f a b r
=
Done r
|
Continue a (b -> f (Status f a b r))
deriving ((forall a b. (a -> b) -> Status f a b a -> Status f a b b)
-> (forall a b. a -> Status f a b b -> Status f a b a)
-> Functor (Status f a b)
forall a b. a -> Status f a b b -> Status f a b a
forall a b. (a -> b) -> Status f a b a -> Status f a b b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
forall (f :: * -> *) a b a b.
Functor f =>
a -> Status f a b b -> Status f a b a
forall (f :: * -> *) a b a b.
Functor f =>
(a -> b) -> Status f a b a -> Status f a b b
$cfmap :: forall (f :: * -> *) a b a b.
Functor f =>
(a -> b) -> Status f a b a -> Status f a b b
fmap :: forall a b. (a -> b) -> Status f a b a -> Status f a b b
$c<$ :: forall (f :: * -> *) a b a b.
Functor f =>
a -> Status f a b b -> Status f a b a
<$ :: forall a b. a -> Status f a b b -> Status f a b a
Functor)
continueStatus
:: (Monad m)
=> (x -> m (Status m a b r))
-> Status m a b x
-> m (Status m a b r)
continueStatus :: forall (m :: * -> *) x a b r.
Monad m =>
(x -> m (Status m a b r)) -> Status m a b x -> m (Status m a b r)
continueStatus x -> m (Status m a b r)
kk = Status m a b x -> m (Status m a b r)
loop
where
loop :: Status m a b x -> m (Status m a b r)
loop = \case
Done x
x -> x -> m (Status m a b r)
kk x
x
Continue a
a b -> m (Status m a b x)
k -> Status m a b r -> m (Status m a b r)
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Status m a b r -> m (Status m a b r))
-> ((b -> m (Status m a b r)) -> Status m a b r)
-> (b -> m (Status m a b r))
-> m (Status m a b r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> (b -> m (Status m a b r)) -> Status m a b r
forall (f :: * -> *) a b r.
a -> (b -> f (Status f a b r)) -> Status f a b r
Continue a
a ((b -> m (Status m a b r)) -> m (Status m a b r))
-> (b -> m (Status m a b r)) -> m (Status m a b r)
forall a b. (a -> b) -> a -> b
$ b -> m (Status m a b x)
k (b -> m (Status m a b x))
-> (Status m a b x -> m (Status m a b r))
-> b
-> m (Status m a b r)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (x -> m (Status m a b r)) -> Status m a b x -> m (Status m a b r)
forall (m :: * -> *) x a b r.
Monad m =>
(x -> m (Status m a b r)) -> Status m a b x -> m (Status m a b r)
continueStatus x -> m (Status m a b r)
kk
{-# INLINE continueStatus #-}
loopStatus
:: (Monad m)
=> (a -> m b)
-> Status m a b r
-> m r
loopStatus :: forall (m :: * -> *) a b r.
Monad m =>
(a -> m b) -> Status m a b r -> m r
loopStatus a -> m b
f = Status m a b r -> m r
loop
where
loop :: Status m a b r -> m r
loop = \case
Done r
r -> r -> m r
forall a. a -> m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure r
r
Continue a
a b -> m (Status m a b r)
k -> a -> m b
f a
a m b -> (b -> m (Status m a b r)) -> m (Status m a b r)
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= b -> m (Status m a b r)
k m (Status m a b r) -> (Status m a b r -> m r) -> m r
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> m b) -> Status m a b r -> m r
forall (m :: * -> *) a b r.
Monad m =>
(a -> m b) -> Status m a b r -> m r
loopStatus a -> m b
f
{-# INLINE loopStatus #-}
inputToYield :: Input i f a -> Yield () i f a
inputToYield :: forall i (f :: * -> *) a. Input i f a -> Yield () i f a
inputToYield Input i f a
Input = () -> Yield () i f i
forall a b (f :: * -> *). a -> Yield a b f b
Yield ()
{-# INLINE inputToYield #-}
outputToYield :: Output o f a -> Yield o () f a
outputToYield :: forall o (f :: * -> *) a. Output o f a -> Yield o () f a
outputToYield (Output o
o) = o -> Yield o () f ()
forall a b (f :: * -> *). a -> Yield a b f b
Yield o
o
{-# INLINE outputToYield #-}