File Paths in Haskell
Here’s the translation of the Go file paths example to Haskell:
Our program demonstrates how to work with file paths in Haskell using the filepath
module. This module provides functions to parse and construct file paths in a way that is portable between operating systems.
import System.FilePath
import Data.List (stripPrefix)
main :: IO ()
main = do
-- `combine` should be used to construct paths in a
-- portable way. It takes any number of arguments
-- and constructs a hierarchical path from them.
let p = combine "dir1" $ combine "dir2" "filename"
putStrLn $ "p: " ++ p
-- You should always use `combine` instead of
-- concatenating '/' or '\' manually. In addition
-- to providing portability, `combine` will also
-- normalize paths by removing superfluous separators
-- and directory changes.
putStrLn $ combine "dir1//" "filename"
putStrLn $ combine "dir1/../dir1" "filename"
-- `takeDirectory` and `takeFileName` can be used to split a path to the
-- directory and the file. Alternatively, `splitFileName` will
-- return both in the same call.
putStrLn $ "takeDirectory p: " ++ takeDirectory p
putStrLn $ "takeFileName p: " ++ takeFileName p
-- We can check whether a path is absolute.
putStrLn $ show $ isAbsolute "dir/file"
putStrLn $ show $ isAbsolute "/dir/file"
let filename = "config.json"
-- Some file names have extensions following a dot. We
-- can split the extension out of such names with `takeExtension`.
let ext = takeExtension filename
putStrLn ext
-- To find the file's name with the extension removed,
-- use `dropExtension`.
putStrLn $ dropExtension filename
-- `makeRelative` finds a relative path between a base and a
-- target. It returns the target unchanged if it cannot
-- be made relative to base.
putStrLn $ makeRelative "a/b" "a/b/t/file"
putStrLn $ makeRelative "a/b" "a/c/t/file"
To run the program, save it as file-paths.hs
and use runhaskell
:
$ runhaskell file-paths.hs
p: dir1/dir2/filename
dir1/filename
dir1/filename
takeDirectory p: dir1/dir2
takeFileName p: filename
False
True
.json
config
t/file
../c/t/file
In this Haskell version:
- We use the
System.FilePath
module, which provides similar functionality to Go’sfilepath
package. combine
is used instead ofJoin
to construct file paths.takeDirectory
andtakeFileName
are used instead ofDir
andBase
.isAbsolute
checks if a path is absolute.takeExtension
extracts the file extension.dropExtension
removes the extension from a filename.makeRelative
finds a relative path between two paths.
Note that Haskell’s filepath
module doesn’t have an exact equivalent to Go’s filepath.Rel
. The makeRelative
function is similar but behaves slightly differently when the paths can’t be made relative.
Haskell’s approach to file paths is similar to Go’s, providing a portable way to work with paths across different operating systems.