Should I be able to expect a Haskell compiler be smart enough to optimize the following definition:
h x y = p (m x) (n y)
into something like this:
h x = let z = m x in \y -> p z (n y)
? This could be convenient if m were expensive to evaluate, and I used h‘s definition in the following way:
main = print $ map (h 2) hugeList
But what if
mis cheap to evaluate, but its result expensive to store? Saym x = [x .. ]andpneeds to traverse different prefixes of that list, depending onn y. If thenm 2is shared inmap (h 2) hugeList, and any of the list elements requires a long prefix, you have huge memory requirements even if all subsequent elements only require the first element of the list to return the result.So an automatic sharing of
m xcan also be a pessimisation, hence you should not expect all compilers to automatically share it.Generally, it is difficult for the compiler to decide whether sharing is beneficial or even detrimental, so you should make sharing explicit where you really want it. (Nevertheless, expect compilers to introduce sharing even where you do not want it sometimes.)