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


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

The I/O monad includes a simple exception handling system. Any I/O
operation may raise an exception instead of returning a result.

Exceptions in the I/O monad are represented by values of type IOError.
This is an abstract type: its constructors are hidden from the user.
The IO library defines functions that construct and examine IOError
values. The only Prelude function that creates an IOError value is
userError. User error values include a string describing the error.

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

实际上,我经常在Control.Exception.Base中看到带有SomeException的catch构造:

The SomeException type is the root of the exception type hierarchy.
When an exception of type e is thrown, behind the scenes it is
encapsulated in a 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特定扩展吗?

最佳答案 GHC仍然具有IOError等报告中描述的所有机制.

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

这就把我们带到了今天我们所熟知和喜爱的Control.Exception模块.

正如本文所述,该库基本上是在用户空间中实现的,只需要一些语言级结构,如存在性和可输入性.

点赞