查看Parallel and Concurrent Programming in Haskell中的bracket
函数:
bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket before after during = do
a <- before
c <- during a `onException` after a
after a
return c
如果发生异常,为什么after
函数只被调用一次?换句话说,如果发生异常,我会对after a
的明显执行感到困惑。
但是,代码显示after a
只会被调用,据我所知,曾经:
λ: >data MyException = MyException deriving Show
λ: >instance Exception MyException
λ: >let e = return MyException :: IO MyException
λ: >bracket e (const $ putStrLn "clean up!") return
clean up!
MyException
答案 0 :(得分:6)
当你想获取资源,做一些工作,然后发布资源时,最好使用
bracket
,因为bracket
将安装必要的异常处理程序来释放在计算过程中引发异常的情况下的资源。 如果引发异常,则bracket
将重新引发异常(执行发布后)。
与
finally
类似,但只有在计算引发异常时才执行最终操作。
因此,如果从during a
抛出异常,则会执行对after a
的第一次调用,然后重新抛出异常,跳过第二个after a
;如果没有异常,则仅执行第二个。
请注意,在您的示例代码中,您返回异常,而不是抛出它 - 抛出,您需要使用throw
或者{{ {1}}。