Next Previous Contents

6.4 Other Utilities

The bracket functions are useful for making sure that resources are released properly by code that may raise exceptions:

        bracket         :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
        bracket_        :: IO a -> IO b -> IO c -> IO c
        finally         :: IO a -> IO b -> IO b

For example, to open a file, do some work on it and then close it again, we might use something like:

process_file = bracket (openFile "filename") closeFile 
               (do 
                 ...
                )

bracket works as follows: it executes its first argument ("open"), then its third argument, followed finally by its second argument ("close"). If the third argument happened to raise an exception, then the close operation will still be performed, and the exception will be re-raised.

This means that in the example above the file will always be closed, even if an error occurs during processing.

The arguments to bracket are in this order so that we can partially apply it, like:

withFile name = bracket (openFile name) closeFile

The bracket_ function is a variant of bracket that throws away the result of the open, and finally is an even simpler version where we just want some closing code.


Next Previous Contents