
Ian Lynagh wrote:
On Sun, Dec 09, 2007 at 09:17:56PM +0000, Neil Mitchell wrote:
The first is this: Prelude System.FilePath> "." > "foo" "./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 hold.
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" ("","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 Cheers, Simon