packages feed

conduit 1.0.10 → 1.0.10.1

raw patch · 5 files changed

+112/−18 lines, 5 files

Files

Data/Conduit/Binary.hs view
@@ -396,3 +396,4 @@                 f (S.index bs i)                 loop (i + 1)             | otherwise = return ()+{-# INLINE [1] mapM_ #-}
Data/Conduit/Internal.hs view
@@ -50,6 +50,7 @@     , sourceList     , withUpstream     , unwrapResumable+    , Data.Conduit.Internal.enumFromTo     ) where  import Control.Applicative (Applicative (..))@@ -555,21 +556,29 @@ -- -- Since 0.4.1 mapOutput :: Monad m => (o1 -> o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r-mapOutput f (HaveOutput p c o) = HaveOutput (mapOutput f p) c (f o)-mapOutput f (NeedInput p c) = NeedInput (mapOutput f . p) (mapOutput f . c)-mapOutput _ (Done r) = Done r-mapOutput f (PipeM mp) = PipeM (liftM (mapOutput f) mp)-mapOutput f (Leftover p i) = Leftover (mapOutput f p) i+mapOutput f =+    go+  where+    go (HaveOutput p c o) = HaveOutput (go p) c (f o)+    go (NeedInput p c) = NeedInput (go . p) (go . c)+    go (Done r) = Done r+    go (PipeM mp) = PipeM (liftM (go) mp)+    go (Leftover p i) = Leftover (go p) i+{-# INLINE mapOutput #-}  -- | Same as 'mapOutput', but use a function that returns @Maybe@ values. -- -- Since 0.5.0 mapOutputMaybe :: Monad m => (o1 -> Maybe o2) -> Pipe l i o1 u m r -> Pipe l i o2 u m r-mapOutputMaybe f (HaveOutput p c o) = maybe id (\o' p' -> HaveOutput p' c o') (f o) (mapOutputMaybe f p)-mapOutputMaybe f (NeedInput p c) = NeedInput (mapOutputMaybe f . p) (mapOutputMaybe f . c)-mapOutputMaybe _ (Done r) = Done r-mapOutputMaybe f (PipeM mp) = PipeM (liftM (mapOutputMaybe f) mp)-mapOutputMaybe f (Leftover p i) = Leftover (mapOutputMaybe f p) i+mapOutputMaybe f =+    go+  where+    go (HaveOutput p c o) = maybe id (\o' p' -> HaveOutput p' c o') (f o) (mapOutputMaybe f p)+    go (NeedInput p c) = NeedInput (go . p) (go . c)+    go (Done r) = Done r+    go (PipeM mp) = PipeM (liftM (go) mp)+    go (Leftover p i) = Leftover (go p) i+{-# INLINE mapOutputMaybe #-}  -- | Apply a function to all the input values of a @Pipe@. --@@ -584,6 +593,18 @@ mapInput _ _  (Done r)           = Done r mapInput f f' (PipeM mp)         = PipeM (liftM (mapInput f f') mp) mapInput f f' (Leftover p i)     = maybe id (flip Leftover) (f' i) $ mapInput f f' p++enumFromTo :: (Enum o, Eq o, Monad m)+           => o+           -> o+           -> Pipe l i o u m ()+enumFromTo start stop =+    loop start+  where+    loop i+        | i == stop = HaveOutput (Done ()) (return ()) i+        | otherwise = HaveOutput (loop (succ i)) (return ()) i+{-# INLINE enumFromTo #-}  -- | Convert a list into a source. --
Data/Conduit/List.hs view
@@ -70,6 +70,7 @@ import Data.Monoid (Monoid, mempty, mappend) import qualified Data.Foldable as F import Data.Conduit+import qualified Data.Conduit.Internal as CI import Control.Monad (when, (<=<), liftM) import Control.Monad.Trans.Class (lift) @@ -102,12 +103,8 @@            => a            -> a            -> Producer m a-enumFromTo start stop =-    go start-  where-    go i-        | i == stop = yield i-        | otherwise = yield i >> go (succ i)+enumFromTo x = CI.ConduitM . CI.enumFromTo x+{-# INLINE enumFromTo #-}  -- | Produces an infinite stream of repeated applications of f to x. iterate :: Monad m => (a -> a) -> a -> Producer m a@@ -180,6 +177,18 @@       -> Consumer a m () mapM_ f = awaitForever $ lift . f +srcMapM_ :: Monad m => Source m a -> (a -> m ()) -> m ()+srcMapM_ (CI.ConduitM src) f =+    go src+  where+    go (CI.Done ()) = return ()+    go (CI.PipeM mp) = mp >>= go+    go (CI.Leftover p ()) = go p+    go (CI.HaveOutput p _ o) = f o >> go p+    go (CI.NeedInput _ c) = go (c ())+{-# INLINE srcMapM_ #-}+{-# RULES "connect to mapM_" forall f src. src $$ mapM_ f = srcMapM_ src f #-}+ -- | Ignore a certain number of values in the stream. This function is -- semantically equivalent to: --@@ -234,7 +243,16 @@ -- Since 0.3.0 map :: Monad m => (a -> b) -> Conduit a m b map f = awaitForever $ yield . f+{-# INLINE [1] map #-} +-- Since a Source never has any leftovers, fusion rules on it are safe.+{-# RULES "source/map fusion $=" forall f src. src $= map f = mapFuseRight src f #-}+{-# RULES "source/map fusion =$=" forall f src. src =$= map f = mapFuseRight src f #-}++mapFuseRight :: Monad m => Source m a -> (a -> b) -> Source m b+mapFuseRight (CI.ConduitM src) f = CI.ConduitM (CI.mapOutput f src)+{-# INLINE mapFuseRight #-}+ {-  It might be nice to include these rewrite rules, but they may have subtle@@ -423,12 +441,42 @@ filter :: Monad m => (a -> Bool) -> Conduit a m a filter f = awaitForever $ \i -> when (f i) (yield i) +filterFuseRight :: Monad m => Source m a -> (a -> Bool) -> Source m a+filterFuseRight (CI.ConduitM src) f =+    CI.ConduitM (go src)+  where+    go (CI.Done ()) = CI.Done ()+    go (CI.PipeM mp) = CI.PipeM (liftM go mp)+    go (CI.Leftover p i) = CI.Leftover (go p) i+    go (CI.HaveOutput p c o)+        | f o = CI.HaveOutput (go p) c o+        | otherwise = go p+    go (CI.NeedInput p c) = CI.NeedInput (go . p) (go . c)+-- Intermediate finalizers are dropped, but this is acceptable: the next+-- yielded value would be demanded by downstream in any event, and that new+-- finalizer will always override the existing finalizer.+{-# RULES "source/filter fusion $=" forall f src. src $= filter f = filterFuseRight src f #-}+{-# RULES "source/filter fusion =$=" forall f src. src =$= filter f = filterFuseRight src f #-}+{-# INLINE filterFuseRight #-}+ -- | Ignore the remainder of values in the source. Particularly useful when -- combined with 'isolate'. -- -- Since 0.3.0 sinkNull :: Monad m => Consumer a m () sinkNull = awaitForever $ \_ -> return ()+{-# RULES "connect to sinkNull" forall src. src $$ sinkNull = srcSinkNull src #-}++srcSinkNull :: Monad m => Source m a -> m ()+srcSinkNull (CI.ConduitM src) =+    go src+  where+    go (CI.Done ()) = return ()+    go (CI.PipeM mp) = mp >>= go+    go (CI.Leftover p ()) = go p+    go (CI.HaveOutput p _ _) = go p+    go (CI.NeedInput _ c) = go (c ())+{-# INLINE srcSinkNull #-}  -- | A source that outputs no values. Note that this is just a type-restricted -- synonym for 'mempty'.
conduit.cabal view
@@ -1,5 +1,5 @@ Name:                conduit-Version:             1.0.10+Version:             1.0.10.1 Synopsis:            Streaming data processing library. Description:     @conduit@ is a solution to the streaming data problem, allowing for production, transformation, and consumption of streams of data in constant memory. It is an alternative to lazy I\/O which guarantees deterministic resource handling, and fits in the same general solution space as @enumerator@\/@iteratee@ and @pipes@. For a tutorial, please visit <https://haskell.fpcomplete.com/user/snoyberg/library-documentation/conduit-overview>.@@ -48,6 +48,7 @@                        Data.Conduit.Lazy                        Data.Conduit.Internal                        Data.Conduit.Util+                       -- Hiding while some details are worked out Data.Conduit.Lift   Build-depends:       base                     >= 4.3          && < 5                      , resourcet                >= 0.4.3        && < 0.5                      , lifted-base              >= 0.1
test/main.hs view
@@ -5,6 +5,7 @@ import Test.QuickCheck.Monadic (assert, monadicIO, run)  import qualified Data.Conduit as C+-- FIXME import qualified Data.Conduit.Lift as C import qualified Data.Conduit.Util as C import qualified Data.Conduit.Internal as CI import qualified Data.Conduit.List as CL@@ -29,7 +30,7 @@ import Control.Monad.IO.Class (liftIO) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Writer (execWriter, tell, runWriterT)-import Control.Monad.Trans.State (evalStateT, get, put)+import Control.Monad.Trans.State (evalStateT, get, put, modify) import Control.Applicative (pure, (<$>), (<*>)) import Data.Functor.Identity (Identity,runIdentity) import Control.Monad (forever)@@ -1075,6 +1076,28 @@             it "test1" $ verify test1L test1R "p1" "p2" "p3"             -- FIXME this is broken it "test2" $ verify test2L test2R "p2" "p1" "p3"             it "test3" $ verify test3L test3R "p2" "p3" "p1"++    {- FIXME+    describe "Data.Conduit.Lift" $ do+        it "execStateC" $ do+            let sink = C.execStateC 0 $ CL.mapM_ $ modify . (+)+                src = mapM_ C.yield [1..10 :: Int]+            res <- src C.$$ sink+            res `shouldBe` sum [1..10]++        it "execWriterT" $ do+            let sink = C.execWriterC $ CL.mapM_ $ tell . return+                src = mapM_ C.yield [1..10 :: Int]+            res <- src C.$$ sink+            res `shouldBe` [1..10]++        it "runErrorT" $ do+            let sink = C.runErrorC $ do+                    x <- C.catchErrorC (lift $ throwError "foo") return+                    return $ x ++ "bar"+            res <- return () C.$$ sink+            res `shouldBe` Right ("foobar" :: String)+            -}  it' :: String -> IO () -> Spec it' = it