为什么在没有UndecidableInstances
的情况下,以下实例声明会失败覆盖条件?似乎如果在上下文中满足功能依赖性,则在新实例中满足它。
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE UndecidableInstances #-}
class Foo a b | a -> b where
instance (Foo a b, Foo a' b') => Foo (a, a') (b, b') where
如果我尝试使用类型系列复制相同的东西,则没有问题。
{-# LANGUAGE TypeFamilies #-}
type family Bar a
type instance Bar (a, b) = (Bar a, Bar b)
答案 0 :(得分:2)
我相信在选择实例时实际上并没有考虑到实例的约束。它们成为在每个使用场所证明的额外限制,而不是限制实例的适用性。
因此,您的实例声明等同于instance Foo (a, b) (c, d)
,这显然不符合覆盖条件。
添加(Foo a b, Foo a' b')
只会使得某些使用的实例会导致"没有这样的实例"错误,它实际上并没有改变你的实例将被选择的类型。
答案 1 :(得分:2)
来自GHC docs:
覆盖条件。对于每个功能依赖,tvsleft - > TVsright,该类,S(tvsright)中的每个类型变量都必须出现 在S(tvsleft)中,S是每个类型变量的替换映射 在类声明中实例中的相应类型 声明。
在您的课程中,您有a -> b
,tvsleft = a
和tvsright = b
。
替换S
将a
映射到S(a)=(a,a')
,将b
映射到S(b)=(b,b')
。
因此,我们在S(tvsright)=S(b)=(b,b')
(b
和b'
)中找到了类型变量
出现在S(tvsleft)=S(a)=(a,a')
中。因此覆盖条件失败。
正如@Ben所说,覆盖条件不考虑上下文: 只有实例主管很重要。