overlapping instances and functional dependencies

Wolfgang Jeltsch wolfgang@jeltsch.net
Mon, 18 Aug 2003 00:37:33 +0200


I wrote on Saturday, 2003-08-09, 01:32, CEST:
> Hello,
>
> I have this code:
>     class C a b c | a b -> c where
>         f :: a -> b -> c
>
>     instance C a b c => C a (x,y,b) c where
>         f a (_,_,b) = f a b
>
>     instance C a (a,c,b) c where
>         f _ (_,c,_) = c
> ghci -fglasgow-exts -fallow-overlapping-instances compiles it without
> complaint but hugs -98 +o says:
>     ERROR "ClassProblem.hs":7 - Instances are not consistent with
>     dependencies
>     *** This instance    : C a (a,b,c) b
>     *** Conflicts with   : C a (b,c,d) e
>     *** For class        : C a b c
>     *** Under dependency : a b -> c
> Can anyone tell me what the reason for this is and, maybe, how to avoid
> these problems with Hugs?
>
> Wolfgang

Hal Daume answered on Saturday, 2003-08-09, 01:53, CEST:
> Suppose somewhere we have an instance:
>
>  instance C Int Bool Int
>
> when the first instance decl you have says we also have
>
>   instance C Int (x,y,Bool) Int
>
> in this case, Int + (x,y,Bool) should uniq. specify Int.
>
> however, we also have:
>
>   instance C a (a,c,b) c
>
> where, if we let a=Int, b=Bool, c=Char, then we get that
>   Int + (Int,Char,Bool) should uniq. specify Char.
>
> these two confict because if, in the first case, we instantiate x to Int and
> y to Char, then one says that the third param should be a Bool and the other
> says the third param should be a Char.
>
> (or at least this is my understanding -- someone might correct me)
>
>  - Hal

Hello,

I wouldn't suppose that there is a conflict in your example. The question is 
for which t there is an instance C Int (Int,Char,Bool) t. There are two 
competing instance declarations:
    (1) instance C a b c => C a (x,y,b) c [...]
        Because in your example there is an instance C Int Bool Int we would
        get the instance C Int (Int,Char,Bool) Int.
    (2) instance C a (a,c,b) c [...]
        This clearly votes for C Int (Int,Char,Bool) Char.
But the second instance declaration is more specific. In the first one we have 
the "pattern" "arbitrary type - triple type - arbitrary type" with no further 
restrictions. In the second one we have the same "pattern" but with the 
restriction that the first parameter must equal the type of the first triple 
element and the third parameter must equal the type of the second triple 
element. Because of the handling of overlapping instances, the compiler 
should take the second instance declaration and deduce the instance C Int 
(Int,Char,Bool) Char.

What's wrong with my interpretation?

Wolfgang