【发布时间】:2013-07-13 07:39:35
【问题描述】:
今天早上我注意到一些有趣的事情,我想问一下它是否重要。
所以在 Haskell 中,未定义语义包含非终止。所以应该是不可能有函数的
isUndefined :: a -> Bool
因为语义表明这解决了停机问题。
但是,我相信 GHC 的一些内置函数可以“相当可靠地”打破这一限制。尤其是catch#。
以下代码允许“相当可靠地”检测未定义的值:
import Control.Exception
import System.IO.Unsafe
import Unsafe.Coerce
isUndefined :: a -> Bool
isUndefined x = unsafePerformIO $ catch ((unsafeCoerce x :: IO ()) >> return False) ((\e -> return $ show e == "Prelude.undefined") :: SomeException -> IO Bool)
另外,这真的算吗,因为您会注意到它使用了几个“不安全”的功能?
朱尔斯
编辑:有些人似乎认为我声称已经解决了停机问题 XD 我不是一个怪人。我只是说 undefined 的语义有一个相当严重的中断,因为他们声明 undefined 的值应该在某种意义上与非终止没有区别。这个功能允许的。我只是想检查一下人们是否同意这一点以及人们对此有何看法,在 Haskell 的 GHC 实现中为了方便而添加某些不安全功能的意外副作用是不是更进一步? :)
编辑:修复了要编译的代码
【问题讨论】:
-
当然,当你在代码中输入
unsafe这个词时,各种东西都可能会被破坏! -
还有一个错误的假设:停止问题确实不说明您无法检测到非终止,它只是说您不能为 每个程序。您的
isUndefined函数绝对不会在x的所有可能值上终止 -
是的,GHC 中的
undefined已“损坏”,但已损坏得很好。在 99% 的情况下,以这种方式实现undefined在语义上是等效的,如果你使用unsafe*函数,你已经进入了黑魔法 -
您使用的是哪个版本?这甚至不适合我。
-
@AndrewC:对不起,这更像是一个理论问题,我在提交之前没有测试代码,这只是一个想法。我已经对其进行了编辑,现在它应该可以在 GHC 7.6.3 上编译。