conduit-extra 0.1.1 → 0.1.2
raw patch · 3 files changed
+84/−2 lines, 3 filesdep +containersdep +monad-loopsdep +primitivedep ~conduit
Dependencies added: containers, monad-loops, primitive, vector
Dependency ranges changed: conduit
Files
- Data/Conduit/Extra/Utils.hs +65/−0
- Data/Conduit/Extra/ZipSink.hs +13/−1
- conduit-extra.cabal +6/−1
+ Data/Conduit/Extra/Utils.hs view
@@ -0,0 +1,65 @@+{- | Functions currently under development which have not been moved to their+ final destination.+-}++module Data.Conduit.Extra.Utils where++import Control.Applicative+import Control.Monad.Loops+import Control.Monad.Primitive+import Control.Monad.Trans.Class+import Control.Monad.Trans.State+import Data.Conduit+import Data.Conduit.List as CL+import Data.Foldable+import Data.Sequence as Seq+import Data.Vector as Boxed (Vector, freeze)+import Data.Vector.Mutable as Boxed hiding (length)+import qualified Data.Vector.Unboxed as Unboxed+import qualified Data.Vector.Unboxed.Mutable as Unboxed++takeWhile :: Monad m => (a -> Bool) -> Conduit a m a+takeWhile f = loop where+ loop = await >>= maybe (return ()) go+ go x | f x = yield x >> loop+ | otherwise = leftover x++collect :: PrimMonad m => Int -> Sink a m (Vector a)+collect size = do+ v <- lift $ unsafeNew size+ forM_ [0..size-1] $ \i -> do+ me <- await+ case me of+ Nothing ->+ error $ "Too many elements for a vector of size "+ ++ show size+ Just e -> lift $ unsafeWrite v i e+ lift $ freeze v++collectUnboxed :: (PrimMonad m, Unboxed.Unbox a)+ => Int -> Sink a m (Unboxed.Vector a)+collectUnboxed size = do+ v <- lift $ Unboxed.unsafeNew size+ forM_ [0..size-1] $ \i -> do+ me <- await+ case me of+ Nothing ->+ error $ "Too many elements for an unboxed vector of size "+ ++ show size+ Just e -> lift $ Unboxed.unsafeWrite v i e+ lift $ Unboxed.freeze v++-- | Remove the last N elements from the stream. This requires holding up to+-- N elements in memory.+dropRight :: Monad m => Int -> Conduit a m a+dropRight size = do+ xs <- Seq.fromList <$> CL.take size+ flip evalStateT xs $ whileM_ ((== size) . Seq.length <$> get) $ do+ xs' <- get+ case viewl xs' of+ EmptyL -> error "impossible"+ y :< ys -> do+ mz <- lift await+ case mz of+ Nothing -> put Seq.empty+ Just z -> put (ys |> z) >> lift (yield y)
Data/Conduit/Extra/ZipSink.hs view
@@ -1,5 +1,16 @@-module Data.Conduit.Extra.ZipSink where+{-# LANGUAGE CPP #-}+module Data.Conduit.Extra.ZipSink+ ( ZipSink (..)+ , broadcast+ ) where +#if MIN_VERSION_conduit(1, 0, 13)+import Data.Conduit (ZipSink (..), sequenceSinks, Sink)+import Data.Traversable (Traversable)++broadcast :: (Traversable f, Monad m) => f (Sink i m r) -> Sink i m (f r)+broadcast = sequenceSinks+#else import Control.Applicative import Control.Monad import Data.Conduit as C@@ -31,3 +42,4 @@ broadcast :: (Traversable f, Monad m) => f (Sink i m r) -> Sink i m (f r) broadcast = getZipSink . sequenceA . fmap ZipSink+#endif
conduit-extra.cabal view
@@ -1,5 +1,5 @@ Name: conduit-extra-Version: 0.1.1+Version: 0.1.2 Synopsis: Experimental helper functions for conduit. Description: This package is meant as a testing ground for new concepts in conduit. The idea is to have a much lower barrier to entry for this library relative to conduit itself. This way, conduit itself will continue to have a best-practices, minimal, stable API, while people are free to try crazy new features.@@ -17,10 +17,15 @@ , Data.Conduit.Extra.Pipes , Data.Conduit.Extra.Resumable , Data.Conduit.Extra.ZipSink+ , Data.Conduit.Extra.Utils Build-depends: base >= 4 && < 5 , conduit >= 1.0 , mtl+ , monad-loops+ , containers+ , primitive , transformers+ , vector , void ghc-options: -Wall