<br><br><div class="gmail_quote">On Thu, Jul 29, 2010 at 10:35 AM, Jason Dagit <span dir="ltr">&lt;<a href="mailto:dagit@codersbase.com">dagit@codersbase.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br><br><div class="gmail_quote"><div class="im">On Thu, Jul 29, 2010 at 6:15 AM, Duncan Coutts <span dir="ltr">&lt;<a href="mailto:duncan.coutts@googlemail.com" target="_blank">duncan.coutts@googlemail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><br></div><div>
<br>
</div>No idea what WrappedByteString is.<br></blockquote><div><br></div></div><div>WrappedByteString is a newtype wrapper around ByteString that has a phantom type.  This allows instances of to be written such that ByteString can be used with the iteratee library.  You can see the source here if you&#39;re interested:</div>

<div><a href="http://hackage.haskell.org/packages/archive/iteratee/0.3.5/doc/html/src/Data-Iteratee-WrappedByteString.html" target="_blank">http://hackage.haskell.org/packages/archive/iteratee/0.3.5/doc/html/src/Data-Iteratee-WrappedByteString.html</a></div>
<div class="im">
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
It would look like attoparsec&#39;s resumable parser:<br>
<br>
data Result a = Fail !ByteString<br>
              | Partial (ByteString -&gt; Result a)<br>
              | Done !ByteString a<br>
<br>
runGet :: Get a -&gt; ByteString -&gt; Result a<br>
<br>
Point is you feed it strict bytestring chunks. Then decoding a lazy<br>
bytestring can be implemented on top easily, as can decoding a sequence<br>
lazily.<br></blockquote><div> </div></div><div>Like attoparsec you&#39;ll probably want to write some other utility functions for working with Results.  Attoparsec defines feed, parseWith, maybeResult, and eitherResult.  I think you&#39;ll want something similar here. </div>
</div></blockquote><div><br></div><div>And I forgot to mention....</div><div><br></div><div>Given those constructors for Result, how will you decode a sequence lazily?  I agree you can consume the input lazily but, decodings won&#39;t produce any values until you hit Done. This is something I noticed with attoparsec as well.  You can feed it incrementally, but it doesn&#39;t produce output until it reaches a Done state.  In one project, were the input was line based records, I used ByteString&#39;s hGetLine to read individual lines and then parse them individually.  That gave me a Result for each line and I could build incremental processing of records on top of that.</div>
<div><br></div><div>Perhaps I was using attoparsec incorrectly, but as far as I can tell it doesn&#39;t have a way to incrementally produce results.  I think what needs to be added is a way to &#39;yield&#39; and &#39;resume&#39;.  What I can&#39;t figure out, is how to meaningfully return &#39;partial results&#39; in general.  In cases where the top level combinator is something like manyTill it makes sense, but in other cases it&#39;s unclear to me.  And I think you&#39;d need to add a constructor above that is some variation of &quot;PartiallyDone a ByteString (ByteString -&gt; Result a)&quot;.</div>
<div><br></div><div>Jason</div></div>