2017-05-20 92 views
1

如何获取目录中的目录列表?Haskell获取目录中的目录

我想出下面,但我希望有一个更优雅的方式:

import System.Directory 
import qualified Filesystem.Path as FsP 
import Filesystem.Path.CurrentOS 
import Control.Monad 

getDirectories :: Prelude.FilePath -> IO [Prelude.FilePath] 
getDirectories x = do 
    listDirectory x 
    >>= (return . fmap decodeString) 
    >>= return . fmap (FsP.append (decodeString x)) 
    >>= (return . fmap encodeString) 
    >>= filterM doesDirectoryExist 
+0

当你已经使用'>> ='操作符时,你需要'do'符号吗? – Redu

+0

你是对的,这是不需要的。 –

回答

6

它看起来像您使用的是过时的包system-filepath,如何使用filepath包来替代:

import   Control.Monad (filterM) 
import   System.Directory (doesDirectoryExist, listDirectory) 
import   System.FilePath ((</>)) 

getDirectories :: FilePath -> IO [FilePath] 
getDirectories filePath = do 
    allFiles <- listDirectory filePath 
    filterM (doesDirectoryExist . (filePath </>)) allFiles 

,或者您更明确使用绑定操作:

import   Control.Monad (filterM) 
import   System.Directory (doesDirectoryExist, listDirectory) 
import   System.FilePath ((</>)) 

getDirectories :: FilePath -> IO [FilePath] 
getDirectories filePath = listDirectory filePath 
         >>= filterM (doesDirectoryExist . (filePath </>)) 

注意:您版本的函数将返回预置到列表中的每个输出目录中输入文件路径。虽然这可能是你想要的,但我给你的getDirectories版本可能更一般,因为它的行为与listDirectory完全相同,只是简单地修剪文件/可执行文件。

编辑:改变了从进口到System.FilePath.PosixSystem.FilePath真正的平台独立性。感谢Justin Raymond的建议。

3

所有你需要的是System.Directory

import Control.Monad (filterM) 
import System.Directory (doesDirectoryExist, getCurrentDirectory, getDirectoryContents) 

listDirs :: IO [FilePath] 
listDirs = getCurrentDirectory >>= getDirectoryContents >>= filterM doesDirectoryExist 

如果要传递文件路径作为参数,则不要使用getCurrentDirectory

import Control.Monad (filterM) 
import System.Directory (doesDirectoryExist, getCurrentDirectory) 

listDirs :: FilePath -> IO [FilePath] 
listDirs path = getDirectoryContents path >>= filterM (doesDirectoryExist . (++) path) 
+0

“getCurrentDirectory”的例子应该可以工作,但另一个不会。 'getDirectoryContents'给你的相对路径中的内容不是绝对的! –

+0

@ basil-henry fixed –

+0

那么你现在缺少路径分隔符“/”或“\”(在Windows上)。在我的解决方案中,我使用'filepath'包中的'()'来执行依赖于平台的路径追加。 –