conduit-combinators 0.1.0.0 → 0.2.0.0
raw patch · 5 files changed
+76/−27 lines, 5 filesdep ~mono-traversable
Dependency ranges changed: mono-traversable
Files
- Conduit.hs +1/−1
- Data/Conduit/Combinators.hs +38/−11
- Data/Conduit/Combinators/Unqualified.hs +19/−6
- conduit-combinators.cabal +2/−2
- test/Spec.hs +16/−7
Conduit.hs view
@@ -3,7 +3,7 @@ -- 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).+-- (or for chunked functions, replacing a trailing E with CE). -- This means that the Conduit module can be imported unqualified -- without causing naming conflicts. --
Data/Conduit/Combinators.hs view
@@ -66,6 +66,7 @@ , sinkLazy , sinkList , sinkVector+ , sinkVectorN , sinkBuilder , sinkLazyBuilder , sinkNull@@ -604,6 +605,32 @@ sinkList = CL.consume {-# INLINE sinkList #-} +-- | Sink incoming values into a vector, growing the vector as necessary to fit+-- more elements.+--+-- 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)+ => Consumer a m (v a)+sinkVector = do+ let initSize = 10+ mv0 <- liftBase $ VM.new initSize+ let go maxSize i mv | i >= maxSize = do+ let newMax = maxSize + 10+ mv' <- liftBase $ VM.grow mv newMax+ go newMax i mv'+ go maxSize i mv = 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 maxSize (i + 1) mv+ go initSize 0 mv0+{-# INLINEABLE sinkVector #-}+ -- | 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.@@ -612,10 +639,10 @@ -- 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+sinkVectorN :: (MonadBase base m, V.Vector v a, PrimMonad base)+ => Int -- ^ maximum allowed size+ -> Consumer a m (v a)+sinkVectorN maxSize = do mv <- liftBase $ VM.new maxSize let go i | i >= maxSize = liftBase $ V.unsafeFreeze mv go i = do@@ -626,7 +653,7 @@ liftBase $ VM.write mv i x go (i + 1) go 0-{-# INLINEABLE sinkVector #-}+{-# INLINEABLE sinkVectorN #-} -- | Convert incoming values to a builder and fold together all builder values. --@@ -665,7 +692,7 @@ -- | 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 :: (Monad m, MonoFoldable a) => Consumer a m (Maybe (NonNull.NonNull a)) awaitNonNull = go where@@ -728,10 +755,10 @@ -- 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)+ awaitNonNull >>= maybe (return Nothing) (loop . NonNull.last) where - loop prev = awaitNonNull >>= maybe (return $ Just prev) (loop . NonNull.last . NonNull.asNotEmpty)+ loop prev = awaitNonNull >>= maybe (return $ Just prev) (loop . NonNull.last) {-# INLINE lastE #-} -- | Count how many values are in the stream.@@ -769,7 +796,7 @@ start' x = case NonNull.fromNullable x of Nothing -> start- Just y -> loop $ NonNull.maximum $ NonNull.asNotEmpty y+ Just y -> loop $ NonNull.maximum y loop prev = await >>= maybe (return $ Just prev) (loop . ofoldl' max prev) {-# INLINE maximumE #-} @@ -794,7 +821,7 @@ start' x = case NonNull.fromNullable x of Nothing -> start- Just y -> loop $ NonNull.minimum $ NonNull.asNotEmpty y+ Just y -> loop $ NonNull.minimum y loop prev = await >>= maybe (return $ Just prev) (loop . ofoldl' min prev) {-# INLINE minimumE #-} @@ -1174,7 +1201,7 @@ loop where loop = do- v <- sinkVector size+ v <- sinkVectorN size unless (V.null v) $ do yield v loop
Data/Conduit/Combinators/Unqualified.hs view
@@ -55,6 +55,7 @@ , sinkLazy , sinkList , sinkVector+ , sinkVectorN , sinkBuilder , sinkLazyBuilder , sinkNull@@ -546,20 +547,32 @@ 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.+-- | Sink incoming values into a vector, growing the vector as necessary to fit+-- more elements. -- -- 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)+ => Consumer a m (v a) sinkVector = CC.sinkVector {-# INLINE sinkVector #-} +-- | 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+sinkVectorN :: (MonadBase base m, V.Vector v a, PrimMonad base)+ => Int -- ^ maximum allowed size+ -> Consumer a m (v a)+sinkVectorN = CC.sinkVectorN+{-# INLINE sinkVectorN #-}+ -- | Convert incoming values to a builder and fold together all builder values. -- -- Defined as: @foldMap toBuilder@.@@ -597,7 +610,7 @@ -- | 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 :: (Monad m, MonoFoldable a) => Consumer a m (Maybe (NonNull.NonNull a)) awaitNonNull = CC.awaitNonNull {-# INLINE awaitNonNull #-}
conduit-combinators.cabal view
@@ -1,5 +1,5 @@ name: conduit-combinators-version: 0.1.0.0+version: 0.2.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@@ -21,7 +21,7 @@ , transformers , transformers-base , primitive- , mono-traversable >= 0.3 && < 0.4+ , mono-traversable >= 0.4 && < 0.5 , vector , system-fileio , system-filepath
test/Spec.hs view
@@ -155,20 +155,29 @@ 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+ prop "sinkVector regular" $ \xs -> do+ res <- yieldMany xs $$ sinkVector+ res `shouldBe` V.fromList (xs :: [Int])+ prop "sinkVector unboxed" $ \xs -> do+ res <- yieldMany xs $$ sinkVector+ res `shouldBe` VU.fromList (xs :: [Int])+ prop "sinkVector storable" $ \xs -> do+ res <- yieldMany xs $$ sinkVector+ res `shouldBe` VS.fromList (xs :: [Int])+ prop "sinkVectorN regular" $ \xs' -> do let maxSize = 20 xs = take maxSize xs'- res <- yieldMany xs' $$ sinkVector maxSize+ res <- yieldMany xs' $$ sinkVectorN maxSize res `shouldBe` V.fromList (xs :: [Int])- prop "sinkVector unboxed" $ \xs' -> do+ prop "sinkVectorN unboxed" $ \xs' -> do let maxSize = 20 xs = take maxSize xs'- res <- yieldMany xs' $$ sinkVector maxSize+ res <- yieldMany xs' $$ sinkVectorN maxSize res `shouldBe` VU.fromList (xs :: [Int])- prop "sinkVector storable" $ \xs' -> do+ prop "sinkVectorN storable" $ \xs' -> do let maxSize = 20 xs = take maxSize xs'- res <- yieldMany xs' $$ sinkVector maxSize+ res <- yieldMany xs' $$ sinkVectorN maxSize res `shouldBe` VS.fromList (xs :: [Int]) prop "sinkBuilder" $ \(map T.pack -> inputs) -> let builder = runIdentity (yieldMany inputs $$ sinkBuilder) :: TextBuilder@@ -183,7 +192,7 @@ sinkList res `shouldBe` drop toSkip (xs :: [Int]) prop "awaitNonNull" $ \xs ->- fmap (NN.toNullable .NN.asNotEmpty) (runIdentity $ yieldMany xs $$ awaitNonNull)+ fmap NN.toNullable (runIdentity $ yieldMany xs $$ awaitNonNull) `shouldBe` listToMaybe (filter (not . null) (xs :: [[Int]])) prop "headE" $ \xs -> runIdentity (yieldMany xs $$ ((,) <$> headCE <*> foldC))