Compilers like GHC for Haskell use inlining as one of its most important optimising tools. Doing that is not possible for recursive functions, in general. A few techniques have been developed to amend this problem, such as Stream Fusion, which allow the combination of list consuming/producing functions. Those techniques require specialised, specific algorithms and only work for a restricted set of recursive functions.
My question is: what determines which recursive functions can, and which recursive functions can not be fused that way? Is there a programming system with well-behaved recursion where any arbitrary function could be fused this way?