可扩展的“SomeException”如何适应Haskell标准?

时间:2015-01-30 10:43:52

标签: exception haskell standards

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

  

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

     

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

Haskell 98标准的文本几乎相同。

在实践中,我经常看到来自Control.Exception.Base:

的SomeException的catch构造
  

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

使用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特定扩展吗?

1 个答案:

答案 0 :(得分:2)

GHC仍然拥有IOError等报告中描述的所有机制。

然而,在实践中发现非常有限,因为人们需要为不精确和后来的异步异常引入新的异常类型。因此诞生了一个新的模块来统一管理所有这些类型。然而,这个模块的问题是,虽然它扩展了可用的异常范围,但它以固定的方式实现了这一点。因此诞生了对扩展的可扩展机制的渴望。 Simon Marlow(http://community.haskell.org/~simonmar/papers/ext-exceptions.pdf)在2006年的一篇论文中提供了设计,动机和实施。

这将我们带到了今天我们所熟悉和喜爱的Control.Exception模块。

正如论文所描述的那样,该库基本上是在用户空间中实现的,只需要一些语言级结构,如存在性和Typeable