Haskell/GHC不可判定实例-非终止类型检查示例?
我编写了一些Haskell代码,需要编译-XUndecidableInstances。我确实理解为什么会发生这种情况,因为有一个特定的条件被违反,因此GHC大喊大叫 然而,我从来没有遇到过这样的情况,类型检查器实际上会挂起或陷入一个无休止的循环 非终止实例定义是什么样的-您能举个例子吗?例如:Haskell/GHC不可判定实例-非终止类型检查示例?,haskell,ghc,typechecking,decidable,Haskell,Ghc,Typechecking,Decidable,我编写了一些Haskell代码,需要编译-XUndecidableInstances。我确实理解为什么会发生这种情况,因为有一个特定的条件被违反,因此GHC大喊大叫 然而,我从来没有遇到过这样的情况,类型检查器实际上会挂起或陷入一个无休止的循环 非终止实例定义是什么样的-您能举个例子吗?例如: {-# LANGUAGE UndecidableInstances #-} class C a where f :: a -> a instance C [[a]] => C [a
{-# LANGUAGE UndecidableInstances #-}
class C a where
f :: a -> a
instance C [[a]] => C [a] where
f = id
g x = x + f [x]
发生的情况:当键入f[x]
时,编译器需要确保x::C[a]
对于某些a
。实例声明指出,x
只能是C[a]
类型,前提是它也是C[[a]]
。因此,编译器需要确保x::C[[a]]
等,并在无限循环中捕获
另请参见在以下内容中有一个经典的、有点令人担忧的示例(涉及与函数依赖项的交互): 我们需要
mul x[y]
具有与y
相同的类型,因此,采用x::x
和y::y
,我们需要
instance Mul x [y] y
根据给定的实例,我们可以得到。当然,对于某些z
,我们必须取y~[z]
,以便
instance Mul x y z
i、 e
我们在一个循环中
这是令人不安的,因为Mul
实例看起来像是它的递归在结构上减少了,这与Petr答案中明显病态的实例不同。然而,它使GHC循环(无聊的门槛踢进来,以避免挂起)
问题是,我肯定我在什么时候提到过,尽管z
在功能上依赖于y
,但识别y~[z]
还是存在的。如果我们对函数依赖项使用函数表示法,我们可能会看到约束显示为y~Mul x[y]
,并拒绝替换,因为它违反了发生检查
我很好奇,我想我应该试一试
class Mul' a b where
type MulT a b
mul' :: a -> b -> MulT a b
instance Mul' a b => Mul' a [b] where
type MulT a [b] = [MulT a b]
mul' a = map (mul' a)
g b x y = if b then mul' x [y] else y
启用了UndedicatableInstances
后,循环需要很长时间才能超时。禁用UndedicatableInstances
后,实例仍被接受,typechecker仍在循环,但截断发生得更快
所以。。。有趣的旧世界。回答得很好,谢谢!我接受了Petr的回答,因为它不涉及对类型系统的额外扩展。不用担心!当我们在一般地区时,我只是想提高人们对一个已知的小精灵的认识。谢谢你的提问!
instance Mul x [z] z
class Mul' a b where
type MulT a b
mul' :: a -> b -> MulT a b
instance Mul' a b => Mul' a [b] where
type MulT a [b] = [MulT a b]
mul' a = map (mul' a)
g b x y = if b then mul' x [y] else y