
Tom Schrijvers wrote:
Stefan,
I tried lexically scoped type variables, but to no avail:
instance forall a b. (C a, C b) => C (a, b) where type T (a, b) = (T a, T b) val = (val :: T a, val :: T b)
The problem is ambiguity. The type checker can't determine which val function to use, i.e. which dictionary to pass to val. Assume:
instance C Int where type T Int = Int val = 0
instance C Bool where type T Bool = Int val = 1
Now, if you want some val :: Int, which one do you get? The one of C Int of C Bool? Depending on the choice you may get a different result. We can't have that in a deterministic functional language. Hence the error. Adding a type signature doesn't change the matter.
I don't see how your example explains this particular error. I agree Int cannot be generalized to (T Int) or (T Bool). I see Stefan's local type signature is not (val :: a) like your (val ::Int) but (val :: T a) which is a whole different beast. And (T a) is the type that ghc should assign here. The C (a,b) instance wants val :: T (a,b), The T (a,b) is declared as "(T a, T b)". The annotated val returns "(T a, T b)". One never needs the sort of Int to (T Int) generalization. So what is a better explanation or example to clarify why GHC cannot accept the original code? -- Chris