Directories in Standard ML
Here’s the translation of the Go code to Standard ML, with explanations in Markdown format suitable for Hugo:
(* Standard ML doesn't have a built-in directory manipulation module,
so we'll use the SMLofNJ.OS.FileSys module for file system operations *)
structure FileSys = SMLofNJ.OS.FileSys
(* Helper function to handle errors *)
fun check result =
case result of
SOME err => raise err
| NONE => ()
(* Helper function to create an empty file *)
fun createEmptyFile name =
let
val outStream = TextIO.openOut name
in
TextIO.closeOut outStream
end
(* Main function *)
fun main () =
let
(* Create a new sub-directory in the current working directory *)
val _ = check (FileSys.mkDir "subdir")
(* Create files and directories *)
val _ = createEmptyFile "subdir/file1"
val _ = check (FileSys.mkDir "subdir/parent")
val _ = check (FileSys.mkDir "subdir/parent/child")
val _ = createEmptyFile "subdir/parent/file2"
val _ = createEmptyFile "subdir/parent/file3"
val _ = createEmptyFile "subdir/parent/child/file4"
(* List directory contents *)
val dirStream = FileSys.openDir "subdir/parent"
fun listDir () =
case FileSys.readDir dirStream of
SOME entry => (print (" " ^ entry ^ " " ^
Bool.toString (FileSys.isDir entry) ^ "\n");
listDir ())
| NONE => FileSys.closeDir dirStream
val _ = (
print "Listing subdir/parent\n";
listDir ()
)
(* Change directory *)
val _ = FileSys.chDir "subdir/parent/child"
val currentDir = FileSys.getDir ()
val _ = print ("Current directory: " ^ currentDir ^ "\n")
(* Change back to the original directory *)
val _ = FileSys.chDir "../../.."
(* Recursive directory traversal *)
fun visit path =
let
val isDir = FileSys.isDir path
val _ = print (" " ^ path ^ " " ^ Bool.toString isDir ^ "\n")
val dirStream = if isDir then FileSys.openDir path else raise Fail "Not a directory"
fun traverse () =
case FileSys.readDir dirStream of
SOME entry =>
let
val fullPath = OS.Path.joinDirFile {dir = path, file = entry}
in
visit fullPath;
traverse ()
end
| NONE => FileSys.closeDir dirStream
in
if isDir then traverse () else ()
end
val _ = (
print "Visiting subdir\n";
visit "subdir"
)
in
()
end
(* Run the main function *)
val _ = main ()
This Standard ML code demonstrates directory operations similar to the original Go example. Here are some key differences and explanations:
Standard ML doesn’t have a built-in module for directory operations, so we use
SMLofNJ.OS.FileSys
from the Standard ML of New Jersey implementation.Error handling is done using pattern matching on
SOME err
andNONE
instead of explicit error checks.File creation is done using
TextIO.openOut
andTextIO.closeOut
instead ofos.WriteFile
.Directory listing is implemented using
FileSys.openDir
andFileSys.readDir
in a recursive function.Changing directories is done with
FileSys.chDir
.The recursive directory traversal is implemented using a custom
visit
function that usesFileSys.openDir
andFileSys.readDir
.Standard ML doesn’t have an exact equivalent of Go’s
defer
, so cleanup operations are handled manually.
To run this program, you would typically save it as a .sml
file and use an Standard ML interpreter or compiler to execute it. The exact command might vary depending on your Standard ML implementation.
$ sml directories.sml
This code provides a similar functionality to the original Go example, demonstrating directory operations in Standard ML.