使用System.Directory分别提取文件和目录

时间:2017-01-31 09:56:56

标签: haskell

我是Haskell的新手。我熟悉monads,但不熟练。我正在获取目录的内容并返回它们。现在,我需要将目录中的文件与不是目录的文件分开。

System.Directory有一个名为

的函数
doesFileExist :: FilePath -> IO Bool

我已经创建了一个返回目录内容的函数。这是类型签名:

getListOfFiles :: FilePath -> IO (Either IOException [FilePath])

现在,我想创建一个返回一对的函数。该对的第一个元素应该只包含不是目录的文件路径;第二个应该只包含那些作为目录的文件路径。

总结一下,给定功能:

doesFileExist :: FilePath -> IO Bool
getListOfFiles :: FilePath -> IO (Either IOException [FilePath])

如何获得功能:

getFilesAndDirs :: (FilePath -> IO (Either IOException [FilePath]),  FilePath -> IO (Either IOException [FilePath]))

该对的第一个元素应该只包含不是目录的文件;第二个应该只包含那些目录。函数doesFileExist有助于确定文件是否是目录。

由于我是Haskell的新手,我发现很难为此制定代码。我尝试了很多东西,但遇到了类型错误。

1 个答案:

答案 0 :(得分:0)

这一对的第一个组成部分应该是

getOnlyFiles :: FilePath -> IO (Either IOException [FilePath])
getOnlyFiles fp = do
   efs <- getListOfFiles fp
   case efs of
      Left err -> return (Left err)
      Right fs -> Rigth <$> filterM doesFileExist fs

第二个组件是相同的,除了您需要fmap not . doesFileExist而不是doesFileExist

但请注意,使用此类对需要扫描目录两次。更好的设计IMO将使用返回(包裹)对的函数,例如

getFilesAndDirs :: FilePath -> IO (Either IOException ([FilePath],[FilePath]))

如果图书馆提供partitionM我们可以利用它。可悲的是,它没有,但我们总能自己定义它。