当我第一次阅读有关-XUndecidableInstances
.
事实上,我遇到过很多需要不可判定实例的应用程序,但没有一个应用程序实际上会导致与不可判定性相关的任何问题。卢克的例子是有问题的,原因完全不同
class Group g where
(%) :: g -> g -> g
...
instance Num g => Group g where
...
– 好吧,这显然会与任何适当的实例重叠,所以不确定性Group
是我们最不担心的:这实际上是不确定的!
但很公平,因为我一直在脑海中保留“不可判定的实例可能会使编译器挂起”。
当我在 CodeGolf.SE 上阅读这个挑战时,它是从哪里获得的,要求提供可以无限挂起编译器的代码。好吧,这听起来像是在不确定的情况下工作,对吧?
事实证明我无法让他们这样做。以下内容立即编译,至少从 GHC-7.10 开始:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y
instance C y => C y
main = return ()
我什至可以使用类方法,它们只会在运行时导致循环:
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y where y::y
instance C y => C y where y=z
z :: C y=>y; z=y
main = print (y :: Int)
但是运行时循环并不罕见,您可以在 Haskell98 中轻松编写这些代码。
我还尝试了不同的、不那么直接的循环,例如
{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
data A x=A
data B x=B
class C y
instance C (A x) => C (B x)
instance C (B x) => C (A x)
同样,在编译时没有问题。
那么,在解析不可判定的类型类实例时,实际上需要什么来挂起编译器呢?