
Ah, now I see the issue seems to be closeley related to full lazy lambda lifting. Given.. f = \x -> <blah> x where <blah> has no free occurences of x, then I thought the compiler would reduce this immediately to f = <blah>
Full lazy lambda lifting would give something like this.. b = <blah> f = \x -> b x But this still requires, the (\x -> b x) to be reduced to b to get.. b = <blah> f = b (and hence f = <blah>)
This transformation (eta reduction) is done by GHC under certain circumstances; in particular I believe that in the case where a binding can be eta-reduced so that its right hand side becomes a variable, then the reduction will be performed on the grounds that we can then substitute the binding everywhere without loss of efficiency or increase in code size. However, sometimes it is more beneficial to do the opposite, namely eta expansion. This is because in GHC a call to a known function with all the arguments present is the fastest type of call. Eg: f = \x -> h a x could be reduced to f = h a but if h has arity 2, then the call to h changes from a fast to a slow one, and futhermore we can't make any fast calls to f. On the other hand, the code for the second version is somewhat smaller. There are some subtle tradeoffs here, and this is one of the areas where we often tweak GHC's behaviour in order to try to pick the right balance more often. Cheers, Simon