On Sun, Mar 3, 2013 at 10:24 PM, Joey Adams <joeyadams3.14159@gmail.com> wrote:
...Here's a possible API for a resumable Conduit:
...
newtype ResumableConduit i m o = -- hidden --
newResumableConduit :: Monad m => Conduit i m o -> ResumableConduit i m o
-- | Feed the 'Source' through the conduit, and send any output from the
-- conduit to the 'Sink'. When the 'Sink' returns, close the 'Source', but
-- leave the 'ResumableConduit' open so more data can be passed through it.
runResumableConduit
:: Monad m
=> ResumableConduit i m o
-> Source m i
-> Sink o m r
-> m (ResumableConduit i m o, r)While trying to implement this, I found a more elegant interface for resuming the ResumableConduit:
-- | Fuse a 'ResumableConduit' to a 'Sink'. When the 'Sink' returns,
-- it returns the 'ResumableConduit' so the caller can reuse it.
(=$++) :: Monad m-> Sink i m (ResumableConduit i m o, r)
=> ResumableConduit i m o
-> Sink o m rThis takes advantage of Sink's return value to forward the ResumableConduit. I don't think a ($=++) can be implemented.
Advantages:* (=$++) is easier to implement than 'runResumableConduit' since it only has to fuse two pipes together instead of three.* Pretty syntax: (resumable', a) <- source $$ resumable =$++ sink