
Pedro Some responses to your long message! (Which I attach for background) Your example was unusual in that it used a lot of top-level definitions. GHC treats them slightly specially. Given: x = g 4 y = f x GHC does not transform into this: y = f (g 4) which it would do in a nested let. Why not? Because the latter will generate code that dynamically allocates a thunk for (g 4), while the former will make a static thunk. (An alternative would be to treat them uniformly and only pull out those nested thunks at the very last minute; but GHC doesn't do that right now.) A disadvantage is that it's not statically visible to the simplifier that x is used once. If we have a RULE for f (g n), it might not fire -- because of the worry that someone else might be sharing x. I think this is the root cause of much of your trouble. Incidentally , it makes no difference giving x an INLINE pragma. GHC is very cautious about duplicating non-values and currently not even INLINE will make it less cautious. That's another thing we could consider changing. I'll respond to part 2 (about generic programming) separately Simon