>
>
>
>
>
>
>
>
>
>
>
> module Control.Quiver (
>
> P, Consumer, Producer, Effect,
> consume, produce, enclose, deliver,
> decouple, deplete,
>
> fetch, fetch',
> emit, emit', emit_,
> qlift,
> qpure, qpure_, qid,
> qconcat, qconcat_,
> runEffect,
> (>>->), (>->>),
> ) where
> import Control.Quiver.Internal
> infixl 0 >>->, >->>
>
>
>
>
> fetch :: a' -> P a' a b b' f (Maybe a)
> fetch x = consume x (deliver . Just) (deliver Nothing)
>
>
>
>
> fetch' :: a' -> Producer b b' f a -> P a' a b b' f a
> fetch' x q = consume x deliver q
>
>
>
>
> emit :: b -> P a' a b b' f (Maybe b')
> emit y = produce y (deliver . Just) (deliver Nothing)
>
>
>
>
>
> emit' :: b -> Consumer a' a f b' -> P a' a b b' f b'
> emit' y q = produce y deliver q
>
>
>
> emit_ :: b -> P a' a b b' f ()
> emit_ y = produce y (deliver . const ()) (deliver ())
>
> qlift :: Functor f => f r -> P a' a b b' f r
> qlift = enclose . fmap deliver
>
>
>
>
>
> qpure :: (b' -> a') -> (a -> b) -> b' -> P a' a b b' f ()
> qpure g f = cloop
> where
> cloop y = let y' = g y in consume y' ploop (deliver ())
> ploop x = let x' = f x in produce x' cloop (deliver ())
>
>
>
> qpure_ :: (a -> b) -> P () a b b' f ()
> qpure_ f = cloop
> where
> cloop = consume () ploop (deliver ())
> ploop x = produce (f x) (const cloop) (deliver ())
>
> qid :: b -> P b a a b f ()
> qid = cloop
> where
> cloop z = consume z ploop (deliver ())
> ploop x = produce x cloop (deliver ())
>
>
>
> qconcat :: [b] -> P [b] [a] a b f ([a], [b])
> qconcat = cloop
> where
> cloop ys = consume ys (ploop []) (deliver ([], []))
> ploop ys (x:xs) = produce x (\y -> ploop (y:ys) xs) (deliver (xs, reverse ys))
> ploop ys [] = cloop (reverse ys)
>
> qconcat_ :: P () [a] a b f [a]
> qconcat_ = cloop
> where
> cloop = consume () ploop (deliver [])
> ploop (x:xs) = produce x (const $ ploop xs) (deliver xs)
> ploop [] = cloop
>
>
>
> runEffect :: Monad f => Effect f r -> f r
> runEffect p = loop p
> where
> loop (Consume _ _ q) = loop q
> loop (Produce _ _ q) = loop q
> loop (Enclose f) = f >>= loop
> loop (Deliver r) = return r
>
>
>
>
>
>
> (>>->) :: Functor f => P a' a b b' f r1 -> P b' b c c' f r2 -> P a' a c c' f (r1, r2)
> (Consume x1 k1 q1) >>-> p2 = consume x1 ((>>-> p2) . k1) (q1 >>-> p2)
> (Produce y1 k1 q1) >>-> p2 = loop p2
> where
> loop (Consume x2 k2 _) = k1 x2 >>-> k2 y1
> loop (Produce y2 k2 q2) = produce y2 (loop . k2) (loop' q2)
> loop (Enclose f2) = enclose (fmap loop f2)
> loop (Deliver r2) = fmap (, r2) q1
> loop' (Consume x2 k2 _) = k1 x2 >>-> k2 y1
> loop' (Produce _ _ q2) = loop' q2
> loop' (Enclose f2) = enclose (fmap loop' f2)
> loop' (Deliver r2) = fmap (, r2) q1
> (Enclose f1) >>-> p2 = enclose (fmap (>>-> p2) f1)
> (Deliver r1) >>-> p2 = fmap (r1 ,) (decouple p2)
>
>
>
>
>
>
> (>->>) :: Functor f => P a' a b b' f r1 -> P b' b c c' f r2 -> P a' a c c' f (r1, r2)
> p1 >->> (Consume x2 k2 q2) = loop p1
> where
> loop (Consume x1 k1 q1) = consume x1 (loop . k1) (loop' q1)
> loop (Produce y1 k1 _) = k1 x2 >->> k2 y1
> loop (Enclose f1) = enclose (fmap loop f1)
> loop (Deliver r1) = fmap (r1 ,) q2
> loop' (Consume _ _ q1) = loop' q1
> loop' (Produce y1 k1 _) = k1 x2 >->> k2 y1
> loop' (Enclose f1) = enclose (fmap loop' f1)
> loop' (Deliver r1) = fmap (r1 ,) q2
> p1 >->> (Produce y2 k2 q2) = produce y2 ((p1 >->>) . k2) (p1 >->> q2)
> p1 >->> (Enclose f2) = enclose (fmap (p1 >->>) f2)
> p1 >->> (Deliver r2) = fmap (, r2) (deplete p1)