GHC doesn't actually perform stream fusion. Not by default, anyway: The default (by that I mean "ships with base", not that it's baked into the compiler) is something weaker, called build/foldr fusion, described by this rule:
foldr z f (build g) = g f z
Foldr is the usual catamorphism for the inductive list type, and build is an "abstracted constructor", of sorts:
build :: (forall b. (a -> b -> b) -> b -> b) -> [a]
build f = f (:) []
Note that build's argument is rank-2 polymorphic, and also the same as foldr's type.
Foldr is the usual catamorphism for the inductive list type, and build is an "abstracted constructor", of sorts:
Note that build's argument is rank-2 polymorphic, and also the same as foldr's type.