
yi huang
I just read several tutorials on iteratee, i find that iteratee is similar to python's generator, both allow streamlined data processing. For example, i can implement enumFile and printChunks in python like this:
EOF = None def enum_file(bufsize, filename): with open(filename) as input: while True: data = input.read(bufsize) if not data: break yield data yield EOF
def print_chunks(print_empty, generator): for chunk in generator: if chunk==EOF: print 'EOF' return if len(chunk)==0 and not print_empty: continue print chunk
print_chunks(True, enum_file(2, "data"))
But i find iteratee far more complicated than python's generator, is that because iteratee can do something python's generator can't, or i simply need to be more familar with functional programming style.
I don't know Python very well, but I suspect that its generators are really a sort of coroutines. Iteratees are also coroutines, but their architecture is quite different. The difference is that conceptually an iteratee does not know about its input. In Python the generator stops to wait for the iterator to request more input: The consumer talks to the producer. This control flow is turned inside out in iteratees, where the iteratee stops to wait for the enumerator to provide more input. The producer talks to the consumer in iteratees. This is a conceptual difference, so what's the advantage? The main advantage of iteratees, compared to generators, can be seen in a statically typed language such as Haskell. Let's say that instead of printing the input lines your consumer would instead just calculate its length and return it. Let's call this consumer 'length'. If you would translate generators to Haskell, you would find that your 'length' consumer would suddenly include a MonadIO constraint, even though it doesn't need it. With iteratees' inversion of control only the part which needs the MonadIO constraint really has it. An enumerator is really a function from an iteratee to an iteratee. It converts an arbitrary iteratee to an iteratee with additional input, adding the constraints necessary to fulfill this task. While with the generator concept you apply a producer to a consumer, with iteratees you apply a consumer to an producer. Hope that helps. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/