
Robert Dockins wrote:
This is true in a sense, but I think making the distinction explicit is helpful for a number of the operations we want to do. For example, what is the parent of the relative path "."? Answer is "..". What is the parent of "/." on unix? Answer is "/.".
While true, I don't see what this has to do with the choice between PathStart and Maybe PathRoot. The types are isomorphic; we can detect and simplify the /.. case either way.
Relative paths can refer to different things in the filesystem depending on process-local state, whereas absolute paths will always refer to the same thing (until the filesystem changes, or if you do something esoteric like "chroot"). Relative paths are really "path fragments."
Okay, this is a good point. There is a difference between a path fragment (i.e. a path with no starting point specified) and a path which explicitly starts in the process's default directory. You're right that the pathname "foo/bar" can only sensibly be put in the former category. The problem is that where Posix has just Absolute | Relative Win32 has Absolute / \ / \ Rel:Abs Abs:Rel \ / \ / Relative where "Rel:Abs" means something like "\foo" and "Abs:Rel" means something like "c:foo". I never realized before what a nightmare it is to handle this sensibly. The problem is that pathAppend "c:\foo\bar" "d:." == "d:.", but pathAppend "d:\foo\bar" "d:." == "d:\foo\bar\.". Therefore, pathAppend "\foo\bar" "d:." doesn't have a value at all, since its meaning depends on the current drive in a way that can't be expressed in the Win32 path syntax. Because of the above problem, I'm willing to treat path fragments (Relative in both lattices) as a special case. But we still need to be able to round-trip rel:abs and abs:rel pathnames, meaning that the PathRoot type won't necessarily be a genuine cwd-independent root any more.
There are a few others. I took a look at MSDN earlier and was astounded.
Is there an MSDN page that actually gives a grammar, or at least a taxonomy, of Win32 pathnames? That would be useful. Incidentally, NT doesn't do a perfect job of parsing its own pathnames. While experimenting I managed to create a file named "..", different from the directory ".." (both show up in the directory listing), which I was subsequently unable to read or delete. The command was something like "cat > ..:foo". I doubt that this behavior is by design.
pathCleanup :: p -> p -- remove .. and suchlike
This can't be done safely except in a few special cases (e.g. "/.." -> "/"). I'm not sure it should be here.
More than you would think, if you follow the conventions of modern unix shells.
It's not a general convention even in the shell, just a peculiarity of the cd builtin: GNU bash, version 2.05b.0(1)-release (i386-pc-linux-gnu) # mkdir /bar # mkdir /bar/baz # ln -s /bar/baz /foo # echo /file > /file # echo /bar/file > /bar/file # cat /foo/../file /bar/file # ls /foo/.. baz file # cd /foo # cat ../file /bar/file In the vast majority of cases it's not safe to collapse "/foo/.." to "/". On reflection I think the function should be provided, but with a name like pathCancel and a usage warning in the documentation. If it's not provided people will write it themselves without realizing that it's unsafe. -- Ben