Better trace of failed type equalities
Motivation
When type-class instances contain type-equalities, they can be checked much later, in a completely different context, when the instances are being used. Sometimes, they're used very very indirectly, far from the code that invoked the instance.
The error is about a type mismatch, and it is attributed to the code that caused the instance resolution to reach the instance, with no mention of where the type equality was, or the chain of instances that were used to reach it.
Proposal
When a type equality causes a unification failure, the error should include where the type equality was invoked, and the chain of instances used to reach it.
Example
{-# LANGUAGE TypeFamilies #-}
class Example e where
example :: e -> ()
example = const ()
instance a ~ Int => Example [a] where
data Bar a = Bar a
instance Example a => Example (Bar a)
bar :: Bar String
bar = Bar "Hello"
f :: ()
f = example bar -- the error complains here only
The error on the "example bar" line is Couldn't match type ‘Char’ with ‘Int’
. No mention of how or why it tried to unify Char
with Int
. Of course in this small example it is easy to figure out. But in a large code-base, with much larger types, it is very difficult to understand why it is complaining - in a position completely unrelated to the real error.