I noticed this problem some time ago. Beyond just breaking
monadic associativity, there are many other issues with standard
definitions of iteratees:
1. It does not make sense in general to bind with an
iteratee that has already consumed input, but there's no
type-level difference between a "virgin" iteratee and one that
has already consumed input;
2. Error recovery is ill-defined because errors do not
describe what portion of the input they have already consumed;
3. Iteratees sometimes need to manage resources, but
they're not designed to do so which leads to hideous
workarounds;
4. Iteratees cannot incrementally produce output, it's all
or nothing, which makes them terrible for many real world
problems that require both incremental input and incremental
output.
Overall, I regard iteratees as only a partial success.
They're leaky and somewhat unsafe abstractions.