2013-05-23 5 views
7

मैं हास्केल में किसी फ़ोल्डर के सभी सबफ़ोल्डर को गिनना चाहता हूं। सभी फ़ोल्डर सामग्री प्राप्त करना आसान है, getDirectoryContents फ़ंक्शन है। लेकिन मैं उन्हें कैसे फ़िल्टर करूं? चूंकि getDirectoryContentsIO [FilePath] और filter[a] की अपेक्षा करता है, इसलिए मैं उन दोनों को सीधे एक साथ नहीं रख सकता। (। जाहिर है, मैं monads के साथ एक ताजा मछली हूँ और कर-अंकन)मैं फ़ोल्डर के सभी सबफ़ोल्डर कैसे ढूंढूं?

getAllFolders :: FilePath -> IO [FilePath] 
getAllFolder path = do 
    allItems <- getDirectoryContents path 
    -- now what? the predicate is doesDirectoryExist 

उत्तर

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 तो

getAllFolders path = do 
    contents <- getDirectoryContents path 
    filterM doesDirectoryExist contents 

एक नाम करने के लिए निर्देशिका की सामग्री बंधन के बिना है Control.Monad में परिभाषित किया गया है, या,,

getAllFolders path = getDirectoryContents path >>= filterM doesDirectoryExist 

और बिंदु से मुक्त :

getAllFolders = getDirectoryContents >=> filterM doesDirectoryExist 
+0

धन्यवाद! रिश्तेदार/पूर्ण फ़ाइलपैथ के साथ एक अतिरिक्त समस्या है, लेकिन मैं इसे समझ सकता हूं। – zoul

+2

सापेक्ष पथों के साथ यह समस्या लगातार मुझे ऊपर ले जा रही है - उस बिंदु पर जहां मैंने पुस्तकालय का आविष्कार किया था बस इसे पाने के लिए! साथ ही, 'getDirectoryContents' हमेशा' .' और '..' लौटाता है, जो परेशान है। – MathematicalOrchid

+0

'> =>' mmmm। हमें '> =>' पसंद है। – AndrewC

3

filterMControl.Monad द्वारा की पेशकश की तरह लग रहा है जवाब है:

getAllFolders :: FilePath -> IO [FilePath] 
getAllFolders path = do 
    allItems <- getDirectoryContents path 
    justFolders <- filterM doesDirectoryExist allItems 
    return justFolders 
+0

सही आप पिछले दो पंक्तियों को 'फिल्टरएम करता है डायरेक्टोरीएक्सिस्ट ऑल इटम्स' में भी जोड़ सकते हैं, क्योंकि 'x <- foo; वापसी x' सिर्फ 'foo' जैसा ही है। – hammar

+0

ग्रेट, धन्यवाद। – zoul

संबंधित मुद्दे