简体   繁体   English

Haskell 中的异常处理和纯度

[英]Exception handling and purity in Haskell

In The acquire-use-release cycle section from Real World Haskell , the type of bracket is shown:Real World Haskell的获取-使用-发布周期部分中,显示了bracket的类型:

 ghci>:type bracket bracket:: IO a -> (a -> IO b) -> (a -> IO c) -> IO c

Now, from the description of bracket , I understand that an exception might be thrown while the function of type a -> IO c is running.现在,根据bracket的描述,我了解到在 a 类型a -> IO c运行时可能会引发异常。 With reference to the book, this exception is caught by the calling function, via handle :参考这本书,这个异常是通过调用 function 捕获的,通过handle

 getFileSize path = handle (\_ -> return Nothing) $ bracket (openFile path ReadMode) hClose $ \h -> do size <- hFileSize h return (Just size)

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 .我不禁想到,当bracket的第三个参数中确实发生异常时, bracket不会返回IO c

How does this go well with purity?这个 go 纯度如何?

I think the answer might be exactly this , but I'm not sure.我认为答案可能正是这个,但我不确定。

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 .我不禁想到,当括号的第三个参数中确实发生异常时,括号不会返回IO c

Prelude> fail "gotcha" :: IO Bool
*** Exception: user error (gotcha)

As you note, no Bool (respectively, c ) value is produced.如您所述,不会产生Bool (分别为c )值。 That's ok, because the action does not conclude – instead it re-raises the exception.没关系,因为该操作没有结束——而是重新引发异常。 That exception might then either crash the program, or it might be caught again somewhere else in calling code – importantly, whoever catches it will a) not get the result value (“the c ”), you never do that in case of an exception;然后,该异常可能会导致程序崩溃,或者它可能会在调用代码的其他地方再次被捕获 - 重要的是,无论谁捕获它都会a)没有得到结果值(“ c ”),你永远不会在发生异常的情况下这样做; b) doesn't need to worry about closing the file handle, because that has already been done by bracket . b)不需要担心关闭文件句柄,因为这已经由bracket完成了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM