I agree. C is weird in that the programmer has to throw away almost all of his intent and just tells the machine exactly what instructions to perform. You can read C and sort of get the idea of what the programmer wanted to do, but it's difficult. In Haskell, there is very little "how" and a lot of "what" (and "why"), and so there is much more opportunity for optimization. Your work with stream fusion is a great example -- what a C programmer might think is a bunch of loops can be condensed down to one loop "sometime later". And in Haskell, these effects can be composed, whereas in C, you are stuck with what the programmer wrote.
This is why I am always confused when people say "functional programming is slow" -- current C implementations are very close to being as fast as theoretically possible, where as current FP implementations are nowhere near that (there are many optimization opportunities that are currently unexplored or unimplemented). And even with only a few optimizations, many FP implementations (GHC, OCaml, SBCL) are almost as fast as C already!
This is why I am always confused when people say "functional programming is slow" -- current C implementations are very close to being as fast as theoretically possible, where as current FP implementations are nowhere near that (there are many optimization opportunities that are currently unexplored or unimplemented). And even with only a few optimizations, many FP implementations (GHC, OCaml, SBCL) are almost as fast as C already!