File Paths in F#
open System
open System.IO
// The Path module provides functions to parse and construct file paths
// in a way that is portable between operating systems.
// Join 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 = Path.Combine("dir1", "dir2", "filename")
printfn "p: %s" p
// You should always use Path.Combine instead of concatenating
// separators manually. In addition to providing portability,
// Path.Combine will also normalize paths by removing superfluous
// separators and directory changes.
printfn "%s" (Path.Combine("dir1//", "filename"))
printfn "%s" (Path.Combine("dir1/../dir1", "filename"))
// GetDirectoryName and GetFileName can be used to split a path to the
// directory and the file.
printfn "GetDirectoryName(p): %s" (Path.GetDirectoryName(p))
printfn "GetFileName(p): %s" (Path.GetFileName(p))
// We can check whether a path is absolute.
printfn "%b" (Path.IsPathRooted("dir/file"))
printfn "%b" (Path.IsPathRooted("/dir/file"))
let filename = "config.json"
// Some file names have extensions following a dot.
// We can split the extension out of such names with GetExtension.
let ext = Path.GetExtension(filename)
printfn "%s" ext
// To find the file's name with the extension removed,
// use GetFileNameWithoutExtension.
printfn "%s" (Path.GetFileNameWithoutExtension(filename))
// GetRelativePath finds a relative path between a base and a target.
// It returns an empty string if the target cannot be made relative to base.
let rel = Path.GetRelativePath("a/b", "a/b/t/file")
printfn "%s" rel
let rel2 = Path.GetRelativePath("a/b", "a/c/t/file")
printfn "%s" rel2
This F# code demonstrates file path operations using the System.IO.Path
module, which provides similar functionality to Go’s filepath
package. Here are some key points:
Path.Combine
is used to join path components, similar tofilepath.Join
in Go.Path.GetDirectoryName
andPath.GetFileName
are used to split a path into directory and file components, analogous tofilepath.Dir
andfilepath.Base
.Path.IsPathRooted
checks if a path is absolute, similar tofilepath.IsAbs
.Path.GetExtension
extracts the file extension, likefilepath.Ext
.Path.GetFileNameWithoutExtension
removes the extension from a filename, which is similar to usingstrings.TrimSuffix
with the extension in Go.Path.GetRelativePath
finds a relative path between two paths, analogous tofilepath.Rel
.
Note that F# uses different naming conventions (PascalCase for functions) and has some slightly different behaviors. For example, Path.GetRelativePath
returns an empty string instead of an error when a relative path can’t be computed.
To run this F# program, you would typically save it as a .fsx
file and use the F# interactive or compile it with the F# compiler.
$ dotnet fsi file-paths.fsx
or
$ dotnet fsc file-paths.fsx
$ dotnet file-paths.exe
This will output the results of the various file path operations, demonstrating how to work with file paths in a cross-platform manner using F#.