2016-07-17 18 views
2
bracket 
     :: IO a   --^computation to run first (\"acquire resource\") 
     -> (a -> IO b) --^computation to run last (\"release resource\") 
     -> (a -> IO c) --^computation to run in-between 
     -> IO c   -- returns the value from the in-between computation 
bracket before after thing = 
    mask $ \restore -> do 
    a <- before 
    r <- restore (thing a) `onException` after a 
    _ <- after a 
    return r 

这与某些API设计模式或约定有关吗?为什么不使用以下签名部分?为什么括号需要`release`来产生被忽略的结果?

 -> (a -> IO()) --^computation to run last (empty result) 

 -> (a -> IO a) --^computation to run last (`a` cannot be ignored) 

回答

7

我认为你有它向后 - bracket会忽略你的释放操作的结果。

如果发布操作的签名是a -> IO()那么您将不得不提供总是返回()的函数。通过使签名a -> IO b您的发布函数可以返回任何东西,因为 类型变量b未在签名-i.e中的任何其他地方引用。它与任何其他类型的变量完全无关。

+0

为什么'main'没有'IO a'类型? – sevo

+3

'main'可以具有'IO a'或'IO Int'作为类型。 – Michael

+1

@sevo,如果程序可以通过完成主要操作而退出,并且输入'IO a'或'IO Void',那么最好坚持'main'应该有'IO()'类型的规则由于未捕获的异常或对'exitWith'或类似的显式调用而退出。但'main'允许有任何'IO'类型。 – dfeuer

相关问题