Defer in PureScript

Our example demonstrates the concept of cleanup actions in PureScript. While PureScript doesn’t have a direct equivalent to Go’s defer, we can achieve similar functionality using the Effect monad and the bracket function from the Control.Monad.Error.Class module.

module Main where

import Prelude

import Effect (Effect)
import Effect.Console (log)
import Node.FS.Sync as FS
import Data.Either (Either(..))
import Control.Monad.Error.Class (try)
import Control.Monad.Except (runExcept)

main :: Effect Unit
main = do
  result <- try $ bracket
    (createFile "/tmp/example.txt")
    closeFile
    writeFile
  case result of
    Left err -> log $ "Error: " <> show err
    Right _ -> pure unit

createFile :: String -> Effect FS.FileDescriptor
createFile path = do
  log "creating"
  FS.openSync path FS.W

writeFile :: FS.FileDescriptor -> Effect Unit
writeFile fd = do
  log "writing"
  FS.writeSync fd "data"

closeFile :: FS.FileDescriptor -> Effect Unit
closeFile fd = do
  log "closing"
  FS.closeSync fd

In this PureScript example, we’re using the bracket function to ensure that our file is properly closed after we’re done with it, regardless of whether an error occurs during the writing process.

The bracket function takes three arguments:

  1. An action to acquire a resource (in our case, opening a file)
  2. An action to release the resource (closing the file)
  3. An action to use the resource (writing to the file)

This pattern ensures that the cleanup action (closing the file) is always performed, similar to how defer works in other languages.

We’re using the Node.FS.Sync module for file operations, which provides synchronous file system functions. In a real-world application, you might prefer to use asynchronous versions of these functions.

To run this program, you would typically compile it with the PureScript compiler and then run it with Node.js:

$ spago build
$ node -e "require('./output/Main').main()"
creating
writing
closing

This example demonstrates how to handle resource management and cleanup in PureScript, providing a similar functionality to the defer keyword in other languages.