module Control.Proxy.Pipe (
Pipe,
Producer,
Consumer,
Pipeline,
await,
yield,
pipe,
(<+<),
(>+>),
idP,
runPipe
) where
import Control.Monad (forever)
import Control.Monad.Trans.Free
import Control.Proxy.Core
import Control.Proxy.Class
import Data.Closed (C)
type Pipe a b = Proxy () a () b
type Producer b = Pipe () b
type Consumer a = Pipe a C
type Pipeline = Pipe () C
await :: (Monad m) => Pipe a b m a
await = request ()
pipe :: (Monad m) => (a -> b) -> Pipe a b m r
pipe f = forever $ do
x <- await
yield (f x)
yield :: (Monad m) => b -> Pipe a b m ()
yield = respond
infixr 9 <+<
infixl 9 >+>
(<+<) :: (Monad m) => Pipe b c m r -> Pipe a b m r -> Pipe a c m r
p1 <+< p2 = ((\() -> p1) <-< (\() -> p2)) ()
(>+>) :: (Monad m) => Pipe a b m r -> Pipe b c m r -> Pipe a c m r
(>+>) = flip (<+<)
idP :: (Monad m) => Pipe a a m r
idP = idT ()
runPipe :: (Monad m) => Pipeline m r -> m r
runPipe = runPipe' . unProxy
runPipe' p = do
x <- runFreeT p
case x of
Pure r -> return r
Free (Request _ f) -> runPipe' (f ())
Free (Respond _ f) -> runPipe' (f ())