conduit-1.0.13: Data/Conduit/Util.hs
-- | Various utility functions versions of @conduit@.
module Data.Conduit.Util
( -- * Misc
zip
, zipSources
, zipSinks
, passthroughSink
) where
import Prelude hiding (zip)
import Data.Conduit.Internal (Pipe (..), Source, Sink, ConduitM (..), Conduit, awaitForever, yield, await, zipSinks, zipSources)
import Data.Void (absurd)
import Control.Monad.Trans.Class (lift)
-- | Deprecated synonym for 'zipSources'.
--
-- Since 0.3.0
zip :: Monad m => Source m a -> Source m b -> Source m (a, b)
zip = zipSources
{-# DEPRECATED zip "Use zipSources instead" #-}
-- | Turn a @Sink@ into a @Conduit@ in the following way:
--
-- * All input passed to the @Sink@ is yielded downstream.
--
-- * When the @Sink@ finishes processing, the result is passed to the provided to the finalizer function.
--
-- Note that the @Sink@ will stop receiving input as soon as the downstream it
-- is connected to shuts down.
--
-- An example usage would be to write the result of a @Sink@ to some mutable
-- variable while allowing other processing to continue.
--
-- Since 1.0.10
passthroughSink :: Monad m
=> Sink i m r
-> (r -> m ()) -- ^ finalizer
-> Conduit i m i
passthroughSink (ConduitM sink0) final =
ConduitM $ go [] sink0
where
go _ (Done r) = do
lift $ final r
awaitForever yield
go is (Leftover sink i) = go (i:is) sink
go _ (HaveOutput _ _ o) = absurd o
go is (PipeM mx) = do
x <- lift mx
go is x
go (i:is) (NeedInput next _) = go is (next i)
go [] (NeedInput next done) = do
mx <- await
case mx of
Nothing -> go [] (done ())
Just x -> do
yield x
go [] (next x)