packages feed

conduit-extra 0.1.4 → 0.1.5

raw patch · 4 files changed

+84/−1 lines, 4 files

Files

Data/Conduit/Extra.hs view
@@ -1,11 +1,13 @@ module Data.Conduit.Extra     ( module Data.Conduit.Extra.ZipSink+    , module Data.Conduit.Extra.ZipConduit     , module Data.Conduit.Extra.Resumable     , fuseLeftovers     , fuseReturnLeftovers     ) where  import Data.Conduit.Extra.ZipSink+import Data.Conduit.Extra.ZipConduit import Data.Conduit.Extra.Resumable import Data.Conduit import Data.Conduit.Internal (Pipe (..), ConduitM (..))
+ Data/Conduit/Extra/ZipConduit.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE DeriveFunctor #-}+module Data.Conduit.Extra.ZipConduit+    ( ZipConduit (..)+    , sequenceConduits+    ) where++import Data.Conduit+import Data.Conduit.Internal (Pipe (..), ConduitM (..), injectLeftovers)+import Data.Void (absurd)+import Control.Monad (liftM)+import Control.Applicative (Applicative (..))+import Data.Traversable (Traversable, sequenceA)++zipConduit :: Monad m+           => ConduitM i o m (x -> y)+           -> ConduitM i o m x+           -> ConduitM i o m y+zipConduit (ConduitM left0) (ConduitM right0) =+    ConduitM $ go (return ()) (return ()) (injectLeftovers left0) (injectLeftovers right0)+  where+    go _ _ (Done f) (Done x) = Done (f x)+    go _ finalY (HaveOutput x finalX o) y = HaveOutput+        (go finalX finalY x y)+        (finalX >> finalY)+        o+    go finalX _ x (HaveOutput y finalY o) = HaveOutput+        (go finalX finalY x y)+        (finalX >> finalY)+        o+    go _ _ (Leftover _ i) _ = absurd i+    go _ _ _ (Leftover _ i) = absurd i+    go finalX finalY (PipeM mx) y = PipeM (flip (go finalX finalY) y `liftM` mx)+    go finalX finalY x (PipeM my) = PipeM (go finalX finalY x `liftM` my)+    go finalX finalY (NeedInput px cx) (NeedInput py cy) = NeedInput+        (\i -> go finalX finalY (px i) (py i))+        (\u -> go finalX finalY (cx u) (cy u))+    go finalX finalY (NeedInput px cx) (Done y) = NeedInput+        (\i -> go finalX finalY (px i) (Done y))+        (\u -> go finalX finalY (cx u) (Done y))+    go finalX finalY (Done x) (NeedInput py cy) = NeedInput+        (\i -> go finalX finalY (Done x) (py i))+        (\u -> go finalX finalY (Done x) (cy u))++-- | Provides an alternative @Applicative@ instance for @ConduitM@. In this instance,+-- every incoming value is provided to all @ConduitM@s, and output is coalesced together.+-- Leftovers from individual @ConduitM@s will be used within that component, and then discarded+-- at the end of their computation. Output and finalizers will both be handled in a left-biased manner.+--+-- As an example, take the following program:+--+-- @+-- main :: IO ()+-- main = do+--     let src = mapM_ yield [1..3 :: Int]+--         conduit1 = CL.map (+1)+--         conduit2 = CL.concatMap (replicate 2)+--         conduit = getZipConduit $ ZipConduit conduit1 <* ZipConduit conduit2+--         sink = CL.mapM_ print+--     src $$ conduit =$ sink+-- @+--+-- It will produce the output: 2, 1, 1, 3, 2, 2, 4, 3, 3+--+-- Since 0.1.5+newtype ZipConduit i o m r = ZipConduit { getZipConduit :: ConduitM i o m r }+    deriving Functor+instance Monad m => Applicative (ZipConduit i o m) where+    pure = ZipConduit . pure+    ZipConduit left <*> ZipConduit right = ZipConduit (zipConduit left right)++-- | Provide identical input to all of the @Conduit@s and combine their outputs+-- into a single stream.+--+-- Implemented on top of @ZipConduit@, see that data type for more details.+--+-- Since 0.1.5+sequenceConduits :: (Traversable f, Monad m) => f (ConduitM i o m r) -> ConduitM i o m (f r)+sequenceConduits = getZipConduit . sequenceA . fmap ZipConduit
conduit-extra.cabal view
@@ -1,5 +1,5 @@ Name:                conduit-extra-Version:             0.1.4+Version:             0.1.5 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,6 +17,7 @@                      , Data.Conduit.Extra.Pipes                      , Data.Conduit.Extra.Resumable                      , Data.Conduit.Extra.ZipSink+                     , Data.Conduit.Extra.ZipConduit                      , Data.Conduit.Extra.Utils   Build-depends:       base                     >= 4            && < 5                      , conduit                  >= 1.0
test/main.hs view
@@ -13,6 +13,7 @@ import qualified Data.Conduit.Extra as CE import Data.Conduit (runResourceT) import qualified Data.Conduit.ExtraSpec as ES+import qualified Data.Conduit.Extra.ZipConduitSpec as ZipConduit   main :: IO ()@@ -33,3 +34,4 @@             x `shouldBe` (505000 :: Integer)      ES.spec+    ZipConduit.spec