2013-05-23 18 views
7

Haskell'deki bir klasörün tüm alt klasörlerini sıralamak istiyorum. Tüm klasör içeriğini almak kolay, bir getDirectoryContents işlevi var. Ama onları nasıl filtreleyebilirim? getDirectoryContents bir IO [FilePath] döndürdüğünden ve filter[a] beklediğinden, bu ikisini doğrudan birlikte ekleyemiyorum. (. Açıkçası, ben monads ile taze balık değilim ve do-notasyonu)Bir klasörün tüm alt klasörlerini nasıl bulurum?

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

cevap

7

sorun olduğunu getDirectoryContents değildir dönüşü vardır tip IO [FilePath], sen

getAllFolders path = do 
    contents <- getDirectoryContents path 
    -- do something with contents now, it's a plain [FilePath] 

sorun yani sonuç bağlanarak FilePath s düz listesini almak doesDirectoryExist, FilePath -> IO Bool türüne sahiptir. Böyle şeyler için, bir isme dizinin içeriğini bağlayıcı olmadan

getAllFolders path = getDirectoryContents path >>= filterM doesDirectoryExist 

ve nokta içermeyen orada, Control.Monad tanımlanan

ghci> :t Control.Monad.filterM 
Control.Monad.filterM :: Monad m => (a -> m Bool) -> [a] -> m [a] 

filterM yüzden

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

veya :

getAllFolders = getDirectoryContents >=> filterM doesDirectoryExist 
+0

Teşekkürler! Göreli/mutlak dosya yollarında ek bir sorun var, ama bunu anlayabiliyorum. – zoul

+2

Göreli yollar ile ilgili bu problem sürekli beni harekete geçiriyor - etrafta dolaşmak için bir kütüphane tasarladığım noktaya kadar! Ayrıca, getDirectoryContents' her zaman döndürür '' '' '' ', can sıkıcı bir durumdur. – MathematicalOrchid

+0

'> =>' mmmm. Biz seviyoruz. – AndrewC

3

Control.Monad sunduğu filterM benziyor yanıt:

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

Doğru. Ayrıca, son iki satırı sadece 'filterM doesDirectoryExist allItems' ile birleştirebilirsiniz, çünkü x <- foo; x' döndürmek sadece foo’yla aynıdır. – hammar

+0

Harika, teşekkürler. – zoul

İlgili konular