Ticket #2598 (new feature request)
Avoid excessive specialisation in SpecConstr
|Reported by:||simonpj||Owned by:|
|Type of failure:||None/Unknown||Difficulty:||Unknown|
|Test Case:||Blocked By:|
This ticket captures an email thread so it doesn't get lost.
Consider this (from haddock/src/Haddock/Backends/Hoogle.hs):
dropComment (' ':'-':'-':' ':_) =  dropComment (x:xs) = x : dropComment xs dropComment  = 
This desugars thus:
dropComment xs = case xs of (C# x1 : xs1) -> case x1 of ' '# -> case xs1 of (C# x2:xs2) -> case x2 of '-' -> .... DEFAULT -> dropComment (C# x2 : xs2) DEFAULT -> ...  -> ...
I have elided the branches that are less interesting, and I have done a bit of multi-level pattern matching to save space.
The thing to notice is this: at the recursive call, we know that the argument is a cons, with C# at the front. So SpecConstr dutifully creates a specialized version. And similarly for each subsequent character! Indeed, if the match fails after matching (' ': '-' : ) prefix, the recursive call even knows that the first char is '-'!
Hence we get as many specializations as we have characters in the input match.
So SpecConstr is behaving as expected. Can anyone think of a heuristic to squash this behavior? At the moment we take the first N specializations and then stop. One heuristic might be "if there are lots of recursive calls, don't specialize". But that is very close to "if there are lots of specializations, drop some". Mind you, perhaps we should be more vigorous still: "if there are more than N, don't do any" on the grounds that randomly choosing the first few is unlikely to be useful.