
Hi, Chris Thanks for your answer. I guess that my intuitions of what functional dependencies and context meant were not very accurate (see below)
class C m f n | m -> n, f -> n where c :: m -> f -> Bool
The "m->n" functional dependency means that I tell you "C x _ z" is an instance then you whenever you match "x" that you must have the corresponding "z".
That's what I thought..
instance C (M n) (F n) n where c _ _ = True
This promises that "C x _ z" with x=="M n" has z==n
I agree....
instance C m (F N) N => C m F' N where c m (F' f) = c m f
By the "m->n" functional dependency, the above implies that _any_ "m" must map to the type M2.N: "m -> M2.N"
This kills you in M3...
Here I was expecting the context "C m (F N) N" to work as a logical guard, something like: 'for all m such that "C m (F N) N" holds, "C m F' N" must hold too' and since '"C m (F N) N" holds' would already imply 'm -> N', then "C m F' N" would not produce any contradiction. I guess this view doesn't hold when FlexibleInstances is on.... Anyway, it makes (kind of) sense now...
By the way, if you make the class C fundep declaration into:
class C m f n | m f -> n where
then it compiles. This means ((M n) and (F n) imply N) and ("any m" and F' imply N') which no longer conflict.
Thanks again for the tip, I will try it out! Daniel