1

I'm having a strange problem when copying a list of files in Haskell. If I run the following code:

copy :: [FilePath] -> FilePath -> IO ()
-- Precondition: dir must be a directory.
copy fs dir = do
    isDir <- doesDirectoryExist dir
    if (isDir)
    then do
        mapM_ putStrLn fs -- Poor man's debug.
        mapM_  (`copyFile` dir) fs
    else ioError (userError $ dir ++ " is not a directory.")

The output of mapM_ putStrLn fs gives a single file, which extists, however the second mapM_ fails with the following message:

./.copyFile4363.tmp: copyFile: inappropriate type (Is a directory)

I'm really puzzled, since in both uses of mapM_ the list fs is passed as parameter.

Am I overlooking something?

Damian Nadales
  • 4,907
  • 1
  • 21
  • 34

1 Answers1

4

From System.Directory Haddock (emphasis mine):

copyFile :: FilePath -> FilePath -> IO () Source

copyFile old new copies the existing file from old to new. If the new file already exists, it is atomically replaced by the old file. Neither path may refer to an existing directory. The permissions of old are copied to new, if possible.

Community
  • 1
  • 1
Ørjan Johansen
  • 18,119
  • 3
  • 43
  • 53
  • Indeed! I overlooked that piece of documentation. I cannot find a bash `cp` equivalent in Haskell :( Related: http://stackoverflow.com/questions/6807025/what-is-the-haskell-way-to-copy-a-directory – Damian Nadales Oct 22 '15 at 10:29
  • @DamianNadales For shell stuff, I keep seeing more and more people referring to the [turtle](https://hackage.haskell.org/package/turtle) library. It has a [`cp`](https://hackage.haskell.org/package/turtle-1.2.2/docs/Turtle-Prelude.html#v:cp) function, but I couldn't see from the docs whether it supports a directory target. – Ørjan Johansen Oct 22 '15 at 10:38
  • I think it doesn't since `cp` uses the `Filesystem` implementation of `copyFile`. However turtle is a good starting point for start adding functionality. – Damian Nadales Oct 22 '15 at 10:51