-- | 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)