Exception “可扩展”是如何定义的;“一些例外”;是否符合Haskell标准?

Exception “可扩展”是如何定义的;“一些例外”;是否符合Haskell标准?,exception,haskell,standards,Exception,Haskell,Standards,在Haskell 2010标准的第7.3节中,我阅读了以下内容: I/O monad包括一个简单的异常处理系统。任何I/O 操作可能引发异常,而不是返回结果 I/O monad中的异常由IOError类型的值表示。 这是一个抽象类型:它的构造函数对用户隐藏。 IO库定义了构造和检查IOError的函数 价值观创建IOError值的唯一Prelude函数是 用户错误。用户错误值包括描述错误的字符串 Haskell 98标准的文本几乎相同 然而,在实践中,我经常看到catch构造带有Control.

在Haskell 2010标准的第7.3节中,我阅读了以下内容:

I/O monad包括一个简单的异常处理系统。任何I/O 操作可能引发异常,而不是返回结果

I/O monad中的异常由IOError类型的值表示。 这是一个抽象类型:它的构造函数对用户隐藏。 IO库定义了构造和检查IOError的函数 价值观创建IOError值的唯一Prelude函数是 用户错误。用户错误值包括描述错误的字符串

Haskell 98标准的文本几乎相同

然而,在实践中,我经常看到catch构造带有Control.Exception.Base中的一些异常:

SomeException类型是异常类型层次结构的根。 当抛出类型e的异常时,在幕后它是 封装在一个异常中

import GHC.IO(failIO)
import Control.Exception(catch, SomeException(..))

main :: IO ()
main = (x >>= print) `catchAll` \e -> print ("caught: " ++ show e)

x :: IO Int
x = failIO "Failed to get x!"

catchAll :: IO a -> (SomeException -> IO a) -> IO a
catchAll = catch
GHC的一个小型实验表明,IOException也封装在SomeException中

import GHC.IO(failIO)
import Control.Exception(catch, SomeException(..))

main :: IO ()
main = (x >>= print) `catchAll` \e -> print ("caught: " ++ show e)

x :: IO Int
x = failIO "Failed to get x!"

catchAll :: IO a -> (SomeException -> IO a) -> IO a
catchAll = catch
运行上述程序将为我们提供:

caught: user error (Failed to get x!)

这与标准有什么关系?它是Haskell标准的GHC特定扩展吗?

GHC仍然拥有报告中描述的所有机器,用于
IOError

然而,在实践中,这被发现是非常有限的,因为人们需要为不精确的异常和后来的异步异常引入新的异常类型。因此,一个新的模块诞生了,以统一管理所有这些类型。然而,该模块随后出现了一个问题,即虽然它扩展了可用异常的范围,但它是以固定的方式扩展的。因此产生了对扩展的可扩展机制的渴望。Simon Marlow()在2006年的一篇论文中提供了设计、动机和实现

这就把我们带到了
Control.Exception
模块,我们现在知道并喜欢它


正如本文所描述的,该库基本上是在userland中实现的,只需要一些语言级别的构造,如存在主义和可类型化,我相信它是一个扩展。如果您坚持报告例外,那么一切都应该按照报告进行。一旦您使用GHC特定的扩展,它们的语义就不再受报告的约束。