Thanks, that was it! I was wondering how it knew whether its elements were bytes or chunks, and that answer it.
On Tuesday, September 15, 2015 at 6:30:17 PM UTC-4, Gabriel Gonzalez wrote: > > Are you sure you are using the correct `splitAt`? From your latest code > snippet it looks like you changed it to use `Pipes.Parse.splitAt` but you > should be using `Pipes.ByteString.splitAt`. > > The difference between the two is that: > > * `Pipes.Parse.splitAt` will skip `n` elements (where the elements in this > case are chunks) so you skip `n` chunks > * `Pipes.ByteString.splitAt` will skip `n` bytes (regardless of what the > chunk sizes are) > > However, you are right that `decodeGet` buffers the entire decoded > bytestring in memory before discarding it at the end whereas `skipNBytes` > will run in constant space. The original rationale for this was that the > author of `pipes-binary` wanted `decodeGet` to be able to recover from > failures by rewinding the input stream to where it began. > > On 9/15/15 3:02 PM, Dylan Tisdall wrote: > > Thanks for the heads-up Michael; that makes more sense now. > > However, I've tried to implement Gabriel's suggestion, and it's not > behaving as I'd expect in my target application. I'm wondering if someone > can help me figure out why. I've got the relevant code snipped below, with > the suggested skipNBytes and then a decoder for my application. > > skipNBytes :: Monad m => Int -> P.Parser P.ByteString m () > skipNBytes n = zoom (P.splitAt n) P.skipAll > > > decoder :: P.Parser P.ByteString IO () > decoder = do > headerLenRes <- P.decodeGet getWord32le > lift $ print (headerLenRes :: Either P.DecodingError Word32) > case headerLenRes of > Left err -> lift $ print err > Right hLenRes -> parseRest ((fromIntegral hLenRes) - 4) > where > parseRest hLen = do > skipNBytes $ hLen > --P.decodeGet $ getByteString hLen > mdh <- P.decode > lift $ print (mdh :: Either P.DecodingError MDH.MDH) > > > Leaving the details aside (e.g., MDH.MDH implements Binary so I can just > call P.decode to parse it), my problem is that > > skipNBytes $hLen > > doesn't seem to consume the same number of bytes as > > P.decodeGet $ getByteString hLen > > If I use the second line, I parse a correct MDH.MDH out of my input > stream. If I use the skipNBytes line, I end up in the wrong place in my > input stream. I had assumed these two lines were identical, except for the > fact that the second buffers all the data before throwing it away, with the > first reads it in one byte at a time and throws it away. That's not what > I'm seeing, though. Any suggestions for what I'm missing? > > > Thanks, > Dylan > > > On Tuesday, September 15, 2015 at 4:54:46 PM UTC-4, Michael Thompson > wrote: >> >> By the way, to forestall confusion, `zoom` is in `Lens.Micro.Mtl` in >> order to sort out the dependencies. `Lens.Micro.Mtl` is also needed for >> `view`, but not for `(^.)`, because, following `Control.Lens`, `view` is >> typed as >> >> view :: MonadReader s m => Getting a s a -> m a >> >> The convenient way to get all the customary combinators for pipes use is >> thus >> >> import Lens.Micro.Platform >> >> which just has a couple natural dependencies outside the boot libraries. >> I haven't come across any difficulty with that. >> > -- > 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 haskell-pipe...@googlegroups.com <javascript:>. > To post to this group, send email to haskel...@googlegroups.com > <javascript:>. > > > -- 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 haskell-pipes+unsubscr...@googlegroups.com. To post to this group, send email to haskell-pipes@googlegroups.com.