2017-05-20 91 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'包中的'()'來執行依賴於平臺的路徑追加。 –