[Haskell-cafe] [iteratee] empty chunk as special case of input

Sergey Mironov ierton at gmail.com
Thu Jul 14 14:45:58 CEST 2011


2011/7/14 John Lato <jwlato at gmail.com>:
> Sorry for the followup, but I forgot about one other important reason
> (probably the real reason) for the nullC case in bindIteratee.  Note
> what happens in the regular case: the iteratee is run, and if it's in
> a completed state, the result is passed to the bound function (in the
> "m_done" line), which is then also run.  Examine what happens if the
> inner iteratee is also complete:
>
>> const . flip onDone stream
>
> which would be more clearly written as
>
>> \b _str -> onDone b stream
>
> so in this case the leftover stream result from the first iteratee
> (stream) is used as the result of the second iteratee, and the
> leftover stream from the second iteratee (_str) is discarded.

> This doesn't seem right; what should happen is that the two streams
> should be appended somehow.

Yes I see. From this point ov view, the way of ignoring second
iteratee's leftover stream is neither worse or better comparing to
other possible ways, like ignoring stream of first iteratee or
appending them together somehow. I thought about it, and now it seems
that all this problem exists because of iteratee's possibility to jump
into done state without processing any data.

I came to iteratees from IncrementalGet library (binary-strict
package), and thought that they are using similar concepts, but now I
see big difference - IncrementalGet's approach doesn't allow such
state change. That is how they define /Get/ (iteratee-like structure).

newtype Get r a = Get { unGet :: S -> (a -> S -> IResult r) -> IResult r }

data IResult a = IFailed S String
               | IFinished S a
               | IPartial (B.ByteString -> IResult a)

data S = S ...  -- contains data chunk (bytestring) and some other state holders

unGet has similar design in onDone branch, but onCont is hidden inside
IResult. So, user can't obtain the result without providing a stream
as input. Well, there is also black magic there..  but I think It
makes impossible to have two conflicting iteratees like bindIteratee
may discover.

I would like to compare  those approaches and decide what is "better"
(it depends on task of course, but how?).. binary-strict's code is
easier to understand, but iteratees are more general and offer more
features, including very powerfull stream transformations. Is it good
idea to merge somehow those approaces? For example, if I'll replace
IncrementalGet's hardcoded stream type with type variable like
iterarees do, will I be able to implement convStream on top of Get,
how do you think? What about enumeratees?

By the way, Iteratee package contains itertut.lhs - very good
tutorial, thanks! It says that CPS was used to eliminate constructors.
How do yo think, may I hope that one day compiler will be able to
transform constructor-based approach, introduced there, into CPS
automatically?

Thanks,
Sergey



More information about the Haskell-Cafe mailing list