我想枚举Haskell中文件夹的所有子文件夹。获取所有文件夹内容很简单,有一个getDirectoryContents
功能。但是我该如何过滤它们呢?由于getDirectoryContents
返回IO [FilePath]
而filter
预计[a]
,我不能将这两者直接放在一起。 (显然,我是一条带有monad和do-notation的新鲜鱼。)
getAllFolders :: FilePath -> IO [FilePath]
getAllFolder path = do
allItems <- getDirectoryContents path
-- now what? the predicate is doesDirectoryExist
答案 0 :(得分:7)
问题不在于getDirectoryContents
具有返回类型IO [FilePath]
,您通过绑定结果得到FilePath
的简单列表,
getAllFolders path = do
contents <- getDirectoryContents path
-- do something with contents now, it's a plain [FilePath]
问题是谓词doesDirectoryExist
的类型为FilePath -> IO Bool
。对于这样的事情,有
ghci> :t Control.Monad.filterM
Control.Monad.filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM
中定义了 Control.Monad
,所以
getAllFolders path = do
contents <- getDirectoryContents path
filterM doesDirectoryExist contents
或者,不将目录的内容绑定到名称
getAllFolders path = getDirectoryContents path >>= filterM doesDirectoryExist
和无点:
getAllFolders = getDirectoryContents >=> filterM doesDirectoryExist
答案 1 :(得分:3)
filterM
提供的Control.Monad
似乎就是答案:
getAllFolders :: FilePath -> IO [FilePath]
getAllFolders path = do
allItems <- getDirectoryContents path
justFolders <- filterM doesDirectoryExist allItems
return justFolders