In the specific case of `pipes-http`, it actually is safe to run the
`Producer` multiple times. This is because it is internally just
reading off of an `IO ByteString` action.
To be honest, I think the easiest solution is to just teach users to
only pass over `Producer`s once. This has worked fine for `conduit`
users, so I see no reason why `pipes` should complicate things by
behaving differently.
Note that the issue of whether or not a `Producer` is resumable is
orthogonal to whether or not it should be replayable (which is the
*real* issue). Even if you restrict yourself to non-resumable
`Producer`s and only permit `runEffect` and `(>->)` (or `($$)`/`(=$=)`
for `conduit`) you can still trigger pathological behavior just by
replaying `Producer`s. All you have to do is run a `Producer` to
completion twice to mess with any protocol:
runEffect $ someProducer >-> consumer1
-- The following line will probably produce garbage
runEffect $ someProducer >-> consumer2
There's no good solution within the language to prevent users from
screwing things up. For example, consider the `once` function I
mentioned previously in this thread:
once :: Producer a IO r -> IO (Producer a IO r)
The easy way to break this function is to call `once` twice generating
two separate `Producer`s. The second generated `Producer` is most
likely garbage. Asking the user to not call `once` twice is just as
unsafe as asking the user not to run a given `Producer` twice, so you're
back to where you started.
On 01/31/2014 04:03 PM, Brendan Hay wrote:
Something similar would be useful as a response body for your recent
Pipes HTTP library POC, wherein the result is not wrapped inside the
`withXXX` idiom.
This seems to involve pipes-safe - would a hypothetical
`ResumableProducer` be possible?
On Fri, Jan 31, 2014 at 9:55 AM, Gabriel Gonzalez
<[email protected] <mailto:[email protected]>> wrote:
Oops, two more mistakes:
It's `toParser_`, not `toParser'`.
Also, `maxLines` still has a mistake because it doesn't re-yield
the newline byte. Maybe I should provide a `line` lens that
includes the newline byte for simplicity. Anyway, it's a
digression from the discussion.
On 01/31/2014 03:49 PM, Gabriel Gonzalez wrote:
Alright, so I added two utilities to `pipes-parse` for converting
`Consumer`s to `Parser`s:
toParser :: Monad m => Consumer (Maybe a) m r -> Parser a m r
toParser' :: Monad m => Consumer a m X -> Parser a m ()
These cover most common cases with good efficiency.
Also, I noticed there was a slight mistake in my example
implementation of `maxLines` because it was not consuming the
newline byte. The correct version is this:
maxLines n = iso (cut n) join
where
cut 0 p = return p
cut n p = do
p' <- p ^. PB.line
p'' <- lift (execStateT PB.drawByte p') -- Drain
newline byte
cut (n - 1) p''
--
You received this message because you are subscribed to the
Google Groups "Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected]
<mailto:[email protected]>.
To post to this group, send email to
[email protected]
<mailto:[email protected]>.
--
You received this message because you are subscribed to the Google
Groups "Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected]
<mailto:haskell-pipes%[email protected]>.
To post to this group, send email to
[email protected]
<mailto:[email protected]>.
--
You received this message because you are subscribed to the Google
Groups "Haskell Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected].
To post to this group, send email to [email protected].
--
You received this message because you are subscribed to the Google Groups "Haskell
Pipes" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].