Fundep-laden code compiled and ran fine in 6.8, fails in 6.10
I was kindly alerted by Ian Lynagh that some code of mine on hackage was causing 6.10-rc1 to fail to terminate. This code compiles and runs find on 6.8. Instead of diverging, 6.10.1 raises a type error. I've made a test case, and I'm creating this ticket to figure out what's going in. Is it,
A) The code is incorrect and 6.8 was erroneously accepting it, and only by luck producing a valid program
B) The code is correct and 6.10.1's typechecker is being overly conservative.
At the core is overlapping instances. I've spent considerable effort removing them from the library, because I can't just look at the code and say for certain "this will never overlap with that" because its too complicated. Overlap errors become the users problem, I myself having been bitten by them many times as a user of my own library. The solution is to do without overlapping instances. The types of my instances then go from something nice like
instance (A t) => C t
instance (B t) => C t --overlap
to something nasty like
instance (A (T (T x))) => C (T (T x))
instance (B (T (T (T x)))) => C (T (T (T x))) --no overlap
It's uglier for me to read and write but ultimately better for the user because I've eliminated a category of errors. If the compiler will let me, I try to abbreviate 'T (T (T x)))' to 't' in the instance head, but I'm not always able to because 't' is more general than 'T (T (T x)))'. I'm not entirely sure how that factors into things. To see what I'm talking about, compile the attached file and look for the error that says
Couldn't match expected type `vmt' against inferred type `vv :. (b' :. v)'
`vmt' is a rigid type variable...
It has something to do with functional dependencies. The fundep involved demands that 'vmt' be of the type 'x :. y :. z :. etc' but in this particular case it's so verbose I just call it 'vmt'. 6.8 lets me do that. 6.10 doesn't. Who's right?