expandUser :: FilePath -> IO FilePath
expandUser p = if "~/" `isPrefixOf` p
then do u <- getLoginName
return $ u ++ drop 2 p
else return p
expandUser "~" = fmap homeDirectory getLoginName
expandUser ('~':'/':p) = getLoginName >>=
fmap ((++ p) . homeDirectory)
getUserEntryForName
expandUser ('~':up) = let (u,p) = break (== '/') up
in fmap ((++ (drop 1 p)) . homeDirectory
(getUserEntryForName u)
expandUser p = p
Although arguably there should be some error checking.