packages feed

quiver 0.0.0.12 → 1.0.0

raw patch · 6 files changed

+340/−63 lines, 6 filesdep +mmorphdep +transformersPVP ok

version bump matches the API change (PVP)

Dependencies added: mmorph, transformers

API changes (from Hackage documentation)

+ Control.Quiver: qhoist :: Functor f => (forall x. f x -> g x) -> P a a' b b' f r -> P a a' b b' g r
+ Control.Quiver.Internal: instance MFunctor (P a a' b b')
+ Control.Quiver.Internal: instance MMonad (P a a' b b')
+ Control.Quiver.Internal: instance MonadIO f => MonadIO (P a a' b b' f)
+ Control.Quiver.Internal: instance MonadTrans (P a a' b b')
+ Control.Quiver.Internal: qembed :: Monad g => (forall x. f x -> P a a' b b' g x) -> P a a' b b' f r -> P a a' b b' g r
+ Control.Quiver.Internal: qhoist :: Functor f => (forall x. f x -> g x) -> P a a' b b' f r -> P a a' b b' g r
+ Control.Quiver.Internal: qlift :: Functor f => f r -> P a a' b b' f r
+ Control.Quiver.SP: (>>?) :: Monad f => P a a' b b' f (SPResult e) -> P a a' b b' f (SPResult e) -> P a a' b b' f (SPResult e)
+ Control.Quiver.SP: spcomplete :: P a a' b b' f (SPResult e)
+ Control.Quiver.SP: spfailed :: e -> P a a' b b' f (SPResult e)
+ Control.Quiver.SP: spincomplete :: P a a' b b' f (SPResult e)
+ Control.Quiver.SP: type SConsumer a f e = forall b. SP a b f e
+ Control.Quiver.SP: type SEffect f e = forall a b. SP a b f e
+ Control.Quiver.SP: type SProducer b f e = forall a. SP a b f e
+ Control.Quiver.Trans: qRunErrorT :: Functor m => P a a' b b' (ErrorT e m) r -> P a a' b b' m (Either e r)
+ Control.Quiver.Trans: qRunExceptT :: Functor m => P a a' b b' (ExceptT e m) r -> P a a' b b' m (Either e r)
+ Control.Quiver.Trans: qRunLazyRWST :: (Functor m, Monoid mw) => P a a' b b' (RWST mr mw ms m) r -> mr -> ms -> P a a' b b' m (r, ms, mw)
+ Control.Quiver.Trans: qRunLazyStateT :: Functor m => P a a' b b' (StateT ms m) r -> ms -> P a a' b b' m (r, ms)
+ Control.Quiver.Trans: qRunLazyWriterT :: (Functor m, Monoid mw) => P a a' b b' (WriterT mw m) r -> P a a' b b' m (r, mw)
+ Control.Quiver.Trans: qRunMaybeT :: Functor m => P a a' b b' (MaybeT m) r -> P a a' b b' m (Maybe r)
+ Control.Quiver.Trans: qRunRWST :: (Functor m, Monoid mw) => P a a' b b' (RWST mr mw ms m) r -> mr -> ms -> P a a' b b' m (r, ms, mw)
+ Control.Quiver.Trans: qRunReaderT :: Functor m => P a a' b b' (ReaderT mr m) r -> mr -> P a a' b b' m r
+ Control.Quiver.Trans: qRunStateT :: Functor m => P a a' b b' (StateT ms m) r -> ms -> P a a' b b' m (r, ms)
+ Control.Quiver.Trans: qRunStrictRWST :: (Functor m, Monoid mw) => P a a' b b' (RWST mr mw ms m) r -> mr -> ms -> P a a' b b' m (r, ms, mw)
+ Control.Quiver.Trans: qRunStrictStateT :: Functor m => P a a' b b' (StateT ms m) r -> ms -> P a a' b b' m (r, ms)
+ Control.Quiver.Trans: qRunStrictWriterT :: (Functor m, Monoid mw) => P a a' b b' (WriterT mw m) r -> P a a' b b' m (r, mw)
+ Control.Quiver.Trans: qRunWriterT :: (Functor m, Monoid mw) => P a a' b b' (WriterT mw m) r -> P a a' b b' m (r, mw)

Files

