Haskell 中的异常处理和纯度
Exception handling and purity in Haskell
在 Real World Haskell 的获取-使用-释放周期 部分中,bracket
的类型显示为:
ghci> :type bracket
bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
现在,从description of bracket
,我了解到当类型a -> IO c
的函数是运行 时可能会抛出异常。参考书上,这个异常被调用函数捕获,通过 handle
:
getFileSize path = handle (\_ -> return Nothing) $
bracket (openFile path ReadMode) hClose $ \h -> do
size <- hFileSize h
return (Just size)
我不禁想到,当 bracket
的第三个参数确实发生异常时,bracket
不会返回 IO c
。
这与纯度如何相得益彰?
我认为答案可能完全 ,但我不确定。
I can't help but thinking that when the exception does occur from within bracket's 3rd argument, bracket is not returning an IO c
.
Prelude> fail "gotcha" :: IO Bool
*** Exception: user error (gotcha)
如您所见,不会产生 Bool
(分别为 c
)值。没关系,因为操作 不会结束 – 而是重新引发异常。该异常可能会导致程序崩溃,或者它可能会在调用代码的其他地方再次被捕获——重要的是,无论谁捕获它,都将 a) 得不到结果值(“c
"),你永远不会在异常情况下这样做; b) 不需要担心关闭文件句柄,因为 bracket
.
已经完成了
在 Real World Haskell 的获取-使用-释放周期 部分中,bracket
的类型显示为:
ghci> :type bracket bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
现在,从description of bracket
,我了解到当类型a -> IO c
的函数是运行 时可能会抛出异常。参考书上,这个异常被调用函数捕获,通过 handle
:
getFileSize path = handle (\_ -> return Nothing) $ bracket (openFile path ReadMode) hClose $ \h -> do size <- hFileSize h return (Just size)
我不禁想到,当 bracket
的第三个参数确实发生异常时,bracket
不会返回 IO c
。
这与纯度如何相得益彰?
我认为答案可能完全
I can't help but thinking that when the exception does occur from within bracket's 3rd argument, bracket is not returning an
IO c
.
Prelude> fail "gotcha" :: IO Bool
*** Exception: user error (gotcha)
如您所见,不会产生 Bool
(分别为 c
)值。没关系,因为操作 不会结束 – 而是重新引发异常。该异常可能会导致程序崩溃,或者它可能会在调用代码的其他地方再次被捕获——重要的是,无论谁捕获它,都将 a) 得不到结果值(“c
"),你永远不会在异常情况下这样做; b) 不需要担心关闭文件句柄,因为 bracket
.