packages feed

pipes-extra 0.0.1 → 0.1.0

raw patch · 7 files changed

+107/−62 lines, 7 filesdep +transformersdep −mtldep ~pipes-corePVP ok

version bump matches the API change (PVP)

Dependencies added: transformers

Dependencies removed: mtl

Dependency ranges changed: pipes-core

API changes (from Hackage documentation)

- Control.Pipe.ChunkPipe: ChunkPipe :: Pipe a b m (a, r) -> ChunkPipe a b m r
- Control.Pipe.ChunkPipe: instance (Monoid a, Monad m) => Monad (ChunkPipe a b m)
- Control.Pipe.ChunkPipe: newtype ChunkPipe a b m r
- Control.Pipe.ChunkPipe: nonchunked :: (Monoid a, Monad m) => Pipe a b m r -> ChunkPipe a b m r
- Control.Pipe.ChunkPipe: unChunkPipe :: ChunkPipe a b m r -> Pipe a b m (a, r)
- Control.Pipe.Coroutine: suspendE :: Coroutine a b m r -> SomeException -> Pipe a b m r
+ Control.Pipe.PutbackPipe: PutbackPipe :: Pipe (Either a a) (Either b a) m r -> PutbackPipe a b m r
+ Control.Pipe.PutbackPipe: await :: Monad m => PutbackPipe a b m a
+ Control.Pipe.PutbackPipe: fromPipe :: Monad m => Pipe a b m r -> PutbackPipe a b m r
+ Control.Pipe.PutbackPipe: instance Monad m => Applicative (PutbackPipe a b m)
+ Control.Pipe.PutbackPipe: instance Monad m => Functor (PutbackPipe a b m)
+ Control.Pipe.PutbackPipe: instance Monad m => Monad (PutbackPipe a b m)
+ Control.Pipe.PutbackPipe: instance MonadIO m => MonadIO (PutbackPipe a b m)
+ Control.Pipe.PutbackPipe: instance MonadTrans (PutbackPipe a b)
+ Control.Pipe.PutbackPipe: newtype PutbackPipe a b m r
+ Control.Pipe.PutbackPipe: putback :: Monad m => a -> PutbackPipe a b m ()
+ Control.Pipe.PutbackPipe: runPutback :: Monad m => PutbackPipe a b m r -> Pipe a b m r
+ Control.Pipe.PutbackPipe: tryAwait :: Monad m => PutbackPipe a b m (Maybe a)
+ Control.Pipe.PutbackPipe: unPutback :: PutbackPipe a b m r -> Pipe (Either a a) (Either b a) m r
+ Control.Pipe.PutbackPipe: yield :: Monad m => b -> PutbackPipe a b m ()
- Control.Pipe.Coroutine: resume :: Monad m => Pipe a b m r -> Pipe a x m (Either r (b, Coroutine a b m r))
+ Control.Pipe.Coroutine: resume :: Coroutine a b m r -> Pipe a b m r
- Control.Pipe.Coroutine: suspend :: Coroutine a b m r -> Pipe a b m r
+ Control.Pipe.Coroutine: suspend :: Monad m => Pipe a b m r -> Pipe a x m (Either r (b, Coroutine a b m r))
- Control.Pipe.Coroutine: terminate :: Monad m => Coroutine a b m r -> Pipe a x m ()
+ Control.Pipe.Coroutine: terminate :: Monad m => Coroutine a b m r -> Pipe a b m ()

Files

