Я считаю, что все больше и больше скриптов в haskell. Но есть некоторые случаи, когда я действительно не уверен, как это сделать "правильно".
например скопируйте каталог рекурсивно (a la unix cp -r
).
Поскольку я в основном использую Linux и Mac Os, я обычно обманываю:
import System.Cmd
import System.Exit
copyDir :: FilePath -> FilePath -> IO ExitCode
copyDir src dest = system $ "cp -r " ++ src ++ " " ++ dest
Но каков рекомендуемый способ скопировать каталог в независимую от платформы?
Я не нашел ничего подходящего для взлома.
Это моя довольно наивная реализация, которую я использую до сих пор:
import System.Directory
import System.FilePath((</>))
import Control.Applicative((<$>))
import Control.Exception(throw)
import Control.Monad(when,forM_)
copyDir :: FilePath -> FilePath -> IO ()
copyDir src dst = do
whenM (not <$> doesDirectoryExist src) $
throw (userError "source does not exist")
whenM (doesFileOrDirectoryExist dst) $
throw (userError "destination already exists")
createDirectory dst
content <- getDirectoryContents src
let xs = filter (`notElem` [".", ".."]) content
forM_ xs $ \name -> do
let srcPath = src </> name
let dstPath = dst </> name
isDirectory <- doesDirectoryExist srcPath
if isDirectory
then copyDir srcPath dstPath
else copyFile srcPath dstPath
where
doesFileOrDirectoryExist x = orM [doesDirectoryExist x, doesFileExist x]
orM xs = or <$> sequence xs
whenM s r = s >>= flip when r
Любые предложения о том, что на самом деле способ сделать это?
Я обновил это с предложениями hammar и FUZxxl.
... но все же для меня такая неуклюжая для такой общей задачи!