Skip to content

Missed opportunity for combineIdenticalAlts

Consider

fun1 x = case x of
          []    -> length x
          (_:_) -> length x

fun2 x = case x of
          []    -> length x
          (_:_) -> id (length x)

You might think that both would turn into

foo x = length x

because the alternatives are identical. Actually, neither do. Because in the [] branch we replace x with [], thus

fun1 x = case x of
          []    -> length []
          (_:_) -> length x

Doing this is basically a good idea; x is no longer free in the RHS, and any thunks or closures in that RHS will have fewer free vars. But it does make them look different.

It turns out that !2161 (closed) (fixing binder-swapping) makes the right thing happen for fun1, because the combine-identical-alternative stuff happens before the simplifier inlines x. But fun2 defeates it. This sensitivity to exactly when things happen is bad.

The Right Thing is for the equality test in GHC.Core.Utils realise that in the [] branch, [] and x are equal. This should not be hard to do.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information