Defer in Haskell
In Haskell, we don’t have a direct equivalent of the defer keyword. However, we can achieve similar functionality using the bracket function from the Control.Exception module. This function ensures that a resource is properly released after use, even if an exception occurs.
Here’s how we can implement the file creation, writing, and closing example in Haskell:
import System.IO
import Control.Exception (bracket)
import System.Exit (exitFailure)
main :: IO ()
main = bracket (createFile "/tmp/defer.txt") closeFile writeFile
createFile :: FilePath -> IO Handle
createFile path = do
putStrLn "creating"
handle <- openFile path WriteMode
return handle
writeFile :: Handle -> IO ()
writeFile handle = do
putStrLn "writing"
hPutStrLn handle "data"
closeFile :: Handle -> IO ()
closeFile handle = do
putStrLn "closing"
hClose handleIn this Haskell version:
We use the
bracketfunction to ensure that the file is closed after we’re done with it.brackettakes three arguments:- A function to acquire the resource (
createFile) - A function to release the resource (
closeFile) - A function to use the resource (
writeFile)
- A function to acquire the resource (
The
createFilefunction opens a file for writing and returns aHandle.The
writeFilefunction writes some data to the file.The
closeFilefunction closes the file handle.The
mainfunction usesbracketto tie these operations together, ensuring that the file is closed even if an exception occurs during writing.
To run the program:
$ runhaskell defer.hs
creating
writing
closingThis Haskell implementation achieves the same goal as the original example, ensuring that resources are properly managed and cleaned up, even in the presence of exceptions.
Note that Haskell’s type system and its emphasis on pure functions make it less common to need explicit resource management like this. In many cases, you might use higher-level abstractions that handle resource management automatically. However, when you do need to manage resources explicitly, the bracket function (and related functions in the Control.Exception module) provide a powerful and flexible way to do so.