Расширение пути в Хаскелле

Я хочу сделать функцию для расширения имен формы ~user с домашним каталогом этого пользователя (обычно /home/user/), в том числе ~root, который обычно /root/, Я знаю о getHomeDirectory метод, чтобы получить дом текущего пользователя, но я не знаю ни одной функции, чтобы определить домашний каталог данного пользователя.

До сих пор

У меня есть следующая функция, которая заменяет ведущий ~ в любом пути к файлу с домашним каталогом пользователя

-- join path with '/', except at root
-- opposite of breakPath
rejoinPath :: [FilePath] -> FilePath
rejoinPath []   = ""
rejoinPath (p:ps)
    | p == "/"  =  p ++ go ps
    | otherwise =  go (p:ps)
    where
        go :: [FilePath] -> FilePath
        go []     = ""
        go [p]    = p
        go (p:ps) = p ++ "/" ++ go ps

-- split path on '/', erasing separator except at root
-- opposite of rejoinPath
breakPath :: FilePath -> [FilePath]
breakPath []    = []
breakPath (c:cs)
    | c == '/'  = "/" : go "" cs
    | otherwise = go [c] cs
    where
        go :: FilePath -> FilePath -> [FilePath]
        go z []         = [z]
        go z (c:cs)
            | c == '/'  = z : go "" cs
            | otherwise = go (z ++ [c]) cs

expandHome :: FilePath -> IO FilePath
expandHome p = rejoinPath <$> (go $ breakPath p)
    where
        go []           = pure []
        go (p:ps)
            | p == "~"  = do 
                            home <- getHomeDirectory
                            pure $ home : ps
            | otherwise = pure $ p : ps

Я понимаю, что getHomeDirectory читает из HOME переменная окружения, и что другие домашние каталоги будет значительно сложнее приобрести, но я надеюсь, что это не невозможно или слишком сложно.

Заметка

Сейчас меня интересуют только системы Linux; Я понимаю, что Windows и Mac имеют совершенно разные стили.

1 ответ

Решение

Похоже, что это доступно в пакете Unix с использованием getUserEntryForName, а затем homeDirectory поле UserEntry,

import System.Posix.User

main :: IO ()
main = do entry <- getUserEntryForName "djf"
          putStrLn (homeDirectory entry)
Другие вопросы по тегам