cascading type errors in ghc

Evan Laforge qdunkan at
Tue Aug 6 21:03:23 CEST 2013

On Sun, Jul 28, 2013 at 9:01 AM, Simon Peyton-Jones
<simonpj at> wrote:
> Giving good type error messages is tricky!

Indeed, and I'm fully aware this is a Hard Problem.

> You get different behaviour for literals because 0 has type (forall a. Num a => a), whereas you declared x1 to have type Int.  GHC could have additionally said "Can't find an instance for Num Bool, but it suppresses such errors if there are more serious ones at hand.  Hence the difference you observed.
> Previous GHCs would often bale out altogether if they tried to unify Int with Bool, and recover at some outer point.  That's good for not getting lots of errors, but it might suppress genuinely separate errors.  Nowadays we gather all the unsolved constraints without an exception-style bale-out, which probably accounts for you seeing more errors.

Yeah, that makes a lot of sense, thanks for the explanation.

I don't know how others like to work, but I like when a compiler bails
early, because I fix errors one at a time, and I search for the
easiest looking ones before worrying about the complicated looking

> The good news is that error generation is all in one module TcErrors.lhs, so it's easy to adjust these things.  For example, given a nearby bunch of errors, you could suppress all but one.  I don't know whether that would on balance make things better or not.  But it's certainly easy to experiment (if you build yourself a GHC).

Maybe we could do better with some heuristics, e.g. categorize errors
into "simple" and "advanced", and have simple errors suppress advanced
ones.  This already happens to an extent: syntax error will suppress
unbound name errors, which will suppress type errors, which will
suppress typeclass instance errors.  These rough categorizations sort
of come for free because of the layers in ghc itself, but nonetheless
they have a nice effect where you fix problems in layers from simple
to complicated.  I like it because it matches my simple->complicated

Of course that just moves the problem over to telling simple from
advanced, so you'd probably have to look at an error from several
different angles to try to discover a simpler interpretation.  I
suppose I shouldn't wade further in here unless I'm prepared to quit
my day job and go be an intern at GHC HQ to implement a research
project :)

More information about the Glasgow-haskell-users mailing list