I’m reading Higher-order Type-level Programming in Haskell, and I have some questions. This is one.
Here’s a paragraph from page 3, §2.3:
2.3.1 Inference. Consider the call (
f x), wheref :: Monad m => m a -> m a, andx :: F Intfor some type familyF. Is the call well-typed? We must instatiatefwith suitable typestmandta, and then we need to satisfy the “wanted” equality (see Section 5.1)tm ta ~ F Int, where (~) means type equality. How can we do that? You might think thattm = Fandta = Intwould work, and so it might. But supposeF Intreduces toMaybe Bool; thentm=Maybeandta=Boolwould also work. Worse, ifF Intreduces toBoolthen the program is ill-typed.
My first reaction upon reading it was along the lines of “so what?”, in the sense that it felt all clear. Also, regarding the part
Worse, if
F Intreduces toBoolthen the program is ill-typed.
I even thuoght “lucky us, as we do want the program to fail type-checking, in this case”, don’t we?
So I went on to the following paragraph:
So, during type inference, GHC never decomposes “wanted” equalities headed by a type family, like
tm ta ~ F Int. But given a wanted equality liketm ta ~ Maybe IntGHC does (and must) decompose it into two simpler wanted equalitiestm ~ Maybeandta ~ Int.
I know it all sounds simple, but I feel the need to reword the above in a way that better resonates with me and somebody tell me if I’m correct.
Do I understand that the bottom line is that type families are “eagerly applied” before the type checking phase?
As in, with reference to the examples in the first excerpt, given tm ta ~ F Int, the type checker would first of all “eagerly” apply the type family, so that F is eliminated, and then proceed to either assign tm = Maybe and ta = Bool (in case F Int reduces to Maybe Bool) or reject the code as ill-typed (if F Int reduces to Bool)?