{-# LANGUAGE
BangPatterns,
DataKinds,
GADTs,
KindSignatures,
RankNTypes,
ScopedTypeVariables,
StandaloneKindSignatures,
TypeOperators #-}
module Bluefin.Algae.Coroutine
(
Coroutine(..)
, yield
, withCoroutine
, forCoroutine
, (:->)
, apply
, withFunction
, Pipe(..)
, PipeEvent(..)
, CoPipe(..)
, stepPipe
, applyCoPipe
, next
, simpleCoPipe
, voidCoPipe
, nothingPipe
, nothingCoPipe
, mapPipe
, mapCoPipe
, eitherPipe
, eitherCoPipe
, openPipe
, openCoPipe
, runPipe
, runCoPipe
, forPipe
, forCoPipe
, loopPipe
, loopCoPipe
, feedPipe
, feedCoPipe
, CoPipeSEff
, toCoPipe
, PipeSEff
, toPipe
, withCoPipe
, CoPipeEff
, fromCoPipe
, PipeEff
, fromPipe
) where
import Data.Coerce (coerce)
import Data.Function (fix)
import Data.Functor ((<&>))
import Data.Kind (Type)
import Data.Void (Void, absurd)
import Bluefin.Eff
import Bluefin.Algae
data Coroutine o i :: AEffect where
Yield :: o -> Coroutine o i i
yield :: z :> zz => Handler (Coroutine o i) z -> o -> Eff zz i
yield :: forall (z :: Effects) (zz :: Effects) o i.
(z :> zz) =>
Handler (Coroutine o i) z -> o -> Eff zz i
yield Handler (Coroutine o i) z
h o
o = Handler (Coroutine o i) z -> Coroutine o i i -> Eff zz i
forall (s :: Effects) (ss :: Effects) (f :: AEffect) a.
(s :> ss) =>
Handler f s -> f a -> Eff ss a
call Handler (Coroutine o i) z
h (o -> Coroutine o i i
forall o i. o -> Coroutine o i i
Yield o
o)
type (:->) :: Type -> Type -> AEffect
type (:->) = Coroutine
apply :: z :> zz => Handler (a :-> b) z -> a -> Eff zz b
apply :: forall (z :: Effects) (zz :: Effects) o i.
(z :> zz) =>
Handler (Coroutine o i) z -> o -> Eff zz i
apply = Handler (Coroutine a b) z -> a -> Eff zz b
forall (z :: Effects) (zz :: Effects) o i.
(z :> zz) =>
Handler (Coroutine o i) z -> o -> Eff zz i
yield
withFunction :: forall a b r zz.
(a -> Eff zz b) ->
ScopedEff (a :-> b) zz r ->
Eff zz r
withFunction :: forall a b r (zz :: Effects).
(a -> Eff zz b) -> ScopedEff (a :-> b) zz r -> Eff zz r
withFunction a -> Eff zz b
f ScopedEff (a :-> b) zz r
g = ScopedEff (a :-> b) zz r -> (a -> Eff zz b) -> Eff zz r
forall o i a (zz :: Effects).
ScopedEff (Coroutine o i) zz a -> (o -> Eff zz i) -> Eff zz a
forCoroutine Handler (a :-> b) s -> Eff (s :& zz) r
ScopedEff (a :-> b) zz r
g a -> Eff zz b
f
newtype Pipe i o m a = MkPipe (m (PipeEvent i o m a))
data PipeEvent i o m a
= Done a
| Yielding o (CoPipe i o m a)
newtype CoPipe i o m a
= MkCoPipe (i -> Pipe i o m a)
stepPipe :: Pipe i o m a -> m (PipeEvent i o m a)
stepPipe :: forall i o (m :: AEffect) a. Pipe i o m a -> m (PipeEvent i o m a)
stepPipe (MkPipe m (PipeEvent i o m a)
p) = m (PipeEvent i o m a)
p
applyCoPipe :: CoPipe i o m a -> i -> Pipe i o m a
applyCoPipe :: forall i o (m :: AEffect) a. CoPipe i o m a -> i -> Pipe i o m a
applyCoPipe (MkCoPipe i -> Pipe i o m a
k) = i -> Pipe i o m a
k
next :: Functor m => CoPipe i o m Void -> i -> m (o, CoPipe i o m Void)
next :: forall (m :: AEffect) i o.
Functor m =>
CoPipe i o m Void -> i -> m (o, CoPipe i o m Void)
next (MkCoPipe i -> Pipe i o m Void
f) i
i = PipeEvent i o m Void -> (o, CoPipe i o m Void)
forall {i} {a} {m :: AEffect}.
PipeEvent i a m Void -> (a, CoPipe i a m Void)
go (PipeEvent i o m Void -> (o, CoPipe i o m Void))
-> m (PipeEvent i o m Void) -> m (o, CoPipe i o m Void)
forall (f :: AEffect) a b. Functor f => (a -> b) -> f a -> f b
<$> Pipe i o m Void -> m (PipeEvent i o m Void)
forall i o (m :: AEffect) a. Pipe i o m a -> m (PipeEvent i o m a)
stepPipe (i -> Pipe i o m Void
f i
i) where
go :: PipeEvent i a m Void -> (a, CoPipe i a m Void)
go (Done Void
v) = Void -> (a, CoPipe i a m Void)
forall a. Void -> a
absurd Void
v
go (Yielding a
o CoPipe i a m Void
k) = (a
o, CoPipe i a m Void
k)
simpleCoPipe :: Functor m => (i -> m o) -> CoPipe i o m void
simpleCoPipe :: forall (m :: AEffect) i o void.
Functor m =>
(i -> m o) -> CoPipe i o m void
simpleCoPipe i -> m o
f = (CoPipe i o m void -> CoPipe i o m void) -> CoPipe i o m void
forall a. (a -> a) -> a
fix ((CoPipe i o m void -> CoPipe i o m void) -> CoPipe i o m void)
-> (CoPipe i o m void -> CoPipe i o m void) -> CoPipe i o m void
forall a b. (a -> b) -> a -> b
$ \CoPipe i o m void
self -> (i -> Pipe i o m void) -> CoPipe i o m void
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe (\i
i -> m (PipeEvent i o m void) -> Pipe i o m void
forall i o (m :: AEffect) a. m (PipeEvent i o m a) -> Pipe i o m a
MkPipe ((\o
o -> o -> CoPipe i o m void -> PipeEvent i o m void
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding o
o CoPipe i o m void
self) (o -> PipeEvent i o m void) -> m o -> m (PipeEvent i o m void)
forall (f :: AEffect) a b. Functor f => (a -> b) -> f a -> f b
<$> i -> m o
f i
i))
mapPipe :: Functor m => (i' -> i) -> (o -> o') -> (a -> a') -> Pipe i o m a -> Pipe i' o' m a'
mapPipe :: forall (m :: AEffect) i' i o o' a a'.
Functor m =>
(i' -> i)
-> (o -> o') -> (a -> a') -> Pipe i o m a -> Pipe i' o' m a'
mapPipe i' -> i
fi o -> o'
fo a -> a'
fa = Pipe i o m a -> Pipe i' o' m a'
mapPipe_
where
mapPipe_ :: Pipe i o m a -> Pipe i' o' m a'
mapPipe_ (MkPipe m (PipeEvent i o m a)
p) = m (PipeEvent i' o' m a') -> Pipe i' o' m a'
forall i o (m :: AEffect) a. m (PipeEvent i o m a) -> Pipe i o m a
MkPipe (PipeEvent i o m a -> PipeEvent i' o' m a'
loop (PipeEvent i o m a -> PipeEvent i' o' m a')
-> m (PipeEvent i o m a) -> m (PipeEvent i' o' m a')
forall (f :: AEffect) a b. Functor f => (a -> b) -> f a -> f b
<$> m (PipeEvent i o m a)
p)
loop :: PipeEvent i o m a -> PipeEvent i' o' m a'
loop (Done a
a) = a' -> PipeEvent i' o' m a'
forall i o (m :: AEffect) a. a -> PipeEvent i o m a
Done (a -> a'
fa a
a)
loop (Yielding o
o CoPipe i o m a
k) = o' -> CoPipe i' o' m a' -> PipeEvent i' o' m a'
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding (o -> o'
fo o
o) (CoPipe i o m a -> CoPipe i' o' m a'
mapCoPipe_ CoPipe i o m a
k)
mapCoPipe_ :: CoPipe i o m a -> CoPipe i' o' m a'
mapCoPipe_ (MkCoPipe i -> Pipe i o m a
k) = (i' -> Pipe i' o' m a') -> CoPipe i' o' m a'
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe (Pipe i o m a -> Pipe i' o' m a'
mapPipe_ (Pipe i o m a -> Pipe i' o' m a')
-> (i' -> Pipe i o m a) -> i' -> Pipe i' o' m a'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe i o m a
k (i -> Pipe i o m a) -> (i' -> i) -> i' -> Pipe i o m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i' -> i
fi)
mapCoPipe :: Functor m => (i' -> i) -> (o -> o') -> (a -> a') -> CoPipe i o m a -> CoPipe i' o' m a'
mapCoPipe :: forall (m :: AEffect) i' i o o' a a'.
Functor m =>
(i' -> i)
-> (o -> o') -> (a -> a') -> CoPipe i o m a -> CoPipe i' o' m a'
mapCoPipe i' -> i
fi o -> o'
fo a -> a'
fa (MkCoPipe i -> Pipe i o m a
k) = (i' -> Pipe i' o' m a') -> CoPipe i' o' m a'
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe ((i' -> i)
-> (o -> o') -> (a -> a') -> Pipe i o m a -> Pipe i' o' m a'
forall (m :: AEffect) i' i o o' a a'.
Functor m =>
(i' -> i)
-> (o -> o') -> (a -> a') -> Pipe i o m a -> Pipe i' o' m a'
mapPipe i' -> i
fi o -> o'
fo a -> a'
fa (Pipe i o m a -> Pipe i' o' m a')
-> (i' -> Pipe i o m a) -> i' -> Pipe i' o' m a'
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe i o m a
k (i -> Pipe i o m a) -> (i' -> i) -> i' -> Pipe i o m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i' -> i
fi)
runPipe :: Monad m => CoPipe i o m Void -> Pipe o i m a -> m a
runPipe :: forall (m :: AEffect) i o a.
Monad m =>
CoPipe i o m Void -> Pipe o i m a -> m a
runPipe CoPipe i o m Void
t (MkPipe m (PipeEvent o i m a)
p) = m (PipeEvent o i m a)
p m (PipeEvent o i m a) -> (PipeEvent o i m a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \PipeEvent o i m a
e -> case PipeEvent o i m a
e of
Done a
a -> a -> m a
forall a. a -> m a
forall (f :: AEffect) a. Applicative f => a -> f a
pure a
a
Yielding i
i CoPipe o i m a
k -> do
(o
o, CoPipe i o m Void
t') <- CoPipe i o m Void -> i -> m (o, CoPipe i o m Void)
forall (m :: AEffect) i o.
Functor m =>
CoPipe i o m Void -> i -> m (o, CoPipe i o m Void)
next CoPipe i o m Void
t i
i
CoPipe i o m Void -> CoPipe o i m a -> o -> m a
forall (m :: AEffect) i o a.
Monad m =>
CoPipe i o m Void -> CoPipe o i m a -> o -> m a
runCoPipe CoPipe i o m Void
t' CoPipe o i m a
k o
o
runCoPipe :: Monad m => CoPipe i o m Void -> CoPipe o i m a -> o -> m a
runCoPipe :: forall (m :: AEffect) i o a.
Monad m =>
CoPipe i o m Void -> CoPipe o i m a -> o -> m a
runCoPipe CoPipe i o m Void
t (MkCoPipe o -> Pipe o i m a
k) o
i = CoPipe i o m Void -> Pipe o i m a -> m a
forall (m :: AEffect) i o a.
Monad m =>
CoPipe i o m Void -> Pipe o i m a -> m a
runPipe CoPipe i o m Void
t (o -> Pipe o i m a
k o
i)
forPipe :: Monad m =>
Pipe i o m a ->
(o -> m i) ->
m a
forPipe :: forall (m :: AEffect) i o a.
Monad m =>
Pipe i o m a -> (o -> m i) -> m a
forPipe Pipe i o m a
p o -> m i
h = Pipe i o m a -> m (PipeEvent i o m a)
forall i o (m :: AEffect) a. Pipe i o m a -> m (PipeEvent i o m a)
stepPipe Pipe i o m a
p m (PipeEvent i o m a) -> (PipeEvent i o m a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= PipeEvent i o m a -> m a
loop
where
loop :: PipeEvent i o m a -> m a
loop (Done a
a) = a -> m a
forall a. a -> m a
forall (f :: AEffect) a. Applicative f => a -> f a
pure a
a
loop (Yielding o
o CoPipe i o m a
k) = o -> m i
h o
o m i -> (i -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \i
i -> Pipe i o m a -> m (PipeEvent i o m a)
forall i o (m :: AEffect) a. Pipe i o m a -> m (PipeEvent i o m a)
stepPipe (CoPipe i o m a -> i -> Pipe i o m a
forall i o (m :: AEffect) a. CoPipe i o m a -> i -> Pipe i o m a
applyCoPipe CoPipe i o m a
k i
i) m (PipeEvent i o m a) -> (PipeEvent i o m a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= PipeEvent i o m a -> m a
loop
forCoPipe :: Monad m =>
CoPipe i o m a ->
(o -> m i) ->
i -> m a
forCoPipe :: forall (m :: AEffect) i o a.
Monad m =>
CoPipe i o m a -> (o -> m i) -> i -> m a
forCoPipe (MkCoPipe i -> Pipe i o m a
k) o -> m i
h i
i = Pipe i o m a -> (o -> m i) -> m a
forall (m :: AEffect) i o a.
Monad m =>
Pipe i o m a -> (o -> m i) -> m a
forPipe (i -> Pipe i o m a
k i
i) o -> m i
h
voidCoPipe :: CoPipe Void o m a
voidCoPipe :: forall o (m :: AEffect) a. CoPipe Void o m a
voidCoPipe = (Void -> Pipe Void o m a) -> CoPipe Void o m a
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe Void -> Pipe Void o m a
forall a. Void -> a
absurd
eitherPipe :: Monad m =>
(i -> Either i1 i2) ->
CoPipe i1 o m a ->
Pipe i2 o m a ->
Pipe i o m a
eitherPipe :: forall (m :: AEffect) i i1 i2 o a.
Monad m =>
(i -> Either i1 i2)
-> CoPipe i1 o m a -> Pipe i2 o m a -> Pipe i o m a
eitherPipe i -> Either i1 i2
split CoPipe i1 o m a
t0 (MkPipe m (PipeEvent i2 o m a)
p) = m (PipeEvent i o m a) -> Pipe i o m a
forall i o (m :: AEffect) a. m (PipeEvent i o m a) -> Pipe i o m a
MkPipe (m (PipeEvent i o m a) -> Pipe i o m a)
-> m (PipeEvent i o m a) -> Pipe i o m a
forall a b. (a -> b) -> a -> b
$ m (PipeEvent i2 o m a)
p m (PipeEvent i2 o m a)
-> (PipeEvent i2 o m a -> PipeEvent i o m a)
-> m (PipeEvent i o m a)
forall (f :: AEffect) a b. Functor f => f a -> (a -> b) -> f b
<&> \PipeEvent i2 o m a
e -> case PipeEvent i2 o m a
e of
Done a
a -> a -> PipeEvent i o m a
forall i o (m :: AEffect) a. a -> PipeEvent i o m a
Done a
a
Yielding o
o CoPipe i2 o m a
k -> o -> CoPipe i o m a -> PipeEvent i o m a
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding o
o ((i -> Either i1 i2)
-> CoPipe i1 o m a -> CoPipe i2 o m a -> CoPipe i o m a
forall (m :: AEffect) i i1 i2 o a.
Functor m =>
(i -> Either i1 i2)
-> CoPipe i1 o m a -> CoPipe i2 o m a -> CoPipe i o m a
eitherCoPipe i -> Either i1 i2
split CoPipe i1 o m a
t0 CoPipe i2 o m a
k)
eitherCoPipe :: Functor m =>
(i -> Either i1 i2) ->
CoPipe i1 o m a ->
CoPipe i2 o m a ->
CoPipe i o m a
eitherCoPipe :: forall (m :: AEffect) i i1 i2 o a.
Functor m =>
(i -> Either i1 i2)
-> CoPipe i1 o m a -> CoPipe i2 o m a -> CoPipe i o m a
eitherCoPipe i -> Either i1 i2
split = CoPipe i1 o m a -> CoPipe i2 o m a -> CoPipe i o m a
loop
where
loop :: CoPipe i1 o m a -> CoPipe i2 o m a -> CoPipe i o m a
loop CoPipe i1 o m a
t1 CoPipe i2 o m a
t2 = (i -> Pipe i o m a) -> CoPipe i o m a
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe (m (PipeEvent i o m a) -> Pipe i o m a
forall i o (m :: AEffect) a. m (PipeEvent i o m a) -> Pipe i o m a
MkPipe (m (PipeEvent i o m a) -> Pipe i o m a)
-> (i -> m (PipeEvent i o m a)) -> i -> Pipe i o m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CoPipe i1 o m a
-> CoPipe i2 o m a -> Either i1 i2 -> m (PipeEvent i o m a)
transduce_ CoPipe i1 o m a
t1 CoPipe i2 o m a
t2 (Either i1 i2 -> m (PipeEvent i o m a))
-> (i -> Either i1 i2) -> i -> m (PipeEvent i o m a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Either i1 i2
split)
transduce_ :: CoPipe i1 o m a
-> CoPipe i2 o m a -> Either i1 i2 -> m (PipeEvent i o m a)
transduce_ (MkCoPipe i1 -> Pipe i1 o m a
t1) CoPipe i2 o m a
t2 (Left i1
i1) = Pipe i1 o m a -> m (PipeEvent i1 o m a)
forall i o (m :: AEffect) a. Pipe i o m a -> m (PipeEvent i o m a)
stepPipe (i1 -> Pipe i1 o m a
t1 i1
i1) m (PipeEvent i1 o m a)
-> (PipeEvent i1 o m a -> PipeEvent i o m a)
-> m (PipeEvent i o m a)
forall (f :: AEffect) a b. Functor f => f a -> (a -> b) -> f b
<&> \PipeEvent i1 o m a
e -> case PipeEvent i1 o m a
e of
Done a
a -> a -> PipeEvent i o m a
forall i o (m :: AEffect) a. a -> PipeEvent i o m a
Done a
a
Yielding o
o CoPipe i1 o m a
t1' -> o -> CoPipe i o m a -> PipeEvent i o m a
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding o
o (CoPipe i1 o m a -> CoPipe i2 o m a -> CoPipe i o m a
loop CoPipe i1 o m a
t1' CoPipe i2 o m a
t2)
transduce_ CoPipe i1 o m a
t1 (MkCoPipe i2 -> Pipe i2 o m a
t2) (Right i2
i2) = Pipe i2 o m a -> m (PipeEvent i2 o m a)
forall i o (m :: AEffect) a. Pipe i o m a -> m (PipeEvent i o m a)
stepPipe (i2 -> Pipe i2 o m a
t2 i2
i2) m (PipeEvent i2 o m a)
-> (PipeEvent i2 o m a -> PipeEvent i o m a)
-> m (PipeEvent i o m a)
forall (f :: AEffect) a b. Functor f => f a -> (a -> b) -> f b
<&> \PipeEvent i2 o m a
e -> case PipeEvent i2 o m a
e of
Done a
a -> a -> PipeEvent i o m a
forall i o (m :: AEffect) a. a -> PipeEvent i o m a
Done a
a
Yielding o
o CoPipe i2 o m a
t2' -> o -> CoPipe i o m a -> PipeEvent i o m a
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding o
o (CoPipe i1 o m a -> CoPipe i2 o m a -> CoPipe i o m a
loop CoPipe i1 o m a
t1 CoPipe i2 o m a
t2')
loopPipe :: Monad m => Pipe o o m a -> m a
loopPipe :: forall (m :: AEffect) o a. Monad m => Pipe o o m a -> m a
loopPipe (MkPipe m (PipeEvent o o m a)
p) = m (PipeEvent o o m a)
p m (PipeEvent o o m a) -> (PipeEvent o o m a -> m a) -> m a
forall a b. m a -> (a -> m b) -> m b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \PipeEvent o o m a
e -> case PipeEvent o o m a
e of
Done a
a -> a -> m a
forall a. a -> m a
forall (f :: AEffect) a. Applicative f => a -> f a
pure a
a
Yielding o
o CoPipe o o m a
k -> CoPipe o o m a -> o -> m a
forall (m :: AEffect) o a. Monad m => CoPipe o o m a -> o -> m a
loopCoPipe CoPipe o o m a
k o
o
loopCoPipe :: Monad m => CoPipe o o m a -> o -> m a
loopCoPipe :: forall (m :: AEffect) o a. Monad m => CoPipe o o m a -> o -> m a
loopCoPipe (MkCoPipe o -> Pipe o o m a
k) o
o = Pipe o o m a -> m a
forall (m :: AEffect) o a. Monad m => Pipe o o m a -> m a
loopPipe (o -> Pipe o o m a
k o
o)
openPipe :: Applicative m => Pipe i o m () -> Pipe i (Maybe o) m void
openPipe :: forall (m :: AEffect) i o void.
Applicative m =>
Pipe i o m () -> Pipe i (Maybe o) m void
openPipe (MkPipe m (PipeEvent i o m ())
p) = m (PipeEvent i (Maybe o) m void) -> Pipe i (Maybe o) m void
forall i o (m :: AEffect) a. m (PipeEvent i o m a) -> Pipe i o m a
MkPipe (m (PipeEvent i o m ())
p m (PipeEvent i o m ())
-> (PipeEvent i o m () -> PipeEvent i (Maybe o) m void)
-> m (PipeEvent i (Maybe o) m void)
forall (f :: AEffect) a b. Functor f => f a -> (a -> b) -> f b
<&> \PipeEvent i o m ()
e -> case PipeEvent i o m ()
e of
Done ()
_ -> Maybe o
-> CoPipe i (Maybe o) m void -> PipeEvent i (Maybe o) m void
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding Maybe o
forall a. Maybe a
Nothing CoPipe i (Maybe o) m void
forall (m :: AEffect) i o void.
Applicative m =>
CoPipe i (Maybe o) m void
nothingCoPipe
Yielding o
o CoPipe i o m ()
k -> Maybe o
-> CoPipe i (Maybe o) m void -> PipeEvent i (Maybe o) m void
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding (o -> Maybe o
forall a. a -> Maybe a
Just o
o) (CoPipe i o m () -> CoPipe i (Maybe o) m void
forall (m :: AEffect) i o void.
Applicative m =>
CoPipe i o m () -> CoPipe i (Maybe o) m void
openCoPipe CoPipe i o m ()
k))
openCoPipe :: Applicative m => CoPipe i o m () -> CoPipe i (Maybe o) m void
openCoPipe :: forall (m :: AEffect) i o void.
Applicative m =>
CoPipe i o m () -> CoPipe i (Maybe o) m void
openCoPipe (MkCoPipe i -> Pipe i o m ()
k) = (i -> Pipe i (Maybe o) m void) -> CoPipe i (Maybe o) m void
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe (Pipe i o m () -> Pipe i (Maybe o) m void
forall (m :: AEffect) i o void.
Applicative m =>
Pipe i o m () -> Pipe i (Maybe o) m void
openPipe (Pipe i o m () -> Pipe i (Maybe o) m void)
-> (i -> Pipe i o m ()) -> i -> Pipe i (Maybe o) m void
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe i o m ()
k)
nothingPipe :: Applicative m => Pipe i (Maybe o) m void
nothingPipe :: forall (m :: AEffect) i o void.
Applicative m =>
Pipe i (Maybe o) m void
nothingPipe = m (PipeEvent i (Maybe o) m void) -> Pipe i (Maybe o) m void
forall i o (m :: AEffect) a. m (PipeEvent i o m a) -> Pipe i o m a
MkPipe (PipeEvent i (Maybe o) m void -> m (PipeEvent i (Maybe o) m void)
forall a. a -> m a
forall (f :: AEffect) a. Applicative f => a -> f a
pure (Maybe o
-> CoPipe i (Maybe o) m void -> PipeEvent i (Maybe o) m void
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding Maybe o
forall a. Maybe a
Nothing CoPipe i (Maybe o) m void
forall (m :: AEffect) i o void.
Applicative m =>
CoPipe i (Maybe o) m void
nothingCoPipe))
nothingCoPipe :: Applicative m => CoPipe i (Maybe o) m void
nothingCoPipe :: forall (m :: AEffect) i o void.
Applicative m =>
CoPipe i (Maybe o) m void
nothingCoPipe = (i -> Pipe i (Maybe o) m void) -> CoPipe i (Maybe o) m void
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe (\i
_ -> Pipe i (Maybe o) m void
forall (m :: AEffect) i o void.
Applicative m =>
Pipe i (Maybe o) m void
nothingPipe)
type PipeSEff i o zz a = ScopedEff (Coroutine o i) zz a
type PipeEff i o zz a = forall z. z :> zz => Handler (Coroutine o i) z -> Eff zz a
type CoPipeSEff i o zz a = i -> ScopedEff (Coroutine o i) zz a
type CoPipeEff i o zz a = forall z. z :> zz => i -> Handler (Coroutine o i) z -> Eff zz a
feedPipe :: Monad m => [i] -> Pipe i o m a -> m [o]
feedPipe :: forall (m :: AEffect) i o a.
Monad m =>
[i] -> Pipe i o m a -> m [o]
feedPipe [i]
is (MkPipe m (PipeEvent i o m a)
m) = m (PipeEvent i o m a)
m m (PipeEvent i o m a) -> (PipeEvent i o m a -> m [o]) -> m [o]
forall a b. m a -> (a -> m b) -> m b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \PipeEvent i o m a
e -> case PipeEvent i o m a
e of
Done a
_ -> [o] -> m [o]
forall a. a -> m a
forall (f :: AEffect) a. Applicative f => a -> f a
pure []
Yielding o
o CoPipe i o m a
k -> (o
o o -> [o] -> [o]
forall a. a -> [a] -> [a]
:) ([o] -> [o]) -> m [o] -> m [o]
forall (f :: AEffect) a b. Functor f => (a -> b) -> f a -> f b
<$> [i] -> CoPipe i o m a -> m [o]
forall (m :: AEffect) i o a.
Monad m =>
[i] -> CoPipe i o m a -> m [o]
feedCoPipe [i]
is CoPipe i o m a
k
feedCoPipe :: Monad m => [i] -> CoPipe i o m a -> m [o]
feedCoPipe :: forall (m :: AEffect) i o a.
Monad m =>
[i] -> CoPipe i o m a -> m [o]
feedCoPipe [] CoPipe i o m a
_ = [o] -> m [o]
forall a. a -> m a
forall (f :: AEffect) a. Applicative f => a -> f a
pure []
feedCoPipe (i
i : [i]
is) (MkCoPipe i -> Pipe i o m a
k) = [i] -> Pipe i o m a -> m [o]
forall (m :: AEffect) i o a.
Monad m =>
[i] -> Pipe i o m a -> m [o]
feedPipe [i]
is (i -> Pipe i o m a
k i
i)
toCoPipe :: forall o i a zz.
CoPipeSEff i o zz a -> CoPipe i o (Eff zz) a
toCoPipe :: forall o i a (zz :: Effects).
CoPipeSEff i o zz a -> CoPipe i o (Eff zz) a
toCoPipe CoPipeSEff i o zz a
f = (i -> Pipe i o (Eff zz) a) -> CoPipe i o (Eff zz) a
forall i o (m :: AEffect) a. (i -> Pipe i o m a) -> CoPipe i o m a
MkCoPipe (\i
i -> PipeSEff i o zz a -> Pipe i o (Eff zz) a
forall o i a (zz :: Effects).
PipeSEff i o zz a -> Pipe i o (Eff zz) a
toPipe (\Handler (Coroutine o i) s
h -> CoPipeSEff i o zz a
f i
i Handler (Coroutine o i) s
h))
fromCoPipe :: CoPipe i o (Eff zz) a -> CoPipeEff i o zz a
fromCoPipe :: forall i o (zz :: Effects) a.
CoPipe i o (Eff zz) a -> CoPipeEff i o zz a
fromCoPipe (MkCoPipe i -> Pipe i o (Eff zz) a
k) i
i Handler (Coroutine o i) z
h = Pipe i o (Eff zz) a -> PipeEff i o zz a
forall i o (zz :: Effects) a.
Pipe i o (Eff zz) a -> PipeEff i o zz a
fromPipe (i -> Pipe i o (Eff zz) a
k i
i) Handler (Coroutine o i) z
h
toPipe :: forall o i a zz.
PipeSEff i o zz a ->
Pipe i o (Eff zz) a
toPipe :: forall o i a (zz :: Effects).
PipeSEff i o zz a -> Pipe i o (Eff zz) a
toPipe PipeSEff i o zz a
f = Eff zz (PipeEvent i o (Eff zz) a) -> Pipe i o (Eff zz) a
forall i o (m :: AEffect) a. m (PipeEvent i o m a) -> Pipe i o m a
MkPipe (HandlerBody (Coroutine o i) zz (PipeEvent i o (Eff zz) a)
-> ScopedEff (Coroutine o i) zz (PipeEvent i o (Eff zz) a)
-> Eff zz (PipeEvent i o (Eff zz) a)
forall (f :: AEffect) (ss :: Effects) a.
HandlerBody f ss a -> ScopedEff f ss a -> Eff ss a
handle Coroutine o i x
-> (x -> Eff zz (PipeEvent i o (Eff zz) a))
-> Eff zz (PipeEvent i o (Eff zz) a)
HandlerBody (Coroutine o i) zz (PipeEvent i o (Eff zz) a)
coroutineHandler (Eff (s :& zz) a -> Eff (s :& zz) (PipeEvent i o (Eff zz) a)
forall (z :: Effects).
Eff (z :& zz) a -> Eff (z :& zz) (PipeEvent i o (Eff zz) a)
wrap (Eff (s :& zz) a -> Eff (s :& zz) (PipeEvent i o (Eff zz) a))
-> (Handler (Coroutine o i) s -> Eff (s :& zz) a)
-> Handler (Coroutine o i) s
-> Eff (s :& zz) (PipeEvent i o (Eff zz) a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handler (Coroutine o i) s -> Eff (s :& zz) a
PipeSEff i o zz a
f))
where
coroutineHandler :: HandlerBody (Coroutine o i) zz (PipeEvent i o (Eff zz) a)
coroutineHandler :: HandlerBody (Coroutine o i) zz (PipeEvent i o (Eff zz) a)
coroutineHandler (Yield o
o) x -> Eff zz (PipeEvent i o (Eff zz) a)
k = PipeEvent i o (Eff zz) a -> Eff zz (PipeEvent i o (Eff zz) a)
forall a. a -> Eff zz a
forall (f :: AEffect) a. Applicative f => a -> f a
pure (o -> CoPipe i o (Eff zz) a -> PipeEvent i o (Eff zz) a
forall i o (m :: AEffect) a.
o -> CoPipe i o m a -> PipeEvent i o m a
Yielding o
o ((x -> Eff zz (PipeEvent i o (Eff zz) a)) -> CoPipe i o (Eff zz) a
forall a b. Coercible a b => a -> b
coerce x -> Eff zz (PipeEvent i o (Eff zz) a)
k))
wrap :: Eff (z :& zz) a -> Eff (z :& zz) (PipeEvent i o (Eff zz) a)
wrap :: forall (z :: Effects).
Eff (z :& zz) a -> Eff (z :& zz) (PipeEvent i o (Eff zz) a)
wrap = (a -> PipeEvent i o (Eff zz) a)
-> Eff (z :& zz) a -> Eff (z :& zz) (PipeEvent i o (Eff zz) a)
forall a b. (a -> b) -> Eff (z :& zz) a -> Eff (z :& zz) b
forall (f :: AEffect) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> PipeEvent i o (Eff zz) a
forall i o (m :: AEffect) a. a -> PipeEvent i o m a
Done
fromPipe :: Pipe i o (Eff zz) a -> PipeEff i o zz a
fromPipe :: forall i o (zz :: Effects) a.
Pipe i o (Eff zz) a -> PipeEff i o zz a
fromPipe (MkPipe Eff zz (PipeEvent i o (Eff zz) a)
p) Handler (Coroutine o i) z
h = Eff zz (PipeEvent i o (Eff zz) a)
p Eff zz (PipeEvent i o (Eff zz) a)
-> (PipeEvent i o (Eff zz) a -> Eff zz a) -> Eff zz a
forall a b. Eff zz a -> (a -> Eff zz b) -> Eff zz b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \PipeEvent i o (Eff zz) a
e -> case PipeEvent i o (Eff zz) a
e of
Done a
a -> a -> Eff zz a
forall a. a -> Eff zz a
forall (f :: AEffect) a. Applicative f => a -> f a
pure a
a
Yielding o
o CoPipe i o (Eff zz) a
k -> Handler (Coroutine o i) z -> o -> Eff zz i
forall (z :: Effects) (zz :: Effects) o i.
(z :> zz) =>
Handler (Coroutine o i) z -> o -> Eff zz i
yield Handler (Coroutine o i) z
h o
o Eff zz i -> (i -> Eff zz a) -> Eff zz a
forall a b. Eff zz a -> (a -> Eff zz b) -> Eff zz b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \i
i -> CoPipe i o (Eff zz) a -> CoPipeEff i o zz a
forall i o (zz :: Effects) a.
CoPipe i o (Eff zz) a -> CoPipeEff i o zz a
fromCoPipe CoPipe i o (Eff zz) a
k i
i Handler (Coroutine o i) z
h
withCoPipe :: forall o i a zz.
CoPipe i o (Eff zz) a ->
ScopedEff (Coroutine i o) zz a ->
Eff zz a
withCoPipe :: forall o i a (zz :: Effects).
CoPipe i o (Eff zz) a -> ScopedEff (Coroutine i o) zz a -> Eff zz a
withCoPipe CoPipe i o (Eff zz) a
g ScopedEff (Coroutine i o) zz a
f = CoPipe i o (Eff zz) a
-> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a) -> Eff zz a
forall g. g -> Eff zz (g -> Eff zz a) -> Eff zz a
with CoPipe i o (Eff zz) a
g (HandlerBody (Coroutine i o) zz (CoPipe i o (Eff zz) a -> Eff zz a)
-> ScopedEff (Coroutine i o) zz (CoPipe i o (Eff zz) a -> Eff zz a)
-> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a)
forall (f :: AEffect) (ss :: Effects) a.
HandlerBody f ss a -> ScopedEff f ss a -> Eff ss a
handle Coroutine i o x
-> (x -> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a))
-> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a)
HandlerBody (Coroutine i o) zz (CoPipe i o (Eff zz) a -> Eff zz a)
coroutineHandler ((a -> CoPipe i o (Eff zz) a -> Eff zz a)
-> Eff (s :& zz) a
-> Eff (s :& zz) (CoPipe i o (Eff zz) a -> Eff zz a)
forall a b. (a -> b) -> Eff (s :& zz) a -> Eff (s :& zz) b
forall (f :: AEffect) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> CoPipe i o (Eff zz) a -> Eff zz a
forall z. a -> z -> Eff zz a
wrap (Eff (s :& zz) a
-> Eff (s :& zz) (CoPipe i o (Eff zz) a -> Eff zz a))
-> (Handler (Coroutine i o) s -> Eff (s :& zz) a)
-> Handler (Coroutine i o) s
-> Eff (s :& zz) (CoPipe i o (Eff zz) a -> Eff zz a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Handler (Coroutine i o) s -> Eff (s :& zz) a
ScopedEff (Coroutine i o) zz a
f))
where
coroutineHandler :: HandlerBody (Coroutine i o) zz (CoPipe i o (Eff zz) a -> Eff zz a)
coroutineHandler :: HandlerBody (Coroutine i o) zz (CoPipe i o (Eff zz) a -> Eff zz a)
coroutineHandler (Yield i
o) x -> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a)
k = (CoPipe i o (Eff zz) a -> Eff zz a)
-> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a)
forall a. a -> Eff zz a
forall (f :: AEffect) a. Applicative f => a -> f a
pure ((CoPipe i o (Eff zz) a -> Eff zz a)
-> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a))
-> (CoPipe i o (Eff zz) a -> Eff zz a)
-> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a)
forall a b. (a -> b) -> a -> b
$ \CoPipe i o (Eff zz) a
g1 -> do
Pipe i o (Eff zz) a -> Eff zz (PipeEvent i o (Eff zz) a)
forall i o (m :: AEffect) a. Pipe i o m a -> m (PipeEvent i o m a)
stepPipe (CoPipe i o (Eff zz) a -> i -> Pipe i o (Eff zz) a
forall i o (m :: AEffect) a. CoPipe i o m a -> i -> Pipe i o m a
applyCoPipe CoPipe i o (Eff zz) a
g1 i
o) Eff zz (PipeEvent i o (Eff zz) a)
-> (PipeEvent i o (Eff zz) a -> Eff zz a) -> Eff zz a
forall a b. Eff zz a -> (a -> Eff zz b) -> Eff zz b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \PipeEvent i o (Eff zz) a
e -> case PipeEvent i o (Eff zz) a
e of
Done a
a -> a -> Eff zz a
forall a. a -> Eff zz a
forall (f :: AEffect) a. Applicative f => a -> f a
pure a
a
Yielding o
i CoPipe i o (Eff zz) a
g2 -> CoPipe i o (Eff zz) a
-> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a) -> Eff zz a
forall g. g -> Eff zz (g -> Eff zz a) -> Eff zz a
with CoPipe i o (Eff zz) a
g2 (x -> Eff zz (CoPipe i o (Eff zz) a -> Eff zz a)
k o
x
i)
wrap :: a -> z -> Eff zz a
wrap :: forall z. a -> z -> Eff zz a
wrap a
a z
_ = a -> Eff zz a
forall a. a -> Eff zz a
forall (f :: AEffect) a. Applicative f => a -> f a
pure a
a
with :: forall g. g -> Eff zz (g -> Eff zz a) -> Eff zz a
with :: forall g. g -> Eff zz (g -> Eff zz a) -> Eff zz a
with g
g' Eff zz (g -> Eff zz a)
m = Eff zz (g -> Eff zz a)
m Eff zz (g -> Eff zz a) -> ((g -> Eff zz a) -> Eff zz a) -> Eff zz a
forall a b. Eff zz a -> (a -> Eff zz b) -> Eff zz b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= \g -> Eff zz a
f' -> g -> Eff zz a
f' g
g'
withCoroutine :: forall o i a zz.
(i -> ScopedEff (Coroutine o i) zz a) ->
ScopedEff (Coroutine i o) zz a ->
Eff zz a
withCoroutine :: forall o i a (zz :: Effects).
(i -> ScopedEff (Coroutine o i) zz a)
-> ScopedEff (Coroutine i o) zz a -> Eff zz a
withCoroutine i -> ScopedEff (Coroutine o i) zz a
g ScopedEff (Coroutine i o) zz a
f = CoPipe i o (Eff zz) a -> ScopedEff (Coroutine i o) zz a -> Eff zz a
forall o i a (zz :: Effects).
CoPipe i o (Eff zz) a -> ScopedEff (Coroutine i o) zz a -> Eff zz a
withCoPipe ((i -> ScopedEff (Coroutine o i) zz a) -> CoPipe i o (Eff zz) a
forall o i a (zz :: Effects).
CoPipeSEff i o zz a -> CoPipe i o (Eff zz) a
toCoPipe i -> Handler (Coroutine o i) s -> Eff ('Union s zz) a
i -> ScopedEff (Coroutine o i) zz a
g) Handler (Coroutine i o) s -> Eff (s :& zz) a
ScopedEff (Coroutine i o) zz a
f
forCoroutine :: forall o i a zz.
ScopedEff (Coroutine o i) zz a ->
(o -> Eff zz i) ->
Eff zz a
forCoroutine :: forall o i a (zz :: Effects).
ScopedEff (Coroutine o i) zz a -> (o -> Eff zz i) -> Eff zz a
forCoroutine ScopedEff (Coroutine o i) zz a
f o -> Eff zz i
h = HandlerBody (Coroutine o i) zz a
-> ScopedEff (Coroutine o i) zz a -> Eff zz a
forall (f :: AEffect) (ss :: Effects) a.
HandlerBody f ss a -> ScopedEff f ss a -> Eff ss a
handle Coroutine o i x -> (x -> Eff zz a) -> Eff zz a
HandlerBody (Coroutine o i) zz a
coroutineHandler Handler (Coroutine o i) s -> Eff (s :& zz) a
ScopedEff (Coroutine o i) zz a
f
where
coroutineHandler :: HandlerBody (Coroutine o i) zz a
coroutineHandler :: HandlerBody (Coroutine o i) zz a
coroutineHandler (Yield o
o) x -> Eff zz a
k = o -> Eff zz i
h o
o Eff zz i -> (i -> Eff zz a) -> Eff zz a
forall a b. Eff zz a -> (a -> Eff zz b) -> Eff zz b
forall (m :: AEffect) a b. Monad m => m a -> (a -> m b) -> m b
>>= i -> Eff zz a
x -> Eff zz a
k