File Paths in Idris

Here’s the translation of the Go code example to Idris, formatted in Markdown suitable for Hugo:

The System.FilePath module provides functions to parse and construct file paths in a way that is portable between operating systems; dir/file on Linux vs. dir\file on Windows, for example.

import System.FilePath
import Data.String

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", "dir2", "filename"]
    putStrLn $ "p: " ++ p

    -- You should always use `combine` instead of
    -- concatenating `/`s or `\`s 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"]

    -- `dirname` and `basename` can be used to split a path to the
    -- directory and the file. 
    putStrLn $ "Dir(p): " ++ dirname p
    putStrLn $ "Base(p): " ++ basename 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 `extension`.
    let ext = extension filename
    putStrLn $ show ext

    -- To find the file's name with the extension removed,
    -- use `withoutExtension`.
    putStrLn $ withoutExtension filename

    -- `makeRelative` finds a relative path between a *base* and a
    -- *target*. It returns the target unchanged if the target 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.idr and use the Idris compiler:

$ idris file_paths.idr -o file_paths
$ ./file_paths
p: dir1/dir2/filename
dir1/filename
dir1/filename
Dir(p): dir1/dir2
Base(p): filename
False
True
Just ".json"
config
t/file
../c/t/file

Note that Idris’s System.FilePath module provides similar functionality to Go’s filepath package, but with some differences in function names and behavior. The combine function in Idris is similar to Join in Go, dirname is similar to Dir, basename to Base, and so on.

Idris, being a purely functional language, handles some operations differently. For example, error handling is typically done through return types like Maybe or Either rather than through explicit error returns as in Go.

Also, Idris doesn’t have a direct equivalent to Go’s strings.TrimSuffix. Instead, we use the withoutExtension function to remove the file extension.

This example demonstrates how to work with file paths in Idris, providing a similar level of portability and functionality as the Go example.