问题
Why does the following instance declaration fail the coverage condition in the absence of UndecidableInstances
? It seems that if the functional dependency is satisfied in the context then it is satisfied in the new instance.
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
class Foo a b | a -> b where
instance (Foo a b, Foo a' b') => Foo (a, a') (b, b') where
If I try to replicate the same thing with a type family there is no problem.
{-# LANGUAGE TypeFamilies #-}
type family Bar a
type instance Bar (a, b) = (Bar a, Bar b)
回答1:
I believe it's that constraints on instances aren't actually taken into account when selecting an instance. They become additional constraints to be proved at each use site, rather than limiting the applicability of the instance.
So your instance declaration is kind of equivalent to instance Foo (a, b) (c, d)
, which rather obviously fails the coverage condition.
Adding the (Foo a b, Foo a' b')
only makes it so that some of the uses of the instance would result in "no such instance" errors, it doesn't actually change the types for which your instance will be selected.
回答2:
From the GHC docs:
The Coverage Condition. For each functional dependency, tvsleft -> tvsright, of the class, every type variable in S(tvsright) must appear in S(tvsleft), where S is the substitution mapping each type variable in the class declaration to the corresponding type in the instance declaration.
In your class you have a -> b
, so tvsleft = a
and tvsright = b
.
The substitution S
maps a
into S(a)=(a,a')
and b
into S(b)=(b,b')
.
So, we find type variables in S(tvsright)=S(b)=(b,b')
(both b
and b'
) which do not
appear in S(tvsleft)=S(a)=(a,a')
. Hence the coverage condition fails.
As @Ben said, the coverage condition does not take the context into account: only the instance head matters.
来源:https://stackoverflow.com/questions/26275940/why-does-this-instance-fail-the-coverage-condition