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" rel2This 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.Combineis used to join path components, similar tofilepath.Joinin Go.Path.GetDirectoryNameandPath.GetFileNameare used to split a path into directory and file components, analogous tofilepath.Dirandfilepath.Base.Path.IsPathRootedchecks if a path is absolute, similar tofilepath.IsAbs.Path.GetExtensionextracts the file extension, likefilepath.Ext.Path.GetFileNameWithoutExtensionremoves the extension from a filename, which is similar to usingstrings.TrimSuffixwith the extension in Go.Path.GetRelativePathfinds 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.fsxor
$ dotnet fsc file-paths.fsx
$ dotnet file-paths.exeThis will output the results of the various file path operations, demonstrating how to work with file paths in a cross-platform manner using F#.