> Additionally, it becomes easier to shoot yourself in the foot (which is mentioned in the alternative title, but doesn't seem to be expanded on much) -- say, by closing a Handle or even merely not draining the input before proceeding with other I/O, if the outside system expects you to.
Hmm, I find the opposite - iteratee-style streaming libraries are pretty much the only way you can implement something like "open this file and transform it in this way" as a library function and ensure it gets used safely, because the stream can be responsible for resource management.
(I'm opposed to Haskell-style implicit laziness though, I agree with strict and explicit chunking being the way to go).
> But once you have a bunch of dependencies with their own (byte)string/text types, errors/exceptions, and ways to do I/O, all of which should be combined and work together, those become rather annoying.
Sure. I think the answer to that is that iteratees are pretty foundational and should be built into the language, in the same way that e.g. monad is not just a library type but something that's fundamentally part of the "platform" and maybe even the standard library. Efforts like the "Haskell platform" help us move in that direction.