为什么类型 class 覆盖条件在 Haskell 而不是 PureScript 中失败

Why does type class coverage condition fail in Haskell but not PureScript

我有两个我认为是等效类型 class 和实例定义的实现。 PureScript 版本构建没有错误,但 Haskell 版本失败并出现错误 Un-determined variables: e, f.

我可以在 Haskell 完成这项工作吗?

Haskell:

class Foo a b c | a b -> c where
newtype Bar a b = Bar (a, b)
instance (Foo a c e, Foo b d f) => Foo (Bar a b) (Bar c d) (Bar e f) where

纯脚本:

class Foo a b c | a b -> c
newtype Bar a b = Bar (Tuple a b)
instance (Foo a c e, Foo b d f) => Foo (Bar a b) (Bar c d) (Bar e f) 

您必须启用UndecidableInstances;那么您的声明将起作用。为什么需要这样做有点微妙,即 not 启用它如何导致类型检查器中的循环。但是假设在您的程序中,您以某种方式导致需要解决以下约束:

Foo (Bar a b) (Bar c d) a

约束求解器会很高兴地观察到我们必须选择您编写的实例,因此决定 a ~ Bar a0 a1 对于某些 a0a1,这意味着我们想解决约束条件:

Foo (Bar (Bar a0 a1) b) (Bar c d) (Bar a0 a1)

现在我们可以调度到上下文,这意味着我们现在需要解决以下两个约束:

( Foo (Bar a0 a1) c a0
, Foo b d a1
)

但是等等!第一个约束与我们开始时的约束具有相同的形式,但具有不同的类型变量。一个循环!