Control/Pipe/Binary.hs view
@@ -15,7 +15,8 @@   ) where  import Control.Monad-import Control.Monad.Trans (MonadIO, liftIO, lift)+import Control.Monad.IO.Class+import Control.Monad.Trans.Class import Control.Pipe import Control.Pipe.Exception import Control.Pipe.Combinators (tryAwait, feed)@@ -105,6 +106,7 @@     go leftover = do       mchunk <- tryAwait       case mchunk of+        Nothing | B.null leftover -> idP         Nothing -> yield leftover >> idP         Just chunk -> split chunk leftover     split chunk leftover
− Control/Pipe/ChunkPipe.hs
@@ -1,29 +0,0 @@--- | This module contains utilities to create and combine pipes that accept--- "chunked" input and return unconsumed portions of their internal buffer.------ The main interface is an alternative monad instance for Pipe, which passes--- leftover data along automatically.-module Control.Pipe.ChunkPipe (-  ChunkPipe(..),-  nonchunked,-  ) where--import Control.Pipe-import Data.Monoid---- | Newtype wrapper for Pipe proving a monad instance that takes care of--- passing leftover data automatically.------ An individual 'ChunkPipe' is just a regular pipe, but returns unconsumed--- input in a pair alongside the actual return value.-newtype ChunkPipe a b m r = ChunkPipe { unChunkPipe :: Pipe a b m (a, r) }--instance (Monoid a, Monad m) => Monad (ChunkPipe a b m) where-  return = nonchunked . return-  (ChunkPipe p) >>= f = ChunkPipe $ p >>= \(leftover, result) ->-    (yield leftover >> idP) >+> unChunkPipe (f result)---- | Create a 'ChunkPipe' out of a regular pipe that is able to consume all its--- input.-nonchunked :: (Monoid a, Monad m) => Pipe a b m r -> ChunkPipe a b m r-nonchunked p = ChunkPipe $ p >>= \r -> return (mempty, r)
Control/Pipe/Coroutine.hs view
@@ -1,46 +1,45 @@+{-# LANGUAGE DeriveDataTypeable #-} module Control.Pipe.Coroutine (   Coroutine,-  coroutine,-  suspend,-  suspendE,   resume,+  suspend,+  coroutine,   step,   terminate   ) where  import Control.Monad import Control.Pipe+import Control.Pipe.Exception import qualified Control.Exception as E+import Data.Typeable+import Prelude hiding (catch)  data Coroutine a b m r = Coroutine-  { suspend :: Pipe a b m r-  , suspendE :: E.SomeException -> Pipe a b m r }+  { resume :: Pipe a b m r+  , finalizer :: [m ()]+  } -resume :: Monad m-       => Pipe a b m r-       -> Pipe a x m (Either r (b, Coroutine a b m r))-resume (Pure r) = return $ Left r-resume (Throw e) = throwP e-resume (Free c h) = go c >>= \x -> case x of-  Left p       -> resume p-  Right (b, p) -> return $ Right (b, Coroutine p h)-  where-    go (Await k) = liftM (Left . k) await-    go (Yield b p) = return $ Right (b, p)-    go (M m s) = liftM Left $ liftP s m+suspend :: Monad m+        => Pipe a b m r+        -> Pipe a x m (Either r (b, Coroutine a b m r))+suspend (Pure r w) = Pure (Left r) w+suspend (Throw e w) = Throw e w+suspend (Yield x p w) = return (Right (x, Coroutine p w))+suspend (M s m h) = M s (liftM suspend m) (suspend . h)+suspend (Await k h) = Await (suspend . k) (suspend . h)  coroutine :: Monad m           => Pipe a b m r           -> Coroutine a b m r-coroutine p = Coroutine p throwP+coroutine p = Coroutine p []  step :: Monad m      => Coroutine a b m r      -> Pipe a x m (Either r (b, Coroutine a b m r))-step = resume . suspend+step = suspend . resume  terminate :: Monad m           => Coroutine a b m r-          -> Pipe a x m ()-terminate (Coroutine _ h) =-  void (catchP discard h) >+> return ()+          -> Pipe a b m ()+terminate p = mapM_ masked (finalizer p)
+ Control/Pipe/PutbackPipe.hs view
@@ -0,0 +1,73 @@+-- | This module contains an alternative pipe implementation, 'PutbackPipe',+-- providing an additional primitive 'putback', which allows data to be+-- inserted into the input stream of the current pipe.+--+-- PutbackPipes can be used to implement pipes with left-over data, and can be+-- composed vertically (using the Monad instance), but not horizontally.+--+-- To make use of a PutbackPipe within a 'Pipeline', you need to convert it to+-- a regular 'Pipe' using 'runPutback'.+module Control.Pipe.PutbackPipe (+  PutbackPipe(..),+  fromPipe,+  putback,+  yield,+  await,+  tryAwait,+  runPutback+  ) where++import Control.Applicative+import Control.Monad+import Control.Monad.IO.Class+import Control.Monad.Trans.Class+import qualified Control.Pipe as P+import Control.Pipe ((>+>), Pipe)+import qualified Control.Pipe.Combinators as PC+import Control.Pipe.Monoidal++-- | The 'PutbackPipe' data type.+newtype PutbackPipe a b m r = PutbackPipe {+  unPutback :: Pipe (Either a a) (Either b a) m r+  }++instance Monad m => Monad (PutbackPipe a b m) where+    return = PutbackPipe . return+    (PutbackPipe p) >>= f = PutbackPipe (p >>= unPutback . f)++instance MonadTrans (PutbackPipe a b) where+  lift = PutbackPipe . lift++instance Monad m => Functor (PutbackPipe a b m) where+  fmap f (PutbackPipe p) = PutbackPipe (liftM f p)++instance Monad m => Applicative (PutbackPipe a b m) where+  pure = return+  (<*>) = ap++instance MonadIO m => MonadIO (PutbackPipe a b m) where+  liftIO a = PutbackPipe (liftIO a)++-- | Create a 'PutbackPipe' from a regular pipe.+fromPipe :: Monad m => Pipe a b m r -> PutbackPipe a b m r+fromPipe p = PutbackPipe (joinP >+> p >+> P.pipe Left)++-- | Put back an element into the input stream.+putback :: Monad m => a -> PutbackPipe a b m ()+putback = PutbackPipe . P.yield . Right++-- | Same as 'P.yield' for regular pipes.+yield :: Monad m => b -> PutbackPipe a b m ()+yield = PutbackPipe . P.yield . Left++-- | Same as 'P.await' for regular pipes.+await :: Monad m => PutbackPipe a b m a+await = PutbackPipe $ liftM (either id id) P.await++-- | Same as 'PC.tryAwait' for regular pipes.+tryAwait :: Monad m => PutbackPipe a b m (Maybe a)+tryAwait = PutbackPipe $ liftM (fmap (either id id)) PC.tryAwait++-- | Convert a 'PutbackPipe' to a regular pipe.+runPutback :: Monad m => PutbackPipe a b m r -> Pipe a b m r+runPutback = loopP . unPutback
Control/Pipe/Tee.hs view
@@ -17,10 +17,10 @@   teeFileBS   ) where -import Control.Monad.Trans   (MonadIO(..))+import Control.Monad.IO.Class import Control.Pipe-import Control.Pipe.Binary   (fileWriter)-import Data.ByteString       (ByteString)+import Control.Pipe.Binary+import Data.ByteString  -- | Acts like 'idP', but also passes a copy to the supplied consumer. tee :: (Monad m)
Control/Pipe/Zip.hs view
@@ -22,15 +22,15 @@              => Producer a m r              -> Pipe (Either () (ProducerControl r)) a m r controllable p = do-  x <- pipe (const ()) >+> resume p+  x <- pipe (const ()) >+> suspend p   case x of     Left r -> return r     Right (b, p') ->       join $ onException         (await >>= \c -> case c of-          Left () -> yield b >> return (controllable (suspend p'))+          Left () -> yield b >> return (controllable (resume p'))           Right (Done r) -> return $ (pipe (const ()) >+> terminate p') >> return r-          Right (Error e) -> return $ controllable (suspendE p' e))+          Right (Error e) -> return $ (pipe (const ()) >+> terminate p') >> throw e)         (pipe (const ()) >+> terminate p')  controllable_ :: Monad m
pipes-extra.cabal view
@@ -1,5 +1,5 @@ Name: pipes-extra-Version: 0.0.1+Version: 0.1.0 License: BSD3 License-file: LICENSE Author: Paolo Capriotti@@ -19,12 +19,12 @@ Library     Build-Depends:         base (== 4.*),-        mtl,-        pipes-core (== 0.0.*),+        transformers (>= 0.2 && < 0.4),+        pipes-core (== 0.1.*),         bytestring (== 0.9.*)     Exposed-Modules:         Control.Pipe.Binary,         Control.Pipe.Coroutine,-        Control.Pipe.ChunkPipe,+        Control.Pipe.PutbackPipe,         Control.Pipe.Tee,         Control.Pipe.Zip