packages feed

quiver 0.0.0.1 → 0.0.0.2

raw patch · 3 files changed

+283/−77 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Control.Quiver: data Q a' a b' b f c
- Control.Quiver: evacuate :: Functor f => Q a' a b' b f c -> forall x' x. Q a' a x' x f c
- Control.Quiver: liftQ :: Functor f => f c -> Q a' a b' b f c
- Control.Quiver.Internal: Consume :: a' -> (a -> Q a' a b' b f c) -> (forall x' x. Q x' x b' b f c) -> Q a' a b' b f c
- Control.Quiver.Internal: Deliver :: c -> Q a' a b' b f c
- Control.Quiver.Internal: Enclose :: (f (Q a' a b' b f c)) -> Q a' a b' b f c
- Control.Quiver.Internal: Produce :: b -> (b' -> Q a' a b' b f c) -> (forall x' x. Q a' a x' x f c) -> Q a' a b' b f c
- Control.Quiver.Internal: data Q a' a b' b f c
- Control.Quiver.Internal: evacuate :: Functor f => Q a' a b' b f c -> forall x' x. Q a' a x' x f c
- Control.Quiver.Internal: instance GHC.Base.Applicative f => GHC.Base.Applicative (Control.Quiver.Internal.Q a' a b' b f)
- Control.Quiver.Internal: instance GHC.Base.Functor f => GHC.Base.Functor (Control.Quiver.Internal.Q a' a b' b f)
- Control.Quiver.Internal: instance GHC.Base.Monad f => GHC.Base.Monad (Control.Quiver.Internal.Q a' a b' b f)
+ Control.Quiver: data P a' a b' b f r
+ Control.Quiver: deplete :: Functor f => P a' a b' b f r -> Consumer a' a f r
+ Control.Quiver: liftP :: Functor f => f r -> P a' a b' b f r
+ Control.Quiver: type Consumer a' a f r = forall b' b. P a' a b' b f r
+ Control.Quiver: type Effect f r = forall a' a b' b. P a' a b' b f r
+ Control.Quiver: type Producer b' b f r = forall a' a. P a' a b' b f r
+ Control.Quiver.Internal: [Consume] :: a' -> (a -> P a' a b' b f r) -> (Producer b' b f r) -> P a' a b' b f r
+ Control.Quiver.Internal: [Deliver] :: r -> P a' a b' b f r
+ Control.Quiver.Internal: [Enclose] :: (f (P a' a b' b f r)) -> P a' a b' b f r
+ Control.Quiver.Internal: [Produce] :: b -> (b' -> P a' a b' b f r) -> (Consumer a' a f r) -> P a' a b' b f r
+ Control.Quiver.Internal: data P a' a b' b f r
+ Control.Quiver.Internal: deplete :: Functor f => P a' a b' b f r -> Consumer a' a f r
+ Control.Quiver.Internal: instance Applicative f => Applicative (P a' a b' b f)
+ Control.Quiver.Internal: instance Functor f => Functor (P a' a b' b f)
+ Control.Quiver.Internal: instance Monad f => Monad (P a' a b' b f)
+ Control.Quiver.Internal: type Consumer a' a f r = forall b' b. P a' a b' b f r
+ Control.Quiver.Internal: type Effect f r = forall a' a b' b. P a' a b' b f r
+ Control.Quiver.Internal: type Producer b' b f r = forall a' a. P a' a b' b f r
- Control.Quiver: (>->>) :: Functor f => Q a' a t' t f c1 -> Q t' t b' b f c2 -> Q a' a b' b f (c1, c2)
+ Control.Quiver: (>->>) :: Functor f => P a' a b' b f r1 -> P b' b c' c f r2 -> P a' a c' c f (r1, r2)
- Control.Quiver: (>>->) :: Functor f => Q a' a t' t f c1 -> Q t' t b' b f c2 -> Q a' a b' b f (c1, c2)
+ Control.Quiver: (>>->) :: Functor f => P a' a b' b f r1 -> P b' b c' c f r2 -> P a' a c' c f (r1, r2)
- Control.Quiver: consume :: a' -> (a -> Q a' a b' b f c) -> (forall x' x. Q x' x b' b f c) -> Q a' a b' b f c
+ Control.Quiver: consume :: a' -> (a -> P a' a b' b f r) -> Producer b' b f r -> P a' a b' b f r
- Control.Quiver: decouple :: Functor f => Q a' a b' b f c -> forall x' x. Q x' x b' b f c
+ Control.Quiver: decouple :: Functor f => P a' a b' b f r -> Producer b' b f r
- Control.Quiver: deliver :: c -> Q a' a b' b f c
+ Control.Quiver: deliver :: r -> P a' a b' b f r
- Control.Quiver: emit :: b -> Q a' a b' b f (Maybe b')
+ Control.Quiver: emit :: b -> P a' a b' b f (Maybe b')
- Control.Quiver: emit' :: b -> (forall x' x. Q a' a x' x f b') -> Q a' a b' b f b'
+ Control.Quiver: emit' :: b -> Consumer a' a f b' -> P a' a b' b f b'
- Control.Quiver: emit_ :: b -> Q a' a b' b f ()
+ Control.Quiver: emit_ :: b -> P a' a b' b f ()
- Control.Quiver: enclose :: f (Q a' a b' b f c) -> Q a' a b' b f c
+ Control.Quiver: enclose :: f (P a' a b' b f r) -> P a' a b' b f r
- Control.Quiver: fetch :: a' -> Q a' a b' b f (Maybe a)
+ Control.Quiver: fetch :: a' -> P a' a b' b f (Maybe a)
- Control.Quiver: fetch' :: a' -> (forall x' x. Q x' x b' b f a) -> Q a' a b' b f a
+ Control.Quiver: fetch' :: a' -> Producer b' b f a -> P a' a b' b f a
- Control.Quiver: produce :: b -> (b' -> Q a' a b' b f c) -> (forall x' x. Q a' a x' x f c) -> Q a' a b' b f c
+ Control.Quiver: produce :: b -> (b' -> P a' a b' b f r) -> Consumer a' a f r -> P a' a b' b f r
- Control.Quiver.Internal: consume :: a' -> (a -> Q a' a b' b f c) -> (forall x' x. Q x' x b' b f c) -> Q a' a b' b f c
+ Control.Quiver.Internal: consume :: a' -> (a -> P a' a b' b f r) -> Producer b' b f r -> P a' a b' b f r
- Control.Quiver.Internal: decouple :: Functor f => Q a' a b' b f c -> forall x' x. Q x' x b' b f c
+ Control.Quiver.Internal: decouple :: Functor f => P a' a b' b f r -> Producer b' b f r
- Control.Quiver.Internal: deliver :: c -> Q a' a b' b f c
+ Control.Quiver.Internal: deliver :: r -> P a' a b' b f r
- Control.Quiver.Internal: enclose :: f (Q a' a b' b f c) -> Q a' a b' b f c
+ Control.Quiver.Internal: enclose :: f (P a' a b' b f r) -> P a' a b' b f r
- Control.Quiver.Internal: produce :: b -> (b' -> Q a' a b' b f c) -> (forall x' x. Q a' a x' x f c) -> Q a' a b' b f c
+ Control.Quiver.Internal: produce :: b -> (b' -> P a' a b' b f r) -> Consumer a' a f r -> P a' a b' b f r

Files

quiver.cabal view
@@ -1,5 +1,5 @@ name:           quiver-version:        0.0.0.1+version:        0.0.0.2 synopsis:       Quiver finite stream processing library homepage:       https://github.com/zadarnowski/quiver category:       Control@@ -13,9 +13,16 @@ description:      /Quiver/ is a powerful stream processing library for-    combinatorial and monadic transformations of both inductive-    and coinductive data structures.+    combinatorial and monadic representation of computations+    over both inductive and coinductive data streams. +    It is similar to Gabriel Gonzalez's /pipes/ and+    Michael Snoyman's /conduit/, but generalises both+    with support for functor-based computations and+    a clean support for finite (i.e., inductive) data+    streams, both upstream and downstream of the computation+    being defined.+ cabal-version:  >= 1.18 build-type:     Simple license:        BSD3@@ -28,7 +35,7 @@ source-repository this   type:         git   location:     https://github.com/zadarnowski/quiver.git-  tag:          0.0.0.1+  tag:          0.0.0.2  library   hs-source-dirs:   src
src/Control/Quiver.lhs view
@@ -1,12 +1,25 @@+> -- | Module:    Control.Quiver+> -- Description: Core Quiver definitions+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- This module provides the core types and combinators+> -- of the Quiver stream processing library.+ > {-# LANGUAGE RankNTypes, TupleSections #-}  > module Control.Quiver (->   Q,+>   -- Imported from @Control.Quiver.Internal@:+>   P, Consumer, Producer, Effect, >   consume, produce, enclose, deliver,->   decouple, evacuate,+>   decouple, deplete,+>   -- Defined below: >   fetch, fetch', >   emit, emit', emit_,->   liftQ,+>   liftP, >   (>>->), (>->>), > ) where @@ -14,50 +27,91 @@  > infixl 0 >>->, >->> -> fetch :: a' -> Q a' a b' b f (Maybe a)-> fetch x = Consume x (Deliver . Just) (Deliver Nothing)+> -- | @fetch x@ represents a singleton stream processor that+> --   sends the request value @x@ upstream and delivers the+> --   next input value received, or @Nothing@ if the upstream+> --   processor has been depleted. -> fetch' :: a' -> (forall x' x . Q x' x b' b f a) -> Q a' a b' b f a-> fetch' x r = Consume x Deliver r+> fetch :: a' -> P a' a b' b f (Maybe a)+> fetch x = consume x (deliver . Just) (deliver Nothing) -> emit :: b -> Q a' a b' b f (Maybe b')-> emit y = Produce y (Deliver . Just) (Deliver Nothing)+> -- | @fetch' x q@ represents a singleton stream processor that+> --   sends the request value @x@ upstream and delivers the next+> --   input value received, or, if the upstream processor has+> --   been depleted, continues with the decoupled processor @q@. -> emit' :: b -> (forall x' x . Q a' a x' x f b') -> Q a' a b' b f b'-> emit' y r = Produce y Deliver r+> fetch' :: a' -> Producer b' b f a -> P a' a b' b f a+> fetch' x q = consume x deliver q -> emit_ :: b -> Q a' a b' b f ()-> emit_ y = Produce y (Deliver . const ()) (Deliver ())+> -- | @emit y@ represents a singleton stream processor that+> --   produces a single output value @y@ and delivers the+> --   response received from the downstream processor, or+> --   @Nothing@ if the downstream processor has been decoupled. -> liftQ :: Functor f => f c -> Q a' a b' b f c-> liftQ = Enclose . fmap Deliver+> emit :: b -> P a' a b' b f (Maybe b')+> emit y = produce y (deliver . Just) (deliver Nothing) -> (>>->) :: Functor f => Q a' a t' t f c1 -> Q t' t b' b f c2 -> Q a' a b' b f (c1, c2)-> (Consume x1 k1 r1) >>-> q2 = Consume x1 ((>>-> q2) . k1) (r1 >>-> q2)-> (Produce y1 k1 r1) >>-> q2 = loop q2+> -- | @emit' y q@ represents a singleton stream processor that+> --   produces a single output value @y@ and delivers the+> --   response received from the downstream processor, or,+> --   if the downstream processor has been decoupled, continues+> --   with the depleted processor @q@.++> emit' :: b -> Consumer a' a f b' -> P a' a b' b f b'+> emit' y q = produce y deliver q++> -- | @emit' y q@ represents a singleton stream processor that+> --   produces a single output value @y@, ignoring any response+> --   received from the downstream processor.++> emit_ :: b -> P a' a b' b f ()+> emit_ y = produce y (deliver . const ()) (deliver ())++> -- | @liftP@ lifts the value of a base functor into a stream processor.++> liftP :: Functor f => f r -> P a' a b' b f r+> liftP = enclose . fmap deliver++> -- | The @>>->@ represents a push-based composition of stream processor.+> --   @p1 >>-> p2@ represents a stream processor that forwards the output+> --   of @p1@ to @p2@, delivering the result of both processors.+> --   The new processor is /driven/ by @p2@, so, if the base functor+> --   represents a non-commutative monad, any effects of @p2@ will be+> --   observed before those of @p1@.++> (>>->) :: 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 r2) = Produce y2 (loop . k2) (loop' r2)->   loop  (Enclose f2)       = Enclose (fmap loop f2)->   loop  (Deliver z2)       = fmap (, z2) r1+>   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  _  _ r2) = loop' r2->   loop' (Enclose f2)       = Enclose (fmap loop' f2)->   loop' (Deliver z2)       = fmap (, z2) r1-> (Enclose f1) >>-> q2 = Enclose (fmap (>>-> q2) f1)-> (Deliver z1) >>-> q2 = fmap (z1 ,) (decouple q2)+>   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 => Q a' a t' t f c1 -> Q t' t b' b f c2 -> Q a' a b' b f (c1, c2)-> q1 >->> (Consume x2 k2 r2) = loop q1+> -- | The @>->>@ represents a pull-based composition of stream processor.+> --   @p1 >->> p2@ represents a stream processor that forwards the output+> --   of @p1@ to @p2@, delivering the result of both processors.+> --   The new processor is /driven/ by @p1@, so, if the base functor+> --   represents a non-commutative monad, any effects of @p1@ will be+> --   observed before those of @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 r1) = Consume x1 (loop . k1) (loop' r1)+>   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 z1)       = fmap (z1 ,) r2->   loop' (Consume  _  _ t1) = loop' t1+>   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 z1)       = fmap (z1 ,) r2-> q1 >->> (Produce y2 k2 r2) = Produce y2 ((q1 >->>) . k2) (q1 >->> r2)-> q1 >->> (Enclose f2)       = Enclose (fmap (q1 >->>) f2)-> q1 >->> (Deliver z2)       = fmap (, z2) (evacuate q1)+>   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)
src/Control/Quiver/Internal.lhs view
@@ -1,56 +1,201 @@+> -- | Module:    Control.Quiver.Internal+> -- Description: Common definitions+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- This module provides a host of common definitions,+> -- including the main Quiver /processor/ type @P@,+> -- that are reexported by other Quiver modules as+> -- required.+> --+> -- This is the only module in the Quiver library that+> -- exposes the actual four constructors of the stream+> -- processor type @P@, allowing for definition of low+> -- level stream processor transformations, such as+> -- conversions between @P@ and other stream processing+> -- libraries.+> --+> -- As a matter of style, Quiver users should strive to+> -- avoid explicit pattern matching on the @P@ type and+> -- rely instead on the various high level combinators+> -- exported elsewhere, in order to improve chances of+> -- successful deforestation by the various Quiver+> -- rewrite rules.+ > {-# LANGUAGE RankNTypes, TupleSections #-}  > module Control.Quiver.Internal (->   Q (..),+>   P (..), Producer, Consumer, Effect, >   consume, produce, enclose, deliver,->   decouple, evacuate+>   decouple, deplete, > ) where -> data Q a' a b' b f c =->     Consume a' (a  -> Q a' a b' b f c) (forall x' x . Q x' x b' b f c)->   | Produce b  (b' -> Q a' a b' b f c) (forall x' x . Q a' a x' x f c)->   | Enclose (f (Q a' a b' b f c))->   | Deliver c -> consume :: a' -> (a  -> Q a' a b' b f c) -> (forall x' x . Q x' x b' b f c) -> Q a' a b' b f c+  Data Types+  ==========++> -- | The main Quiver /stream processor/ type @P a' a b' b f r@,+> --   representing a producer/consumer structure with /bidirectional/,+> --   /bounded/ communication on both the upstream (consumer) and+> --   downstream (producer) channel. The six type parameters have+> --   the following intuitive meaning:+> --+> --   * @a'@ is the type of a /request/ values sent by the stream+> --     processor to its upstream partner in order to receive the+> --     next element of the input stream.+> --+> --   * @a@ is the type of the actual information being consumed+> --     by this stream processor (i.e., its input stream.)+> --+> --   * @b'@ is the type of the /response/ values received from+> --     the downstream partner for each elemnet of the output+> --     stream produced by this stream processor.+> --+> --   * @f@ is the type of the stream processor's /base functor/;+> --     usually this is a monad used for stateful stream processing,+> --     exception handling and/or real-world interaction.+> --+> --   * @r@ is the stream processor's /delivery type/, used for+> --     monadic stream processor definition.+> --+> --   Every stream processor is a functor over its delivery type.+> --   However, if the base functor @f@ meets the additional requirements+> --   of 'Applicative' or 'Monad', so will the stream processor itself.+> --   Note that, unlike most other stream processing libraries, @f@+> --   is not required to be a monad in most applications, although+> --   only time will tell whether this generalisation has useful+> --   applications in the real world.++> data P a' a b' b f r =++>   -- | @Consume x k q@ represents a /consumer step/, in which+>   --   the request @x@ is sent upstream and the returned input+>   --   value is supplied to the /continuation processor/ @k@,+>   --   or, if the upstream partner has been /depleted/ (i.e.,+>   --   delivered its ultimate result, hence reaching the end+>   --   of processing), to the /decoupled continuation/ @q@.++>   Consume a' (a -> P a' a b' b f r) (Producer b' b f r) |++>   -- | @Produce y k q@ represent a /producer step/, in which+>   --   the output value @y@ is sent downstream, and the returned+>   --   acknowledgement is supplied to the /continuation processor/+>   --   @k@, or, if the downstream partner has been /decoupled/+>   --   (i.e., delivered its ultimate result, hence reaching the end+>   --   of processing), to the /depleted continuation/ @q@.++>   Produce b  (b' -> P a' a b' b f r) (Consumer a' a f r) |++>   -- | @Enclose@ allows for selective application of the base+>   --   functor @f@ the the remainder of the computation.++>   Enclose (f (P a' a b' b f r)) |++>   -- | @Deliver r@ completes processing of information, delivering+>   --   its ultimate result @r@.++>   Deliver r++> -- | A Quiver /producer/, represented by a stream processor+> --   with unspecified input types.++> type Producer b' b f r = forall a' a . P a' a b' b f r++> -- | A Quiver /consumer/, represented by a stream processor+> --   with unspecified output types.++> type Consumer a' a f r = forall b' b . P a' a b' b f r++> -- | A Quiver /effect/, represented by a stream processor+> --   with unspecified input and output types.++> type Effect f r = forall a' a b' b . P a' a b' b f r+++  Instances+  =========++> instance Functor f => Functor (P a' a b' b f) where+>   fmap ff (Consume x k q) = Consume x (fmap ff . k) (fmap ff q)+>   fmap ff (Produce y k q) = Produce y (fmap ff . k) (fmap ff q)+>   fmap ff (Enclose f)     = Enclose (fmap (fmap ff) f)+>   fmap ff (Deliver r)     = Deliver (ff r)++> instance Applicative f => Applicative (P a' a b' b f) where+>   pure = Deliver+>   (Consume x k q) <*> p = Consume x ((<*> p) . k) (q <*> decouple p)+>   (Produce y k q) <*> p = Produce y ((<*> p) . k) (q <*> deplete p)+>   (Enclose f)     <*> p = Enclose (fmap (<*> p) f)+>   (Deliver r)     <*> p = fmap r p++> instance Monad f => Monad (P a' a b' b f) where+>   (Consume x k q) >>= kk = Consume x ((>>= kk) . k) (q >>= decouple . kk)+>   (Produce y k q) >>= kk = Produce y ((>>= kk) . k) (q >>= deplete . kk)+>   (Enclose f)     >>= kk = Enclose (fmap (>>= kk) f)+>   (Deliver r)     >>= kk = kk r+++  Primitive Combinators+  =====================++> -- | @consume x k q@ represents a /consumer step/, in which+> --   the request @x@ is sent upstream and the returned input+> --   value is supplied to the /continuation processor/ @k@,+> --   or, if the upstream partner has been /depleted/ (i.e.,+> --   delivered its ultimate result, hence reaching the end+> --   of processing), to the /decoupled continuation/ @q@.++> consume :: a' -> (a -> P a' a b' b f r) -> Producer b' b f r -> P a' a b' b f r > consume = Consume -> produce :: b  -> (b' -> Q a' a b' b f c) -> (forall x' x . Q a' a x' x f c) -> Q a' a b' b f c+> -- | @produce y k q@ represent a /producer step/, in which+> --   the output value @y@ is sent downstream, and the returned+> --   acknowledgement is supplied to the /continuation processor/+> --   @k@, or, if the downstream partner has been /decoupled/+> --   (i.e., delivered its ultimate result, hence reaching the end+> --   of processing), to the /depleted continuation/ @q@.++> produce :: b  -> (b' -> P a' a b' b f r) -> Consumer a' a f r -> P a' a b' b f r > produce = Produce -> enclose :: f (Q a' a b' b f c) -> Q a' a b' b f c+> -- | @enclose@ allows for selective application of the base+> --   functor @f@ the the remainder of the computation.++> enclose :: f (P a' a b' b f r) -> P a' a b' b f r > enclose = Enclose -> deliver :: c -> Q a' a b' b f c+> -- | @deliver r@ completes processing of information, delivering+> --   its ultimate result @r@.++> deliver :: r -> P a' a b' b f r > deliver = Deliver -> instance Functor f => Functor (Q a' a b' b f) where->   fmap ff (Consume x k r) = Consume x (fmap ff . k) (fmap ff r)->   fmap ff (Produce y k r) = Produce y (fmap ff . k) (fmap ff r)->   fmap ff (Enclose f)     = Enclose (fmap (fmap ff) f)->   fmap ff (Deliver z)     = Deliver (ff z) -> instance Applicative f => Applicative (Q a' a b' b f) where->   pure = Deliver->   (Consume x k r) <*> q = Consume x ((<*> q) . k) (r <*> decouple q)->   (Produce y k r) <*> q = Produce y ((<*> q) . k) (r <*> evacuate q)->   (Enclose f)     <*> q = Enclose (fmap (<*> q) f)->   (Deliver z)     <*> q = fmap z q+  Utilities+  ========= -> instance Monad f => Monad (Q a' a b' b f) where->   (Consume x k r) >>= kk = Consume x ((>>= kk) . k) (r >>= decouple . kk)->   (Produce y k r) >>= kk = Produce y ((>>= kk) . k) (r >>= evacuate . kk)->   (Enclose f)     >>= kk = Enclose (fmap (>>= kk) f)->   (Deliver z)     >>= kk = kk z+> -- | @decouple p@ /decouples/ the stream processor @p@, by replacing+> --   the first consumer step in @p@ with that step's decoupled contination,+> --   effectively converting @p@ into a producer processor that no longer+> --   expects to receive any input. -> decouple :: Functor f => Q a' a b' b f c -> forall x' x . Q x' x b' b f c-> decouple (Consume _ _ r) = r-> decouple (Produce y k r) = Produce y (decouple . k) (decouple r)+> decouple :: Functor f => P a' a b' b f r -> Producer b' b f r+> decouple (Consume _ _ q) = q+> decouple (Produce y k q) = Produce y (decouple . k) (decouple q) > decouple (Enclose f) = Enclose (fmap decouple f)-> decouple (Deliver z) = Deliver z+> decouple (Deliver r) = Deliver r -> evacuate :: Functor f => Q a' a b' b f c -> forall x' x . Q a' a x' x f c-> evacuate (Consume x k r) = Consume x (evacuate . k) (evacuate r)-> evacuate (Produce _ _ r) = r-> evacuate (Enclose f) = Enclose (fmap evacuate f)-> evacuate (Deliver z) = Deliver z+> -- | @deplete p@ /depletes/ the stream processor @p@, by replacing+> --   the first producer step in @p@ with that step's depleted contination,+> --   effectively converting @p@ into a consumer processor that will never+> --   produce any more output.++> deplete :: Functor f => P a' a b' b f r -> Consumer a' a f r+> deplete (Consume x k q) = Consume x (deplete . k) (deplete q)+> deplete (Produce _ _ q) = q+> deplete (Enclose f) = Enclose (fmap deplete f)+> deplete (Deliver r) = Deliver r+