Reputation: 34091
How can I get a list of directories that are in a directory?
I've come up with the below, but I'm hoping there is a more elegant way:
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
Upvotes: 2
Views: 1468
Reputation: 1365
It looks like you are using the package system-filepath which is deprecated, how about using the filepath package instead:
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
Or if you prefer explicitly using the bind operator:
import Control.Monad (filterM)
import System.Directory (doesDirectoryExist, listDirectory)
import System.FilePath ((</>))
getDirectories :: FilePath -> IO [FilePath]
getDirectories filePath = listDirectory filePath
>>= filterM (doesDirectoryExist . (filePath </>))
NOTE: Your version of the function will return the input filepath prepended to every output directory in the list. While this might be what you want, the version of getDirectories
I am giving you may be more general as it behaves exactly like listDirectory
and simply prunes the files/executables.
EDIT: Changed the import from System.FilePath.Posix
to System.FilePath
for true platform independence. Thanks to Justin Raymond for the suggestion.
Upvotes: 8
Reputation: 3568
All you need is System.Directory
.
import Control.Monad (filterM)
import System.Directory (doesDirectoryExist, getCurrentDirectory, getDirectoryContents)
listDirs :: IO [FilePath]
listDirs = getCurrentDirectory >>= getDirectoryContents >>= filterM doesDirectoryExist
If you want to pass the filepath as argument, just doen't use getCurrentDirectory
.
import Control.Monad (filterM)
import System.Directory (doesDirectoryExist, getCurrentDirectory)
listDirs :: FilePath -> IO [FilePath]
listDirs path = getDirectoryContents path >>= filterM (doesDirectoryExist . (++) path)
Upvotes: 4