如何查找文件夹的所有子文件夹?

zou*_*oul 7 io monads haskell

我想枚举Haskell中文件夹的所有子文件夹.获取所有文件夹内容很简单,有一个  getDirectoryContents功能.但是我该如何过滤它们呢?由于getDirectoryContents返回a IO [FilePath]filter期望[a],我不能将这两者直接放在一起.(显然,我是一条带有monad和do-notation的新鲜鱼.)

getAllFolders :: FilePath -> IO [FilePath]
getAllFolder path = do
    allItems <- getDirectoryContents path
    -- now what? the predicate is doesDirectoryExist
Run Code Online (Sandbox Code Playgroud)

Dan*_*her 7

问题不在于getDirectoryContents返回类型IO [FilePath],FilePath通过绑定结果得到s 的简单列表,

getAllFolders path = do
    contents <- getDirectoryContents path
    -- do something with contents now, it's a plain [FilePath]
Run Code Online (Sandbox Code Playgroud)

问题是谓词doesDirectoryExist有类型FilePath -> IO Bool.对于这样的事情,有

ghci> :t Control.Monad.filterM
Control.Monad.filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
Run Code Online (Sandbox Code Playgroud)

filterM定义于Control.Monad,所以

getAllFolders path = do
    contents <- getDirectoryContents path
    filterM doesDirectoryExist contents
Run Code Online (Sandbox Code Playgroud)

或者,不将目录的内容绑定到名称,

getAllFolders path = getDirectoryContents path >>= filterM doesDirectoryExist
Run Code Online (Sandbox Code Playgroud)

和无点:

getAllFolders = getDirectoryContents >=> filterM doesDirectoryExist
Run Code Online (Sandbox Code Playgroud)

  • 相对路径的这个问题不断让我沮丧 - 我发明了一个图书馆只是为了绕过它!此外,`getDirectoryContents`总是返回`.`和`..`,这很烦人. (2认同)