implementation of file-related modules

Simon Marlow simonmar at
Mon Oct 20 14:39:18 EDT 2003

> I've been looking over some of the file-related modules such as
> System.Directory and System.Posix.{Directory,Files}, and I have some
> questions.

My 2p:

> * Some languages have a means of building paths in a portable way.  It
>   would be nice if we had access a file separator (like "/" in unix
>   and "\" in windows).

I've been against doing this in the past, because filename conventions
differ so much between platforms (case sensitivity, length restrictions
on components, syntax for drivenames, what is the meaning of consecutive
pathname separators, etc.).

However, there's clearly a need for some way to do simple pathname
manipulations in a portable way.  So my suggestion is to have something

    parentDirectory :: FilePath -> Mabye FilePath
    relativeToDirectory :: FilePath -> FilePath -> Maybe FilePath
    normaliseFilePath :: FilePath -> FilePath

so you could say things like

    "my.conf" `relativeToDirectory` configDir

It occurs to me that FilePath should be an abstract type.  That would
force the issue: we'd have to deal with all those existing cases which
manipulate FilePaths and work out what abstractions we need.

I don't like the idea of having a System.Directory.Native whose
interface changes depending on the host platform.  I think it's because
platform-dependent APIs tend to lead to fine-grained #ifdefing in client
code, and hence subtle portability problems.  In libraries I try to
stick to modules whose presence (only) depends on the platform, but
there are definitely existing cases which violate this principle.

>     "path.separator" Path separator (for example, ":")

looks like a bad idea to me: application dependent.

>     "file.separator" File separator (for example, "/")
>     "user.home"      User home directory
>     ""	     User account name
>     // might come in useful:
>     "os.arch"    Operating system architecture
>     ""    Operating system name
>     "os.version" Operating system version

System.Info already provides these (except the version).

> * Another item that would be useful in the System.Directory class
>   would be some kind of config file path.  On Debian, that would be
>   "/etc", on some systems, it might tend to be more often
>   "/usr/local/etc".  (I'm not sure if there's a good way to abstract
>   the difference between a user config file and a system config file.
>   User config files tend to be in ~/ and start with a dot whereas
>   system config files end up in /etc, and don't start with a dot.)

The location of config files is something you want to specify via the
build system.  eg. ./configure --prefix=/opt should cause configuration
files to be placed under /opt instead of the default location
(/usr/local?).  Which means that if the config file location were
provided via a Haskell library, that library would have to consult an
environment variable or something.  ( looking through the followups, it
looks like Ketil already mentioned this point).

This just doesn't look like the right abstraction to me.  I think it's
better to let the build system (or library infrastructure) provide this
kind of information, perhaps by auto-generating a module.


More information about the Libraries mailing list