>
>
>
>
>
>
>
>
>
>
>
> module Control.Quiver (
>
> P, Consumer, Producer, Effect,
> consume, produce, enclose, deliver,
> decouple, deplete,
>
> fetch, fetch_,
> emit, emit_,
> qlift, qhoist,
> qpure, qid, qconcat,
> runEffect,
> (>>->), (>->>), (>&>),
> qcompose,
> ) where
> import Control.Quiver.Internal
> infixl 1 >>->, >->>, >&>
>
>
>
>
> fetch :: Functor f => a -> P a a' b b' f (Maybe a')
> fetch x = consume x (deliver . Just) (deliver Nothing)
>
>
>
> fetch_ :: a -> P a a' b b' f ()
> fetch_ x = consume x (deliver . const ()) (deliver ())
>
>
>
>
> emit :: b -> P a a' b b' f (Maybe b')
> emit y = produce y (deliver . Just) (deliver Nothing)
>
>
>
> emit_ :: b -> P a a' b b' f ()
> emit_ y = produce y (deliver . const ()) (deliver ())
>
>
>
>
>
> qpure :: (b' -> a) -> (a' -> b) -> b' -> P a a' b b' f (Either a b)
> qpure g f = cloop
> where
> cloop y = let y' = g y in consume y' ploop (deliver (Left y'))
> ploop x = let x' = f x in produce x' cloop (deliver (Right x'))
>
> 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)
>
>
>
> 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)
>
>
>
>
> (>&>) :: Functor f => P a a' b b' f r -> (r -> r') -> P a a' b b' f r'
> (>&>) = flip fmap
>
>
>
> qcompose :: Functor f => (r1 -> r2 -> r) -> P a a' b b' f r1 -> P b' b c c' f r2 -> P a a' c c' f r
> qcompose ff p1 (Consume x2 k2 q2) = loop p1
> where
> loop (Consume x1 k1 q1) = consume x1 (loop . k1) (loop' q1)
> loop (Produce y1 k1 _) = qcompose ff (k1 x2) (k2 y1)
> loop (Enclose f1) = enclose (fmap loop f1)
> loop (Deliver r1) = fmap (ff r1) q2
> loop' (Consume _ _ q1) = loop' q1
> loop' (Produce y1 k1 _) = qcompose ff (k1 x2) (k2 y1)
> loop' (Enclose f1) = enclose (fmap loop' f1)
> loop' (Deliver r1) = fmap (ff r1) q2
> qcompose ff p1 (Produce y2 k2 q2) = produce y2 ((qcompose ff p1) . k2) (qcompose ff p1 q2)
> qcompose ff p1 (Enclose f2) = enclose (fmap (qcompose ff p1) f2)
> qcompose ff p1 (Deliver r2) = fmap (flip ff r2) (deplete p1)
>