{-# OPTIONS_HADDOCK not-home #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE TypeFamilies #-}
module Data.Conduit.Internal.Pipe
    ( -- ** Types
      Pipe (..)
      -- ** Primitives
    , await
    , awaitE
    , awaitForever
    , yield
    , yieldM
    , leftover
    , unconsM
    , unconsEitherM
      -- ** Finalization
    , bracketP
      -- ** Composition
    , idP
    , pipe
    , pipeL
    , runPipe
    , injectLeftovers
    , (>+>)
    , (<+<)
      -- ** Exceptions
    , catchP
    , handleP
    , tryP
      -- ** Utilities
    , transPipe
    , mapOutput
    , mapOutputMaybe
    , mapInput
    , sourceList
    , withUpstream
    , Data.Conduit.Internal.Pipe.enumFromTo
    , generalizeUpstream
    ) where

import Control.Applicative (Applicative (..))
import Control.Monad ((>=>), liftM, ap)
import Control.Monad.Error.Class(MonadError(..))
import Control.Monad.Reader.Class(MonadReader(..))
import Control.Monad.RWS.Class(MonadRWS())
import Control.Monad.Writer.Class(MonadWriter(..))
import Control.Monad.State.Class(MonadState(..))
import Control.Monad.Trans.Class (MonadTrans (lift))
import Control.Monad.IO.Unlift (MonadIO (liftIO), MonadUnliftIO, withRunInIO)
import Control.Monad.Primitive (PrimMonad, PrimState, primitive)
import Data.Void (Void, absurd)
import Data.Monoid (Monoid (mappend, mempty))
import Data.Semigroup (Semigroup ((<>)))
import Control.Monad.Trans.Resource
import qualified GHC.Exts
import qualified Control.Exception as E

-- | The underlying datatype for all the types in this package.  In has six
-- type parameters:
--
-- * /l/ is the type of values that may be left over from this @Pipe@. A @Pipe@
-- with no leftovers would use @Void@ here, and one with leftovers would use
-- the same type as the /i/ parameter. Leftovers are automatically provided to
-- the next @Pipe@ in the monadic chain.
--
-- * /i/ is the type of values for this @Pipe@'s input stream.
--
-- * /o/ is the type of values for this @Pipe@'s output stream.
--
-- * /u/ is the result type from the upstream @Pipe@.
--
-- * /m/ is the underlying monad.
--
-- * /r/ is the result type.
--
-- A basic intuition is that every @Pipe@ produces a stream of output values
-- (/o/), and eventually indicates that this stream is terminated by sending a
-- result (/r/). On the receiving end of a @Pipe@, these become the /i/ and /u/
-- parameters.
--
-- Since 0.5.0
data Pipe l i o u m r =
    -- | Provide new output to be sent downstream. This constructor has two
    -- fields: the next @Pipe@ to be used and the output value.
    HaveOutput (Pipe l i o u m r) o
    -- | Request more input from upstream. The first field takes a new input
    -- value and provides a new @Pipe@. The second takes an upstream result
    -- value, which indicates that upstream is producing no more results.
  | NeedInput (i -> Pipe l i o u m r) (u -> Pipe l i o u m r)
    -- | Processing with this @Pipe@ is complete, providing the final result.
  | Done r
    -- | Require running of a monadic action to get the next @Pipe@.
  | PipeM (m (Pipe l i o u m r))
    -- | Return leftover input, which should be provided to future operations.
  | Leftover (Pipe l i o u m r) l

instance Monad m => Functor (Pipe l i o u m) where
    fmap :: (a -> b) -> Pipe l i o u m a -> Pipe l i o u m b
fmap = (a -> b) -> Pipe l i o u m a -> Pipe l i o u m b
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM
    {-# INLINE fmap #-}

instance Monad m => Applicative (Pipe l i o u m) where
    pure :: a -> Pipe l i o u m a
pure = a -> Pipe l i o u m a
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done
    {-# INLINE pure #-}
    <*> :: Pipe l i o u m (a -> b) -> Pipe l i o u m a -> Pipe l i o u m b
(<*>) = Pipe l i o u m (a -> b) -> Pipe l i o u m a -> Pipe l i o u m b
forall (m :: * -> *) a b. Monad m => m (a -> b) -> m a -> m b
ap
    {-# INLINE (<*>) #-}

instance Monad m => Monad (Pipe l i o u m) where
    return :: a -> Pipe l i o u m a
return = a -> Pipe l i o u m a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
    {-# INLINE return #-}

    HaveOutput Pipe l i o u m a
p o
o   >>= :: Pipe l i o u m a -> (a -> Pipe l i o u m b) -> Pipe l i o u m b
>>= a -> Pipe l i o u m b
fp = Pipe l i o u m b -> o -> Pipe l i o u m b
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe l i o u m a
p Pipe l i o u m a -> (a -> Pipe l i o u m b) -> Pipe l i o u m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> Pipe l i o u m b
fp)            o
o
    NeedInput i -> Pipe l i o u m a
p u -> Pipe l i o u m a
c    >>= a -> Pipe l i o u m b
fp = (i -> Pipe l i o u m b)
-> (u -> Pipe l i o u m b) -> Pipe l i o u m b
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput  (i -> Pipe l i o u m a
p (i -> Pipe l i o u m a)
-> (a -> Pipe l i o u m b) -> i -> Pipe l i o u m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> Pipe l i o u m b
fp)            (u -> Pipe l i o u m a
c (u -> Pipe l i o u m a)
-> (a -> Pipe l i o u m b) -> u -> Pipe l i o u m b
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> a -> Pipe l i o u m b
fp)
    Done a
x           >>= a -> Pipe l i o u m b
fp = a -> Pipe l i o u m b
fp a
x
    PipeM m (Pipe l i o u m a)
mp         >>= a -> Pipe l i o u m b
fp = m (Pipe l i o u m b) -> Pipe l i o u m b
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM      ((Pipe l i o u m a -> (a -> Pipe l i o u m b) -> Pipe l i o u m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> Pipe l i o u m b
fp) (Pipe l i o u m a -> Pipe l i o u m b)
-> m (Pipe l i o u m a) -> m (Pipe l i o u m b)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` m (Pipe l i o u m a)
mp)
    Leftover Pipe l i o u m a
p l
i     >>= a -> Pipe l i o u m b
fp = Pipe l i o u m b -> l -> Pipe l i o u m b
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover   (Pipe l i o u m a
p Pipe l i o u m a -> (a -> Pipe l i o u m b) -> Pipe l i o u m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= a -> Pipe l i o u m b
fp)            l
i

instance MonadTrans (Pipe l i o u) where
    lift :: m a -> Pipe l i o u m a
lift m a
mr = m (Pipe l i o u m a) -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM (a -> Pipe l i o u m a
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done (a -> Pipe l i o u m a) -> m a -> m (Pipe l i o u m a)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
`liftM` m a
mr)
    {-# INLINE [1] lift #-}

instance MonadIO m => MonadIO (Pipe l i o u m) where
    liftIO :: IO a -> Pipe l i o u m a
liftIO = m a -> Pipe l i o u m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Pipe l i o u m a)
-> (IO a -> m a) -> IO a -> Pipe l i o u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
    {-# INLINE liftIO #-}

instance MonadThrow m => MonadThrow (Pipe l i o u m) where
    throwM :: e -> Pipe l i o u m a
throwM = m a -> Pipe l i o u m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Pipe l i o u m a) -> (e -> m a) -> e -> Pipe l i o u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall (m :: * -> *) e a. (MonadThrow m, Exception e) => e -> m a
throwM
    {-# INLINE throwM #-}


instance Monad m => Semigroup (Pipe l i o u m ()) where
    <> :: Pipe l i o u m () -> Pipe l i o u m () -> Pipe l i o u m ()
(<>) = Pipe l i o u m () -> Pipe l i o u m () -> Pipe l i o u m ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
(>>)
    {-# INLINE (<>) #-}

instance Monad m => Monoid (Pipe l i o u m ()) where
    mempty :: Pipe l i o u m ()
mempty = () -> Pipe l i o u m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    {-# INLINE mempty #-}
#if !(MIN_VERSION_base(4,11,0))
    mappend = (<>)
    {-# INLINE mappend #-}
#endif

instance PrimMonad m => PrimMonad (Pipe l i o u m) where
  type PrimState (Pipe l i o u m) = PrimState m
  primitive :: (State# (PrimState (Pipe l i o u m))
 -> (# State# (PrimState (Pipe l i o u m)), a #))
-> Pipe l i o u m a
primitive = m a -> Pipe l i o u m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Pipe l i o u m a)
-> ((State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a)
-> (State# (PrimState m) -> (# State# (PrimState m), a #))
-> Pipe l i o u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
forall (m :: * -> *) a.
PrimMonad m =>
(State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
primitive

instance MonadResource m => MonadResource (Pipe l i o u m) where
    liftResourceT :: ResourceT IO a -> Pipe l i o u m a
liftResourceT = m a -> Pipe l i o u m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Pipe l i o u m a)
-> (ResourceT IO a -> m a) -> ResourceT IO a -> Pipe l i o u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResourceT IO a -> m a
forall (m :: * -> *) a. MonadResource m => ResourceT IO a -> m a
liftResourceT
    {-# INLINE liftResourceT #-}

instance MonadReader r m => MonadReader r (Pipe l i o u m) where
    ask :: Pipe l i o u m r
ask = m r -> Pipe l i o u m r
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m r
forall r (m :: * -> *). MonadReader r m => m r
ask
    {-# INLINE ask #-}
    local :: (r -> r) -> Pipe l i o u m a -> Pipe l i o u m a
local r -> r
f (HaveOutput Pipe l i o u m a
p o
o) = Pipe l i o u m a -> o -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput ((r -> r) -> Pipe l i o u m a -> Pipe l i o u m a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f Pipe l i o u m a
p) o
o
    local r -> r
f (NeedInput i -> Pipe l i o u m a
p u -> Pipe l i o u m a
c) = (i -> Pipe l i o u m a)
-> (u -> Pipe l i o u m a) -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (\i
i -> (r -> r) -> Pipe l i o u m a -> Pipe l i o u m a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f (i -> Pipe l i o u m a
p i
i)) (\u
u -> (r -> r) -> Pipe l i o u m a -> Pipe l i o u m a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f (u -> Pipe l i o u m a
c u
u))
    local r -> r
_ (Done a
x) = a -> Pipe l i o u m a
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done a
x
    local r -> r
f (PipeM m (Pipe l i o u m a)
mp) = m (Pipe l i o u m a) -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe l i o u m a -> Pipe l i o u m a)
-> m (Pipe l i o u m a) -> m (Pipe l i o u m a)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((r -> r) -> Pipe l i o u m a -> Pipe l i o u m a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f) (m (Pipe l i o u m a) -> m (Pipe l i o u m a))
-> m (Pipe l i o u m a) -> m (Pipe l i o u m a)
forall a b. (a -> b) -> a -> b
$ (r -> r) -> m (Pipe l i o u m a) -> m (Pipe l i o u m a)
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f m (Pipe l i o u m a)
mp)
    local r -> r
f (Leftover Pipe l i o u m a
p l
i) = Pipe l i o u m a -> l -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover ((r -> r) -> Pipe l i o u m a -> Pipe l i o u m a
forall r (m :: * -> *) a. MonadReader r m => (r -> r) -> m a -> m a
local r -> r
f Pipe l i o u m a
p) l
i

-- Provided for doctest
#ifndef MIN_VERSION_mtl
#define MIN_VERSION_mtl(x, y, z) 0
#endif

instance MonadWriter w m => MonadWriter w (Pipe l i o u m) where
#if MIN_VERSION_mtl(2, 1, 0)
    writer :: (a, w) -> Pipe l i o u m a
writer = m a -> Pipe l i o u m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Pipe l i o u m a)
-> ((a, w) -> m a) -> (a, w) -> Pipe l i o u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, w) -> m a
forall w (m :: * -> *) a. MonadWriter w m => (a, w) -> m a
writer
#endif

    tell :: w -> Pipe l i o u m ()
tell = m () -> Pipe l i o u m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> Pipe l i o u m ())
-> (w -> m ()) -> w -> Pipe l i o u m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. w -> m ()
forall w (m :: * -> *). MonadWriter w m => w -> m ()
tell

    listen :: Pipe l i o u m a -> Pipe l i o u m (a, w)
listen (HaveOutput Pipe l i o u m a
p o
o) = Pipe l i o u m (a, w) -> o -> Pipe l i o u m (a, w)
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe l i o u m a -> Pipe l i o u m (a, w)
forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen Pipe l i o u m a
p) o
o
    listen (NeedInput i -> Pipe l i o u m a
p u -> Pipe l i o u m a
c) = (i -> Pipe l i o u m (a, w))
-> (u -> Pipe l i o u m (a, w)) -> Pipe l i o u m (a, w)
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (\i
i -> Pipe l i o u m a -> Pipe l i o u m (a, w)
forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen (i -> Pipe l i o u m a
p i
i)) (\u
u -> Pipe l i o u m a -> Pipe l i o u m (a, w)
forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen (u -> Pipe l i o u m a
c u
u))
    listen (Done a
x) = (a, w) -> Pipe l i o u m (a, w)
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done (a
x,w
forall a. Monoid a => a
mempty)
    listen (PipeM m (Pipe l i o u m a)
mp) =
      m (Pipe l i o u m (a, w)) -> Pipe l i o u m (a, w)
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM (m (Pipe l i o u m (a, w)) -> Pipe l i o u m (a, w))
-> m (Pipe l i o u m (a, w)) -> Pipe l i o u m (a, w)
forall a b. (a -> b) -> a -> b
$
      do (Pipe l i o u m a
p,w
w) <- m (Pipe l i o u m a) -> m (Pipe l i o u m a, w)
forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen m (Pipe l i o u m a)
mp
         Pipe l i o u m (a, w) -> m (Pipe l i o u m (a, w))
forall (m :: * -> *) a. Monad m => a -> m a
return (Pipe l i o u m (a, w) -> m (Pipe l i o u m (a, w)))
-> Pipe l i o u m (a, w) -> m (Pipe l i o u m (a, w))
forall a b. (a -> b) -> a -> b
$ do (a
x,w
w') <- Pipe l i o u m a -> Pipe l i o u m (a, w)
forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen Pipe l i o u m a
p
                     (a, w) -> Pipe l i o u m (a, w)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
x, w
w w -> w -> w
forall a. Monoid a => a -> a -> a
`mappend` w
w')
    listen (Leftover Pipe l i o u m a
p l
i) = Pipe l i o u m (a, w) -> l -> Pipe l i o u m (a, w)
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i o u m a -> Pipe l i o u m (a, w)
forall w (m :: * -> *) a. MonadWriter w m => m a -> m (a, w)
listen Pipe l i o u m a
p) l
i

    pass :: Pipe l i o u m (a, w -> w) -> Pipe l i o u m a
pass (HaveOutput Pipe l i o u m (a, w -> w)
p o
o) = Pipe l i o u m a -> o -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe l i o u m (a, w -> w) -> Pipe l i o u m a
forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
pass Pipe l i o u m (a, w -> w)
p) o
o
    pass (NeedInput i -> Pipe l i o u m (a, w -> w)
p u -> Pipe l i o u m (a, w -> w)
c) = (i -> Pipe l i o u m a)
-> (u -> Pipe l i o u m a) -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (\i
i -> Pipe l i o u m (a, w -> w) -> Pipe l i o u m a
forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
pass (i -> Pipe l i o u m (a, w -> w)
p i
i)) (\u
u -> Pipe l i o u m (a, w -> w) -> Pipe l i o u m a
forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
pass (u -> Pipe l i o u m (a, w -> w)
c u
u))
    pass (PipeM m (Pipe l i o u m (a, w -> w))
mp) = m (Pipe l i o u m a) -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM (m (Pipe l i o u m a) -> Pipe l i o u m a)
-> m (Pipe l i o u m a) -> Pipe l i o u m a
forall a b. (a -> b) -> a -> b
$ m (Pipe l i o u m (a, w -> w))
mp m (Pipe l i o u m (a, w -> w))
-> (Pipe l i o u m (a, w -> w) -> m (Pipe l i o u m a))
-> m (Pipe l i o u m a)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Pipe l i o u m a -> m (Pipe l i o u m a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Pipe l i o u m a -> m (Pipe l i o u m a))
-> (Pipe l i o u m (a, w -> w) -> Pipe l i o u m a)
-> Pipe l i o u m (a, w -> w)
-> m (Pipe l i o u m a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pipe l i o u m (a, w -> w) -> Pipe l i o u m a
forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
pass)
    pass (Done (a
x,w -> w
_)) = a -> Pipe l i o u m a
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done a
x
    pass (Leftover Pipe l i o u m (a, w -> w)
p l
i) = Pipe l i o u m a -> l -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i o u m (a, w -> w) -> Pipe l i o u m a
forall w (m :: * -> *) a. MonadWriter w m => m (a, w -> w) -> m a
pass Pipe l i o u m (a, w -> w)
p) l
i

instance MonadState s m => MonadState s (Pipe l i o u m) where
    get :: Pipe l i o u m s
get = m s -> Pipe l i o u m s
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift m s
forall s (m :: * -> *). MonadState s m => m s
get
    put :: s -> Pipe l i o u m ()
put = m () -> Pipe l i o u m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> Pipe l i o u m ())
-> (s -> m ()) -> s -> Pipe l i o u m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> m ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put
#if MIN_VERSION_mtl(2, 1, 0)
    state :: (s -> (a, s)) -> Pipe l i o u m a
state = m a -> Pipe l i o u m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Pipe l i o u m a)
-> ((s -> (a, s)) -> m a) -> (s -> (a, s)) -> Pipe l i o u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (s -> (a, s)) -> m a
forall s (m :: * -> *) a. MonadState s m => (s -> (a, s)) -> m a
state
#endif

instance MonadRWS r w s m => MonadRWS r w s (Pipe l i o u m)

instance MonadError e m => MonadError e (Pipe l i o u m) where
    throwError :: e -> Pipe l i o u m a
throwError = m a -> Pipe l i o u m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m a -> Pipe l i o u m a) -> (e -> m a) -> e -> Pipe l i o u m a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> m a
forall e (m :: * -> *) a. MonadError e m => e -> m a
throwError
    catchError :: Pipe l i o u m a -> (e -> Pipe l i o u m a) -> Pipe l i o u m a
catchError (HaveOutput Pipe l i o u m a
p o
o) e -> Pipe l i o u m a
f = Pipe l i o u m a -> o -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe l i o u m a -> (e -> Pipe l i o u m a) -> Pipe l i o u m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError Pipe l i o u m a
p e -> Pipe l i o u m a
f) o
o
    catchError (NeedInput i -> Pipe l i o u m a
p u -> Pipe l i o u m a
c) e -> Pipe l i o u m a
f = (i -> Pipe l i o u m a)
-> (u -> Pipe l i o u m a) -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (\i
i -> Pipe l i o u m a -> (e -> Pipe l i o u m a) -> Pipe l i o u m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError (i -> Pipe l i o u m a
p i
i) e -> Pipe l i o u m a
f) (\u
u -> Pipe l i o u m a -> (e -> Pipe l i o u m a) -> Pipe l i o u m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError (u -> Pipe l i o u m a
c u
u) e -> Pipe l i o u m a
f)
    catchError (Done a
x) e -> Pipe l i o u m a
_ = a -> Pipe l i o u m a
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done a
x
    catchError (PipeM m (Pipe l i o u m a)
mp) e -> Pipe l i o u m a
f =
      m (Pipe l i o u m a) -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM (m (Pipe l i o u m a) -> Pipe l i o u m a)
-> m (Pipe l i o u m a) -> Pipe l i o u m a
forall a b. (a -> b) -> a -> b
$ m (Pipe l i o u m a)
-> (e -> m (Pipe l i o u m a)) -> m (Pipe l i o u m a)
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError ((Pipe l i o u m a -> Pipe l i o u m a)
-> m (Pipe l i o u m a) -> m (Pipe l i o u m a)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((Pipe l i o u m a -> (e -> Pipe l i o u m a) -> Pipe l i o u m a)
-> (e -> Pipe l i o u m a) -> Pipe l i o u m a -> Pipe l i o u m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip Pipe l i o u m a -> (e -> Pipe l i o u m a) -> Pipe l i o u m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError e -> Pipe l i o u m a
f) m (Pipe l i o u m a)
mp) (\e
e -> Pipe l i o u m a -> m (Pipe l i o u m a)
forall (m :: * -> *) a. Monad m => a -> m a
return (e -> Pipe l i o u m a
f e
e))
    catchError (Leftover Pipe l i o u m a
p l
i) e -> Pipe l i o u m a
f = Pipe l i o u m a -> l -> Pipe l i o u m a
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i o u m a -> (e -> Pipe l i o u m a) -> Pipe l i o u m a
forall e (m :: * -> *) a.
MonadError e m =>
m a -> (e -> m a) -> m a
catchError Pipe l i o u m a
p e -> Pipe l i o u m a
f) l
i

-- | Wait for a single input value from upstream.
--
-- Since 0.5.0
await :: Pipe l i o u m (Maybe i)
await :: Pipe l i o u m (Maybe i)
await = (i -> Pipe l i o u m (Maybe i))
-> (u -> Pipe l i o u m (Maybe i)) -> Pipe l i o u m (Maybe i)
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Maybe i -> Pipe l i o u m (Maybe i)
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done (Maybe i -> Pipe l i o u m (Maybe i))
-> (i -> Maybe i) -> i -> Pipe l i o u m (Maybe i)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Maybe i
forall a. a -> Maybe a
Just) (\u
_ -> Maybe i -> Pipe l i o u m (Maybe i)
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done Maybe i
forall a. Maybe a
Nothing)
{-# RULES "conduit: CI.await >>= maybe" forall x y. await >>= maybe x y = NeedInput y (const x) #-}
{-# INLINE [1] await #-}

-- | This is similar to @await@, but will return the upstream result value as
-- @Left@ if available.
--
-- Since 0.5.0
awaitE :: Pipe l i o u m (Either u i)
awaitE :: Pipe l i o u m (Either u i)
awaitE = (i -> Pipe l i o u m (Either u i))
-> (u -> Pipe l i o u m (Either u i))
-> Pipe l i o u m (Either u i)
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Either u i -> Pipe l i o u m (Either u i)
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done (Either u i -> Pipe l i o u m (Either u i))
-> (i -> Either u i) -> i -> Pipe l i o u m (Either u i)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Either u i
forall a b. b -> Either a b
Right) (Either u i -> Pipe l i o u m (Either u i)
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done (Either u i -> Pipe l i o u m (Either u i))
-> (u -> Either u i) -> u -> Pipe l i o u m (Either u i)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Either u i
forall a b. a -> Either a b
Left)
{-# RULES "conduit: awaitE >>= either" forall x y. awaitE >>= either x y = NeedInput y x #-}
{-# INLINE [1] awaitE #-}

-- | Wait for input forever, calling the given inner @Pipe@ for each piece of
-- new input. Returns the upstream result type.
--
-- Since 0.5.0
awaitForever :: Monad m => (i -> Pipe l i o r m r') -> Pipe l i o r m r
awaitForever :: (i -> Pipe l i o r m r') -> Pipe l i o r m r
awaitForever i -> Pipe l i o r m r'
inner =
    Pipe l i o r m r
self
  where
    self :: Pipe l i o r m r
self = Pipe l i o r m (Either r i)
forall l i o u (m :: * -> *). Pipe l i o u m (Either u i)
awaitE Pipe l i o r m (Either r i)
-> (Either r i -> Pipe l i o r m r) -> Pipe l i o r m r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (r -> Pipe l i o r m r)
-> (i -> Pipe l i o r m r) -> Either r i -> Pipe l i o r m r
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either r -> Pipe l i o r m r
forall (m :: * -> *) a. Monad m => a -> m a
return (\i
i -> i -> Pipe l i o r m r'
inner i
i Pipe l i o r m r' -> Pipe l i o r m r -> Pipe l i o r m r
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Pipe l i o r m r
self)
{-# INLINE [1] awaitForever #-}

-- | Send a single output value downstream. If the downstream @Pipe@
-- terminates, this @Pipe@ will terminate as well.
--
-- Since 0.5.0
yield :: Monad m
      => o -- ^ output value
      -> Pipe l i o u m ()
yield :: o -> Pipe l i o u m ()
yield = Pipe l i o u m () -> o -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (() -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done ())
{-# INLINE [1] yield #-}

yieldM :: Monad m => m o -> Pipe l i o u m ()
yieldM :: m o -> Pipe l i o u m ()
yieldM = m (Pipe l i o u m ()) -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM (m (Pipe l i o u m ()) -> Pipe l i o u m ())
-> (m o -> m (Pipe l i o u m ())) -> m o -> Pipe l i o u m ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (o -> Pipe l i o u m ()) -> m o -> m (Pipe l i o u m ())
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Pipe l i o u m () -> o -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (() -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done ()))
{-# INLINE [1] yieldM #-}

{-# RULES
    "CI.yield o >> p" forall o (p :: Pipe l i o u m r). yield o >> p = HaveOutput p o
  #-}

  -- Rule does not fire due to inlining of lift
  -- ; "lift m >>= CI.yield" forall m. lift m >>= yield = yieldM m

  -- FIXME: Too much inlining on mapM_, can't enforce; "mapM_ CI.yield" mapM_ yield = sourceList
  -- Maybe we can get a rewrite rule on foldr instead? Need a benchmark to back this up.

-- | Provide a single piece of leftover input to be consumed by the next pipe
-- in the current monadic binding.
--
-- /Note/: it is highly encouraged to only return leftover values from input
-- already consumed from upstream.
--
-- Since 0.5.0
leftover :: l -> Pipe l i o u m ()
leftover :: l -> Pipe l i o u m ()
leftover = Pipe l i o u m () -> l -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (() -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done ())
{-# INLINE [1] leftover #-}
{-# RULES "conduit: leftover l >> p" forall l (p :: Pipe l i o u m r). leftover l >> p = Leftover p l #-}

-- | Split a pipe into head and tail.
--
-- Since 1.3.3
unconsM :: Monad m
        => Pipe Void () o () m ()
        -> m (Maybe (o, Pipe Void () o () m ()))
unconsM :: Pipe Void () o () m () -> m (Maybe (o, Pipe Void () o () m ()))
unconsM = Pipe Void () o () m () -> m (Maybe (o, Pipe Void () o () m ()))
forall (m :: * -> *) i a.
Monad m =>
Pipe Void i a () m () -> m (Maybe (a, Pipe Void i a () m ()))
go
  where
    go :: Pipe Void i a () m () -> m (Maybe (a, Pipe Void i a () m ()))
go (HaveOutput Pipe Void i a () m ()
p a
o) = Maybe (a, Pipe Void i a () m ())
-> m (Maybe (a, Pipe Void i a () m ()))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe (a, Pipe Void i a () m ())
 -> m (Maybe (a, Pipe Void i a () m ())))
-> Maybe (a, Pipe Void i a () m ())
-> m (Maybe (a, Pipe Void i a () m ()))
forall a b. (a -> b) -> a -> b
$ (a, Pipe Void i a () m ()) -> Maybe (a, Pipe Void i a () m ())
forall a. a -> Maybe a
Just (a
o, Pipe Void i a () m ()
p)
    go (NeedInput i -> Pipe Void i a () m ()
_ () -> Pipe Void i a () m ()
c) = Pipe Void i a () m () -> m (Maybe (a, Pipe Void i a () m ()))
go (Pipe Void i a () m () -> m (Maybe (a, Pipe Void i a () m ())))
-> Pipe Void i a () m () -> m (Maybe (a, Pipe Void i a () m ()))
forall a b. (a -> b) -> a -> b
$ () -> Pipe Void i a () m ()
c ()
    go (Done ()) = Maybe (a, Pipe Void i a () m ())
-> m (Maybe (a, Pipe Void i a () m ()))
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (a, Pipe Void i a () m ())
forall a. Maybe a
Nothing
    go (PipeM m (Pipe Void i a () m ())
mp) = m (Pipe Void i a () m ())
mp m (Pipe Void i a () m ())
-> (Pipe Void i a () m () -> m (Maybe (a, Pipe Void i a () m ())))
-> m (Maybe (a, Pipe Void i a () m ()))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pipe Void i a () m () -> m (Maybe (a, Pipe Void i a () m ()))
go
    go (Leftover Pipe Void i a () m ()
_ Void
i) = Void -> m (Maybe (a, Pipe Void i a () m ()))
forall a. Void -> a
absurd Void
i

-- | Split a pipe into head and tail or return its result if it is done.
--
-- Since 1.3.3
unconsEitherM :: Monad m
              => Pipe Void () o () m r
              -> m (Either r (o, Pipe Void () o () m r))
unconsEitherM :: Pipe Void () o () m r -> m (Either r (o, Pipe Void () o () m r))
unconsEitherM = Pipe Void () o () m r -> m (Either r (o, Pipe Void () o () m r))
forall (m :: * -> *) i a a.
Monad m =>
Pipe Void i a () m a -> m (Either a (a, Pipe Void i a () m a))
go
  where
    go :: Pipe Void i a () m a -> m (Either a (a, Pipe Void i a () m a))
go (HaveOutput Pipe Void i a () m a
p a
o) = Either a (a, Pipe Void i a () m a)
-> m (Either a (a, Pipe Void i a () m a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either a (a, Pipe Void i a () m a)
 -> m (Either a (a, Pipe Void i a () m a)))
-> Either a (a, Pipe Void i a () m a)
-> m (Either a (a, Pipe Void i a () m a))
forall a b. (a -> b) -> a -> b
$ (a, Pipe Void i a () m a) -> Either a (a, Pipe Void i a () m a)
forall a b. b -> Either a b
Right (a
o, Pipe Void i a () m a
p)
    go (NeedInput i -> Pipe Void i a () m a
_ () -> Pipe Void i a () m a
c) = Pipe Void i a () m a -> m (Either a (a, Pipe Void i a () m a))
go (Pipe Void i a () m a -> m (Either a (a, Pipe Void i a () m a)))
-> Pipe Void i a () m a -> m (Either a (a, Pipe Void i a () m a))
forall a b. (a -> b) -> a -> b
$ () -> Pipe Void i a () m a
c ()
    go (Done a
r) = Either a (a, Pipe Void i a () m a)
-> m (Either a (a, Pipe Void i a () m a))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either a (a, Pipe Void i a () m a)
 -> m (Either a (a, Pipe Void i a () m a)))
-> Either a (a, Pipe Void i a () m a)
-> m (Either a (a, Pipe Void i a () m a))
forall a b. (a -> b) -> a -> b
$ a -> Either a (a, Pipe Void i a () m a)
forall a b. a -> Either a b
Left a
r
    go (PipeM m (Pipe Void i a () m a)
mp) = m (Pipe Void i a () m a)
mp m (Pipe Void i a () m a)
-> (Pipe Void i a () m a -> m (Either a (a, Pipe Void i a () m a)))
-> m (Either a (a, Pipe Void i a () m a))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pipe Void i a () m a -> m (Either a (a, Pipe Void i a () m a))
go
    go (Leftover Pipe Void i a () m a
_ Void
i) = Void -> m (Either a (a, Pipe Void i a () m a))
forall a. Void -> a
absurd Void
i

-- | Bracket a pipe computation between allocation and release of a resource.
-- We guarantee, via the @MonadResource@ context, that the resource
-- finalization is exception safe. However, it will not necessarily be
-- /prompt/, in that running a finalizer may wait until the @ResourceT@ block
-- exits.
--
-- Since 0.5.0
bracketP :: MonadResource m
         => IO a
            -- ^ computation to run first (\"acquire resource\")
         -> (a -> IO ())
            -- ^ computation to run last (\"release resource\")
         -> (a -> Pipe l i o u m r)
            -- ^ computation to run in-between
         -> Pipe l i o u m r
            -- returns the value from the in-between computation
bracketP :: IO a -> (a -> IO ()) -> (a -> Pipe l i o u m r) -> Pipe l i o u m r
bracketP IO a
alloc a -> IO ()
free a -> Pipe l i o u m r
inside = do
  (ReleaseKey
key, a
seed) <- IO a -> (a -> IO ()) -> Pipe l i o u m (ReleaseKey, a)
forall (m :: * -> *) a.
MonadResource m =>
IO a -> (a -> IO ()) -> m (ReleaseKey, a)
allocate IO a
alloc a -> IO ()
free
  r
res <- a -> Pipe l i o u m r
inside a
seed
  ReleaseKey -> Pipe l i o u m ()
forall (m :: * -> *). MonadIO m => ReleaseKey -> m ()
release ReleaseKey
key
  r -> Pipe l i o u m r
forall (m :: * -> *) a. Monad m => a -> m a
return r
res

-- | The identity @Pipe@.
--
-- Since 0.5.0
idP :: Monad m => Pipe l a a r m r
idP :: Pipe l a a r m r
idP = (a -> Pipe l a a r m r)
-> (r -> Pipe l a a r m r) -> Pipe l a a r m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Pipe l a a r m r -> a -> Pipe l a a r m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput Pipe l a a r m r
forall (m :: * -> *) l a r. Monad m => Pipe l a a r m r
idP) r -> Pipe l a a r m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done

-- | Compose a left and right pipe together into a complete pipe.
--
-- Since 0.5.0
pipe :: Monad m => Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
pipe :: Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
pipe =
    Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
forall (m :: * -> *) l i i u u o r.
Monad m =>
Pipe l i i u m u -> Pipe Void i o u m r -> Pipe l i o u m r
goRight
  where
    goRight :: Pipe l i i u m u -> Pipe Void i o u m r -> Pipe l i o u m r
goRight Pipe l i i u m u
left Pipe Void i o u m r
right =
        case Pipe Void i o u m r
right of
            HaveOutput Pipe Void i o u m r
p o
o   -> Pipe l i o u m r -> o -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe Void i o u m r -> Pipe l i o u m r
recurse Pipe Void i o u m r
p) o
o
            NeedInput i -> Pipe Void i o u m r
rp u -> Pipe Void i o u m r
rc  -> (i -> Pipe Void i o u m r)
-> (u -> Pipe Void i o u m r)
-> Pipe l i i u m u
-> Pipe l i o u m r
goLeft i -> Pipe Void i o u m r
rp u -> Pipe Void i o u m r
rc Pipe l i i u m u
left
            Done r
r2          -> r -> Pipe l i o u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r2
            PipeM m (Pipe Void i o u m r)
mp         -> m (Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe Void i o u m r -> Pipe l i o u m r)
-> m (Pipe Void i o u m r) -> m (Pipe l i o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Pipe Void i o u m r -> Pipe l i o u m r
recurse m (Pipe Void i o u m r)
mp)
            Leftover Pipe Void i o u m r
_ Void
i     -> Void -> Pipe l i o u m r
forall a. Void -> a
absurd Void
i
      where
        recurse :: Pipe Void i o u m r -> Pipe l i o u m r
recurse = Pipe l i i u m u -> Pipe Void i o u m r -> Pipe l i o u m r
goRight Pipe l i i u m u
left

    goLeft :: (i -> Pipe Void i o u m r)
-> (u -> Pipe Void i o u m r)
-> Pipe l i i u m u
-> Pipe l i o u m r
goLeft i -> Pipe Void i o u m r
rp u -> Pipe Void i o u m r
rc Pipe l i i u m u
left =
        case Pipe l i i u m u
left of
            HaveOutput Pipe l i i u m u
left' i
o        -> Pipe l i i u m u -> Pipe Void i o u m r -> Pipe l i o u m r
goRight Pipe l i i u m u
left' (i -> Pipe Void i o u m r
rp i
o)
            NeedInput i -> Pipe l i i u m u
left' u -> Pipe l i i u m u
lc        -> (i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Pipe l i i u m u -> Pipe l i o u m r
recurse (Pipe l i i u m u -> Pipe l i o u m r)
-> (i -> Pipe l i i u m u) -> i -> Pipe l i o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe l i i u m u
left') (Pipe l i i u m u -> Pipe l i o u m r
recurse (Pipe l i i u m u -> Pipe l i o u m r)
-> (u -> Pipe l i i u m u) -> u -> Pipe l i o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe l i i u m u
lc)
            Done u
r1                   -> Pipe l i i u m u -> Pipe Void i o u m r -> Pipe l i o u m r
goRight (u -> Pipe l i i u m u
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done u
r1) (u -> Pipe Void i o u m r
rc u
r1)
            PipeM m (Pipe l i i u m u)
mp                  -> m (Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe l i i u m u -> Pipe l i o u m r)
-> m (Pipe l i i u m u) -> m (Pipe l i o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Pipe l i i u m u -> Pipe l i o u m r
recurse m (Pipe l i i u m u)
mp)
            Leftover Pipe l i i u m u
left' l
i          -> Pipe l i o u m r -> l -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i i u m u -> Pipe l i o u m r
recurse Pipe l i i u m u
left') l
i
      where
        recurse :: Pipe l i i u m u -> Pipe l i o u m r
recurse = (i -> Pipe Void i o u m r)
-> (u -> Pipe Void i o u m r)
-> Pipe l i i u m u
-> Pipe l i o u m r
goLeft i -> Pipe Void i o u m r
rp u -> Pipe Void i o u m r
rc

-- | Same as 'pipe', but automatically applies 'injectLeftovers' to the right @Pipe@.
--
-- Since 0.5.0
pipeL :: Monad m => Pipe l a b r0 m r1 -> Pipe b b c r1 m r2 -> Pipe l a c r0 m r2
-- Note: The following should be equivalent to the simpler:
--
--     pipeL l r = l `pipe` injectLeftovers r
--
-- However, this version tested as being significantly more efficient.
pipeL :: Pipe l a b r0 m r1 -> Pipe b b c r1 m r2 -> Pipe l a c r0 m r2
pipeL =
    Pipe l a b r0 m r1 -> Pipe b b c r1 m r2 -> Pipe l a c r0 m r2
forall (m :: * -> *) l i i u u o r.
Monad m =>
Pipe l i i u m u -> Pipe i i o u m r -> Pipe l i o u m r
goRight
  where
    goRight :: Pipe l i i u m u -> Pipe i i o u m r -> Pipe l i o u m r
goRight Pipe l i i u m u
left Pipe i i o u m r
right =
        case Pipe i i o u m r
right of
            HaveOutput Pipe i i o u m r
p o
o    -> Pipe l i o u m r -> o -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe i i o u m r -> Pipe l i o u m r
recurse Pipe i i o u m r
p) o
o
            NeedInput i -> Pipe i i o u m r
rp u -> Pipe i i o u m r
rc   -> (i -> Pipe i i o u m r)
-> (u -> Pipe i i o u m r) -> Pipe l i i u m u -> Pipe l i o u m r
goLeft i -> Pipe i i o u m r
rp u -> Pipe i i o u m r
rc Pipe l i i u m u
left
            Done r
r2           -> r -> Pipe l i o u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r2
            PipeM m (Pipe i i o u m r)
mp          -> m (Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe i i o u m r -> Pipe l i o u m r)
-> m (Pipe i i o u m r) -> m (Pipe l i o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Pipe i i o u m r -> Pipe l i o u m r
recurse m (Pipe i i o u m r)
mp)
            Leftover Pipe i i o u m r
right' i
i -> Pipe l i i u m u -> Pipe i i o u m r -> Pipe l i o u m r
goRight (Pipe l i i u m u -> i -> Pipe l i i u m u
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput Pipe l i i u m u
left i
i) Pipe i i o u m r
right'
      where
        recurse :: Pipe i i o u m r -> Pipe l i o u m r
recurse = Pipe l i i u m u -> Pipe i i o u m r -> Pipe l i o u m r
goRight Pipe l i i u m u
left

    goLeft :: (i -> Pipe i i o u m r)
-> (u -> Pipe i i o u m r) -> Pipe l i i u m u -> Pipe l i o u m r
goLeft i -> Pipe i i o u m r
rp u -> Pipe i i o u m r
rc Pipe l i i u m u
left =
        case Pipe l i i u m u
left of
            HaveOutput Pipe l i i u m u
left' i
o        -> Pipe l i i u m u -> Pipe i i o u m r -> Pipe l i o u m r
goRight Pipe l i i u m u
left' (i -> Pipe i i o u m r
rp i
o)
            NeedInput i -> Pipe l i i u m u
left' u -> Pipe l i i u m u
lc        -> (i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Pipe l i i u m u -> Pipe l i o u m r
recurse (Pipe l i i u m u -> Pipe l i o u m r)
-> (i -> Pipe l i i u m u) -> i -> Pipe l i o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe l i i u m u
left') (Pipe l i i u m u -> Pipe l i o u m r
recurse (Pipe l i i u m u -> Pipe l i o u m r)
-> (u -> Pipe l i i u m u) -> u -> Pipe l i o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe l i i u m u
lc)
            Done u
r1                   -> Pipe l i i u m u -> Pipe i i o u m r -> Pipe l i o u m r
goRight (u -> Pipe l i i u m u
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done u
r1) (u -> Pipe i i o u m r
rc u
r1)
            PipeM m (Pipe l i i u m u)
mp                  -> m (Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe l i i u m u -> Pipe l i o u m r)
-> m (Pipe l i i u m u) -> m (Pipe l i o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Pipe l i i u m u -> Pipe l i o u m r
recurse m (Pipe l i i u m u)
mp)
            Leftover Pipe l i i u m u
left' l
i          -> Pipe l i o u m r -> l -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i i u m u -> Pipe l i o u m r
recurse Pipe l i i u m u
left') l
i
      where
        recurse :: Pipe l i i u m u -> Pipe l i o u m r
recurse = (i -> Pipe i i o u m r)
-> (u -> Pipe i i o u m r) -> Pipe l i i u m u -> Pipe l i o u m r
goLeft i -> Pipe i i o u m r
rp u -> Pipe i i o u m r
rc

-- | Run a pipeline until processing completes.
--
-- Since 0.5.0
runPipe :: Monad m => Pipe Void () Void () m r -> m r
runPipe :: Pipe Void () Void () m r -> m r
runPipe (HaveOutput Pipe Void () Void () m r
_ Void
o) = Void -> m r
forall a. Void -> a
absurd Void
o
runPipe (NeedInput () -> Pipe Void () Void () m r
_ () -> Pipe Void () Void () m r
c) = Pipe Void () Void () m r -> m r
forall (m :: * -> *) r. Monad m => Pipe Void () Void () m r -> m r
runPipe (() -> Pipe Void () Void () m r
c ())
runPipe (Done r
r) = r -> m r
forall (m :: * -> *) a. Monad m => a -> m a
return r
r
runPipe (PipeM m (Pipe Void () Void () m r)
mp) = m (Pipe Void () Void () m r)
mp m (Pipe Void () Void () m r)
-> (Pipe Void () Void () m r -> m r) -> m r
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Pipe Void () Void () m r -> m r
forall (m :: * -> *) r. Monad m => Pipe Void () Void () m r -> m r
runPipe
runPipe (Leftover Pipe Void () Void () m r
_ Void
i) = Void -> m r
forall a. Void -> a
absurd Void
i

-- | Transforms a @Pipe@ that provides leftovers to one which does not,
-- allowing it to be composed.
--
-- This function will provide any leftover values within this @Pipe@ to any
-- calls to @await@. If there are more leftover values than are demanded, the
-- remainder are discarded.
--
-- Since 0.5.0
injectLeftovers :: Monad m => Pipe i i o u m r -> Pipe l i o u m r
injectLeftovers :: Pipe i i o u m r -> Pipe l i o u m r
injectLeftovers =
    [i] -> Pipe i i o u m r -> Pipe l i o u m r
forall (m :: * -> *) a o u r l.
Monad m =>
[a] -> Pipe a a o u m r -> Pipe l a o u m r
go []
  where
    go :: [a] -> Pipe a a o u m r -> Pipe l a o u m r
go [a]
ls (HaveOutput Pipe a a o u m r
p o
o) = Pipe l a o u m r -> o -> Pipe l a o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput ([a] -> Pipe a a o u m r -> Pipe l a o u m r
go [a]
ls Pipe a a o u m r
p) o
o
    go (a
l:[a]
ls) (NeedInput a -> Pipe a a o u m r
p u -> Pipe a a o u m r
_) = [a] -> Pipe a a o u m r -> Pipe l a o u m r
go [a]
ls (Pipe a a o u m r -> Pipe l a o u m r)
-> Pipe a a o u m r -> Pipe l a o u m r
forall a b. (a -> b) -> a -> b
$ a -> Pipe a a o u m r
p a
l
    go [] (NeedInput a -> Pipe a a o u m r
p u -> Pipe a a o u m r
c) = (a -> Pipe l a o u m r)
-> (u -> Pipe l a o u m r) -> Pipe l a o u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput ([a] -> Pipe a a o u m r -> Pipe l a o u m r
go [] (Pipe a a o u m r -> Pipe l a o u m r)
-> (a -> Pipe a a o u m r) -> a -> Pipe l a o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Pipe a a o u m r
p) ([a] -> Pipe a a o u m r -> Pipe l a o u m r
go [] (Pipe a a o u m r -> Pipe l a o u m r)
-> (u -> Pipe a a o u m r) -> u -> Pipe l a o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe a a o u m r
c)
    go [a]
_ (Done r
r) = r -> Pipe l a o u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r
    go [a]
ls (PipeM m (Pipe a a o u m r)
mp) = m (Pipe l a o u m r) -> Pipe l a o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe a a o u m r -> Pipe l a o u m r)
-> m (Pipe a a o u m r) -> m (Pipe l a o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ([a] -> Pipe a a o u m r -> Pipe l a o u m r
go [a]
ls) m (Pipe a a o u m r)
mp)
    go [a]
ls (Leftover Pipe a a o u m r
p a
l) = [a] -> Pipe a a o u m r -> Pipe l a o u m r
go (a
la -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
ls) Pipe a a o u m r
p

-- | Transform the monad that a @Pipe@ lives in.
--
-- Note that the monad transforming function will be run multiple times,
-- resulting in unintuitive behavior in some cases. For a fuller treatment,
-- please see:
--
-- <https://github.com/snoyberg/conduit/wiki/Dealing-with-monad-transformers>
--
-- This function is just a synonym for 'hoist'.
--
-- Since 0.4.0
transPipe :: Monad m => (forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
transPipe :: (forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
transPipe forall a. m a -> n a
f (HaveOutput Pipe l i o u m r
p o
o) = Pipe l i o u n r -> o -> Pipe l i o u n r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput ((forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
forall (m :: * -> *) (n :: * -> *) l i o u r.
Monad m =>
(forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
transPipe forall a. m a -> n a
f Pipe l i o u m r
p) o
o
transPipe forall a. m a -> n a
f (NeedInput i -> Pipe l i o u m r
p u -> Pipe l i o u m r
c) = (i -> Pipe l i o u n r)
-> (u -> Pipe l i o u n r) -> Pipe l i o u n r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput ((forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
forall (m :: * -> *) (n :: * -> *) l i o u r.
Monad m =>
(forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
transPipe forall a. m a -> n a
f (Pipe l i o u m r -> Pipe l i o u n r)
-> (i -> Pipe l i o u m r) -> i -> Pipe l i o u n r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe l i o u m r
p) ((forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
forall (m :: * -> *) (n :: * -> *) l i o u r.
Monad m =>
(forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
transPipe forall a. m a -> n a
f (Pipe l i o u m r -> Pipe l i o u n r)
-> (u -> Pipe l i o u m r) -> u -> Pipe l i o u n r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe l i o u m r
c)
transPipe forall a. m a -> n a
_ (Done r
r) = r -> Pipe l i o u n r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r
transPipe forall a. m a -> n a
f (PipeM m (Pipe l i o u m r)
mp) =
    n (Pipe l i o u n r) -> Pipe l i o u n r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM (m (Pipe l i o u n r) -> n (Pipe l i o u n r)
forall a. m a -> n a
f (m (Pipe l i o u n r) -> n (Pipe l i o u n r))
-> m (Pipe l i o u n r) -> n (Pipe l i o u n r)
forall a b. (a -> b) -> a -> b
$ (Pipe l i o u m r -> Pipe l i o u n r)
-> m (Pipe l i o u m r) -> m (Pipe l i o u n r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
forall (m :: * -> *) (n :: * -> *) l i o u r.
Monad m =>
(forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
transPipe forall a. m a -> n a
f) (m (Pipe l i o u m r) -> m (Pipe l i o u n r))
-> m (Pipe l i o u m r) -> m (Pipe l i o u n r)
forall a b. (a -> b) -> a -> b
$ m (Pipe l i o u m r) -> m (Pipe l i o u m r)
forall (m :: * -> *) l i o u r.
Monad m =>
m (Pipe l i o u m r) -> m (Pipe l i o u m r)
collapse m (Pipe l i o u m r)
mp)
  where
    -- Combine a series of monadic actions into a single action.  Since we
    -- throw away side effects between different actions, an arbitrary break
    -- between actions will lead to a violation of the monad transformer laws.
    -- Example available at:
    --
    -- http://hpaste.org/75520
    collapse :: m (Pipe l i o u m r) -> m (Pipe l i o u m r)
collapse m (Pipe l i o u m r)
mpipe = do
        Pipe l i o u m r
pipe' <- m (Pipe l i o u m r)
mpipe
        case Pipe l i o u m r
pipe' of
            PipeM m (Pipe l i o u m r)
mpipe' -> m (Pipe l i o u m r) -> m (Pipe l i o u m r)
collapse m (Pipe l i o u m r)
mpipe'
            Pipe l i o u m r
_ -> Pipe l i o u m r -> m (Pipe l i o u m r)
forall (m :: * -> *) a. Monad m => a -> m a
return Pipe l i o u m r
pipe'
transPipe forall a. m a -> n a
f (Leftover Pipe l i o u m r
p l
i) = Pipe l i o u n r -> l -> Pipe l i o u n r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover ((forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
forall (m :: * -> *) (n :: * -> *) l i o u r.
Monad m =>
(forall a. m a -> n a) -> Pipe l i o u m r -> Pipe l i o u n r
transPipe forall a. m a -> n a
f Pipe l i o u m r
p) l
i

-- | Apply a function to all the output values of a @Pipe@.
--
-- This mimics the behavior of `fmap` for a `Source` and `Conduit` in pre-0.4
-- days.
--
-- Since 0.4.1
mapOutput :: Monad m => (o1 -> o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r
mapOutput :: (o1 -> o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r
mapOutput o1 -> o2
f =
    Pipe l i o1 u m r -> Pipe l i o2 u m r
go
  where
    go :: Pipe l i o1 u m r -> Pipe l i o2 u m r
go (HaveOutput Pipe l i o1 u m r
p o1
o) = Pipe l i o2 u m r -> o2 -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe l i o1 u m r -> Pipe l i o2 u m r
go Pipe l i o1 u m r
p) (o1 -> o2
f o1
o)
    go (NeedInput i -> Pipe l i o1 u m r
p u -> Pipe l i o1 u m r
c) = (i -> Pipe l i o2 u m r)
-> (u -> Pipe l i o2 u m r) -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Pipe l i o1 u m r -> Pipe l i o2 u m r
go (Pipe l i o1 u m r -> Pipe l i o2 u m r)
-> (i -> Pipe l i o1 u m r) -> i -> Pipe l i o2 u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe l i o1 u m r
p) (Pipe l i o1 u m r -> Pipe l i o2 u m r
go (Pipe l i o1 u m r -> Pipe l i o2 u m r)
-> (u -> Pipe l i o1 u m r) -> u -> Pipe l i o2 u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe l i o1 u m r
c)
    go (Done r
r) = r -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r
    go (PipeM m (Pipe l i o1 u m r)
mp) = m (Pipe l i o2 u m r) -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe l i o1 u m r -> Pipe l i o2 u m r)
-> m (Pipe l i o1 u m r) -> m (Pipe l i o2 u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Pipe l i o1 u m r -> Pipe l i o2 u m r
go) m (Pipe l i o1 u m r)
mp)
    go (Leftover Pipe l i o1 u m r
p l
i) = Pipe l i o2 u m r -> l -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i o1 u m r -> Pipe l i o2 u m r
go Pipe l i o1 u m r
p) l
i
{-# INLINE mapOutput #-}

-- | Same as 'mapOutput', but use a function that returns @Maybe@ values.
--
-- Since 0.5.0
mapOutputMaybe :: Monad m => (o1 -> Maybe o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r
mapOutputMaybe :: (o1 -> Maybe o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r
mapOutputMaybe o1 -> Maybe o2
f =
    Pipe l i o1 u m r -> Pipe l i o2 u m r
go
  where
    go :: Pipe l i o1 u m r -> Pipe l i o2 u m r
go (HaveOutput Pipe l i o1 u m r
p o1
o) = (Pipe l i o2 u m r -> Pipe l i o2 u m r)
-> (o2 -> Pipe l i o2 u m r -> Pipe l i o2 u m r)
-> Maybe o2
-> Pipe l i o2 u m r
-> Pipe l i o2 u m r
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Pipe l i o2 u m r -> Pipe l i o2 u m r
forall a. a -> a
id (\o2
o' Pipe l i o2 u m r
p' -> Pipe l i o2 u m r -> o2 -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput Pipe l i o2 u m r
p' o2
o') (o1 -> Maybe o2
f o1
o) (Pipe l i o1 u m r -> Pipe l i o2 u m r
go Pipe l i o1 u m r
p)
    go (NeedInput i -> Pipe l i o1 u m r
p u -> Pipe l i o1 u m r
c) = (i -> Pipe l i o2 u m r)
-> (u -> Pipe l i o2 u m r) -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Pipe l i o1 u m r -> Pipe l i o2 u m r
go (Pipe l i o1 u m r -> Pipe l i o2 u m r)
-> (i -> Pipe l i o1 u m r) -> i -> Pipe l i o2 u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe l i o1 u m r
p) (Pipe l i o1 u m r -> Pipe l i o2 u m r
go (Pipe l i o1 u m r -> Pipe l i o2 u m r)
-> (u -> Pipe l i o1 u m r) -> u -> Pipe l i o2 u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe l i o1 u m r
c)
    go (Done r
r) = r -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r
    go (PipeM m (Pipe l i o1 u m r)
mp) = m (Pipe l i o2 u m r) -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe l i o1 u m r -> Pipe l i o2 u m r)
-> m (Pipe l i o1 u m r) -> m (Pipe l i o2 u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (Pipe l i o1 u m r -> Pipe l i o2 u m r
go) m (Pipe l i o1 u m r)
mp)
    go (Leftover Pipe l i o1 u m r
p l
i) = Pipe l i o2 u m r -> l -> Pipe l i o2 u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i o1 u m r -> Pipe l i o2 u m r
go Pipe l i o1 u m r
p) l
i
{-# INLINE mapOutputMaybe #-}

-- | Apply a function to all the input values of a @Pipe@.
--
-- Since 0.5.0
mapInput :: Monad m
         => (i1 -> i2) -- ^ map initial input to new input
         -> (l2 -> Maybe l1) -- ^ map new leftovers to initial leftovers
         -> Pipe l2 i2 o u m r
         -> Pipe l1 i1 o u m r
mapInput :: (i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
mapInput i1 -> i2
f l2 -> Maybe l1
f' (HaveOutput Pipe l2 i2 o u m r
p o
o) = Pipe l1 i1 o u m r -> o -> Pipe l1 i1 o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput ((i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
forall (m :: * -> *) i1 i2 l2 l1 o u r.
Monad m =>
(i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
mapInput i1 -> i2
f l2 -> Maybe l1
f' Pipe l2 i2 o u m r
p) o
o
mapInput i1 -> i2
f l2 -> Maybe l1
f' (NeedInput i2 -> Pipe l2 i2 o u m r
p u -> Pipe l2 i2 o u m r
c)    = (i1 -> Pipe l1 i1 o u m r)
-> (u -> Pipe l1 i1 o u m r) -> Pipe l1 i1 o u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput ((i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
forall (m :: * -> *) i1 i2 l2 l1 o u r.
Monad m =>
(i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
mapInput i1 -> i2
f l2 -> Maybe l1
f' (Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r)
-> (i1 -> Pipe l2 i2 o u m r) -> i1 -> Pipe l1 i1 o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i2 -> Pipe l2 i2 o u m r
p (i2 -> Pipe l2 i2 o u m r)
-> (i1 -> i2) -> i1 -> Pipe l2 i2 o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i1 -> i2
f) ((i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
forall (m :: * -> *) i1 i2 l2 l1 o u r.
Monad m =>
(i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
mapInput i1 -> i2
f l2 -> Maybe l1
f' (Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r)
-> (u -> Pipe l2 i2 o u m r) -> u -> Pipe l1 i1 o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe l2 i2 o u m r
c)
mapInput i1 -> i2
_ l2 -> Maybe l1
_  (Done r
r)           = r -> Pipe l1 i1 o u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r
mapInput i1 -> i2
f l2 -> Maybe l1
f' (PipeM m (Pipe l2 i2 o u m r)
mp)         = m (Pipe l1 i1 o u m r) -> Pipe l1 i1 o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r)
-> m (Pipe l2 i2 o u m r) -> m (Pipe l1 i1 o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM ((i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
forall (m :: * -> *) i1 i2 l2 l1 o u r.
Monad m =>
(i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
mapInput i1 -> i2
f l2 -> Maybe l1
f') m (Pipe l2 i2 o u m r)
mp)
mapInput i1 -> i2
f l2 -> Maybe l1
f' (Leftover Pipe l2 i2 o u m r
p l2
i)     = (Pipe l1 i1 o u m r -> Pipe l1 i1 o u m r)
-> (l1 -> Pipe l1 i1 o u m r -> Pipe l1 i1 o u m r)
-> Maybe l1
-> Pipe l1 i1 o u m r
-> Pipe l1 i1 o u m r
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Pipe l1 i1 o u m r -> Pipe l1 i1 o u m r
forall a. a -> a
id ((Pipe l1 i1 o u m r -> l1 -> Pipe l1 i1 o u m r)
-> l1 -> Pipe l1 i1 o u m r -> Pipe l1 i1 o u m r
forall a b c. (a -> b -> c) -> b -> a -> c
flip Pipe l1 i1 o u m r -> l1 -> Pipe l1 i1 o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover) (l2 -> Maybe l1
f' l2
i) (Pipe l1 i1 o u m r -> Pipe l1 i1 o u m r)
-> Pipe l1 i1 o u m r -> Pipe l1 i1 o u m r
forall a b. (a -> b) -> a -> b
$ (i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
forall (m :: * -> *) i1 i2 l2 l1 o u r.
Monad m =>
(i1 -> i2)
-> (l2 -> Maybe l1) -> Pipe l2 i2 o u m r -> Pipe l1 i1 o u m r
mapInput i1 -> i2
f l2 -> Maybe l1
f' Pipe l2 i2 o u m r
p

enumFromTo :: (Enum o, Eq o, Monad m)
           => o
           -> o
           -> Pipe l i o u m ()
enumFromTo :: o -> o -> Pipe l i o u m ()
enumFromTo o
start o
stop =
    o -> Pipe l i o u m ()
loop o
start
  where
    loop :: o -> Pipe l i o u m ()
loop o
i
        | o
i o -> o -> Bool
forall a. Eq a => a -> a -> Bool
== o
stop = Pipe l i o u m () -> o -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (() -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done ()) o
i
        | Bool
otherwise = Pipe l i o u m () -> o -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (o -> Pipe l i o u m ()
loop (o -> o
forall a. Enum a => a -> a
succ o
i)) o
i
{-# INLINE enumFromTo #-}

-- | Convert a list into a source.
--
-- Since 0.3.0
sourceList :: Monad m => [a] -> Pipe l i a u m ()
sourceList :: [a] -> Pipe l i a u m ()
sourceList =
    [a] -> Pipe l i a u m ()
forall o l i u (m :: * -> *). [o] -> Pipe l i o u m ()
go
  where
    go :: [o] -> Pipe l i o u m ()
go [] = () -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done ()
    go (o
o:[o]
os) = Pipe l i o u m () -> o -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput ([o] -> Pipe l i o u m ()
go [o]
os) o
o
{-# INLINE [1] sourceList #-}

-- | The equivalent of @GHC.Exts.build@ for @Pipe@.
--
-- Since 0.4.2
build :: Monad m => (forall b. (o -> b -> b) -> b -> b) -> Pipe l i o u m ()
build :: (forall b. (o -> b -> b) -> b -> b) -> Pipe l i o u m ()
build forall b. (o -> b -> b) -> b -> b
g = (o -> Pipe l i o u m () -> Pipe l i o u m ())
-> Pipe l i o u m () -> Pipe l i o u m ()
forall b. (o -> b -> b) -> b -> b
g (\o
o Pipe l i o u m ()
p -> Pipe l i o u m () -> o -> Pipe l i o u m ()
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput Pipe l i o u m ()
p o
o) (() -> Pipe l i o u m ()
forall (m :: * -> *) a. Monad m => a -> m a
return ())

{-# RULES
    "sourceList/build" forall (f :: (forall b. (a -> b -> b) -> b -> b)). sourceList (GHC.Exts.build f) = build f #-}

-- | Returns a tuple of the upstream and downstream results. Note that this
-- will force consumption of the entire input stream.
--
-- Since 0.5.0
withUpstream :: Monad m
             => Pipe l i o u m r
             -> Pipe l i o u m (u, r)
withUpstream :: Pipe l i o u m r -> Pipe l i o u m (u, r)
withUpstream Pipe l i o u m r
down =
    Pipe l i o u m r
down Pipe l i o u m r
-> (r -> Pipe l i o u m (u, r)) -> Pipe l i o u m (u, r)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= r -> Pipe l i o u m (u, r)
forall (m :: * -> *) b l b o a.
Monad m =>
b -> Pipe l b o a m (a, b)
go
  where
    go :: b -> Pipe l b o a m (a, b)
go b
r =
        Pipe l b o a m (a, b)
loop
      where
        loop :: Pipe l b o a m (a, b)
loop = Pipe l b o a m (Either a b)
forall l i o u (m :: * -> *). Pipe l i o u m (Either u i)
awaitE Pipe l b o a m (Either a b)
-> (Either a b -> Pipe l b o a m (a, b)) -> Pipe l b o a m (a, b)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (a -> Pipe l b o a m (a, b))
-> (b -> Pipe l b o a m (a, b))
-> Either a b
-> Pipe l b o a m (a, b)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (\a
u -> (a, b) -> Pipe l b o a m (a, b)
forall (m :: * -> *) a. Monad m => a -> m a
return (a
u, b
r)) (\b
_ -> Pipe l b o a m (a, b)
loop)

infixr 9 <+<
infixl 9 >+>

-- | Fuse together two @Pipe@s, connecting the output from the left to the
-- input of the right.
--
-- Notice that the /leftover/ parameter for the @Pipe@s must be @Void@. This
-- ensures that there is no accidental data loss of leftovers during fusion. If
-- you have a @Pipe@ with leftovers, you must first call 'injectLeftovers'.
--
-- Since 0.5.0
(>+>) :: Monad m => Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
>+> :: Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
(>+>) = Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
forall (m :: * -> *) l i i u u o r.
Monad m =>
Pipe l i i u m u -> Pipe Void i o u m r -> Pipe l i o u m r
pipe
{-# INLINE (>+>) #-}

-- | Same as '>+>', but reverse the order of the arguments.
--
-- Since 0.5.0
(<+<) :: Monad m => Pipe Void b c r1 m r2 -> Pipe l a b r0 m r1 -> Pipe l a c r0 m r2
<+< :: Pipe Void b c r1 m r2 -> Pipe l a b r0 m r1 -> Pipe l a c r0 m r2
(<+<) = (Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2)
-> Pipe Void b c r1 m r2
-> Pipe l a b r0 m r1
-> Pipe l a c r0 m r2
forall a b c. (a -> b -> c) -> b -> a -> c
flip Pipe l a b r0 m r1 -> Pipe Void b c r1 m r2 -> Pipe l a c r0 m r2
forall (m :: * -> *) l i i u u o r.
Monad m =>
Pipe l i i u m u -> Pipe Void i o u m r -> Pipe l i o u m r
pipe
{-# INLINE (<+<) #-}

-- | See 'catchC' for more details.
--
-- Since 1.0.11
catchP :: (MonadUnliftIO m, E.Exception e)
       => Pipe l i o u m r
       -> (e -> Pipe l i o u m r)
       -> Pipe l i o u m r
catchP :: Pipe l i o u m r -> (e -> Pipe l i o u m r) -> Pipe l i o u m r
catchP Pipe l i o u m r
p0 e -> Pipe l i o u m r
onErr =
    Pipe l i o u m r -> Pipe l i o u m r
go Pipe l i o u m r
p0
  where
    go :: Pipe l i o u m r -> Pipe l i o u m r
go (Done r
r) = r -> Pipe l i o u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r
    go (PipeM m (Pipe l i o u m r)
mp) = m (Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM (m (Pipe l i o u m r) -> Pipe l i o u m r)
-> m (Pipe l i o u m r) -> Pipe l i o u m r
forall a b. (a -> b) -> a -> b
$ ((forall a. m a -> IO a) -> IO (Pipe l i o u m r))
-> m (Pipe l i o u m r)
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (((forall a. m a -> IO a) -> IO (Pipe l i o u m r))
 -> m (Pipe l i o u m r))
-> ((forall a. m a -> IO a) -> IO (Pipe l i o u m r))
-> m (Pipe l i o u m r)
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run ->
      IO (Pipe l i o u m r)
-> (e -> IO (Pipe l i o u m r)) -> IO (Pipe l i o u m r)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
E.catch (m (Pipe l i o u m r) -> IO (Pipe l i o u m r)
forall a. m a -> IO a
run ((Pipe l i o u m r -> Pipe l i o u m r)
-> m (Pipe l i o u m r) -> m (Pipe l i o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Pipe l i o u m r -> Pipe l i o u m r
go m (Pipe l i o u m r)
mp)) (Pipe l i o u m r -> IO (Pipe l i o u m r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Pipe l i o u m r -> IO (Pipe l i o u m r))
-> (e -> Pipe l i o u m r) -> e -> IO (Pipe l i o u m r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Pipe l i o u m r
onErr)
    go (Leftover Pipe l i o u m r
p l
i) = Pipe l i o u m r -> l -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i o u m r -> Pipe l i o u m r
go Pipe l i o u m r
p) l
i
    go (NeedInput i -> Pipe l i o u m r
x u -> Pipe l i o u m r
y) = (i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Pipe l i o u m r -> Pipe l i o u m r
go (Pipe l i o u m r -> Pipe l i o u m r)
-> (i -> Pipe l i o u m r) -> i -> Pipe l i o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe l i o u m r
x) (Pipe l i o u m r -> Pipe l i o u m r
go (Pipe l i o u m r -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> u -> Pipe l i o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. u -> Pipe l i o u m r
y)
    go (HaveOutput Pipe l i o u m r
p o
o) = Pipe l i o u m r -> o -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe l i o u m r -> Pipe l i o u m r
go Pipe l i o u m r
p) o
o
{-# INLINABLE catchP #-}

-- | The same as @flip catchP@.
--
-- Since 1.0.11
handleP :: (MonadUnliftIO m, E.Exception e)
        => (e -> Pipe l i o u m r)
        -> Pipe l i o u m r
        -> Pipe l i o u m r
handleP :: (e -> Pipe l i o u m r) -> Pipe l i o u m r -> Pipe l i o u m r
handleP = (Pipe l i o u m r -> (e -> Pipe l i o u m r) -> Pipe l i o u m r)
-> (e -> Pipe l i o u m r) -> Pipe l i o u m r -> Pipe l i o u m r
forall a b c. (a -> b -> c) -> b -> a -> c
flip Pipe l i o u m r -> (e -> Pipe l i o u m r) -> Pipe l i o u m r
forall (m :: * -> *) e l i o u r.
(MonadUnliftIO m, Exception e) =>
Pipe l i o u m r -> (e -> Pipe l i o u m r) -> Pipe l i o u m r
catchP
{-# INLINE handleP #-}

-- | See 'tryC' for more details.
--
-- Since 1.0.11
tryP :: (MonadUnliftIO m, E.Exception e)
     => Pipe l i o u m r
     -> Pipe l i o u m (Either e r)
tryP :: Pipe l i o u m r -> Pipe l i o u m (Either e r)
tryP Pipe l i o u m r
p = ((r -> Either e r)
-> Pipe l i o u m r -> Pipe l i o u m (Either e r)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap r -> Either e r
forall a b. b -> Either a b
Right Pipe l i o u m r
p) Pipe l i o u m (Either e r)
-> (e -> Pipe l i o u m (Either e r))
-> Pipe l i o u m (Either e r)
forall (m :: * -> *) e l i o u r.
(MonadUnliftIO m, Exception e) =>
Pipe l i o u m r -> (e -> Pipe l i o u m r) -> Pipe l i o u m r
`catchP` (Either e r -> Pipe l i o u m (Either e r)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either e r -> Pipe l i o u m (Either e r))
-> (e -> Either e r) -> e -> Pipe l i o u m (Either e r)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. e -> Either e r
forall a b. a -> Either a b
Left)
{-# INLINABLE tryP #-}

-- | Generalize the upstream return value for a @Pipe@ from unit to any type.
--
-- Since 1.1.5
generalizeUpstream :: Monad m => Pipe l i o () m r -> Pipe l i o u m r
generalizeUpstream :: Pipe l i o () m r -> Pipe l i o u m r
generalizeUpstream =
    Pipe l i o () m r -> Pipe l i o u m r
forall (m :: * -> *) l i o r u.
Monad m =>
Pipe l i o () m r -> Pipe l i o u m r
go
  where
    go :: Pipe l i o () m r -> Pipe l i o u m r
go (HaveOutput Pipe l i o () m r
p o
o) = Pipe l i o u m r -> o -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> o -> Pipe l i o u m r
HaveOutput (Pipe l i o () m r -> Pipe l i o u m r
go Pipe l i o () m r
p) o
o
    go (NeedInput i -> Pipe l i o () m r
x () -> Pipe l i o () m r
y) = (i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
(i -> Pipe l i o u m r)
-> (u -> Pipe l i o u m r) -> Pipe l i o u m r
NeedInput (Pipe l i o () m r -> Pipe l i o u m r
go (Pipe l i o () m r -> Pipe l i o u m r)
-> (i -> Pipe l i o () m r) -> i -> Pipe l i o u m r
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i -> Pipe l i o () m r
x) (\u
_ -> Pipe l i o () m r -> Pipe l i o u m r
go (() -> Pipe l i o () m r
y ()))
    go (Done r
r) = r -> Pipe l i o u m r
forall l i o u (m :: * -> *) r. r -> Pipe l i o u m r
Done r
r
    go (PipeM m (Pipe l i o () m r)
mp) = m (Pipe l i o u m r) -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
m (Pipe l i o u m r) -> Pipe l i o u m r
PipeM ((Pipe l i o () m r -> Pipe l i o u m r)
-> m (Pipe l i o () m r) -> m (Pipe l i o u m r)
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM Pipe l i o () m r -> Pipe l i o u m r
go m (Pipe l i o () m r)
mp)
    go (Leftover Pipe l i o () m r
p l
l) = Pipe l i o u m r -> l -> Pipe l i o u m r
forall l i o u (m :: * -> *) r.
Pipe l i o u m r -> l -> Pipe l i o u m r
Leftover (Pipe l i o () m r -> Pipe l i o u m r
go Pipe l i o () m r
p) l
l
{-# INLINE generalizeUpstream #-}

{- Rules don't fire due to inlining of lift
{-# RULES "conduit: Pipe: lift x >>= f" forall m f. lift m >>= f = PipeM (liftM f m) #-}
{-# RULES "conduit: Pipe: lift x >> f" forall m f. lift m >> f = PipeM (liftM (\_ -> f) m) #-}
-}