理解`括号'功能

时间:2017-10-24 11:48:53

标签: haskell

查看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

1 个答案:

答案 0 :(得分:6)

来自the docs for bracket

  

当你想获取资源,做一些工作,然后发布资源时,最好使用bracket,因为bracket将安装必要的异常处理程序来释放在计算过程中引发异常的情况下的资源。 如果引发异常,则bracket将重新引发异常(执行发布后)。

onException

  

finally类似,但只有在计算引发异常时才执行最终操作。

因此,如果从during a抛出异常,则会执行对after a的第一次调用,然后重新抛出异常,跳过第二个after a;如果没有异常,则仅执行第二个。

请注意,在您的示例代码中,您返回异常,而不是抛出它 - 抛出,您需要使用throw或者{{ {1}}。