为什么此实例无法覆盖条件?

时间:2014-10-09 10:20:36

标签: haskell typeclass functional-dependencies

为什么在没有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)

2 个答案:

答案 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 -> btvsleft = atvsright = b。 替换Sa映射到S(a)=(a,a'),将b映射到S(b)=(b,b')

因此,我们在S(tvsright)=S(b)=(b,b')bb')中找到了类型变量 出现在S(tvsleft)=S(a)=(a,a')中。因此覆盖条件失败。

正如@Ben所说,覆盖条件不考虑上下文: 只有实例主管很重要。