packages feed

conduit-combinators (empty) → 0.1.0.0

raw patch · 7 files changed

+3218/−0 lines, 7 filesdep +basedep +basic-preludedep +bytestringsetup-changed

Dependencies added: base, basic-prelude, bytestring, chunked-data, conduit, conduit-combinators, hspec, mono-traversable, primitive, silently, system-fileio, system-filepath, text, transformers, transformers-base, vector

Files

+ Conduit.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE CPP #-}+-- | Your intended one-stop-shop for conduit functionality.+-- This re-exports functions from many commonly used modules.+-- When there is a conflict with standard functions, functions+-- in this module are disambiguated by adding a trailing C+-- (or for chunked functions, replacing a trailing E with EC).+-- This means that the Conduit module can be imported unqualified+-- without causing naming conflicts.+--+-- For more information on the naming scheme and intended usages of the+-- combinators, please see the "Data.Conduit.Combinators" documentation.+module Conduit+    ( -- * Core conduit library+      module Data.Conduit+    , module Data.Conduit.Util+#if MIN_VERSION_conduit(1, 0, 11)+    , module Data.Conduit.Lift+#endif+      -- * Commonly used combinators+    , module Data.Conduit.Combinators.Unqualified+      -- * Monadic lifting+    , MonadIO (..)+    , MonadTrans (..)+    , MonadBase (..)+      -- * Pure pipelines+    , Identity (..)+    ) where++import Data.Conduit+import Data.Conduit.Util hiding (zip)+import Control.Monad.IO.Class (MonadIO (..))+import Control.Monad.Trans.Class (MonadTrans (..))+import Control.Monad.Base (MonadBase (..))+#if MIN_VERSION_conduit(1, 0, 11)+import Data.Conduit.Lift+#endif+import Data.Conduit.Combinators.Unqualified+import Data.Functor.Identity (Identity (..))
+ Data/Conduit/Combinators.hs view
@@ -0,0 +1,1433 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses     #-}+{-# LANGUAGE NoImplicitPrelude         #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+-- | This module is meant as a replacement for Data.Conduit.List.+-- That module follows a naming scheme which was originally inspired+-- by its enumerator roots. This module is meant to introduce a naming+-- scheme which encourages conduit best practices.+--+-- There are two versions of functions in this module. Those with a trailing+-- E work in the individual elements of a chunk of data, e.g., the bytes of+-- a ByteString, the Chars of a Text, or the Ints of a Vector Int. Those+-- without a trailing E work on unchunked streams.+--+-- FIXME: discuss overall naming, usage of mono-traversable, etc+--+-- Mention take (Conduit) vs drop (Consumer)+module Data.Conduit.Combinators+    ( -- * Producers+      -- ** Pure+      yieldMany+    , unfold+    , enumFromTo+    , iterate+    , repeat+    , replicate+    , sourceLazy++      -- ** Monadic+    , repeatM+    , repeatWhileM+    , replicateM++      -- ** I\/O+    , sourceFile+    , sourceHandle+    , sourceIOHandle+    , stdin++      -- * Consumers+      -- ** Pure+    , drop+    , dropE+    , dropWhile+    , dropWhileE+    , fold+    , foldE+    , foldl+    , foldlE+    , foldMap+    , foldMapE+    , all+    , allE+    , any+    , anyE+    , and+    , andE+    , or+    , orE+    , elem+    , elemE+    , notElem+    , notElemE+    , sinkLazy+    , sinkList+    , sinkVector+    , sinkBuilder+    , sinkLazyBuilder+    , sinkNull+    , awaitNonNull+    , headE+    , peek+    , peekE+    , last+    , lastE+    , length+    , lengthE+    , maximum+    , maximumE+    , minimum+    , minimumE+    , null+    , nullE+    , sum+    , sumE+    , product+    , productE+    , find++      -- ** Monadic+    , mapM_+    , mapM_E+    , foldM+    , foldME+    , foldMapM+    , foldMapME++      -- ** I\/O+    , sinkFile+    , sinkHandle+    , sinkIOHandle+    , print+    , stdout+    , stderr++      -- * Transformers+      -- ** Pure+    , map+    , mapE+    , omapE+    , concatMap+    , concatMapE+    , take+    , takeE+    , takeWhile+    , takeWhileE+    , takeExactly+    , takeExactlyE+    , concat+    , filter+    , filterE+    , mapWhile+    , conduitVector+    , scanl+    , concatMapAccum+    , intersperse++      -- ** Monadic+    , mapM+    , mapME+    , omapME+    , concatMapM+    , filterM+    , filterME+    , iterM+    , scanlM+    , concatMapAccumM++      -- ** Textual+    , encodeUtf8+    , decodeUtf8+    , line+    , lineAscii+    , unlines+    , unlinesAscii+    , linesUnbounded+    , linesUnboundedAscii+    ) where++-- BEGIN IMPORTS++import Data.Builder+import qualified Data.NonNull as NonNull+import qualified Data.Traversable+import           Control.Applicative         ((<$>))+import           Control.Category            (Category (..))+import           Control.Monad               (unless, when, (>=>), liftM, forever)+import           Control.Monad.Base          (MonadBase (liftBase))+import           Control.Monad.IO.Class      (MonadIO (..))+import           Control.Monad.Primitive     (PrimMonad)+import           Control.Monad.Trans.Class   (lift)+import           Data.Conduit+import qualified Data.Conduit.List           as CL+import           Data.IOData+import           Data.Monoid                 (Monoid (..))+import           Data.MonoTraversable+import qualified Data.Sequences              as Seq+import           Data.Sequences.Lazy+import qualified Data.Vector.Generic         as V+import qualified Data.Vector.Generic.Mutable as VM+import qualified Filesystem                  as F+import           Filesystem.Path             (FilePath)+import           Prelude                     (Bool (..), Eq (..), Int,+                                              Maybe (..), Monad (..), Num (..),+                                              Ord (..), fromIntegral, maybe,+                                              ($), Functor (..), Enum, seq, Show, Char)+import Data.Word (Word8)+import qualified Prelude+import           System.IO                   (Handle)+import qualified System.IO                   as SIO+import qualified Data.Textual.Encoding as DTE+import qualified Data.Conduit.Text as CT+import Data.ByteString (ByteString)+import Data.Text (Text)++-- END IMPORTS++-- | Yield each of the values contained by the given @MonoFoldable@.+--+-- This will work on many data structures, including lists, @ByteString@s, and @Vector@s.+--+-- Since 1.0.0+yieldMany :: (Monad m, MonoFoldable mono)+          => mono+          -> Producer m (Element mono)+yieldMany = ofoldMap yield+{-# INLINE yieldMany #-}++-- | Generate a producer from a seed value.+--+-- Since 1.0.0+unfold :: Monad m+       => (b -> Maybe (a, b))+       -> b+       -> Producer m a+unfold = CL.unfold+{-# INLINE unfold #-}++-- | Enumerate from a value to a final value, inclusive, via 'succ'.+--+-- This is generally more efficient than using @Prelude@\'s @enumFromTo@ and+-- combining with @sourceList@ since this avoids any intermediate data+-- structures.+--+-- Since 1.0.0+enumFromTo :: (Monad m, Enum a, Eq a) => a -> a -> Producer m a+enumFromTo = CL.enumFromTo++-- | Produces an infinite stream of repeated applications of f to x.+--+-- Since 1.0.0+iterate :: Monad m => (a -> a) -> a -> Producer m a+iterate = CL.iterate+{-# INLINE iterate #-}++-- | Produce an infinite stream consisting entirely of the given value.+--+-- Since 1.0.0+repeat :: Monad m => a -> Producer m a+repeat = iterate id+{-# INLINE repeat #-}++-- | Produce a finite stream consisting of n copies of the given value.+--+-- Since 1.0.0+replicate :: Monad m+          => Int+          -> a+          -> Producer m a+replicate count0 a =+    loop count0+  where+    loop count = if count <= 0+        then return ()+        else yield a >> loop (count - 1)+{-# INLINE replicate #-}++-- | Generate a producer by yielding each of the strict chunks in a @LazySequence@.+--+-- For more information, see 'toChunks'.+--+-- Since 1.0.0+sourceLazy :: (Monad m, LazySequence lazy strict)+           => lazy+           -> Producer m strict+sourceLazy = yieldMany . toChunks+{-# INLINE sourceLazy #-}++-- | Repeatedly run the given action and yield all values it produces.+--+-- Since 1.0.0+repeatM :: Monad m+        => m a+        -> Producer m a+repeatM m = forever $ lift m >>= yield+{-# INLINE repeatM #-}++-- | Repeatedly run the given action and yield all values it produces, until+-- the provided predicate returns @False@.+--+-- Since 1.0.0+repeatWhileM :: Monad m+             => m a+             -> (a -> Bool)+             -> Producer m a+repeatWhileM m f =+    loop+  where+    loop = do+        x <- lift m+        when (f x) $ yield x >> loop++-- | Perform the given action n times, yielding each result.+--+-- Since 1.0.0+replicateM :: Monad m+           => Int+           -> m a+           -> Producer m a+replicateM count0 m =+    loop count0+  where+    loop count = if count <= 0+        then return ()+        else lift m >>= yield >> loop (count - 1)+{-# INLINE replicateM #-}++-- | Read all data from the given file.+--+-- This function automatically opens and closes the file handle, and ensures+-- exception safety via @MonadResource. It works for all instances of @IOData@,+-- including @ByteString@ and @Text@.+--+-- Since 1.0.0+sourceFile :: (MonadResource m, IOData a) => FilePath -> Producer m a+sourceFile fp = sourceIOHandle (F.openFile fp SIO.ReadMode)+{-# INLINE sourceFile #-}++-- | Read all data from the given @Handle@.+--+-- Does not close the @Handle@ at any point.+--+-- Since 1.0.0+sourceHandle :: (MonadIO m, IOData a) => Handle -> Producer m a+sourceHandle h =+    loop+  where+    loop = do+        x <- liftIO (hGetChunk h)+        if onull x+            then return ()+            else yield x >> loop+{-# INLINEABLE sourceHandle #-}++-- | Open a @Handle@ using the given function and stream data from it.+--+-- Automatically closes the file at completion.+--+-- Since 1.0.0+sourceIOHandle :: (MonadResource m, IOData a) => SIO.IO Handle -> Producer m a+sourceIOHandle alloc = bracketP alloc SIO.hClose sourceHandle+{-# INLINE sourceIOHandle #-}++-- | @sourceHandle@ applied to @stdin@.+--+-- Since 1.0.0+stdin :: (MonadIO m, IOData a) => Producer m a+stdin = sourceHandle SIO.stdin++-- | Ignore a certain number of values in the stream.+--+-- Since 1.0.0+drop :: Monad m+     => Int+     -> Consumer a m ()+drop =+    loop+  where+    loop i | i <= 0 = return ()+    loop count = await >>= maybe (return ()) (\_ -> loop (count - 1))+{-# INLINE drop #-}++-- | Drop a certain number of elements from a chunked stream.+--+-- Since 1.0.0+dropE :: (Monad m, Seq.IsSequence seq)+      => Seq.Index seq+      -> Consumer seq m ()+dropE =+    loop+  where+    loop i = if i <= 0+        then return ()+        else await >>= maybe (return ()) (go i)++    go i seq = do+        unless (onull y) $ leftover y+        loop i'+      where+        (x, y) = Seq.splitAt i seq+        i' = i - fromIntegral (olength x)+{-# INLINEABLE dropE #-}++-- | Drop all values which match the given predicate.+--+-- Since 1.0.0+dropWhile :: Monad m+          => (a -> Bool)+          -> Consumer a m ()+dropWhile f =+    loop+  where+    loop = await >>= maybe (return ()) go+    go x = if f x then loop else leftover x+{-# INLINE dropWhile #-}++-- | Drop all elements in the chunked stream which match the given predicate.+--+-- Since 1.0.0+dropWhileE :: (Monad m, Seq.IsSequence seq)+           => (Element seq -> Bool)+           -> Consumer seq m ()+dropWhileE f =+    loop+  where+    loop = await >>= maybe (return ()) go++    go seq =+        if onull x then loop else leftover x+      where+        x = Seq.dropWhile f seq+{-# INLINE dropWhileE #-}++-- | Monoidally combine all values in the stream.+--+-- Since 1.0.0+fold :: (Monad m, Monoid a)+     => Consumer a m a+fold = CL.foldMap id+{-# INLINE fold #-}++-- | Monoidally combine all elements in the chunked stream.+--+-- Since 1.0.0+foldE :: (Monad m, MonoFoldable mono, Monoid (Element mono))+      => Consumer mono m (Element mono)+foldE = CL.fold (\accum mono -> accum `mappend` ofoldMap id mono) mempty+{-# INLINE foldE #-}++-- | A strict left fold.+--+-- Since 1.0.0+foldl :: Monad m => (a -> b -> a) -> a -> Consumer b m a+foldl = CL.fold+{-# INLINE foldl #-}++-- | A strict left fold on a chunked stream.+--+-- Since 1.0.0+foldlE :: (Monad m, MonoFoldable mono)+       => (a -> Element mono -> a)+       -> a+       -> Consumer mono m a+foldlE f = CL.fold (ofoldl' f)+{-# INLINE foldlE #-}++-- | Apply the provided mapping function and monoidal combine all values.+--+-- Since 1.0.0+foldMap :: (Monad m, Monoid b)+        => (a -> b)+        -> Consumer a m b+foldMap = CL.foldMap+{-# INLINE foldMap #-}++-- | Apply the provided mapping function and monoidal combine all elements of the chunked stream.+--+-- Since 1.0.0+foldMapE :: (Monad m, MonoFoldable mono, Monoid w)+         => (Element mono -> w)+         -> Consumer mono m w+foldMapE = CL.foldMap . ofoldMap+{-# INLINE foldMapE #-}++-- | Check that all values in the stream return True.+--+-- Subject to shortcut logic: at the first False, consumption of the stream+-- will stop.+--+-- Since 1.0.0+all :: Monad m+    => (a -> Bool)+    -> Consumer a m Bool+all f =+    loop+  where+    loop = await >>= maybe (return True) go+    go x = if f x then loop else return False+{-# INLINE all #-}++-- | Check that all elements in the chunked stream return True.+--+-- Subject to shortcut logic: at the first False, consumption of the stream+-- will stop.+--+-- Since 1.0.0+allE :: (Monad m, MonoFoldable mono)+     => (Element mono -> Bool)+     -> Consumer mono m Bool+allE = all . oall++-- | Check that at least one value in the stream returns True.+--+-- Subject to shortcut logic: at the first True, consumption of the stream+-- will stop.+--+-- Since 1.0.0+any :: Monad m+    => (a -> Bool)+    -> Consumer a m Bool+any f =+    loop+  where+    loop = await >>= maybe (return False) go+    go x = if f x then return True else loop+{-# INLINE any #-}++-- | Check that at least one element in the chunked stream returns True.+--+-- Subject to shortcut logic: at the first True, consumption of the stream+-- will stop.+--+-- Since 1.0.0+anyE :: (Monad m, MonoFoldable mono)+     => (Element mono -> Bool)+     -> Consumer mono m Bool+anyE = any . oany++-- | Are all values in the stream True?+--+-- Consumption stops once the first False is encountered.+--+-- Since 1.0.0+and :: Monad m => Consumer Bool m Bool+and = all id+{-# INLINE and #-}++-- | Are all elements in the chunked stream True?+--+-- Consumption stops once the first False is encountered.+--+-- Since 1.0.0+andE :: (Monad m, MonoFoldable mono, Element mono ~ Bool)+     => Consumer mono m Bool+andE = allE id+{-# INLINE andE #-}++-- | Are any values in the stream True?+--+-- Consumption stops once the first True is encountered.+--+-- Since 1.0.0+or :: Monad m => Consumer Bool m Bool+or = any id+{-# INLINE or #-}++-- | Are any elements in the chunked stream True?+--+-- Consumption stops once the first True is encountered.+--+-- Since 1.0.0+orE :: (Monad m, MonoFoldable mono, Element mono ~ Bool)+    => Consumer mono m Bool+orE  = anyE id+{-# INLINE orE #-}++-- | Are any values in the stream equal to the given value?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+elem :: (Monad m, Eq a) => a -> Consumer a m Bool+elem x = any (== x)+{-# INLINE elem #-}++-- | Are any elements in the chunked stream equal to the given element?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+elemE :: (Monad m, Seq.EqSequence seq)+      => Element seq+      -> Consumer seq m Bool+elemE = any . Seq.elem++-- | Are no values in the stream equal to the given value?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+notElem :: (Monad m, Eq a) => a -> Consumer a m Bool+notElem x = all (/= x)+{-# INLINE notElem #-}++-- | Are no elements in the chunked stream equal to the given element?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+notElemE :: (Monad m, Seq.EqSequence seq)+         => Element seq+         -> Consumer seq m Bool+notElemE = all . Seq.notElem++-- | Consume all incoming strict chunks into a lazy sequence.+-- Note that the entirety of the sequence will be resident at memory.+--+-- This can be used to consume a stream of strict ByteStrings into a lazy+-- ByteString, for example.+--+-- Since 1.0.0+sinkLazy :: (Monad m, LazySequence lazy strict)+         => Consumer strict m lazy+sinkLazy = (fromChunks . ($ [])) <$> CL.fold (\front next -> front . (next:)) id+{-# INLINE sinkLazy #-}++-- | Consume all values from the stream and return as a list. Note that this+-- will pull all values into memory.+--+-- Since 1.0.0+sinkList :: Monad m => Consumer a m [a]+sinkList = CL.consume+{-# INLINE sinkList #-}++-- | Sink incoming values into a vector, up until size @maxSize@.  Subsequent+-- values will be left in the stream. If there are less than @maxSize@ values+-- present, returns a @Vector@ of smaller size.+--+-- Note that using this function is more memory efficient than @sinkList@ and+-- then converting to a @Vector@, as it avoids intermediate list constructors.+--+-- Since 1.0.0+sinkVector :: (MonadBase base m, V.Vector v a, PrimMonad base)+           => Int -- ^ maximum allowed size+           -> Consumer a m (v a)+sinkVector maxSize = do+    mv <- liftBase $ VM.new maxSize+    let go i | i >= maxSize = liftBase $ V.unsafeFreeze mv+        go i = do+            mx <- await+            case mx of+                Nothing -> V.slice 0 i <$> liftBase (V.unsafeFreeze mv)+                Just x -> do+                    liftBase $ VM.write mv i x+                    go (i + 1)+    go 0+{-# INLINEABLE sinkVector #-}++-- | Convert incoming values to a builder and fold together all builder values.+--+-- Defined as: @foldMap toBuilder@.+--+-- Since 1.0.0+sinkBuilder :: (Monad m, Monoid builder, ToBuilder a builder)+            => Consumer a m builder+sinkBuilder = foldMap toBuilder+{-# INLINE sinkBuilder #-}++-- | Same as @sinkBuilder@, but afterwards convert the builder to its lazy+-- representation.+--+-- Alternatively, this could be considered an alternative to @sinkLazy@, with+-- the following differences:+--+-- * This function will allow multiple input types, not just the strict version+-- of the lazy structure.+--+-- * Some buffer copying may occur in this version.+--+-- Since 1.0.0+sinkLazyBuilder :: (Monad m, Monoid builder, ToBuilder a builder, Builder builder lazy)+                => Consumer a m lazy+sinkLazyBuilder = fmap builderToLazy sinkBuilder+{-# INLINE sinkLazyBuilder #-}++-- | Consume and discard all remaining values in the stream.+--+-- Since 1.0.0+sinkNull :: Monad m => Consumer a m ()+sinkNull = CL.sinkNull+{-# INLINE sinkNull #-}++-- | Same as @await@, but discards any leading 'onull' values.+--+-- Since 1.0.0+awaitNonNull :: (Monad m, NonNull.NonNull b, a ~ NonNull.Nullable b) => Consumer a m (Maybe b)+awaitNonNull =+    go+  where+    go = await >>= maybe (return Nothing) go'++    go' = maybe go (return . Just) . NonNull.fromNullable+{-# INLINE awaitNonNull #-}++-- | Get the next element in the chunked stream.+--+-- Since 1.0.0+headE :: (Monad m, Seq.IsSequence seq) => Consumer seq m (Maybe (Element seq))+headE =+    loop+  where+    loop = await >>= maybe (return Nothing) go+    go x =+        case Seq.uncons x of+            Nothing -> loop+            Just (y, z) -> do+                unless (onull z) $ leftover z+                return $ Just y+{-# INLINE headE #-}++-- | View the next value in the stream without consuming it.+--+-- Since 1.0.0+peek :: Monad m => Consumer a m (Maybe a)+peek = CL.peek+{-# INLINE peek #-}++-- | View the next element in the chunked stream without consuming it.+--+-- Since 1.0.0+peekE :: (Monad m, MonoFoldable mono) => Consumer mono m (Maybe (Element mono))+peekE =+    loop+  where+    loop = await >>= maybe (return Nothing) go+    go x =+        case headMay x of+            Nothing -> loop+            Just y -> do+                leftover x+                return $ Just y+{-# INLINE peekE #-}++-- | Retrieve the last value in the stream, if present.+--+-- Since 1.0.0+last :: Monad m => Consumer a m (Maybe a)+last =+    await >>= maybe (return Nothing) loop+  where+    loop prev = await >>= maybe (return $ Just prev) loop+{-# INLINE last #-}++-- | Retrieve the last element in the chunked stream, if present.+--+-- Since 1.0.0+lastE :: (Monad m, Seq.IsSequence seq) => Consumer seq m (Maybe (Element seq))+lastE =+    awaitNonNull >>= maybe (return Nothing) (loop . NonNull.last . NonNull.asNotEmpty)+  where++    loop prev = awaitNonNull >>= maybe (return $ Just prev) (loop . NonNull.last . NonNull.asNotEmpty)+{-# INLINE lastE #-}++-- | Count how many values are in the stream.+--+-- Since 1.0.0+length :: (Monad m, Num len) => Consumer a m len+length = foldl (\x _ -> x + 1) 0+{-# INLINE length #-}++-- | Count how many elements are in the chunked stream.+--+-- Since 1.0.0+lengthE :: (Monad m, Num len, MonoFoldable mono) => Consumer mono m len+lengthE = foldl (\x y -> x + fromIntegral (olength y)) 0+{-# INLINE lengthE #-}++-- | Get the largest value in the stream, if present.+--+-- Since 1.0.0+maximum :: (Monad m, Ord a) => Consumer a m (Maybe a)+maximum =+    await >>= maybe (return Nothing) loop+  where+    loop prev = await >>= maybe (return $ Just prev) (loop . max prev)+{-# INLINE maximum #-}++-- | Get the largest element in the chunked stream, if present.+--+-- Since 1.0.0+maximumE :: (Monad m, Seq.OrdSequence seq) => Consumer seq m (Maybe (Element seq))+maximumE =+    start+  where+    start = await >>= maybe (return Nothing) start'+    start' x =+        case NonNull.fromNullable x of+            Nothing -> start+            Just y -> loop $ NonNull.maximum $ NonNull.asNotEmpty y+    loop prev = await >>= maybe (return $ Just prev) (loop . ofoldl' max prev)+{-# INLINE maximumE #-}++-- | Get the smallest value in the stream, if present.+--+-- Since 1.0.0+minimum :: (Monad m, Ord a) => Consumer a m (Maybe a)+minimum =+    await >>= maybe (return Nothing) loop+  where+    loop prev = await >>= maybe (return $ Just prev) (loop . min prev)+{-# INLINE minimum #-}++-- | Get the smallest element in the chunked stream, if present.+--+-- Since 1.0.0+minimumE :: (Monad m, Seq.OrdSequence seq) => Consumer seq m (Maybe (Element seq))+minimumE =+    start+  where+    start = await >>= maybe (return Nothing) start'+    start' x =+        case NonNull.fromNullable x of+            Nothing -> start+            Just y -> loop $ NonNull.minimum $ NonNull.asNotEmpty y+    loop prev = await >>= maybe (return $ Just prev) (loop . ofoldl' min prev)+{-# INLINE minimumE #-}++-- | True if there are no values in the stream.+--+-- This function does not modify the stream.+--+-- Since 1.0.0+null :: Monad m => Consumer a m Bool+null = (maybe True (\_ -> False)) `fmap` peek+{-# INLINE null #-}++-- | True if there are no elements in the chunked stream.+--+-- This function may remove empty leading chunks from the stream, but otherwise+-- will not modify it.+--+-- Since 1.0.0+nullE :: (Monad m, MonoFoldable mono)+      => Consumer mono m Bool+nullE =+    go+  where+    go = await >>= maybe (return True) go'+    go' x = if onull x then go else leftover x >> return False+{-# INLINE nullE #-}++-- | Get the sum of all values in the stream.+--+-- Since 1.0.0+sum :: (Monad m, Num a) => Consumer a m a+sum = foldl (+) 0+{-# INLINE sum #-}++-- | Get the sum of all elements in the chunked stream.+--+-- Since 1.0.0+sumE :: (Monad m, MonoFoldable mono, Num (Element mono)) => Consumer mono m (Element mono)+sumE = foldlE (+) 0+{-# INLINE sumE #-}++-- | Get the product of all values in the stream.+--+-- Since 1.0.0+product :: (Monad m, Num a) => Consumer a m a+product = foldl (*) 1+{-# INLINE product #-}++-- | Get the product of all elements in the chunked stream.+--+-- Since 1.0.0+productE :: (Monad m, MonoFoldable mono, Num (Element mono)) => Consumer mono m (Element mono)+productE = foldlE (*) 1+{-# INLINE productE #-}++-- | Find the first matching value.+--+-- Since 1.0.0+find :: Monad m => (a -> Bool) -> Consumer a m (Maybe a)+find f =+    loop+  where+    loop = await >>= maybe (return Nothing) go+    go x = if f x then return (Just x) else loop++-- | Apply the action to all values in the stream.+--+-- Since 1.0.0+mapM_ :: Monad m => (a -> m ()) -> Consumer a m ()+mapM_ = CL.mapM_+{-# INLINE mapM_ #-}++-- | Apply the action to all elements in the chunked stream.+--+-- Since 1.0.0+mapM_E :: (Monad m, MonoFoldable mono) => (Element mono -> m ()) -> Consumer mono m ()+mapM_E = CL.mapM_ . omapM_+{-# INLINE mapM_E #-}++-- | A monadic strict left fold.+--+-- Since 1.0.0+foldM :: Monad m => (a -> b -> m a) -> a -> Consumer b m a+foldM = CL.foldM+{-# INLINE foldM #-}++-- | A monadic strict left fold on a chunked stream.+--+-- Since 1.0.0+foldME :: (Monad m, MonoFoldable mono)+       => (a -> Element mono -> m a)+       -> a+       -> Consumer mono m a+foldME f = foldM (ofoldlM f)+{-# INLINE foldME #-}++-- | Apply the provided monadic mapping function and monoidal combine all values.+--+-- Since 1.0.0+foldMapM :: (Monad m, Monoid w) => (a -> m w) -> Consumer a m w+foldMapM = CL.foldMapM+{-# INLINE foldMapM #-}++-- | Apply the provided monadic mapping function and monoidal combine all+-- elements in the chunked stream.+--+-- Since 1.0.0+foldMapME :: (Monad m, MonoFoldable mono, Monoid w)+          => (Element mono -> m w)+          -> Consumer mono m w+foldMapME f =+    CL.foldM go mempty+  where+    go = ofoldlM (\accum e -> mappend accum `liftM` f e)+{-# INLINE foldMapME #-}++-- | Write all data to the given file.+--+-- This function automatically opens and closes the file handle, and ensures+-- exception safety via @MonadResource. It works for all instances of @IOData@,+-- including @ByteString@ and @Text@.+--+-- Since 1.0.0+sinkFile :: (MonadResource m, IOData a) => FilePath -> Consumer a m ()+sinkFile fp = sinkIOHandle (F.openFile fp SIO.WriteMode)+{-# INLINE sinkFile #-}++-- | Print all incoming values to stdout.+--+-- Since 1.0.0+print :: (Show a, MonadIO m) => Consumer a m ()+print = mapM_ (liftIO . Prelude.print)++-- | @sinkHandle@ applied to @stdout@.+--+-- Since 1.0.0+stdout :: (MonadIO m, IOData a) => Consumer a m ()+stdout = sinkHandle SIO.stdout++-- | @sinkHandle@ applied to @stderr@.+--+-- Since 1.0.0+stderr :: (MonadIO m, IOData a) => Consumer a m ()+stderr = sinkHandle SIO.stderr++-- | Write all data to the given @Handle@.+--+-- Does not close the @Handle@ at any point.+--+-- Since 1.0.0+sinkHandle :: (MonadIO m, IOData a) => Handle -> Consumer a m ()+sinkHandle = CL.mapM_ . hPut+{-# INLINE sinkHandle #-}++-- | Open a @Handle@ using the given function and stream data to it.+--+-- Automatically closes the file at completion.+--+-- Since 1.0.0+sinkIOHandle :: (MonadResource m, IOData a) => SIO.IO Handle -> Consumer a m ()+sinkIOHandle alloc = bracketP alloc SIO.hClose sinkHandle+{-# INLINE sinkIOHandle #-}++-- | Apply a transformation to all values in a stream.+--+-- Since 1.0.0+map :: Monad m => (a -> b) -> Conduit a m b+map = CL.map+{-# INLINE map #-}++-- | Apply a transformation to all elements in a chunked stream.+--+-- Since 1.0.0+mapE :: (Monad m, Functor f) => (a -> b) -> Conduit (f a) m (f b)+mapE = CL.map . fmap+{-# INLINE mapE #-}++-- | Apply a monomorphic transformation to all elements in a chunked stream.+--+-- Unlike @mapE@, this will work on types like @ByteString@ and @Text@ which+-- are @MonoFunctor@ but not @Functor@.+--+-- Since 1.0.0+omapE :: (Monad m, MonoFunctor mono) => (Element mono -> Element mono) -> Conduit mono m mono+omapE = CL.map . omap+{-# INLINE omapE #-}++-- | Apply the function to each value in the stream, resulting in a foldable+-- value (e.g., a list). Then yield each of the individual values in that+-- foldable value separately.+--+-- Generalizes concatMap, mapMaybe, and mapFoldable.+--+-- Since 1.0.0+concatMap :: (Monad m, MonoFoldable mono)+          => (a -> mono)+          -> Conduit a m (Element mono)+concatMap f = awaitForever (yieldMany . f)+{-# INLINE concatMap #-}++-- | Apply the function to each element in the chunked stream, resulting in a+-- foldable value (e.g., a list). Then yield each of the individual values in+-- that foldable value separately.+--+-- Generalizes concatMap, mapMaybe, and mapFoldable.+--+-- Since 1.0.0+concatMapE :: (Monad m, MonoFoldable mono, Monoid w)+           => (Element mono -> w)+           -> Conduit mono m w+concatMapE = CL.map . ofoldMap+{-# INLINE concatMapE #-}++-- | Stream up to n number of values downstream.+--+-- Note that, if downstream terminates early, not all values will be consumed.+-- If you want to force /exactly/ the given number of values to be consumed,+-- see 'takeExactly'.+--+-- Since 1.0.0+take :: Monad m => Int -> Conduit a m a+take =+    loop+  where+    loop count = if count <= 0+        then return ()+        else await >>= maybe (return ()) (\i -> yield i >> loop (count - 1))+{-# INLINE take #-}++-- | Stream up to n number of elements downstream in a chunked stream.+--+-- Note that, if downstream terminates early, not all values will be consumed.+-- If you want to force /exactly/ the given number of values to be consumed,+-- see 'takeExactlyE'.+--+-- Since 1.0.0+takeE :: (Monad m, Seq.IsSequence seq)+      => Seq.Index seq+      -> Conduit seq m seq+takeE =+    loop+  where+    loop i = if i <= 0+        then return ()+        else await >>= maybe (return ()) (go i)++    go i seq = do+        unless (onull x) $ yield x+        unless (onull y) $ leftover y+        loop i'+      where+        (x, y) = Seq.splitAt i seq+        i' = i - fromIntegral (olength x)+{-# INLINEABLE takeE #-}++-- | Stream all values downstream that match the given predicate.+--+-- Same caveats regarding downstream termination apply as with 'take'.+--+-- Since 1.0.0+takeWhile :: Monad m+          => (a -> Bool)+          -> Conduit a m a+takeWhile f =+    loop+  where+    loop = await >>= maybe (return ()) go+    go x = if f x+        then yield x >> loop+        else leftover x+{-# INLINE takeWhile #-}++-- | Stream all elements downstream that match the given predicate in a chunked stream.+--+-- Same caveats regarding downstream termination apply as with 'takeE'.+--+-- Since 1.0.0+takeWhileE :: (Monad m, Seq.IsSequence seq)+           => (Element seq -> Bool)+           -> Conduit seq m seq+takeWhileE f =+    loop+  where+    loop = await >>= maybe (return ()) go++    go seq = do+        unless (onull x) $ yield x+        if onull y+            then loop+            else leftover y+      where+        (x, y) = Seq.span f seq+{-# INLINE takeWhileE #-}++-- | Consume precisely the given number of values and feed them downstream.+--+-- This function is in contrast to 'take', which will only consume up to the+-- given number of values, and will terminate early if downstream terminates+-- early. This function will discard any additional values in the stream if+-- they are unconsumed.+--+-- Note that this function takes a downstream @ConduitM@ as a parameter, as+-- opposed to working with normal fusion. For more information, see+-- <http://www.yesodweb.com/blog/2013/10/core-flaw-pipes-conduit>, the section+-- titled \"pipes and conduit: isolate\".+--+-- Since 1.0.0+takeExactly :: Monad m+            => Int+            -> ConduitM a b m r+            -> ConduitM a b m r+takeExactly count inner = take count =$= do+    r <- inner+    CL.sinkNull+    return r+{-# INLINE takeExactly #-}++-- | Same as 'takeExactly', but for chunked streams.+--+-- Since 1.0.0+takeExactlyE :: (Monad m, Seq.IsSequence a)+             => Seq.Index a+             -> ConduitM a b m r+             -> ConduitM a b m r+takeExactlyE count inner = takeE count =$= do+    r <- inner+    CL.sinkNull+    return r+{-# INLINE takeExactlyE #-}++-- | Flatten out a stream by yielding the values contained in an incoming+-- @MonoFoldable@ as individually yielded values.+--+-- Since 1.0.0+concat :: (Monad m, MonoFoldable mono)+       => Conduit mono m (Element mono)+concat = awaitForever yieldMany+{-# INLINE concat #-}++-- | Keep only values in the stream passing a given predicate.+--+-- Since 1.0.0+filter :: Monad m => (a -> Bool) -> Conduit a m a+filter = CL.filter+{-# INLINE filter #-}++-- | Keep only elements in the chunked stream passing a given predicate.+--+-- Since 1.0.0+filterE :: (Seq.IsSequence seq, Monad m) => (Element seq -> Bool) -> Conduit seq m seq+filterE = CL.map . Seq.filter+{-# INLINE filterE #-}++-- | Map values as long as the result is @Just@.+--+-- Since 1.0.0+mapWhile :: Monad m => (a -> Maybe b) -> Conduit a m b+mapWhile f =+    loop+  where+    loop = await >>= maybe (return ()) go+    go x =+        case f x of+            Just y -> yield y >> loop+            Nothing -> leftover x+{-# INLINE mapWhile #-}++-- | Break up a stream of values into vectors of size n. The final vector may+-- be smaller than n if the total number of values is not a strict multiple of+-- n. No empty vectors will be yielded.+--+-- Since 1.0.0+conduitVector :: (MonadBase base m, V.Vector v a, PrimMonad base)+              => Int -- ^ maximum allowed size+              -> Conduit a m (v a)+conduitVector size =+    loop+  where+    loop = do+        v <- sinkVector size+        unless (V.null v) $ do+            yield v+            loop+{-# INLINE conduitVector #-}++-- | Analog of 'Prelude.scanl' for lists.+--+-- Since 1.0.6+scanl :: Monad m => (a -> b -> a) -> a -> Conduit b m a+scanl f =+    loop+  where+    loop seed =+        await >>= maybe (yield seed) go+      where+        go b = do+            let seed' = f seed b+            seed' `seq` yield seed+            loop seed'+{-# INLINE scanl #-}++-- | 'concatMap' with an accumulator.+--+-- Since 1.0.0+concatMapAccum :: Monad m => (a -> accum -> (accum, [b])) -> accum -> Conduit a m b+concatMapAccum = CL.concatMapAccum+{-# INLINE concatMapAccum #-}++-- | Insert the given value between each two values in the stream.+--+-- Since 1.0.0+intersperse :: Monad m => a -> Conduit a m a+intersperse x =+    await >>= omapM_ go+  where+    go y = yield y >> concatMap (\z -> [x, z])+{-# INLINE intersperse #-}++-- | Apply a monadic transformation to all values in a stream.+--+-- If you do not need the transformed values, and instead just want the monadic+-- side-effects of running the action, see 'mapM_'.+--+-- Since 1.0.0+mapM :: Monad m => (a -> m b) -> Conduit a m b+mapM = CL.mapM+{-# INLINE mapM #-}++-- | Apply a monadic transformation to all elements in a chunked stream.+--+-- Since 1.0.0+mapME :: (Monad m, Data.Traversable.Traversable f) => (a -> m b) -> Conduit (f a) m (f b)+mapME = CL.mapM . Data.Traversable.mapM+{-# INLINE mapME #-}++-- | Apply a monadic monomorphic transformation to all elements in a chunked stream.+--+-- Unlike @mapME@, this will work on types like @ByteString@ and @Text@ which+-- are @MonoFunctor@ but not @Functor@.+--+-- Since 1.0.0+omapME :: (Monad m, MonoTraversable mono)+       => (Element mono -> m (Element mono))+       -> Conduit mono m mono+omapME = CL.mapM . omapM+{-# INLINE omapME #-}++-- | Apply the monadic function to each value in the stream, resulting in a+-- foldable value (e.g., a list). Then yield each of the individual values in+-- that foldable value separately.+--+-- Generalizes concatMapM, mapMaybeM, and mapFoldableM.+--+-- Since 1.0.0+concatMapM :: (Monad m, MonoFoldable mono)+           => (a -> m mono)+           -> Conduit a m (Element mono)+concatMapM f = awaitForever (lift . f >=> yieldMany)+{-# INLINE concatMapM #-}++-- | Keep only values in the stream passing a given monadic predicate.+--+-- Since 1.0.0+filterM :: Monad m+        => (a -> m Bool)+        -> Conduit a m a+filterM f =+    awaitForever go+  where+    go x = do+        b <- lift $ f x+        when b $ yield x+{-# INLINE filterM #-}++-- | Keep only elements in the chunked stream passing a given monadic predicate.+--+-- Since 1.0.0+filterME :: (Monad m, Seq.IsSequence seq) => (Element seq -> m Bool) -> Conduit seq m seq+filterME = CL.mapM . Seq.filterM+{-# INLINE filterME #-}++-- | Apply a monadic action on all values in a stream.+--+-- This @Conduit@ can be used to perform a monadic side-effect for every+-- value, whilst passing the value through the @Conduit@ as-is.+--+-- > iterM f = mapM (\a -> f a >>= \() -> return a)+--+-- Since 1.0.0+iterM :: Monad m => (a -> m ()) -> Conduit a m a+iterM = CL.iterM++-- | Analog of 'Prelude.scanl' for lists, monadic.+--+-- Since 1.0.6+scanlM :: Monad m => (a -> b -> m a) -> a -> Conduit b m a+scanlM f =+    loop+  where+    loop seed =+        await >>= maybe (yield seed) go+      where+        go b = do+            seed' <- lift $ f seed b+            seed' `seq` yield seed+            loop seed'+{-# INLINE scanlM #-}++-- | 'concatMapM' with an accumulator.+--+-- Since 1.0.0+concatMapAccumM :: Monad m => (a -> accum -> m (accum, [b])) -> accum -> Conduit a m b+concatMapAccumM = CL.concatMapAccumM+{-# INLINE concatMapAccumM #-}++-- | Encode a stream of text as UTF8.+--+-- Since 1.0.0+encodeUtf8 :: (Monad m, DTE.Utf8 text binary) => Conduit text m binary+encodeUtf8 = map DTE.encodeUtf8++-- | Decode a stream of binary data as UTF8.+--+-- Since 1.0.0+decodeUtf8 :: MonadThrow m => Conduit ByteString m Text+decodeUtf8 = CT.decode CT.utf8++-- | Stream in the entirety of a single line.+--+-- Like @takeExactly@, this will consume the entirety of the line regardless of+-- the behavior of the inner Conduit.+--+-- Since 1.0.0+line :: (Monad m, Seq.IsSequence seq, Element seq ~ Char)+     => ConduitM seq o m r+     -> ConduitM seq o m r+line inner = do+    loop =$= do+        x <- inner+        sinkNull+        return x+  where+    loop = await >>= omapM_ go+    go t =+        if onull y+            then yield x >> loop+            else do+                unless (onull x) $ yield x+                let y' = Seq.drop 1 y+                unless (onull y') $ leftover y'+      where+        (x, y) = Seq.break (== '\n') t+{-# INLINE line #-}++-- | Same as 'line', but operates on ASCII/binary data.+--+-- Since 1.0.0+lineAscii :: (Monad m, Seq.IsSequence seq, Element seq ~ Word8)+          => ConduitM seq o m r+          -> ConduitM seq o m r+lineAscii inner =+    loop =$= do+        x <- inner+        sinkNull+        return x+  where+    loop = await >>= omapM_ go+    go t =+        if onull y+            then yield x >> loop+            else do+                unless (onull x) $ yield x+                let y' = Seq.drop 1 y+                unless (onull y') $ leftover y'+      where+        (x, y) = Seq.break (== 10) t+{-# INLINE lineAscii #-}++-- | Insert a newline character after each incoming chunk of data.+--+-- Since 1.0.0+unlines :: (Monad m, Seq.IsSequence seq, Element seq ~ Char) => Conduit seq m seq+unlines = concatMap (:[Seq.singleton '\n'])+{-# INLINE unlines #-}++-- | Same as 'unlines', but operates on ASCII/binary data.+--+-- Since 1.0.0+unlinesAscii :: (Monad m, Seq.IsSequence seq, Element seq ~ Word8) => Conduit seq m seq+unlinesAscii = concatMap (:[Seq.singleton 10])+{-# INLINE unlinesAscii #-}++-- | Convert a stream of arbitrarily-chunked textual data into a stream of data+-- where each chunk represents a single line. Note that, if you have+-- unknown/untrusted input, this function is /unsafe/, since it would allow an+-- attacker to form lines of massive length and exhaust memory.+--+-- Since 1.0.0+linesUnbounded :: (Monad m, Seq.IsSequence seq, Element seq ~ Char)+               => Conduit seq m seq+linesUnbounded =+    start+  where+    start = await >>= maybe (return ()) loop++    loop t =+        if onull y+            then do+                mt <- await+                case mt of+                    Nothing -> unless (onull t) $ yield t+                    Just t' -> loop (t `mappend` t')+            else yield x >> loop (Seq.drop 1 y)+      where+        (x, y) = Seq.break (== '\n') t++-- | Same as 'linesUnbounded', but for ASCII/binary data.+--+-- Since 1.0.0+linesUnboundedAscii :: (Monad m, Seq.IsSequence seq, Element seq ~ Word8)+                    => Conduit seq m seq+linesUnboundedAscii =+    start+  where+    start = await >>= maybe (return ()) loop++    loop t =+        if onull y+            then do+                mt <- await+                case mt of+                    Nothing -> unless (onull t) $ yield t+                    Just t' -> loop (t `mappend` t')+            else yield x >> loop (Seq.drop 1 y)+      where+        (x, y) = Seq.break (== 10) t
+ Data/Conduit/Combinators/Unqualified.hs view
@@ -0,0 +1,1172 @@+-- WARNING: This module is autogenerated+{-# OPTIONS_HADDOCK not-home #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE MultiParamTypeClasses     #-}+{-# LANGUAGE NoImplicitPrelude         #-}+{-# LANGUAGE NoMonomorphismRestriction #-}+module Data.Conduit.Combinators.Unqualified+    ( -- ** Producers+      -- *** Pure+      yieldMany+    , unfoldC+    , enumFromToC+    , iterateC+    , repeatC+    , replicateC+    , sourceLazy++      -- *** Monadic+    , repeatMC+    , repeatWhileMC+    , replicateMC++      -- *** I\/O+    , sourceFile+    , sourceHandle+    , sourceIOHandle+    , stdinC++      -- ** Consumers+      -- *** Pure+    , dropC+    , dropCE+    , dropWhileC+    , dropWhileCE+    , foldC+    , foldCE+    , foldlC+    , foldlCE+    , foldMapC+    , foldMapCE+    , allC+    , allCE+    , anyC+    , anyCE+    , andC+    , andCE+    , orC+    , orCE+    , elemC+    , elemCE+    , notElemC+    , notElemCE+    , sinkLazy+    , sinkList+    , sinkVector+    , sinkBuilder+    , sinkLazyBuilder+    , sinkNull+    , awaitNonNull+    , headCE+    , peekC+    , peekCE+    , lastC+    , lastCE+    , lengthC+    , lengthCE+    , maximumC+    , maximumCE+    , minimumC+    , minimumCE+    , nullC+    , nullCE+    , sumC+    , sumCE+    , productC+    , productCE+    , findC++      -- *** Monadic+    , mapM_C+    , mapM_CE+    , foldMC+    , foldMCE+    , foldMapMC+    , foldMapMCE++      -- *** I\/O+    , sinkFile+    , sinkHandle+    , sinkIOHandle+    , printC+    , stdoutC+    , stderrC++      -- ** Transformers+      -- *** Pure+    , mapC+    , mapCE+    , omapCE+    , concatMapC+    , concatMapCE+    , takeC+    , takeCE+    , takeWhileC+    , takeWhileCE+    , takeExactlyC+    , takeExactlyCE+    , concatC+    , filterC+    , filterCE+    , mapWhileC+    , conduitVector+    , scanlC+    , concatMapAccumC+    , intersperseC++      -- *** Monadic+    , mapMC+    , mapMCE+    , omapMCE+    , concatMapMC+    , filterMC+    , filterMCE+    , iterMC+    , scanlMC+    , concatMapAccumMC++      -- *** Textual+    , encodeUtf8C+    , decodeUtf8C+    , lineC+    , lineAsciiC+    , unlinesC+    , unlinesAsciiC+    , linesUnboundedC+    , linesUnboundedAsciiC+    ) where++-- BEGIN IMPORTS++import qualified Data.Conduit.Combinators as CC+-- BEGIN IMPORTS++import Data.Builder+import qualified Data.NonNull as NonNull+import qualified Data.Traversable+import           Control.Applicative         ((<$>))+import           Control.Category            (Category (..))+import           Control.Monad               (unless, when, (>=>), liftM, forever)+import           Control.Monad.Base          (MonadBase (liftBase))+import           Control.Monad.IO.Class      (MonadIO (..))+import           Control.Monad.Primitive     (PrimMonad)+import           Control.Monad.Trans.Class   (lift)+import           Data.Conduit+import qualified Data.Conduit.List           as CL+import           Data.IOData+import           Data.Monoid                 (Monoid (..))+import           Data.MonoTraversable+import qualified Data.Sequences              as Seq+import           Data.Sequences.Lazy+import qualified Data.Vector.Generic         as V+import qualified Data.Vector.Generic.Mutable as VM+import qualified Filesystem                  as F+import           Filesystem.Path             (FilePath)+import           Prelude                     (Bool (..), Eq (..), Int,+                                              Maybe (..), Monad (..), Num (..),+                                              Ord (..), fromIntegral, maybe,+                                              ($), Functor (..), Enum, seq, Show, Char)+import Data.Word (Word8)+import qualified Prelude+import           System.IO                   (Handle)+import qualified System.IO                   as SIO+import qualified Data.Textual.Encoding as DTE+import qualified Data.Conduit.Text as CT+import Data.ByteString (ByteString)+import Data.Text (Text)+++-- END IMPORTS++-- | Yield each of the values contained by the given @MonoFoldable@.+--+-- This will work on many data structures, including lists, @ByteString@s, and @Vector@s.+--+-- Since 1.0.0+yieldMany :: (Monad m, MonoFoldable mono)+          => mono+          -> Producer m (Element mono)+yieldMany = CC.yieldMany+{-# INLINE yieldMany #-}++-- | Generate a producer from a seed value.+--+-- Since 1.0.0+unfoldC :: Monad m+       => (b -> Maybe (a, b))+       -> b+       -> Producer m a+unfoldC = CC.unfold+{-# INLINE unfoldC #-}++-- | Enumerate from a value to a final value, inclusive, via 'succ'.+--+-- This is generally more efficient than using @Prelude@\'s @enumFromTo@ and+-- combining with @sourceList@ since this avoids any intermediate data+-- structures.+--+-- Since 1.0.0+enumFromToC :: (Monad m, Enum a, Eq a) => a -> a -> Producer m a+enumFromToC = CC.enumFromTo+{-# INLINE enumFromToC #-}++-- | Produces an infinite stream of repeated applications of f to x.+--+-- Since 1.0.0+iterateC :: Monad m => (a -> a) -> a -> Producer m a+iterateC = CC.iterate+{-# INLINE iterateC #-}++-- | Produce an infinite stream consisting entirely of the given value.+--+-- Since 1.0.0+repeatC :: Monad m => a -> Producer m a+repeatC = CC.repeat+{-# INLINE repeatC #-}++-- | Produce a finite stream consisting of n copies of the given value.+--+-- Since 1.0.0+replicateC :: Monad m+          => Int+          -> a+          -> Producer m a+replicateC = CC.replicate+{-# INLINE replicateC #-}++-- | Generate a producer by yielding each of the strict chunks in a @LazySequence@.+--+-- For more information, see 'toChunks'.+--+-- Since 1.0.0+sourceLazy :: (Monad m, LazySequence lazy strict)+           => lazy+           -> Producer m strict+sourceLazy = CC.sourceLazy+{-# INLINE sourceLazy #-}++-- | Repeatedly run the given action and yield all values it produces.+--+-- Since 1.0.0+repeatMC :: Monad m+        => m a+        -> Producer m a+repeatMC = CC.repeatM+{-# INLINE repeatMC #-}++-- | Repeatedly run the given action and yield all values it produces, until+-- the provided predicate returns @False@.+--+-- Since 1.0.0+repeatWhileMC :: Monad m+             => m a+             -> (a -> Bool)+             -> Producer m a+repeatWhileMC = CC.repeatWhileM+{-# INLINE repeatWhileMC #-}++-- | Perform the given action n times, yielding each result.+--+-- Since 1.0.0+replicateMC :: Monad m+           => Int+           -> m a+           -> Producer m a+replicateMC = CC.replicateM+{-# INLINE replicateMC #-}++-- | Read all data from the given file.+--+-- This function automatically opens and closes the file handle, and ensures+-- exception safety via @MonadResource. It works for all instances of @IOData@,+-- including @ByteString@ and @Text@.+--+-- Since 1.0.0+sourceFile :: (MonadResource m, IOData a) => FilePath -> Producer m a+sourceFile = CC.sourceFile+{-# INLINE sourceFile #-}++-- | Read all data from the given @Handle@.+--+-- Does not close the @Handle@ at any point.+--+-- Since 1.0.0+sourceHandle :: (MonadIO m, IOData a) => Handle -> Producer m a+sourceHandle = CC.sourceHandle+{-# INLINE sourceHandle #-}++-- | Open a @Handle@ using the given function and stream data from it.+--+-- Automatically closes the file at completion.+--+-- Since 1.0.0+sourceIOHandle :: (MonadResource m, IOData a) => SIO.IO Handle -> Producer m a+sourceIOHandle = CC.sourceIOHandle+{-# INLINE sourceIOHandle #-}++-- | @sourceHandle@ applied to @stdin@.+--+-- Since 1.0.0+stdinC :: (MonadIO m, IOData a) => Producer m a+stdinC = CC.stdin+{-# INLINE stdinC #-}++-- | Ignore a certain number of values in the stream.+--+-- Since 1.0.0+dropC :: Monad m+     => Int+     -> Consumer a m ()+dropC = CC.drop+{-# INLINE dropC #-}++-- | Drop a certain number of elements from a chunked stream.+--+-- Since 1.0.0+dropCE :: (Monad m, Seq.IsSequence seq)+      => Seq.Index seq+      -> Consumer seq m ()+dropCE = CC.dropE+{-# INLINE dropCE #-}++-- | Drop all values which match the given predicate.+--+-- Since 1.0.0+dropWhileC :: Monad m+          => (a -> Bool)+          -> Consumer a m ()+dropWhileC = CC.dropWhile+{-# INLINE dropWhileC #-}++-- | Drop all elements in the chunked stream which match the given predicate.+--+-- Since 1.0.0+dropWhileCE :: (Monad m, Seq.IsSequence seq)+           => (Element seq -> Bool)+           -> Consumer seq m ()+dropWhileCE = CC.dropWhileE+{-# INLINE dropWhileCE #-}++-- | Monoidally combine all values in the stream.+--+-- Since 1.0.0+foldC :: (Monad m, Monoid a)+     => Consumer a m a+foldC = CC.fold+{-# INLINE foldC #-}++-- | Monoidally combine all elements in the chunked stream.+--+-- Since 1.0.0+foldCE :: (Monad m, MonoFoldable mono, Monoid (Element mono))+      => Consumer mono m (Element mono)+foldCE = CC.foldE+{-# INLINE foldCE #-}++-- | A strict left fold.+--+-- Since 1.0.0+foldlC :: Monad m => (a -> b -> a) -> a -> Consumer b m a+foldlC = CC.foldl+{-# INLINE foldlC #-}++-- | A strict left fold on a chunked stream.+--+-- Since 1.0.0+foldlCE :: (Monad m, MonoFoldable mono)+       => (a -> Element mono -> a)+       -> a+       -> Consumer mono m a+foldlCE = CC.foldlE+{-# INLINE foldlCE #-}++-- | Apply the provided mapping function and monoidal combine all values.+--+-- Since 1.0.0+foldMapC :: (Monad m, Monoid b)+        => (a -> b)+        -> Consumer a m b+foldMapC = CC.foldMap+{-# INLINE foldMapC #-}++-- | Apply the provided mapping function and monoidal combine all elements of the chunked stream.+--+-- Since 1.0.0+foldMapCE :: (Monad m, MonoFoldable mono, Monoid w)+         => (Element mono -> w)+         -> Consumer mono m w+foldMapCE = CC.foldMapE+{-# INLINE foldMapCE #-}++-- | Check that all values in the stream return True.+--+-- Subject to shortcut logic: at the first False, consumption of the stream+-- will stop.+--+-- Since 1.0.0+allC :: Monad m+    => (a -> Bool)+    -> Consumer a m Bool+allC = CC.all+{-# INLINE allC #-}++-- | Check that all elements in the chunked stream return True.+--+-- Subject to shortcut logic: at the first False, consumption of the stream+-- will stop.+--+-- Since 1.0.0+allCE :: (Monad m, MonoFoldable mono)+     => (Element mono -> Bool)+     -> Consumer mono m Bool+allCE = CC.allE+{-# INLINE allCE #-}++-- | Check that at least one value in the stream returns True.+--+-- Subject to shortcut logic: at the first True, consumption of the stream+-- will stop.+--+-- Since 1.0.0+anyC :: Monad m+    => (a -> Bool)+    -> Consumer a m Bool+anyC = CC.any+{-# INLINE anyC #-}++-- | Check that at least one element in the chunked stream returns True.+--+-- Subject to shortcut logic: at the first True, consumption of the stream+-- will stop.+--+-- Since 1.0.0+anyCE :: (Monad m, MonoFoldable mono)+     => (Element mono -> Bool)+     -> Consumer mono m Bool+anyCE = CC.anyE+{-# INLINE anyCE #-}++-- | Are all values in the stream True?+--+-- Consumption stops once the first False is encountered.+--+-- Since 1.0.0+andC :: Monad m => Consumer Bool m Bool+andC = CC.and+{-# INLINE andC #-}++-- | Are all elements in the chunked stream True?+--+-- Consumption stops once the first False is encountered.+--+-- Since 1.0.0+andCE :: (Monad m, MonoFoldable mono, Element mono ~ Bool)+     => Consumer mono m Bool+andCE = CC.andE+{-# INLINE andCE #-}++-- | Are any values in the stream True?+--+-- Consumption stops once the first True is encountered.+--+-- Since 1.0.0+orC :: Monad m => Consumer Bool m Bool+orC = CC.or+{-# INLINE orC #-}++-- | Are any elements in the chunked stream True?+--+-- Consumption stops once the first True is encountered.+--+-- Since 1.0.0+orCE :: (Monad m, MonoFoldable mono, Element mono ~ Bool)+    => Consumer mono m Bool+orCE = CC.orE+{-# INLINE orCE #-}++-- | Are any values in the stream equal to the given value?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+elemC :: (Monad m, Eq a) => a -> Consumer a m Bool+elemC = CC.elem+{-# INLINE elemC #-}++-- | Are any elements in the chunked stream equal to the given element?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+elemCE :: (Monad m, Seq.EqSequence seq)+      => Element seq+      -> Consumer seq m Bool+elemCE = CC.elemE+{-# INLINE elemCE #-}++-- | Are no values in the stream equal to the given value?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+notElemC :: (Monad m, Eq a) => a -> Consumer a m Bool+notElemC = CC.notElem+{-# INLINE notElemC #-}++-- | Are no elements in the chunked stream equal to the given element?+--+-- Stops consuming as soon as a match is found.+--+-- Since 1.0.0+notElemCE :: (Monad m, Seq.EqSequence seq)+         => Element seq+         -> Consumer seq m Bool+notElemCE = CC.notElemE+{-# INLINE notElemCE #-}++-- | Consume all incoming strict chunks into a lazy sequence.+-- Note that the entirety of the sequence will be resident at memory.+--+-- This can be used to consume a stream of strict ByteStrings into a lazy+-- ByteString, for example.+--+-- Since 1.0.0+sinkLazy :: (Monad m, LazySequence lazy strict)+         => Consumer strict m lazy+sinkLazy = CC.sinkLazy+{-# INLINE sinkLazy #-}++-- | Consume all values from the stream and return as a list. Note that this+-- will pull all values into memory.+--+-- Since 1.0.0+sinkList :: Monad m => Consumer a m [a]+sinkList = CC.sinkList+{-# INLINE sinkList #-}++-- | Sink incoming values into a vector, up until size @maxSize@.  Subsequent+-- values will be left in the stream. If there are less than @maxSize@ values+-- present, returns a @Vector@ of smaller size.+--+-- Note that using this function is more memory efficient than @sinkList@ and+-- then converting to a @Vector@, as it avoids intermediate list constructors.+--+-- Since 1.0.0+sinkVector :: (MonadBase base m, V.Vector v a, PrimMonad base)+           => Int -- ^ maximum allowed size+           -> Consumer a m (v a)+sinkVector = CC.sinkVector+{-# INLINE sinkVector #-}++-- | Convert incoming values to a builder and fold together all builder values.+--+-- Defined as: @foldMap toBuilder@.+--+-- Since 1.0.0+sinkBuilder :: (Monad m, Monoid builder, ToBuilder a builder)+            => Consumer a m builder+sinkBuilder = CC.sinkBuilder+{-# INLINE sinkBuilder #-}++-- | Same as @sinkBuilder@, but afterwards convert the builder to its lazy+-- representation.+--+-- Alternatively, this could be considered an alternative to @sinkLazy@, with+-- the following differences:+--+-- * This function will allow multiple input types, not just the strict version+-- of the lazy structure.+--+-- * Some buffer copying may occur in this version.+--+-- Since 1.0.0+sinkLazyBuilder :: (Monad m, Monoid builder, ToBuilder a builder, Builder builder lazy)+                => Consumer a m lazy+sinkLazyBuilder = CC.sinkLazyBuilder+{-# INLINE sinkLazyBuilder #-}++-- | Consume and discard all remaining values in the stream.+--+-- Since 1.0.0+sinkNull :: Monad m => Consumer a m ()+sinkNull = CC.sinkNull+{-# INLINE sinkNull #-}++-- | Same as @await@, but discards any leading 'onull' values.+--+-- Since 1.0.0+awaitNonNull :: (Monad m, NonNull.NonNull b, a ~ NonNull.Nullable b) => Consumer a m (Maybe b)+awaitNonNull = CC.awaitNonNull+{-# INLINE awaitNonNull #-}++-- | Get the next element in the chunked stream.+--+-- Since 1.0.0+headCE :: (Monad m, Seq.IsSequence seq) => Consumer seq m (Maybe (Element seq))+headCE = CC.headE+{-# INLINE headCE #-}++-- | View the next value in the stream without consuming it.+--+-- Since 1.0.0+peekC :: Monad m => Consumer a m (Maybe a)+peekC = CC.peek+{-# INLINE peekC #-}++-- | View the next element in the chunked stream without consuming it.+--+-- Since 1.0.0+peekCE :: (Monad m, MonoFoldable mono) => Consumer mono m (Maybe (Element mono))+peekCE = CC.peekE+{-# INLINE peekCE #-}++-- | Retrieve the last value in the stream, if present.+--+-- Since 1.0.0+lastC :: Monad m => Consumer a m (Maybe a)+lastC = CC.last+{-# INLINE lastC #-}++-- | Retrieve the last element in the chunked stream, if present.+--+-- Since 1.0.0+lastCE :: (Monad m, Seq.IsSequence seq) => Consumer seq m (Maybe (Element seq))+lastCE = CC.lastE+{-# INLINE lastCE #-}++-- | Count how many values are in the stream.+--+-- Since 1.0.0+lengthC :: (Monad m, Num len) => Consumer a m len+lengthC = CC.length+{-# INLINE lengthC #-}++-- | Count how many elements are in the chunked stream.+--+-- Since 1.0.0+lengthCE :: (Monad m, Num len, MonoFoldable mono) => Consumer mono m len+lengthCE = CC.lengthE+{-# INLINE lengthCE #-}++-- | Get the largest value in the stream, if present.+--+-- Since 1.0.0+maximumC :: (Monad m, Ord a) => Consumer a m (Maybe a)+maximumC = CC.maximum+{-# INLINE maximumC #-}++-- | Get the largest element in the chunked stream, if present.+--+-- Since 1.0.0+maximumCE :: (Monad m, Seq.OrdSequence seq) => Consumer seq m (Maybe (Element seq))+maximumCE = CC.maximumE+{-# INLINE maximumCE #-}++-- | Get the smallest value in the stream, if present.+--+-- Since 1.0.0+minimumC :: (Monad m, Ord a) => Consumer a m (Maybe a)+minimumC = CC.minimum+{-# INLINE minimumC #-}++-- | Get the smallest element in the chunked stream, if present.+--+-- Since 1.0.0+minimumCE :: (Monad m, Seq.OrdSequence seq) => Consumer seq m (Maybe (Element seq))+minimumCE = CC.minimumE+{-# INLINE minimumCE #-}++-- | True if there are no values in the stream.+--+-- This function does not modify the stream.+--+-- Since 1.0.0+nullC :: Monad m => Consumer a m Bool+nullC = CC.null+{-# INLINE nullC #-}++-- | True if there are no elements in the chunked stream.+--+-- This function may remove empty leading chunks from the stream, but otherwise+-- will not modify it.+--+-- Since 1.0.0+nullCE :: (Monad m, MonoFoldable mono)+      => Consumer mono m Bool+nullCE = CC.nullE+{-# INLINE nullCE #-}++-- | Get the sum of all values in the stream.+--+-- Since 1.0.0+sumC :: (Monad m, Num a) => Consumer a m a+sumC = CC.sum+{-# INLINE sumC #-}++-- | Get the sum of all elements in the chunked stream.+--+-- Since 1.0.0+sumCE :: (Monad m, MonoFoldable mono, Num (Element mono)) => Consumer mono m (Element mono)+sumCE = CC.sumE+{-# INLINE sumCE #-}++-- | Get the product of all values in the stream.+--+-- Since 1.0.0+productC :: (Monad m, Num a) => Consumer a m a+productC = CC.product+{-# INLINE productC #-}++-- | Get the product of all elements in the chunked stream.+--+-- Since 1.0.0+productCE :: (Monad m, MonoFoldable mono, Num (Element mono)) => Consumer mono m (Element mono)+productCE = CC.productE+{-# INLINE productCE #-}++-- | Find the first matching value.+--+-- Since 1.0.0+findC :: Monad m => (a -> Bool) -> Consumer a m (Maybe a)+findC = CC.find+{-# INLINE findC #-}++-- | Apply the action to all values in the stream.+--+-- Since 1.0.0+mapM_C :: Monad m => (a -> m ()) -> Consumer a m ()+mapM_C = CC.mapM_+{-# INLINE mapM_C #-}++-- | Apply the action to all elements in the chunked stream.+--+-- Since 1.0.0+mapM_CE :: (Monad m, MonoFoldable mono) => (Element mono -> m ()) -> Consumer mono m ()+mapM_CE = CC.mapM_E+{-# INLINE mapM_CE #-}++-- | A monadic strict left fold.+--+-- Since 1.0.0+foldMC :: Monad m => (a -> b -> m a) -> a -> Consumer b m a+foldMC = CC.foldM+{-# INLINE foldMC #-}++-- | A monadic strict left fold on a chunked stream.+--+-- Since 1.0.0+foldMCE :: (Monad m, MonoFoldable mono)+       => (a -> Element mono -> m a)+       -> a+       -> Consumer mono m a+foldMCE = CC.foldME+{-# INLINE foldMCE #-}++-- | Apply the provided monadic mapping function and monoidal combine all values.+--+-- Since 1.0.0+foldMapMC :: (Monad m, Monoid w) => (a -> m w) -> Consumer a m w+foldMapMC = CC.foldMapM+{-# INLINE foldMapMC #-}++-- | Apply the provided monadic mapping function and monoidal combine all+-- elements in the chunked stream.+--+-- Since 1.0.0+foldMapMCE :: (Monad m, MonoFoldable mono, Monoid w)+          => (Element mono -> m w)+          -> Consumer mono m w+foldMapMCE = CC.foldMapME+{-# INLINE foldMapMCE #-}++-- | Write all data to the given file.+--+-- This function automatically opens and closes the file handle, and ensures+-- exception safety via @MonadResource. It works for all instances of @IOData@,+-- including @ByteString@ and @Text@.+--+-- Since 1.0.0+sinkFile :: (MonadResource m, IOData a) => FilePath -> Consumer a m ()+sinkFile = CC.sinkFile+{-# INLINE sinkFile #-}++-- | Write all data to the given @Handle@.+--+-- Does not close the @Handle@ at any point.+--+-- Since 1.0.0+sinkHandle :: (MonadIO m, IOData a) => Handle -> Consumer a m ()+sinkHandle = CC.sinkHandle+{-# INLINE sinkHandle #-}++-- | Open a @Handle@ using the given function and stream data to it.+--+-- Automatically closes the file at completion.+--+-- Since 1.0.0+sinkIOHandle :: (MonadResource m, IOData a) => SIO.IO Handle -> Consumer a m ()+sinkIOHandle = CC.sinkIOHandle+{-# INLINE sinkIOHandle #-}++-- | Print all incoming values to stdout.+--+-- Since 1.0.0+printC :: (Show a, MonadIO m) => Consumer a m ()+printC = CC.print+{-# INLINE printC #-}++-- | @sinkHandle@ applied to @stdout@.+--+-- Since 1.0.0+stdoutC :: (MonadIO m, IOData a) => Consumer a m ()+stdoutC = CC.stdout+{-# INLINE stdoutC #-}++-- | @sinkHandle@ applied to @stderr@.+--+-- Since 1.0.0+stderrC :: (MonadIO m, IOData a) => Consumer a m ()+stderrC = CC.stderr+{-# INLINE stderrC #-}++-- | Apply a transformation to all values in a stream.+--+-- Since 1.0.0+mapC :: Monad m => (a -> b) -> Conduit a m b+mapC = CC.map+{-# INLINE mapC #-}++-- | Apply a transformation to all elements in a chunked stream.+--+-- Since 1.0.0+mapCE :: (Monad m, Functor f) => (a -> b) -> Conduit (f a) m (f b)+mapCE = CC.mapE+{-# INLINE mapCE #-}++-- | Apply a monomorphic transformation to all elements in a chunked stream.+--+-- Unlike @mapE@, this will work on types like @ByteString@ and @Text@ which+-- are @MonoFunctor@ but not @Functor@.+--+-- Since 1.0.0+omapCE :: (Monad m, MonoFunctor mono) => (Element mono -> Element mono) -> Conduit mono m mono+omapCE = CC.omapE+{-# INLINE omapCE #-}++-- | Apply the function to each value in the stream, resulting in a foldable+-- value (e.g., a list). Then yield each of the individual values in that+-- foldable value separately.+--+-- Generalizes concatMap, mapMaybe, and mapFoldable.+--+-- Since 1.0.0+concatMapC :: (Monad m, MonoFoldable mono)+          => (a -> mono)+          -> Conduit a m (Element mono)+concatMapC = CC.concatMap+{-# INLINE concatMapC #-}++-- | Apply the function to each element in the chunked stream, resulting in a+-- foldable value (e.g., a list). Then yield each of the individual values in+-- that foldable value separately.+--+-- Generalizes concatMap, mapMaybe, and mapFoldable.+--+-- Since 1.0.0+concatMapCE :: (Monad m, MonoFoldable mono, Monoid w)+           => (Element mono -> w)+           -> Conduit mono m w+concatMapCE = CC.concatMapE+{-# INLINE concatMapCE #-}++-- | Stream up to n number of values downstream.+--+-- Note that, if downstream terminates early, not all values will be consumed.+-- If you want to force /exactly/ the given number of values to be consumed,+-- see 'takeExactly'.+--+-- Since 1.0.0+takeC :: Monad m => Int -> Conduit a m a+takeC = CC.take+{-# INLINE takeC #-}++-- | Stream up to n number of elements downstream in a chunked stream.+--+-- Note that, if downstream terminates early, not all values will be consumed.+-- If you want to force /exactly/ the given number of values to be consumed,+-- see 'takeExactlyE'.+--+-- Since 1.0.0+takeCE :: (Monad m, Seq.IsSequence seq)+      => Seq.Index seq+      -> Conduit seq m seq+takeCE = CC.takeE+{-# INLINE takeCE #-}++-- | Stream all values downstream that match the given predicate.+--+-- Same caveats regarding downstream termination apply as with 'take'.+--+-- Since 1.0.0+takeWhileC :: Monad m+          => (a -> Bool)+          -> Conduit a m a+takeWhileC = CC.takeWhile+{-# INLINE takeWhileC #-}++-- | Stream all elements downstream that match the given predicate in a chunked stream.+--+-- Same caveats regarding downstream termination apply as with 'takeE'.+--+-- Since 1.0.0+takeWhileCE :: (Monad m, Seq.IsSequence seq)+           => (Element seq -> Bool)+           -> Conduit seq m seq+takeWhileCE = CC.takeWhileE+{-# INLINE takeWhileCE #-}++-- | Consume precisely the given number of values and feed them downstream.+--+-- This function is in contrast to 'take', which will only consume up to the+-- given number of values, and will terminate early if downstream terminates+-- early. This function will discard any additional values in the stream if+-- they are unconsumed.+--+-- Note that this function takes a downstream @ConduitM@ as a parameter, as+-- opposed to working with normal fusion. For more information, see+-- <http://www.yesodweb.com/blog/2013/10/core-flaw-pipes-conduit>, the section+-- titled \"pipes and conduit: isolate\".+--+-- Since 1.0.0+takeExactlyC :: Monad m+            => Int+            -> ConduitM a b m r+            -> ConduitM a b m r+takeExactlyC = CC.takeExactly+{-# INLINE takeExactlyC #-}++-- | Same as 'takeExactly', but for chunked streams.+--+-- Since 1.0.0+takeExactlyCE :: (Monad m, Seq.IsSequence a)+             => Seq.Index a+             -> ConduitM a b m r+             -> ConduitM a b m r+takeExactlyCE = CC.takeExactlyE+{-# INLINE takeExactlyCE #-}++-- | Flatten out a stream by yielding the values contained in an incoming+-- @MonoFoldable@ as individually yielded values.+--+-- Since 1.0.0+concatC :: (Monad m, MonoFoldable mono)+       => Conduit mono m (Element mono)+concatC = CC.concat+{-# INLINE concatC #-}++-- | Keep only values in the stream passing a given predicate.+--+-- Since 1.0.0+filterC :: Monad m => (a -> Bool) -> Conduit a m a+filterC = CC.filter+{-# INLINE filterC #-}++-- | Keep only elements in the chunked stream passing a given predicate.+--+-- Since 1.0.0+filterCE :: (Seq.IsSequence seq, Monad m) => (Element seq -> Bool) -> Conduit seq m seq+filterCE = CC.filterE+{-# INLINE filterCE #-}++-- | Map values as long as the result is @Just@.+--+-- Since 1.0.0+mapWhileC :: Monad m => (a -> Maybe b) -> Conduit a m b+mapWhileC = CC.mapWhile+{-# INLINE mapWhileC #-}++-- | Break up a stream of values into vectors of size n. The final vector may+-- be smaller than n if the total number of values is not a strict multiple of+-- n. No empty vectors will be yielded.+--+-- Since 1.0.0+conduitVector :: (MonadBase base m, V.Vector v a, PrimMonad base)+              => Int -- ^ maximum allowed size+              -> Conduit a m (v a)+conduitVector = CC.conduitVector+{-# INLINE conduitVector #-}++-- | Analog of 'Prelude.scanl' for lists.+--+-- Since 1.0.6+scanlC :: Monad m => (a -> b -> a) -> a -> Conduit b m a+scanlC = CC.scanl+{-# INLINE scanlC #-}++-- | 'concatMap' with an accumulator.+--+-- Since 1.0.0+concatMapAccumC :: Monad m => (a -> accum -> (accum, [b])) -> accum -> Conduit a m b+concatMapAccumC = CC.concatMapAccum+{-# INLINE concatMapAccumC #-}++-- | Insert the given value between each two values in the stream.+--+-- Since 1.0.0+intersperseC :: Monad m => a -> Conduit a m a+intersperseC = CC.intersperse+{-# INLINE intersperseC #-}++-- | Apply a monadic transformation to all values in a stream.+--+-- If you do not need the transformed values, and instead just want the monadic+-- side-effects of running the action, see 'mapM_'.+--+-- Since 1.0.0+mapMC :: Monad m => (a -> m b) -> Conduit a m b+mapMC = CC.mapM+{-# INLINE mapMC #-}++-- | Apply a monadic transformation to all elements in a chunked stream.+--+-- Since 1.0.0+mapMCE :: (Monad m, Data.Traversable.Traversable f) => (a -> m b) -> Conduit (f a) m (f b)+mapMCE = CC.mapME+{-# INLINE mapMCE #-}++-- | Apply a monadic monomorphic transformation to all elements in a chunked stream.+--+-- Unlike @mapME@, this will work on types like @ByteString@ and @Text@ which+-- are @MonoFunctor@ but not @Functor@.+--+-- Since 1.0.0+omapMCE :: (Monad m, MonoTraversable mono)+       => (Element mono -> m (Element mono))+       -> Conduit mono m mono+omapMCE = CC.omapME+{-# INLINE omapMCE #-}++-- | Apply the monadic function to each value in the stream, resulting in a+-- foldable value (e.g., a list). Then yield each of the individual values in+-- that foldable value separately.+--+-- Generalizes concatMapM, mapMaybeM, and mapFoldableM.+--+-- Since 1.0.0+concatMapMC :: (Monad m, MonoFoldable mono)+           => (a -> m mono)+           -> Conduit a m (Element mono)+concatMapMC = CC.concatMapM+{-# INLINE concatMapMC #-}++-- | Keep only values in the stream passing a given monadic predicate.+--+-- Since 1.0.0+filterMC :: Monad m+        => (a -> m Bool)+        -> Conduit a m a+filterMC = CC.filterM+{-# INLINE filterMC #-}++-- | Keep only elements in the chunked stream passing a given monadic predicate.+--+-- Since 1.0.0+filterMCE :: (Monad m, Seq.IsSequence seq) => (Element seq -> m Bool) -> Conduit seq m seq+filterMCE = CC.filterME+{-# INLINE filterMCE #-}++-- | Apply a monadic action on all values in a stream.+--+-- This @Conduit@ can be used to perform a monadic side-effect for every+-- value, whilst passing the value through the @Conduit@ as-is.+--+-- > iterM f = mapM (\a -> f a >>= \() -> return a)+--+-- Since 1.0.0+iterMC :: Monad m => (a -> m ()) -> Conduit a m a+iterMC = CC.iterM+{-# INLINE iterMC #-}++-- | Analog of 'Prelude.scanl' for lists, monadic.+--+-- Since 1.0.6+scanlMC :: Monad m => (a -> b -> m a) -> a -> Conduit b m a+scanlMC = CC.scanlM+{-# INLINE scanlMC #-}++-- | 'concatMapM' with an accumulator.+--+-- Since 1.0.0+concatMapAccumMC :: Monad m => (a -> accum -> m (accum, [b])) -> accum -> Conduit a m b+concatMapAccumMC = CC.concatMapAccumM+{-# INLINE concatMapAccumMC #-}++-- | Encode a stream of text as UTF8.+--+-- Since 1.0.0+encodeUtf8C :: (Monad m, DTE.Utf8 text binary) => Conduit text m binary+encodeUtf8C = CC.encodeUtf8+{-# INLINE encodeUtf8C #-}++-- | Decode a stream of binary data as UTF8.+--+-- Since 1.0.0+decodeUtf8C :: MonadThrow m => Conduit ByteString m Text+decodeUtf8C = CC.decodeUtf8+{-# INLINE decodeUtf8C #-}++-- | Stream in the entirety of a single line.+--+-- Like @takeExactly@, this will consume the entirety of the line regardless of+-- the behavior of the inner Conduit.+--+-- Since 1.0.0+lineC :: (Monad m, Seq.IsSequence seq, Element seq ~ Char)+     => ConduitM seq o m r+     -> ConduitM seq o m r+lineC = CC.line+{-# INLINE lineC #-}++-- | Same as 'line', but operates on ASCII/binary data.+--+-- Since 1.0.0+lineAsciiC :: (Monad m, Seq.IsSequence seq, Element seq ~ Word8)+          => ConduitM seq o m r+          -> ConduitM seq o m r+lineAsciiC = CC.lineAscii+{-# INLINE lineAsciiC #-}++-- | Insert a newline character after each incoming chunk of data.+--+-- Since 1.0.0+unlinesC :: (Monad m, Seq.IsSequence seq, Element seq ~ Char) => Conduit seq m seq+unlinesC = CC.unlines+{-# INLINE unlinesC #-}++-- | Same as 'unlines', but operates on ASCII/binary data.+--+-- Since 1.0.0+unlinesAsciiC :: (Monad m, Seq.IsSequence seq, Element seq ~ Word8) => Conduit seq m seq+unlinesAsciiC = CC.unlinesAscii+{-# INLINE unlinesAsciiC #-}++-- | Convert a stream of arbitrarily-chunked textual data into a stream of data+-- where each chunk represents a single line. Note that, if you have+-- unknown/untrusted input, this function is /unsafe/, since it would allow an+-- attacker to form lines of massive length and exhaust memory.+--+-- Since 1.0.0+linesUnboundedC :: (Monad m, Seq.IsSequence seq, Element seq ~ Char)+               => Conduit seq m seq+linesUnboundedC = CC.linesUnbounded+{-# INLINE linesUnboundedC #-}++-- | Same as 'linesUnbounded', but for ASCII/binary data.+--+-- Since 1.0.0+linesUnboundedAsciiC :: (Monad m, Seq.IsSequence seq, Element seq ~ Word8)+                    => Conduit seq m seq+linesUnboundedAsciiC = CC.linesUnboundedAscii+{-# INLINE linesUnboundedAsciiC #-}
+ LICENSE view
@@ -0,0 +1,20 @@+The MIT License (MIT)++Copyright (c) 2014 FP Complete++Permission is hereby granted, free of charge, to any person obtaining a copy of+this software and associated documentation files (the "Software"), to deal in+the Software without restriction, including without limitation the rights to+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of+the Software, and to permit persons to whom the Software is furnished to do so,+subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ conduit-combinators.cabal view
@@ -0,0 +1,51 @@+name:                conduit-combinators+version:             0.1.0.0+synopsis:            Commonly used conduit functions, for both chunked and unchunked data+description:         Provides a replacement for Data.Conduit.List, as well as a convenient Conduit module.+homepage:            https://github.com/fpco/conduit-combinators+license:             MIT+license-file:        LICENSE+author:              Michael snoyman+maintainer:          michael@snoyman.com+category:            Data, Conduit+build-type:          Simple+cabal-version:       >=1.8++library+  exposed-modules:     Conduit+                       Data.Conduit.Combinators+  other-modules:       Data.Conduit.Combinators.Unqualified+  build-depends:       base >= 4 && < 5+                     , chunked-data+                     , conduit >= 1.0.12+                     , transformers+                     , transformers-base+                     , primitive+                     , mono-traversable >= 0.3 && < 0.4+                     , vector+                     , system-fileio+                     , system-filepath+                     , text+                     , bytestring++test-suite test+  hs-source-dirs: test+  main-is:        Spec.hs+  type:           exitcode-stdio-1.0+  cpp-options:    -DTEST+  build-depends:  conduit-combinators+                , base+                , hspec >= 1.3+                , basic-prelude+                , text+                , vector+                , transformers+                , chunked-data+                , mono-traversable+                , silently+                , bytestring+  ghc-options:    -Wall++source-repository head+  type:     git+  location: git://github.com/fpco/conduit-combinators.git
+ test/Spec.hs view
@@ -0,0 +1,502 @@+{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-}+{-# OPTIONS_GHC -fno-warn-type-defaults #-}+import Conduit+import Test.Hspec+import Test.Hspec.QuickCheck+import BasicPrelude hiding (encodeUtf8)+import qualified Data.Text as T+import qualified Data.Text.Lazy as TL+import Data.IORef+import qualified Data.Vector as V+import qualified Data.Vector.Unboxed as VU+import qualified Data.Vector.Storable as VS+import Control.Monad.Trans.Writer+import qualified Prelude+import qualified System.IO as IO+import Data.Builder+import Data.Sequences.Lazy+import Data.Textual.Encoding+import qualified Data.NonNull as NN+import System.IO.Silently (hCapture)+import GHC.IO.Handle (hDuplicateTo)+import qualified Data.ByteString as S+import qualified Data.ByteString.Char8 as S8++main :: IO ()+main = hspec $ do+    describe "yieldMany" $ do+        it "list" $+            runIdentity (yieldMany [1..10] $$ sinkList)+            `shouldBe` [1..10]+        it "Text" $+            runIdentity (yieldMany ("Hello World" :: Text) $$ sinkList)+            `shouldBe` "Hello World"+    it "unfold" $+        let f 11 = Nothing+            f i = Just (show i, i + 1)+         in runIdentity (unfoldC f 1 $$ sinkList)+            `shouldBe` map show [1..10]+    it "enumFromTo" $+        runIdentity (enumFromToC 1 10 $$ sinkList) `shouldBe` [1..10]+    it "iterate" $+        let f i = i + 1+            src = iterateC f seed+            seed = 1+            count = 10+            res = runIdentity $ src $$ takeC count =$ sinkList+         in res `shouldBe` take count (iterate f seed)+    it "repeat" $+        let src = repeatC seed+            seed = 1+            count = 10+            res = runIdentity $ src $$ takeC count =$ sinkList+         in res `shouldBe` take count (repeat seed)+    it "replicate" $+        let src = replicateC count seed+            seed = 1+            count = 10+            res = runIdentity $ src $$ sinkList+         in res `shouldBe` replicate count seed+    it "sourceLazy" $+        let tss = ["foo", "bar", "baz"]+            tl = TL.fromChunks tss+            res = runIdentity $ sourceLazy tl $$ sinkList+         in res `shouldBe` tss+    it "repeatM" $+        let src = repeatMC (return seed)+            seed = 1+            count = 10+            res = runIdentity $ src $$ takeC count =$ sinkList+         in res `shouldBe` take count (repeat seed)+    it "repeatWhileM" $ do+        ref <- newIORef 0+        let f = atomicModifyIORef ref $ \i -> (succ i, succ i)+            src = repeatWhileMC f (< 11)+        res <- src $$ sinkList+        res `shouldBe` [1..10]+    it "replicateM" $ do+        ref <- newIORef 0+        let f = atomicModifyIORef ref $ \i -> (succ i, succ i)+            src = replicateMC 10 f+        res <- src $$ sinkList+        res `shouldBe` [1..10]+    it "sourceFile" $ do+        let contents = concat $ replicate 10000 $ "this is some content\n"+            fp = "tmp"+        writeFile fp contents+        res <- runResourceT $ sourceFile fp $$ sinkLazy+        res `shouldBe` TL.fromStrict contents+    it "sourceHandle" $ do+        let contents = concat $ replicate 10000 $ "this is some content\n"+            fp = "tmp"+        writeFile fp contents+        res <- IO.withBinaryFile "tmp" IO.ReadMode $ \h -> sourceHandle h $$ sinkLazy+        res `shouldBe` TL.fromStrict contents+    it "sourceIOHandle" $ do+        let contents = concat $ replicate 10000 $ "this is some content\n"+            fp = "tmp"+        writeFile fp contents+        let open = IO.openBinaryFile "tmp" IO.ReadMode+        res <- runResourceT $ sourceIOHandle open $$ sinkLazy+        res `shouldBe` TL.fromStrict contents+    prop "stdin" $ \(S.pack -> content) -> do+        S.writeFile "tmp" content+        IO.withBinaryFile "tmp" IO.ReadMode $ \h -> do+            hDuplicateTo h IO.stdin+            x <- stdinC $$ foldC+            x `shouldBe` content+    prop "drop" $ \(T.pack -> input) count ->+        runIdentity (yieldMany input $$ (dropC count >>= \() -> sinkList))+        `shouldBe` T.unpack (T.drop count input)+    prop "dropE" $ \(T.pack -> input) ->+        runIdentity (yield input $$ (dropCE 5 >>= \() -> foldC))+        `shouldBe` T.drop 5 input+    prop "dropWhile" $ \(T.pack -> input) sep ->+        runIdentity (yieldMany input $$ (dropWhileC (<= sep) >>= \() -> sinkList))+        `shouldBe` T.unpack (T.dropWhile (<= sep) input)+    prop "dropWhileE" $ \(T.pack -> input) sep ->+        runIdentity (yield input $$ (dropWhileCE (<= sep) >>= \() -> foldC))+        `shouldBe` T.dropWhile (<= sep) input+    it "fold" $+        let list = [[1..10], [11..20]]+            src = yieldMany list+            res = runIdentity $ src $$ foldC+         in res `shouldBe` concat list+    it "foldE" $+        let list = [[1..10], [11..20]]+            src = yieldMany $ Identity list+            res = runIdentity $ src $$ foldCE+         in res `shouldBe` concat list+    it "foldl" $+        let res = runIdentity $ yieldMany [1..10] $$ foldlC (+) 0+         in res `shouldBe` sum [1..10]+    it "foldlE" $+        let res = runIdentity $ yield [1..10] $$ foldlCE (+) 0+         in res `shouldBe` sum [1..10]+    it "foldMap" $+        let src = yieldMany [1..10]+            res = runIdentity $ src $$ foldMapC return+         in res `shouldBe` [1..10]+    it "foldMapE" $+        let src = yield [1..10]+            res = runIdentity $ src $$ foldMapCE return+         in res `shouldBe` [1..10]+    prop "all" $ \input -> runIdentity (yieldMany input $$ allC even) `shouldBe` all evenInt input+    prop "allE" $ \input -> runIdentity (yield input $$ allCE even) `shouldBe` all evenInt input+    prop "any" $ \input -> runIdentity (yieldMany input $$ anyC even) `shouldBe` any evenInt input+    prop "anyE" $ \input -> runIdentity (yield input $$ anyCE even) `shouldBe` any evenInt input+    prop "and" $ \input -> runIdentity (yieldMany input $$ andC) `shouldBe` and input+    prop "andE" $ \input -> runIdentity (yield input $$ andCE) `shouldBe` and input+    prop "or" $ \input -> runIdentity (yieldMany input $$ orC) `shouldBe` or input+    prop "orE" $ \input -> runIdentity (yield input $$ orCE) `shouldBe` or input+    prop "elem" $ \x xs -> runIdentity (yieldMany xs $$ elemC x) `shouldBe` elemInt x xs+    prop "elemE" $ \x xs -> runIdentity (yield xs $$ elemCE x) `shouldBe` elemInt x xs+    prop "notElem" $ \x xs -> runIdentity (yieldMany xs $$ notElemC x) `shouldBe` notElemInt x xs+    prop "notElemE" $ \x xs -> runIdentity (yield xs $$ notElemCE x) `shouldBe` notElemInt x xs+    prop "sinkVector regular" $ \xs' -> do+        let maxSize = 20+            xs = take maxSize xs'+        res <- yieldMany xs' $$ sinkVector maxSize+        res `shouldBe` V.fromList (xs :: [Int])+    prop "sinkVector unboxed" $ \xs' -> do+        let maxSize = 20+            xs = take maxSize xs'+        res <- yieldMany xs' $$ sinkVector maxSize+        res `shouldBe` VU.fromList (xs :: [Int])+    prop "sinkVector storable" $ \xs' -> do+        let maxSize = 20+            xs = take maxSize xs'+        res <- yieldMany xs' $$ sinkVector maxSize+        res `shouldBe` VS.fromList (xs :: [Int])+    prop "sinkBuilder" $ \(map T.pack -> inputs) ->+        let builder = runIdentity (yieldMany inputs $$ sinkBuilder) :: TextBuilder+            ltext = builderToLazy builder+         in ltext `shouldBe` fromChunks inputs+    prop "sinkLazyBuilder" $ \(map T.pack -> inputs) ->+        let lbs = runIdentity (yieldMany inputs $$ sinkLazyBuilder)+         in lbs `shouldBe` encodeUtf8 (fromChunks inputs)+    prop "sinkNull" $ \xs toSkip -> do+        res <- yieldMany xs $$ do+            takeC toSkip =$ sinkNull+            sinkList+        res `shouldBe` drop toSkip (xs :: [Int])+    prop "awaitNonNull" $ \xs ->+        fmap (NN.toNullable .NN.asNotEmpty) (runIdentity $ yieldMany xs $$ awaitNonNull)+        `shouldBe` listToMaybe (filter (not . null) (xs :: [[Int]]))+    prop "headE" $ \xs ->+        runIdentity (yieldMany xs $$ ((,) <$> headCE <*> foldC))+        `shouldBe` (listToMaybe $ concat xs, drop 1 $ concat xs :: [Int])+    prop "peek" $ \xs ->+        runIdentity (yieldMany xs $$ ((,) <$> peekC <*> sinkList))+        `shouldBe` (listToMaybe xs, xs :: [Int])+    prop "peekE" $ \xs ->+        runIdentity (yieldMany xs $$ ((,) <$> peekCE <*> foldC))+        `shouldBe` (listToMaybe $ concat xs, concat xs :: [Int])+    prop "last" $ \xs ->+        runIdentity (yieldMany xs $$ lastC)+        `shouldBe` listToMaybe (reverse (xs :: [Int]))+    prop "lastE" $ \xs ->+        runIdentity (yieldMany xs $$ lastCE)+        `shouldBe` listToMaybe (reverse (concat xs :: [Int]))+    prop "length" $ \xs ->+        runIdentity (yieldMany xs $$ lengthC)+        `shouldBe` length (xs :: [Int])+    prop "lengthE" $ \xs ->+        runIdentity (yieldMany xs $$ lengthCE)+        `shouldBe` length (concat xs :: [Int])+    prop "maximum" $ \xs ->+        runIdentity (yieldMany xs $$ maximumC)+        `shouldBe` (if null (xs :: [Int]) then Nothing else Just (maximum xs))+    prop "maximumE" $ \xs ->+        runIdentity (yieldMany xs $$ maximumCE)+        `shouldBe` (if null (concat xs :: [Int]) then Nothing else Just (maximum $ concat xs))+    prop "minimum" $ \xs ->+        runIdentity (yieldMany xs $$ minimumC)+        `shouldBe` (if null (xs :: [Int]) then Nothing else Just (minimum xs))+    prop "minimumE" $ \xs ->+        runIdentity (yieldMany xs $$ minimumCE)+        `shouldBe` (if null (concat xs :: [Int]) then Nothing else Just (minimum $ concat xs))+    prop "null" $ \xs ->+        runIdentity (yieldMany xs $$ nullC)+        `shouldBe` null (xs :: [Int])+    prop "nullE" $ \xs ->+        runIdentity (yieldMany xs $$ ((,) <$> nullCE <*> foldC))+        `shouldBe` (null (concat xs :: [Int]), concat xs)+    prop "sum" $ \xs ->+        runIdentity (yieldMany xs $$ sumC)+        `shouldBe` sum (xs :: [Int])+    prop "sumE" $ \xs ->+        runIdentity (yieldMany xs $$ sumCE)+        `shouldBe` sum (concat xs :: [Int])+    prop "product" $ \xs ->+        runIdentity (yieldMany xs $$ productC)+        `shouldBe` product (xs :: [Int])+    prop "productE" $ \xs ->+        runIdentity (yieldMany xs $$ productCE)+        `shouldBe` product (concat xs :: [Int])+    prop "find" $ \x xs ->+        runIdentity (yieldMany xs $$ findC (< x))+        `shouldBe` find (< x) (xs :: [Int])+    prop "mapM_" $ \xs ->+        let res = execWriter $ yieldMany xs $$ mapM_C (tell . return)+         in res `shouldBe` (xs :: [Int])+    prop "mapM_E" $ \xs ->+        let res = execWriter $ yield xs $$ mapM_CE (tell . return)+         in res `shouldBe` (xs :: [Int])+    prop "foldM" $ \xs -> do+        res <- yieldMany xs $$ foldMC addM 0+        res `shouldBe` sum xs+    prop "foldME" $ \xs -> do+        res <- yield xs $$ foldMCE addM 0+        res `shouldBe` sum xs+    it "foldMapM" $+        let src = yieldMany [1..10]+            res = runIdentity $ src $$ foldMapMC (return . return)+         in res `shouldBe` [1..10]+    it "foldMapME" $+        let src = yield [1..10]+            res = runIdentity $ src $$ foldMapMCE (return . return)+         in res `shouldBe` [1..10]+    it "sinkFile" $ do+        let contents = concat $ replicate 1000 $ "this is some content\n"+            fp = "tmp"+        runResourceT $ yield contents $$ sinkFile fp+        res <- readFile fp+        res `shouldBe` contents+    it "sinkHandle" $ do+        let contents = concat $ replicate 1000 $ "this is some content\n"+            fp = "tmp"+        IO.withBinaryFile "tmp" IO.WriteMode $ \h -> yield contents $$ sinkHandle h+        res <- readFile fp+        res `shouldBe` contents+    it "sinkIOHandle" $ do+        let contents = concat $ replicate 1000 $ "this is some content\n"+            fp = "tmp"+            open = IO.openBinaryFile "tmp" IO.WriteMode+        runResourceT $ yield contents $$ sinkIOHandle open+        res <- readFile fp+        res `shouldBe` contents+    prop "print" $ \vals -> do+        let expected = Prelude.unlines $ map showInt vals+        (actual, ()) <- hCapture [IO.stdout] $ yieldMany vals $$ printC+        actual `shouldBe` expected+    prop "stdout" $ \vals -> do+        let expected = concat vals+        (actual, ()) <- hCapture [IO.stdout] $ yieldMany vals $$ stdoutC+        actual `shouldBe` expected+    prop "stderr" $ \vals -> do+        let expected = concat vals+        (actual, ()) <- hCapture [IO.stderr] $ yieldMany vals $$ stderrC+        actual `shouldBe` expected+    prop "map" $ \input ->+        runIdentity (yieldMany input $$ mapC succChar =$ sinkList)+        `shouldBe` map succChar input+    prop "mapE" $ \(map V.fromList -> inputs) ->+        runIdentity (yieldMany inputs $$ mapCE succChar =$ foldC)+        `shouldBe` V.map succChar (V.concat inputs)+    prop "omapE" $ \(map T.pack -> inputs) ->+        runIdentity (yieldMany inputs $$ omapCE succChar =$ foldC)+        `shouldBe` T.map succChar (T.concat inputs)+    prop "concatMap" $ \input ->+        runIdentity (yieldMany input $$ concatMapC showInt =$ sinkList)+        `shouldBe` concatMap showInt input+    prop "concatMapE" $ \input ->+        runIdentity (yield input $$ concatMapCE showInt =$ foldC)+        `shouldBe` concatMap showInt input+    prop "take" $ \(T.pack -> input) count ->+        runIdentity (yieldMany input $$ (takeC count >>= \() -> mempty) =$ sinkList)+        `shouldBe` T.unpack (T.take count input)+    prop "takeE" $ \(T.pack -> input) count ->+        runIdentity (yield input $$ (takeCE count >>= \() -> mempty) =$ foldC)+        `shouldBe` T.take count input+    prop "takeWhile" $ \(T.pack -> input) sep ->+        runIdentity (yieldMany input $$ do+            x <- (takeWhileC (<= sep) >>= \() -> mempty) =$ sinkList+            y <- sinkList+            return (x, y))+        `shouldBe` span (<= sep) (T.unpack input)+    prop "takeWhileE" $ \(T.pack -> input) sep ->+        runIdentity (yield input $$ do+            x <- (takeWhileCE (<= sep) >>= \() -> mempty) =$ foldC+            y <- foldC+            return (x, y))+        `shouldBe` T.span (<= sep) input+    it "takeExactly" $+        let src = yieldMany [1..10]+            sink = do+                x <- takeExactlyC 5 $ return 1+                y <- sinkList+                return (x, y)+            res = runIdentity $ src $$ sink+         in res `shouldBe` (1, [6..10])+    it "takeExactlyE" $+        let src = yield ("Hello World" :: Text)+            sink = do+                takeExactlyCE 5 (mempty :: Sink Text Identity ())+                y <- sinkLazy+                return y+            res = runIdentity $ src $$ sink+         in res `shouldBe` " World"+    it "takeExactlyE Vector" $ do+        let src = yield (V.fromList $ T.unpack "Hello World")+            sink = do+                x <- takeExactlyCE 5 $ return 1+                y <- foldC+                return (x, y)+        res <- src $$ sink+        res `shouldBe` (1, V.fromList $ T.unpack " World")+    it "takeExactlyE 2" $+        let src = yield ("Hello World" :: Text)+            sink = do+                x <- takeExactlyCE 5 $ return 1+                y <- sinkLazy+                return (x, y)+            res = runIdentity $ src $$ sink+            -- FIXME type signature on next line is necessary in GHC 7.6.3 to+            -- avoid a crash:+            --+            -- test: internal error: ARR_WORDS object entered!+            --     (GHC version 7.6.3 for x86_64_unknown_linux)+            --     Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug+            -- Aborted (core dumped)+            --+            -- Report upstream when packages are released+         in res `shouldBe` (1, " World" :: LText)+    prop "concat" $ \input ->+        runIdentity (yield (T.pack input) $$ concatC =$ sinkList)+        `shouldBe` input+    prop "filter" $ \input ->+        runIdentity (yieldMany input $$ filterC evenInt =$ sinkList)+        `shouldBe` filter evenInt input+    prop "filterE" $ \input ->+        runIdentity (yield input $$ filterCE evenInt =$ foldC)+        `shouldBe` filter evenInt input+    prop "mapWhile" $ \input (min 20 -> highest) ->+        let f i =+                if i < highest+                    then Just (i + 2 :: Int)+                    else Nothing+            res = runIdentity $ yieldMany input $$ do+                x <- (mapWhileC f >>= \() -> mempty) =$ sinkList+                y <- sinkList+                return (x, y)+            expected = (map (+ 2) $ takeWhile (< highest) input, dropWhile (< highest) input)+         in res `shouldBe` expected+    prop "conduitVector" $ \(take 200 -> input) size' -> do+        let size = min 30 $ succ $ abs size'+        res <- yieldMany input $$ conduitVector size =$ sinkList+        res `shouldSatisfy` all (\v -> V.length v <= size)+        drop 1 (reverse res) `shouldSatisfy` all (\v -> V.length v == size)+        V.concat res `shouldBe` V.fromList (input :: [Int])+    prop "scanl" $ \input seed ->+        let f a b = a + b :: Int+            res = runIdentity $ yieldMany input $$ scanlC f seed =$ sinkList+         in res `shouldBe` scanl f seed input+    it "concatMapAccum" $+        let f a accum = (a + accum, [a, accum])+            res = runIdentity $ yieldMany [1..3] $$ concatMapAccumC f 0 =$ sinkList+         in res `shouldBe` [1, 0, 2, 1, 3, 3]+    prop "intersperse" $ \xs x ->+        runIdentity (yieldMany xs $$ intersperseC x =$ sinkList)+        `shouldBe` intersperse (x :: Int) xs+    prop "mapM" $ \input ->+        runIdentity (yieldMany input $$ mapMC (return . succChar) =$ sinkList)+        `shouldBe` map succChar input+    prop "mapME" $ \(map V.fromList -> inputs) ->+        runIdentity (yieldMany inputs $$ mapMCE (return . succChar) =$ foldC)+        `shouldBe` V.map succChar (V.concat inputs)+    prop "omapME" $ \(map T.pack -> inputs) ->+        runIdentity (yieldMany inputs $$ omapMCE (return . succChar) =$ foldC)+        `shouldBe` T.map succChar (T.concat inputs)+    prop "concatMapM" $ \input ->+        runIdentity (yieldMany input $$ concatMapMC (return . showInt) =$ sinkList)+        `shouldBe` concatMap showInt input+    prop "filterM" $ \input ->+        runIdentity (yieldMany input $$ filterMC (return . evenInt) =$ sinkList)+        `shouldBe` filter evenInt input+    prop "filterME" $ \input ->+        runIdentity (yield input $$ filterMCE (return . evenInt) =$ foldC)+        `shouldBe` filter evenInt input+    prop "iterM" $ \input -> do+        (x, y) <- runWriterT $ yieldMany input $$ iterMC (tell . return) =$ sinkList+        x `shouldBe` (input :: [Int])+        y `shouldBe` input+    prop "scanlM" $ \input seed ->+        let f a b = a + b :: Int+            fm a b = return $ a + b+            res = runIdentity $ yieldMany input $$ scanlMC fm seed =$ sinkList+         in res `shouldBe` scanl f seed input+    it "concatMapAccumM" $+        let f a accum = return (a + accum, [a, accum])+            res = runIdentity $ yieldMany [1..3] $$ concatMapAccumMC f 0 =$ sinkList+         in res `shouldBe` [1, 0, 2, 1, 3, 3]+    prop "encode UTF8" $ \(map T.pack -> inputs) -> do+        let expected = encodeUtf8 $ fromChunks inputs+        actual <- yieldMany inputs+               $$ encodeUtf8C+               =$ sinkLazy+        actual `shouldBe` expected+    prop "encode/decode UTF8" $ \(map T.pack -> inputs) (min 50 . max 1 . abs -> chunkSize) -> do+        let expected = fromChunks inputs+        actual <- yieldMany inputs+               $$ encodeUtf8C+               =$ concatC+               =$ conduitVector chunkSize+               =$ mapC (S.pack . V.toList)+               =$ decodeUtf8C+               =$ sinkLazy+        actual `shouldBe` expected+    prop "line" $ \(map T.pack -> input) size ->+        let src = yieldMany input+            sink = do+                x <- lineC $ takeCE size =$ foldC+                y <- foldC+                return (x, y)+            res = runIdentity $ src $$ sink+            expected =+                let (x, y) = T.break (== '\n') (T.concat input)+                 in (T.take size x, T.drop 1 y)+         in res `shouldBe` expected+    prop "lineAscii" $ \(map S.pack -> input) size ->+        let src = yieldMany input+            sink = do+                x <- lineAsciiC $ takeCE size =$ foldC+                y <- foldC+                return (x, y)+            res = runIdentity $ src $$ sink+            expected =+                let (x, y) = S.break (== 10) (S.concat input)+                 in (S.take size x, S.drop 1 y)+         in res `shouldBe` expected+    prop "unlines" $ \(map T.pack -> input) ->+        runIdentity (yieldMany input $$ unlinesC =$ foldC)+        `shouldBe` T.unlines input+    prop "unlinesAscii" $ \(map S.pack -> input) ->+        runIdentity (yieldMany input $$ unlinesAsciiC =$ foldC)+        `shouldBe` S8.unlines input+    prop "linesUnbounded" $ \(map T.pack -> input) ->+        runIdentity (yieldMany input $$ (linesUnboundedC >>= \() -> mempty) =$ sinkList)+        `shouldBe` T.lines (T.concat input)+    prop "linesUnboundedAscii" $ \(map S.pack -> input) ->+        runIdentity (yieldMany input $$ (linesUnboundedAsciiC >>= \() -> mempty) =$ sinkList)+        `shouldBe` S8.lines (S.concat input)++evenInt :: Int -> Bool+evenInt = even++elemInt :: Int -> [Int] -> Bool+elemInt = elem++notElemInt :: Int -> [Int] -> Bool+notElemInt = notElem++addM :: Monad m => Int -> Int -> m Int+addM x y = return (x + y)++succChar :: Char -> Char+succChar = succ++showInt :: Int -> String+showInt = Prelude.show