+ README.md view
@@ -0,0 +1,34 @@+Quiver+======++    Copyright © 2015 Patryk Zadarnowski «pat@jantar.org».+    All rights reserved.++_Quiver_ is a powerful stream processing library for+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.++The underlying data structure, `P`, is almost identical+to the `Proxy` data structure of the `Pipes` library,+except that the `Consume` and `Produce` constructors+(corresponding, respectively, to `Request` and `Response`+in the Pipes' `Proxy` data type) include an additional+argument which explicitly captures the processor's+behaviour in the event of input stream depletion+(for `Consume`) or output decoupling (for `Produce`).+This simple mechanism subsumes Conduit's need for+elaborate unconsumed-input tracking mechanisms,+and allows us to provide a mathematically-clean+framework for processing of finite data streams.++This library is currently very young, and users should+expect significant changes to the Quiver core combinators+as the underlying theory is developed and the interface+stabilises asymptotically to the future version 1.0.
quiver.cabal view
@@ -1,51 +1,49 @@-name:           quiver-version:        0.0.0.12-synopsis:       Quiver finite stream processing library-homepage:       https://github.com/zadarnowski/quiver-category:       Control-stability:      alpha--author:         Patryk Zadarnowski-maintainer:     Patryk Zadarnowski <pat@jantar.org>+name:               quiver+version:            1.0.0+synopsis:           Quiver finite stream processing library+homepage:           https://github.com/zadarnowski/quiver+category:           Control+stability:          alpha -copyright:      Copyright (c) 2015 Patryk Zadarnowski+author:             Patryk Zadarnowski+maintainer:         Patryk Zadarnowski <pat@jantar.org> -description:+copyright:          Copyright (c) 2015 Patryk Zadarnowski -    /Quiver/ is a powerful stream processing library for-    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.+description:        /Quiver/ is a powerful stream processing library for+                    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-license-file:   LICENSE+cabal-version:      >= 1.18+build-type:         Simple+license:            BSD3+license-file:       LICENSE+extra-source-files: README.md  source-repository head-  type:         git-  location:     https://github.com/zadarnowski/quiver.git+  type:     git+  location: https://github.com/zadarnowski/quiver.git  source-repository this-  type:         git-  location:     https://github.com/zadarnowski/quiver.git-  tag:          0.0.0.12+  type:     git+  location: https://github.com/zadarnowski/quiver.git+  tag:      1.0.0  library   hs-source-dirs:   src   default-language: Haskell2010   ghc-options:      -O2 -Wall -fno-warn-unused-do-bind -fno-warn-missing-signatures--  exposed-modules:-    Control.Quiver-    Control.Quiver.Internal-    Control.Quiver.SP--  build-depends:-    base >= 4.8 && < 5+  exposed-modules:  Control.Quiver+                    Control.Quiver.Internal+                    Control.Quiver.SP+                    Control.Quiver.Trans+  build-depends:    base >= 4.8 && < 5,+                    mmorph >= 1.0.4,+                    transformers >= 0.4.3.0
src/Control/Quiver.lhs view
@@ -19,7 +19,7 @@ >   -- Defined below: >   fetch, fetch_, >   emit, emit_,->   qlift,+>   qlift, qhoist, >   qpure, qid, qconcat, >   runEffect, >   (>>->), (>->>), (>&>),@@ -28,7 +28,7 @@  > import Control.Quiver.Internal -> infixl 0 >>->, >->>, >&>+> infixl 1 >>->, >->>, >&>  > -- | @fetch x@ represents a singleton stream processor that > --   sends the request value @x@ upstream and delivers the@@ -59,11 +59,6 @@  > emit_ :: b -> P a a' b b' f () > emit_ y = produce y (deliver . const ()) (deliver ())--> -- | @qlift@ lifts the value of a base functor into a stream processor.--> qlift :: Functor f => f r -> P a a' b b' f r-> qlift = enclose . fmap deliver  > -- | @qpure g f z@ produces an infinite consumer/producer that > --   uses a pure function @f@ to convert every input value into
src/Control/Quiver/Internal.lhs view
@@ -31,9 +31,13 @@ >   P (..), Producer, Consumer, Effect, >   consume, produce, enclose, deliver, >   decouple, deplete,+>   qlift, qhoist, qembed > ) where +> import Control.Monad.IO.Class+> import Control.Monad.Morph +   Data Types   ========== @@ -143,8 +147,21 @@ >   (Produce y k q) >>= kk = Produce y ((>>= kk) . k) (q >>= deplete . kk) >   (Enclose f)     >>= kk = Enclose (fmap (>>= kk) f) >   (Deliver r)     >>= kk = kk r+>   fail                   = Enclose . fail +> instance MonadTrans (P a a' b b') where+>   lift = qlift +> instance MonadIO f => MonadIO (P a a' b b' f) where+>   liftIO = lift . liftIO++> instance MFunctor (P a a' b b') where+>   hoist = qhoist++> instance MMonad (P a a' b b') where+>   embed = qembed++   Primitive Combinators   ===================== @@ -206,3 +223,37 @@ > deplete (Enclose f) = Enclose (fmap deplete f) > deplete (Deliver r) = Deliver r ++  Generalized Transformers+  ========================++> -- | @qlift@ lifts the value of a base functor into a stream processor;+> --   same as 'lift' from 'MonadTrans', but relaxing constraint on+> --   the base structure from 'Monad' to 'Functor'.++> qlift :: Functor f => f r -> P a a' b b' f r+> qlift = enclose . fmap deliver++> -- | @qhoist@ morphs the value of a base functor into another+> --   functor by applying the supplied functor morphism to every+> --   'Enclose' step of a stream processor; same as 'hoist' from+> --   'MFunctor' but relaxing the constraint on the base structure+> --   from 'Monad' to 'Functor'.++> qhoist :: Functor f => (forall x . f x -> g x) -> P a a' b b' f r -> P a a' b b' g r+> qhoist ff = loop+>  where+>   loop (Consume x k q) = consume x (loop . k) (qhoist ff q)+>   loop (Produce y k q) = produce y (loop . k) (qhoist ff q)+>   loop (Enclose f)     = enclose (ff (fmap loop f))+>   loop (Deliver r)     = deliver r++> -- | @qembed@ ...++> qembed :: Monad g => (forall x . f x -> P a a' b b' g x) -> P a a' b b' f r -> P a a' b b' g r+> qembed ff = loop+>  where+>   loop (Consume x k q) = consume x (loop . k) (decouple $ qembed ff q)+>   loop (Produce y k q) = produce y (loop . k) (deplete $ qembed ff q)+>   loop (Enclose f)     = ff f >>= loop+>   loop (Deliver r)     = deliver r
src/Control/Quiver/SP.lhs view
@@ -15,11 +15,12 @@  > module Control.Quiver.SP ( >   module Control.Quiver,->   SQ, SP, SPResult,+>   SQ, SP, SProducer, SConsumer, SEffect, SPResult, >   pattern SPComplete, >   pattern SPFailed, >   pattern SPIncomplete,->   spfetch, spemit, (>:>), (>>!),+>   spcomplete, spfailed, spincomplete,+>   spfetch, spemit, (>:>), (>>?), (>>!), >   sppure, spid, spconcat, >   spfold, spfold', spfoldl, spfoldl', spfoldr, spfoldr', >   sptraverse, sptraverse_,@@ -28,7 +29,7 @@ > import Control.Quiver  > infixr 5 >:>-> infixl 1 >>!+> infixl 1 >>?, >>!  > -- | A /simple processor step/ with a unit request type and an unspecified > --   response type:@@ -42,22 +43,49 @@  > type SP a b f e = SQ a b f (SPResult e) +> -- | A producer version of a simple processor.++> type SProducer b f e = forall a . SP a b f e++> -- | A consumer version of a simple processor.++> type SConsumer a f e = forall b . SP a b f e++> -- | An effect version of a simple processor.++> type SEffect f e = forall a b . SP a b f e+ > -- | Simple processor result type.  > type SPResult e = Maybe (Maybe e) -> -- | Simple processor result value indicating successful processing of the entire input stream.+> -- | ('Just Nothing') Simple processor result value indicating successful processing of the entire input stream.  > pattern SPComplete = Just Nothing -> -- | Simple processor result value indicating unsuccessful processing of the input stream.+> -- | ('Just (Just e)') Simple processor result value indicating unsuccessful processing of the input stream.  > pattern SPFailed e = Just (Just e) -> -- | Simple processor result value indicating premature termination of the consumer.+> -- | ('Nothing') Simple processor result value indicating premature termination of the consumer.  > pattern SPIncomplete = Nothing +> -- | Delivers an 'SPComplete' result.++> spcomplete :: P a a' b b' f (SPResult e)+> spcomplete = deliver SPComplete++> -- | Delivers an 'SPFailed' result.++> spfailed :: e -> P a a' b b' f (SPResult e)+> spfailed = deliver . SPFailed++> -- | Delivers an 'SPIncomplete' result.++> spincomplete :: P a a' b b' f (SPResult e)+> spincomplete = deliver SPIncomplete+ > -- | @spfetch@ represents a singleton simple stream processor that > --   sends the request value @x@ upstream and delivers the > --   next input value received, or @Nothing@ if the upstream@@ -72,7 +100,7 @@ > --   or 'SPIncomplete' otherwise.  > spemit :: b -> P a a' b b' f (SPResult e)-> spemit y = produce y (const $ deliver SPComplete) (deliver SPIncomplete)+> spemit y = produce y (const spcomplete) spincomplete  > -- | @y >:> p@ represents a singleton stream processor that > --   produces a single output value @y@ and continues with@@ -80,16 +108,24 @@ > --   not be consumed by the downstream processor.  > (>:>) :: b -> P a a' b b' f (SPResult e) -> P a a' b b' f (SPResult e)-> y >:> p = produce y (const p) (deliver SPIncomplete)+> y >:> p = produce y (const p) spincomplete +> -- | @p >>? q@ continues processing of @p@ with @q@ but only+> --   if @p@ completes successsfully by delivering 'SPComplete',+> --   short-circuiting @q@ if @p@ fails with 'SPIncomplete' or+> --   'SPFailed'.++> (>>?) :: Monad f => P a a' b b' f (SPResult e) -> P a a' b b' f (SPResult e) -> P a a' b b' f (SPResult e)+> p >>? q = p >>= maybe spincomplete (maybe q spfailed)+ > -- | @p >>! k@ is equivalent to @p@, with any failures in @p@ > --   supplied to the continuation processor @k@. Note that > --   @k@ is not executed if @p@ completes successfully with > --   'SPComplete' or is interrupted by the downstream processor,-> --   deliverying 'SPIncomplete'.+> --   delivering 'SPIncomplete'.  > (>>!) :: Monad f => P a a' b b' f (SPResult e) -> (e -> P a a' b b' f (SPResult e')) -> P a a' b b' f (SPResult e')-> p >>! k = p >>= maybe (deliver SPIncomplete) (maybe (deliver SPComplete) k)+> p >>! k = p >>= maybe spincomplete (maybe spcomplete k)  > -- | @sppure f@ produces an infinite consumer/producer that > --   uses a pure function @f@ to convert every input value into@@ -98,24 +134,24 @@ > sppure :: (a -> b) -> SP a b f e > sppure f = cloop >  where->   cloop = consume () ploop (deliver SPComplete)->   ploop x = produce (f x) (const cloop) (deliver SPIncomplete)+>   cloop = consume () ploop spcomplete+>   ploop x = produce (f x) (const cloop) spincomplete  > -- | A simple identity processor, equivalent to 'sppure id'.  > spid :: SP a a f e > spid = cloop >  where->   cloop = consume () ploop (deliver SPComplete)->   ploop x = produce x (const cloop) (deliver SPIncomplete)+>   cloop = consume () ploop spcomplete+>   ploop x = produce x (const cloop) spincomplete  > -- | A simple list flattening processor requests.  > spconcat :: SP [a] a f e > spconcat = cloop >  where->   cloop = consume () ploop (deliver SPComplete)->   ploop (x:xs) = produce x (const $ ploop xs) (deliver SPIncomplete)+>   cloop = consume () ploop spcomplete+>   ploop (x:xs) = produce x (const $ ploop xs) spincomplete >   ploop [] = cloop  > -- | A processor that delivers the entire input of the stream folded@@ -176,7 +212,7 @@ > sptraverse :: Monad m => (a -> m b) -> SP a b m e > sptraverse k = loop >  where->   loop = consume () loop' (deliver SPComplete)+>   loop = consume () loop' spcomplete >   loop' x = qlift (k x) >>= (>:> loop)  > -- | A processor that consumes every input elemnet using a monadic function.@@ -184,5 +220,5 @@ > sptraverse_ :: Monad m => (a -> m ()) -> SP a b m e > sptraverse_ k = loop >  where->   loop = consume () loop' (deliver SPComplete)+>   loop = consume () loop' spcomplete >   loop' x = qlift (k x) >> loop
+ src/Control/Quiver/Trans.lhs view
@@ -0,0 +1,163 @@+> -- | Module:    Control.Quiver.Trans+> -- Description: Monad transformers for quiver processors+> -- Copyright:   © 2015 Patryk Zadarnowski <pat@jantar.org>+> -- License:     BSD3+> -- Maintainer:  pat@jantar.org+> -- Stability:   experimental+> -- Portability: portable+> --+> -- This module provides functions for hoisting stream processors+> -- over the various well-known monad transformers into the corresponding+> -- base monad, in a manner analogous to the tranformers' @run@ function.+> --+> -- This is particularly useful for composing quiver processors over+> -- distinct “compatible” monads such as 'ReaderT' and 'StateT'.++> {-# LANGUAGE RankNTypes #-}+> {-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}++> module Control.Quiver.Trans (+>   qRunErrorT,+>   qRunExceptT,+>   qRunMaybeT,+>   qRunRWST, qRunLazyRWST, qRunStrictRWST,+>   qRunReaderT,+>   qRunStateT, qRunLazyStateT, qRunStrictStateT,+>   qRunWriterT, qRunLazyWriterT, qRunStrictWriterT,+> ) where++> import Control.Monad.Trans.Error+> import Control.Monad.Trans.Except+> import Control.Monad.Trans.Maybe+> import Control.Monad.Trans.RWS.Lazy as Lazy+> import Control.Monad.Trans.RWS.Strict as Strict+> import Control.Monad.Trans.Reader+> import Control.Monad.Trans.State.Lazy as Lazy+> import Control.Monad.Trans.State.Strict as Strict+> import Control.Monad.Trans.Writer.Lazy as Lazy+> import Control.Monad.Trans.Writer.Strict as Strict+> import Control.Quiver.Internal++> -- | Hoists a stream processor from an 'ErrorT e m' monad into its base monad @m@.++> qRunErrorT :: Functor m => P a a' b b' (ErrorT e m) r -> P a a' b b' m (Either e r)+> qRunErrorT = loop+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunErrorT q)+>   loop (Produce y k q) = produce y (loop . k) (qRunErrorT q)+>   loop (Enclose f)     = enclose (either (deliver . Left) loop <$> runErrorT f)+>   loop (Deliver r)     = deliver (Right r)++> -- | Hoists a stream processor from an 'ExceptT e m' monad into its base monad @m@.++> qRunExceptT :: Functor m => P a a' b b' (ExceptT e m) r -> P a a' b b' m (Either e r)+> qRunExceptT = loop+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunExceptT q)+>   loop (Produce y k q) = produce y (loop . k) (qRunExceptT q)+>   loop (Enclose f)     = enclose (either (deliver . Left) loop <$> runExceptT f)+>   loop (Deliver r)     = deliver (Right r)++> -- | Hoists a stream processor from a 'MaybeT m' monad into its base monad @m@.++> qRunMaybeT :: Functor m => P a a' b b' (MaybeT m) r -> P a a' b b' m (Maybe r)+> qRunMaybeT = loop+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunMaybeT q)+>   loop (Produce y k q) = produce y (loop . k) (qRunMaybeT q)+>   loop (Enclose f)     = enclose (maybe (deliver Nothing) loop <$> runMaybeT f)+>   loop (Deliver r)     = deliver (Just r)++> -- | Hoists a stream processor from a lazy 'RWST r w s m' monad into its base monad @m@.++> qRunRWST :: (Functor m, Monoid mw) => P a a' b b' (Lazy.RWST mr mw ms m) r -> mr -> ms -> P a a' b b' m (r, ms, mw)+> qRunRWST = qRunLazyRWST++> -- | Hoists a stream processor from a lazy 'RWST r w s m' monad into its base monad @m@.++> qRunLazyRWST :: (Functor m, Monoid mw) => P a a' b b' (Lazy.RWST mr mw ms m) r -> mr -> ms -> P a a' b b' m (r, ms, mw)+> qRunLazyRWST p mr ms = loop p+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunLazyRWST q mr ms)+>   loop (Produce y k q) = produce y (loop . k) (qRunLazyRWST q mr ms)+>   loop (Enclose f)     = enclose (run <$> Lazy.runRWST f mr ms)+>   loop (Deliver r)     = deliver (r, ms, mempty)+>   run ~(p', ms', mw)    = adj mw <$> qRunLazyRWST p' mr ms'+>   adj mw ~(r, ms', mw') = (r, ms', mappend mw mw')++> -- | Hoists a stream processor from a strict 'RWST r w s m' monad into its base monad @m@.++> qRunStrictRWST :: (Functor m, Monoid mw) => P a a' b b' (Strict.RWST mr mw ms m) r -> mr -> ms -> P a a' b b' m (r, ms, mw)+> qRunStrictRWST p mr ms = loop p+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunStrictRWST q mr ms)+>   loop (Produce y k q) = produce y (loop . k) (qRunStrictRWST q mr ms)+>   loop (Enclose f)     = enclose (run <$> Strict.runRWST f mr ms)+>   loop (Deliver r)     = deliver (r, ms, mempty)+>   run (p', ms', mw)    = adj mw <$> qRunStrictRWST p' mr ms'+>   adj mw (r, ms', mw') = (r, ms', mappend mw mw')++> -- | Hoists a stream processor from a 'ReaderT r m' monad into its base monad @m@.++> qRunReaderT :: Functor m => P a a' b b' (ReaderT mr m) r -> mr -> P a a' b b' m r+> qRunReaderT p mr = loop p+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunReaderT q mr)+>   loop (Produce y k q) = produce y (loop . k) (qRunReaderT q mr)+>   loop (Enclose f)     = enclose (loop <$> runReaderT f mr)+>   loop (Deliver r)     = deliver r++> -- | Hoists a stream processor from a lazy 'StateT s m' monad into its base monad @m@.++> qRunStateT :: Functor m => P a a' b b' (Lazy.StateT ms m) r -> ms -> P a a' b b' m (r, ms)+> qRunStateT = qRunLazyStateT++> -- | Hoists a stream processor from a lazy 'StateT s m' monad into its base monad @m@.++> qRunLazyStateT :: Functor m => P a a' b b' (Lazy.StateT ms m) r -> ms -> P a a' b b' m (r, ms)+> qRunLazyStateT p ms = loop p+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunLazyStateT q ms)+>   loop (Produce y k q) = produce y (loop . k) (qRunLazyStateT q ms)+>   loop (Enclose f)     = enclose (run <$> Lazy.runStateT f ms)+>   loop (Deliver r)     = deliver (r, ms)+>   run ~(p', ms')       = qRunLazyStateT p' ms'++> -- | Hoists a stream processor from a strict 'StateT s m' monad into its base monad @m@.++> qRunStrictStateT :: Functor m => P a a' b b' (Strict.StateT ms m) r -> ms -> P a a' b b' m (r, ms)+> qRunStrictStateT p ms = loop p+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunStrictStateT q ms)+>   loop (Produce y k q) = produce y (loop . k) (qRunStrictStateT q ms)+>   loop (Enclose f)     = enclose (uncurry qRunStrictStateT <$> Strict.runStateT f ms)+>   loop (Deliver r)     = deliver (r, ms)++> -- | Hoists a stream processor from a lazy 'WriterT w m' monad into its base monad @m@.++> qRunWriterT :: (Functor m, Monoid mw) => P a a' b b' (Lazy.WriterT mw m) r -> P a a' b b' m (r, mw)+> qRunWriterT = qRunLazyWriterT++> -- | Hoists a stream processor from a lazy 'WriterT w m' monad into its base monad @m@.++> qRunLazyWriterT :: (Functor m, Monoid mw) => P a a' b b' (Lazy.WriterT mw m) r -> P a a' b b' m (r, mw)+> qRunLazyWriterT p = loop p+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunLazyWriterT q)+>   loop (Produce y k q) = produce y (loop . k) (qRunLazyWriterT q)+>   loop (Enclose f)     = enclose (run <$> Lazy.runWriterT f)+>   loop (Deliver r)     = deliver (r, mempty)+>   run ~(p', mw)        = adj mw <$> qRunLazyWriterT p'+>   adj mw ~(r, mw')     = (r, mappend mw mw')++> -- | Hoists a stream processor from a strict 'WriterT w m' monad into its base monad @m@.++> qRunStrictWriterT :: (Functor m, Monoid mw) => P a a' b b' (Strict.WriterT mw m) r -> P a a' b b' m (r, mw)+> qRunStrictWriterT p = loop p+>  where+>   loop (Consume x k q) = consume x (loop . k) (qRunStrictWriterT q)+>   loop (Produce y k q) = produce y (loop . k) (qRunStrictWriterT q)+>   loop (Enclose f)     = enclose (run <$> Strict.runWriterT f)+>   loop (Deliver r)     = deliver (r, mempty)+>   run (p', mw)         = adj mw <$> qRunStrictWriterT p'+>   adj mw (r, mw')      = (r, mappend mw mw')