The type systems of most typed functional programming languages
are based on the Hindley-Milner type system. A practical problem
with these type systems is that it is often hard to understand why
a program is not type correct or a function does not have the
intended type. We suggest that at the core of this problem is the
difficulty of explaining why a given expression has a certain type.
The type system is not defined compositionally. Here we propose to
explain types using a variant of the Hindley-Milner type system that
defines a compositional type explanation graph. We describe how the
programmer understands types by interactive navigation through the
explanation graph. Furthermore, the explanation graph can be the
foundation for algorithmic debugging of type errors, that is,
semi-automatic localisation of the source of a type error without
even having to understand the type inference steps. We implemented a
prototype of a tool to explore the usefulness of the proposed methods.