simonmarhaskell at gmail.com
Tue Dec 11 09:22:14 EST 2007
Ian Lynagh wrote:
> On Sun, Dec 09, 2007 at 09:17:56PM +0000, Neil Mitchell wrote:
>>> The first is this:
>>> Prelude System.FilePath> "." </> "foo"
>>> which means we get things like
>>> [2 of 2] Compiling GHC.Foo ( ./GHC/Foo.hs, ./GHC/Foo.o )
>>> rather than
>>> [2 of 2] Compiling GHC.Foo ( GHC/Foo.hs, GHC/Foo.o )
>>> Is there a reason the result shouldn't be "foo"?
>> My best guess is that "." </> "foo" should equal "./foo". However, I'm
>> not overly wedded to this behaviour, so if the general consensus is
>> the other way, I'll happily implement that.
>>> Possibly relatedly, the current directory seems to be "" rather than
>>> ".". This turns up in at least a couple of areas:
>>> Prelude System.FilePath> normalise "."
>> I would say this is a bug, and that normalise "." should be ".".
> The two answers above together mean that the property
> \x y -> let x' = normalise x
> y' = normalise y
> z = x' </> y'
> in z == normalise z'
> doesn't hold (for x = ".", y = "foo"), but it is one I would expect to
I think you have an extra ' on the last line of the code above. But
anyway, why do you expect that to hold?
There's an implicit context in the definition of normalise. The invariant
we want is that I can use "normalise x" wherever I use "x" and get the same
result. But it can't be that simple, because we can always tell the
difference by looking at the string, so we have to define the allowable
context carefully. It looks like the context we're aiming for is "all
functions in System.FilePath, System.IO and System.Directory".
Which would make "./foo" the same as "foo": as far as the OS is concerned,
these always mean the same thing.
execvp mucks things up by giving a special meaning to "foo". But all this
means is that execvp (and hence rawSystem) is a context that can tell the
difference between "normalise x" and "x", and therefore you shouldn't call
normalise on the path given to rawSystem.
>>> Prelude System.FilePath> splitFileName "foo"
>> I'd say this was expected. In a similar way, takeDirectory "foo" gives
>> "", not "./".
> I'd expect takeDirectory "foo" to be "." and dropFileName "foo" to be
> "./" too.
Right, me too.
But this is more of a pervasive design choice. It looks like
System.FilePath consistently treats "" as a valid FilePath meaning "the
current directory", and this would mean changing that policy.
As far as System.Directory is concerned, "" is not a valid FilePath (i.e.
you can't say getDirectoryContents ""), and the current directory is
denoted by ".". So it would seem sensible for System.FilePath to behave in
the same way.
But then (splitFileName "foo") would have to give (".", "foo"), and therefore
uncurry (</>) (splitFileName x) /= x
which seems odd. But perhaps the right property is
normalise (uncurry (</>) (splitFileName x)) == normalise x
More information about the Libraries