, pipes, "push-category" Pipes. . , pipes, "sequencing", , , Arrow .
newtype Edge ( ), push-based pipe Category, Arrow, ArrowChoice Functor, Applicative . . , Arrow/ArrowChoice/Applicative Edge .
(Edit: https://github.com/Gabriel439/Haskell-RCPL-Library)
{-
{-
import Prelude hiding ((.), id)
import Pipes.Core
import Pipes.Lift
import Control.Monad.Morph
import Control.Category
import Control.Monad.State.Strict
import Control.Arrow
pipes; Pipes.Core push. Push-based
, , , , Proxy. , "kickstarted", push-Proxy .
push-based pipe, Category, Arrow ArrowChoice. Edge typeclass, Category Arrow
newtype Edge m r a b = Edge { unEdge :: a -> Pipe a b m r }
Category "push", push id (<~<) :
instance Monad m => Category (Edge m r) where
id = Edge push
Edge a . Edge b = Edge (a <~< b)
Edge arr, id (.. push) . respond, p />/ respond == p, f .
instance Monad m => Arrow (Edge m r) where
arr f = Edge (push />/ respond . f)
snd "" first
first (Edge p) = Edge $ \(b, d) ->
evalStateP d $ (up \>\ hoist lift . p />/ dn) b
where
up () = do
(b, d) <- request ()
lift (put d)
return b
dn c = do
d <- lift get
respond (c, d)
, ArrowChoice left. left Right, , .
instance (Monad m) => ArrowChoice (Edge m r) where
left (Edge k) = Edge (bef >=> (up \>\ (k />/ dn)))
where
bef x = case x of
Left b -> return b
Right d -> do
_ <- respond (Right d)
x2 <- request ()
bef x2
up () = do
x <- request ()
bef x
dn c = respond (Left c)
Edge "push-based"
type PProducer m r b = Edge m r () b
type PConsumer m r a = forall b . Edge m r a b
Functor Applicative PProducer. case Pipe, . , , , , f yield Pipe.
instance Functor (PProducer m r) where
fmap f (Edge k) = $ Edge $ \() -> go (k ()) where
go p = case p of
Request () ku -> Request () (\() -> go (ku ()))
-- This is the only interesting line
Respond b ku -> Respond (f b) (\() -> go (ku ()))
M m -> M (m >>= \p' -> return (go p'))
Pure r -> Pure r
, Applicative , , .
instance (Monad m) => Applicative (Edge m r ()) where
pure b = Edge $ \() -> forever $ respond b
(Edge k1) <*> (Edge k2) = Edge (\() -> goL (k1 ()) (k2 ()))
where
goL p1 p2 = case p1 of
Request () ku -> Request () (\() -> goL (ku ()) p2)
Respond f ku -> goR f (ku ()) p2
M m -> M (m >>= \p1' -> return (goL p1' p2))
Pure r -> Pure r
goR f p1 p2 = case p2 of
Request () ku -> Request () (\() -> goR f p1 (ku ()))
Respond x ku -> Respond (f x) (\() -> goL p1 (ku ()))
M m -> M (m >>= \p2' -> return (goR f p1 p2'))
Pure r -> Pure r