Using exceptions in imperative code

Alastair Reid
Tue, 29 Jul 2003 19:06:09 +0100

On Tuesday 29 July 2003 2:06 pm, Bayley, Alistair wrote:
> I've got resource acquisition (and release) code which looks like this at
> [...]
> How should I structure it to handle exceptions raised by the various
> functions (envCreate, handleAlloc, dbLogon, etc)?

Use the bracket, bracket_ and finally functions.  For example:

  bracket (open "/etc/lilo.conf") close $ \ hLILO ->
  bracket (open "/etc/passwd") close $ \ hPasswd->
  <do something with the two file handles here>

I find it is often useful to package up common patterns like opening a file, 
creating a window, loading a font, etc like this:

  withFile :: Pathname -> (Handle -> IO a) -> IO a
  withFile path = bracket (open path) close

  withFont :: FontSpec -> (Font -> IO a) -> IO a
  withFont spec = bracket (loadFont spec) deleteFont


You can see this style being used a lot in the HGL documentation from about 
section 2.2 (page 3) onwards:

(The HGL is the library that motivated me to add exception handling to Hugs.)

Alastair Reid