I recently watched a video in which the speaker said that Haskell is not suited for real-world tasks, such as copying files from one folder to another. So I tried to write a program that copies a given file system tree to a new location. The usage of the program is
copy_tree <source path> <target path>
If the target path does not exists, it is created. Then all folders and files under
<source path> are copied to
<target path>. Here is my
copy_tree.hs source. I would like to have feedback and suggestions on how to improve it. Especially, I would like to make it as succinct and as idiomatic as possible.
One thing that I do not like very much is that the code calls
import System.Directory import System.Environment import System.FilePath getSubitems path = getSubitemsRec "" where getChildren path = do isDir <- doesDirectoryExist path if isDir then fmap (filter (`notElem` [".", ".."])) (getDirectoryContents path) else return  getSubitemsRec relPath = do children <- getChildren (path </> relPath) let relChildren = [relPath </> p | p <- children] nephewItems <- mapM getSubitemsRec relChildren return (relChildren ++ (concat nephewItems)) copyItem baseSourcePath baseTargetPath relativePath = do let sourcePath = baseSourcePath </> relativePath let targetPath = baseTargetPath </> relativePath putStrLn $ "Copying " ++ sourcePath ++ " to " ++ targetPath isDir <- doesDirectoryExist sourcePath if isDir then createDirectoryIfMissing False targetPath else copyFile sourcePath targetPath copyTree s t = do subItems <- getSubitems s createDirectoryIfMissing True t mapM_ (copyItem s t) subItems main = do args <- getArgs if (length args) == 2 then copyTree (args !! 0) (args !! 1) else putStrLn "Usage: copy_tree <source> <target>"