Hi Scott,

A type error is an indication of an inconsistency in a program: for
example, it might result if a single variable is expected to have
incompatible types at different points in the code.  Most type
checker implementations will visit the set of program points in
some particular order, and will report an error at the first point
where an inconsistency is detected.  And, of course, a type checker
can't know the programmer's intentions and determine which program
point is the real cause of the problem, so it common to report the
problem at the point where it is detected.  All things being equal,
this means that some 50% of the type checker error messages will
be pointing at the wrong code!  Worse still, it doesn't matter
how long I spend modifying the type checker, for example to visit
program points in a different order: 50% of the errors will still
be `wrong' :-(

Ok, so it doesn't have to be quite that bad.  Perhaps the author
of a type checker has some scope to improve on this situation by
identifying frequently occurring idioms or problems that lead to
type errors, and trying to arrange for the type checker to catch
them with appropriate messages.  Some parts of the Hugs type
checker were rewritten with exactly that goal in mind, so I hope
that Hugs, in practice, does a little better than the 50% that
theory predicts.  There will, however, always be unsatisfactory
or confusing diagnostics if an error message mentions only one
program point.

One way to deal with this is to use a type checker that can enumerate
multiple program points where inconsistencies occured, both before
and after the point where an error was first detected.  Technical
challenges with this include trying to minimize overhead in the
type checker, and trying to present the error messages and the
associated type information to users in a way that guides rather
than overwhelms.  A number of people have investigated these
issues over the years, although nobody has done it yet for Hugs,
as far as I am aware.  (Dominic Duggan's SML/E is a recent example
of this, but in the context of SML.)  I do not believe these are
easy extensions to make to the Hugs type checker: there's a lot
of engineering, and probably a fair bit of research too in figuring
out how to deal with type classes, plus other type system extensions
over SML.

I hope you can see the problems now, at least in general terms.
Moving to your specific example:

   vList = [a,b,c,d,e,f,g] :: Double
   
Hugs reported an error here in the expression [a,b,c,d,e,f,g],
and in particular at the term b.  Of course, Hugs expected each
element of the list to have the same type.  Having already inferred
that a had type String -> Double, it expected b to have the same
type, and was surprised to discover that it had type Double.  Hence
the error:

|     ERROR "hugsmsg2.hs" (line 10): Type error in list
|     *** Expression     : [a,b,c,d,e,f,g]
|     *** Term           : b
|     *** Type           : Double
|     *** Does not match : String -> Double

Tell the story this way, and I hope you'll agree that the error makes
perfect sense ...  Incidentally, had the type checker continued past
the point at which that first inconsistency was detected, it might
have noticed that all the remaining elements of the list also had
type Double, and then it could have guessed, based on probabilities,
that perhaps the error was really in the first term.  Of course, in
a different setting, that might not be correct.  Nevertheless, this
shows how a system might be able to use basic probabilities/frequency
counts to prioritize any lists of program points that it produced.

| I expected that the type annotation on the expression
|     [a,b,c,d,e,f,g] :: Double

(You mean :: [Double] unless you want a rather different type error!)

| would help Hugs pin down the error, since Hugs would
| be able to infer that the expression b agreed between
| its definition and its context.  Instead, Hugs continued
| to complain about b and gave no indication of where it
| was picking up the idea that b needed to be String -> Double.

Your expectations were not unreasonable, but Hugs doesn't happen to
work in exactly that way so it found the error at a different point.
What Hugs needs is a more declarative type checker, by which I mean
one that tells you what the problem is, without requiring the user
to understand exactly how that answer was achieved ...

All the best,
Mark

Reply via email to