我有这个功能:
isUndefined :: () -> Bool
isUndefined x = case unsafePerformIO $ (try (return $! x) :: IO (Either SomeException ())) of
Left _ -> True
Right _ -> False
然后:
isUndefined () = False
isUndefined undefined = True
解决停止问题。当然,这也可以扩展到其他类型。
我的问题:这怎么可能? Control.Exception.try
真的在这里打破了吗?
答案 0 :(得分:8)
Control.Exception.try真的破坏了吗?
unsafePerformIO
在这里破坏了一些东西。在GHC中,undefined
只是引发异常而不是永远循环(这将是无益的)。例外并不意味着被纯(非IO)代码捕获 - 实际上类型系统确实阻止你尝试那么多。
通过使用unsafe*
函数,你告诉GHC“忽略一切,我知道我在做什么”,所有安全带现在都关闭了。帮自己一个忙,假装unsafe*
的东西不存在。