System.FilePath propsal (Was: Cabal feedback notes)

Ben Rudiak-Gould benrg at
Sun Oct 31 15:22:45 EST 2004

On Fri, 29 Oct 2004, Andrew Pimlott wrote:

> Well, it's messy, but I don't believe it's that hard.  Of course, you'll
> never be correct outside the IO monad, but if you enumerate your
> assumptions about what a path means outside of IO, I think you can come
> up with a fairly coherent set of operations.

Okay, lemme try...

    -- Given a directory path "dir" and a file/directory path "rel",
    -- returns a merged path "full" with the property that
    -- (cd dir; do_something_with rel) is equivalent to
    -- (do_something_with full). (XXX is a Nothing return ever needed?)

    mergePath :: FilePath -> FilePath -> FilePath

    -- Given a file/directory path "full", return a path "dir"
    -- referring to a directory which contains that file/dir as an
    -- entry, and a path "rel" such that "mergePath dir rel" refers
    -- to the same file/dir as "full". Returns NeedIO if the answer
    -- cannot be determined without IO operations, and NoParent if
    -- there cannot be an answer. (XXX hideous return type)

    splitPath :: FilePath -> SplitPathResult
    data SplitPathResult = NeedIO | NoParent | Split FilePath FilePath

    -- Given path referring to a file or directory, returns a
    -- canonicalized path, with the intent that two paths referring
    -- to the same file/directory will map to the same canonicalized
    -- path. Note that it is impossible to guarantee that the
    -- implication (same file/dir <=> same canonicalizedPath) holds
    -- in either direction: this function can make only a best-effort
    -- attempt. If the path does not refer to an existing file or
    -- directory, returns Nothing. (XXX not ideal, but what else can
    -- you do?)

    canonicalizePath :: FilePath -> IO (Maybe FilePath)

    -- Does as much as possible to simplify and regularize a path
    -- in a meaning-preserving manner, without IO monad operations.
    -- This function is idempotent, and is the identity on all
    -- FilePaths returned by FilePath library functions.
    -- (XXX there's not much this can do -- it's unsafe to convert
    -- "a/b/../c" to "a/c", for example, though I think "a/b/./c"
    -- to "a/b/c" is safe.)

    normalizePath :: FilePath -> FilePath

    -- Returns True if this path's meaning is independent of any OS
    -- "working directory", False if it isn't. (XXX would probably be
    -- better to make FilePath an abstract type and make it always
    -- independent of working directories.)

    isAbsolutePath :: FilePath -> Bool

    -- Returns True if the path always denotes a directory
    -- regardless of the current filesystem state. (XXX is this
    -- the right thing for eliminating . and .. from directory
    -- listings, or is another function needed?)

    isSpecialDirectory :: FilePath -> Bool

    -- Returns True if the path denotes a root. This implies
    -- isSpecialDirectory and isAbsolutePath, and a NoParent return
    -- from splitPath.

    isRoot :: FilePath -> Bool

    -- getRoots returns a list of paths denoting directories which exist
    -- and satisfy isRoot. Can't guarantee to return all of them, since
    -- they may include e.g. "\\\\foo\\bar" on Win32.

    getRoots :: IO [FilePath]


    * functions which operate on file names rather than paths
    * functions which can be implemented portably in terms of the above
    * isRootedPath -- I can't see a use for this
    * various other stuff

-- Ben

More information about the Libraries mailing list