Overlapping instances, incoherence, and optimisation
Segei Meshveliani reports that his
docon library has rather unexpected behaviour with GHC 7.10. See his email.
The effect is that his test module
Main has different runtime behaviour when compiling with and without
-O. This sounds pretty bad.
The reason is this:
He has overlapping instances for a class, say
instance ... => C (T a), call it (A)
instance C (T Int), call it (B)
The actual situation is more complicated of course
The instances are defined in different modules.
In one module
* instance (B) is not visible
* there is a function
f :: C a => a -> a
fis called at type
So GHC specialises
f_spec :: T Int -> T Int, and exports a RULE
RULE "SPEC" f = f_spec :: T Int -> T Int
The idea is that any other module that calls
f at type
T Int can simply re-use the specialised (and presumably much faster) version of
f. But note that since (B) is not visible, so GHC finds a solution using (A), and embodies that in
- In another module,
Use, which can see (B) and
Spec, we call
T Int. In the absence of the cross-module specialisation rule, or without
-O, GHC would solve the constraint
C (T Int), this time using (B). But because of the rule, with
-O, it re-uses
f_spec. Result: different runtime behaviour.
There is a more detailed discussion on this thread.