Writing Files in PureScript
Here’s the translation of the Go code to PureScript, along with explanations in Markdown format suitable for Hugo:
Writing files in PureScript follows similar patterns to the ones we saw earlier for reading.
module Main where
import Prelude
import Effect (Effect)
import Effect.Console (log)
import Node.Encoding (Encoding(..))
import Node.FS.Sync as FS
import Node.Buffer as Buffer
import Data.ArrayBuffer.Types (Uint8Array)
main :: Effect Unit
main = do
-- To start, here's how to dump a string (or just bytes) into a file.
let d1 = "hello\npurescript\n"
FS.writeTextFile UTF8 "/tmp/dat1" d1
-- For more granular writes, open a file for writing.
fileHandle <- FS.openSync "/tmp/dat2" FS.W
-- It's idiomatic to use bracket to ensure the file is closed
-- after we're done with it.
FS.withFileSync fileHandle \fd -> do
-- You can write byte arrays as you'd expect.
d2 <- Buffer.fromString "some\n" UTF8
n2 <- FS.writeSync fd d2
log $ "wrote " <> show n2 <> " bytes"
-- A string write is also available.
n3 <- FS.writeSync fd =<< Buffer.fromString "writes\n" UTF8
log $ "wrote " <> show n3 <> " bytes"
-- Issue a sync to flush writes to stable storage.
FS.fdatasyncSync fd
-- PureScript doesn't have a built-in buffered writer,
-- but you can implement one using Node.js streams if needed.
n4 <- FS.writeSync fd =<< Buffer.fromString "unbuffered\n" UTF8
log $ "wrote " <> show n4 <> " bytes"
Try running the file-writing code:
$ spago run
wrote 5 bytes
wrote 7 bytes
wrote 11 bytes
Then check the contents of the written files:
$ cat /tmp/dat1
hello
purescript
$ cat /tmp/dat2
some
writes
unbuffered
In this PureScript version, we’ve used the Node.FS.Sync
module to perform file operations. PureScript doesn’t have a direct equivalent to Go’s bufio
for buffered I/O, but you can achieve similar functionality using Node.js streams if needed.
The check
function for error handling is not necessary in PureScript as errors are typically handled through the type system or using the Effect
monad.
Note that PureScript’s file operations are typically performed in the Effect
monad, which represents side-effecting computations.
Next, we’ll look at applying some of the file I/O ideas we’ve just seen to the stdin
and stdout
streams.