Directories in Haskell
Here’s the translation of the Go code to Haskell, along with explanations in Markdown format suitable for Hugo:
Our program demonstrates working with directories in Haskell. Here’s the full source code:
import System.Directory
import System.FilePath
import Control.Exception (catch, SomeException)
import Control.Monad (forM_)
main :: IO ()
main = do
-- Create a new sub-directory in the current working directory.
createDirectory "subdir"
-- When creating temporary directories, it's good practice to ensure their removal.
-- We'll use 'finally' to ensure cleanup happens even if an exception occurs.
(`finally` removeDirectoryRecursive "subdir") $ do
-- Helper function to create a new empty file.
let createEmptyFile name = writeFile name ""
createEmptyFile "subdir/file1"
-- We can create a hierarchy of directories, including parents.
-- This is similar to the command-line `mkdir -p`.
createDirectoryIfMissing True "subdir/parent/child"
createEmptyFile "subdir/parent/file2"
createEmptyFile "subdir/parent/file3"
createEmptyFile "subdir/parent/child/file4"
-- listDirectory lists directory contents.
entries <- listDirectory "subdir/parent"
putStrLn "Listing subdir/parent"
forM_ entries $ \entry -> do
isDir <- doesDirectoryExist $ "subdir/parent" </> entry
putStrLn $ " " ++ entry ++ " " ++ show isDir
-- setCurrentDirectory lets us change the current working directory.
setCurrentDirectory "subdir/parent/child"
-- Now we'll see the contents of `subdir/parent/child` when listing the current directory.
entries <- listDirectory "."
putStrLn "Listing subdir/parent/child"
forM_ entries $ \entry -> do
isDir <- doesDirectoryExist entry
putStrLn $ " " ++ entry ++ " " ++ show isDir
-- Change back to where we started.
setCurrentDirectory "../../.."
-- We can also visit a directory recursively, including all its sub-directories.
putStrLn "Visiting subdir"
walkDir "subdir"
-- walkDir recursively visits directories and files.
walkDir :: FilePath -> IO ()
walkDir dir = do
entries <- listDirectory dir
forM_ entries $ \entry -> do
let path = dir </> entry
isDir <- doesDirectoryExist path
putStrLn $ " " ++ path ++ " " ++ show isDir
when isDir $ walkDir path
To run the program, save it as directories.hs
and use runhaskell
:
$ runhaskell directories.hs
Listing subdir/parent
child True
file2 False
file3 False
Listing subdir/parent/child
file4 False
Visiting subdir
subdir/file1 False
subdir/parent True
subdir/parent/child True
subdir/parent/child/file4 False
subdir/parent/file2 False
subdir/parent/file3 False
This Haskell program demonstrates various operations on directories:
- Creating directories and files
- Listing directory contents
- Changing the current working directory
- Walking a directory tree recursively
The program uses functions from the System.Directory
and System.FilePath
modules to perform these operations. It also demonstrates how to handle exceptions and ensure cleanup using finally
.
Note that Haskell’s approach to file and directory operations is more functional and relies on IO actions, which is different from Go’s more imperative style. However, the core concepts remain similar.