Instantiation doesn't look through dictionaries
The bug is simple to state in terms of GHC's implementation: topInstantiate
does not look past dictionaries. Thus a type like forall a. C a => forall b. ...
only gets its a
instantiated, not its b
. This can be witnessed is some ugly-looking code:
data Rec a b = MkRec { x :: Bool }
class C a where
r :: Rec a b
instance C Int where
r = MkRec { x = True }
foo :: Rec Int Bool
foo = r { x = False }
This fails with
/Users/rae/temp/Bug.hs:10:7: error:
• Ambiguous type variable ‘a0’ arising from a use of ‘r’
prevents the constraint ‘(C a0)’ from being solved.
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instance exist:
instance C Int -- Defined at /Users/rae/temp/Bug.hs:6:10
• In the expression: r
In the expression: r {x = False}
In an equation for ‘foo’: foo = r {x = False}
I have no idea why it's an ambiguous-variable error, but let's not get distracted by that. The problem is that GHC does not instantiate r
vigorously enough to notice that it's a record. The solution is straightforward: have topInstantiate
be recursive, looking past dictionaries. topInstantiate
is used in other places, too, and perhaps there are other similar bugs to find.