Haskell неясные операции с файлом (упростите точки)

У меня есть динамически построенный путь к файлу в haskell, который заканчивается примерно так:

/abc/def/../ghi/./jkl

и я хотел бы уменьшить его до более читаемого

/abc/ghi/jkl

Для печати. Есть ли библиотечная функция для этого в haskell? Я все посмотрел и не могу найти. Это не слишком сложно написать, но это немного грязно, потому что вам нужно "смотреть вперед" на "..", и я бы предпочел использовать функцию искупления, если смогу.

Ответ 1

Остерегайтесь, что это не просто вопрос обработки строк, когда задействованы ссылки:

$ mkdir -p foo/bar
$ ln -s foo/bar baz
$ echo gotcha! >foo/quux
$ cat quux
cat: quux: No such file or directory
$ cat baz/../quux
gotcha!

Итак, вам нужно сделать IO.

Ближайший я могу найти, что вы хотите canonicalizePath от System.Directory. Он возвращает путь, начиная с корневого каталога, поэтому вы можете использовать его в сочетании с makeRelative, также из System.Directory. Но он работает в IO.

Ответ 2

Взгляните на System.FilePath.Posix. Функция normalise делает почти то, что вы хотите:

> normalise "/abc/def/../ghi/./jkl"
"/abc/def/../ghi/jkl"

Вы можете использовать splitDirectories, чтобы разделить имя файла и упростить обработку.

Остерегайтесь граничных случаев, таких как:

/../foo        -- Equal to /foo, at least on my system
../parent/foo  -- Requires a system call to eliminate the possibly-redundant ..