
I think I finally figured out the deeper problem behind an issue I was having getting some things to fuse fully. I'm hoping someone has a brilliant idea for getting around it. Of course, it may be that someone else has thoroughly studied the matter and determined that there's no good solution. Suppose we write crazy :: T -> [U] crazy x = some $ long $ fusion $ pipeline oops f = map f $ crazy x uhOh c n = foldr c n $ crazy Pig ohMy = take bignum $ crazy amigo When GHC compiles crazy, it rewrites the pieces of the pipeline to build/foldr forms, fuses them, and produces crazy x = build someBigFunction In then inlines build, producing crazy x = anotherBiggy So far, this looks reasonably sensible, but it's likely bad. The problem is that GHC will (rightly) conclude that `build someBigFunction` is too big to inline, and therefore the fusion will break at that boundary and we'll produce intermediate lists in the functions that use crazy. Now if we were playing the part of the compiler by hand, we would likely factor out someBigFunction and then *refrain from inlining build*. That is, we would get {-# NOINLINE crazyB #-} crazyB x = someBigFunction crazy = nonInliningBuild crazyB Since we've factored out someBigFunction into crazyB, we can now safely inline crazy itself, allowing the pipeline to continue beyond it. The problem, of course, is that when we *don't* fuse beyond, there is some performance penalty (I have not tried to measure it yet) to passing in (:) and [] at runtime instead of fixing them at compile time.