2016-07-17 4 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の場合、メインアクションを終了することでプログラムを終了できる場合は、 'main'がタイプ' IO() 'を持つべきで、プログラムのみの場合は' IO a'または 'IO Void'未知の例外や 'exitWith'などの明示的な呼び出しの結果として終了します。しかし 'main'は' IO'型を持つことができます。 – dfeuer

関連する問題