Haskell功能依赖冲突

为什么会导致冲突?
class Foo a b | b -> a where
  foo :: a -> b -> Bool

instance Eq a => Foo a a where
  foo = (==)

instance Eq a => Foo a (a -> a) where
  foo x f = f x == x

请注意,如果我删除功能依赖,代码将被编译.

我的印象是,功能依赖只应该禁止像以下这样的东西,实际上它会编译!

class Foo a b | b -> a where
  foo :: a -> b -> Bool

instance Eq a => Foo a a where
  foo = (==)

instance Eq a => Foo Bool a where
  foo _ x = x == x

相同的b参数,但参数不同.不应该b – >不允许这个,因为这意味着一个由b唯一确定?

你是否尝试使用第二个版本?我猜测,当实例编译时,当您调用foo时,您将开始变得模糊和重叠错误.

这里最大的障碍是,屁股不会像您可能期望的那样与类型变量进行交互 – 实例选择并不真正寻找解决方案,它只是通过尝试统一而盲目匹配.具体来说,当你写Foo a a时,a是完全任意的,因此可以使用类似b – >湾当第二个参数的形式为b – > b,它因此匹配两个实例,但是基数表示在一种情况下,第一个参数应该是b – > b,但另一方面应该是b.所以冲突.

由于这显然令人惊讶,所以如果您尝试使用第二个版本,会发生什么:

> bar = foo()()导致:

Couldn't match type `Bool' with `()'
  When using functional dependencies to combine
    Foo Bool a,

…因为基金会通过第二个例子说,任何类型作为第二个参数唯一地将Bool确定为第一个.所以第一个参数必须是Bool.
> bar = foo True()导致:

Couldn't match type `()' with `Bool'
  When using functional dependencies to combine
    Foo a a,

…因为基金会说,通过第一个实例,任何类型作为第二个参数唯一地确定了第一个参数的相同类型.所以第一个参数必须是().
> bar = foo()由于这两个实例,True都导致错误,因为这次他们同意第一个参数应该是Bool.
> bar = foo True True产生于:

Overlapping instances for Foo Bool Bool
  arising from a use of `foo'

因为两个实例都满足,因此重叠.

很开心啊

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...