import System.Directory (getDirectoryContents, doesDirectoryExist)
data Tree a = Directory a [Tree a] | File a deriving (Show)
makeTheTree :: FilePath -> IO (Tree FilePath)
makeTheTree path = do
isDirecotry <- doesDirectoryExist path
if not isDirecotry then
return $ File path
else do
content <- getDirectoryContents path
tree <- mapM makeTheTree (processFiles content)
return $ Directory path tree
where
processFiles :: [FilePath] -> [FilePath]
processFiles files = map ((path ++) . ("/" ++)) $ discardDots files
discardDots :: [FilePath] -> [FilePath]
discardDots = filter (\file -> file /= "." && file /= "..")
traverseBF :: Tree a -> [a]
traverseBF tree = tbf [tree] where
tbf [] = []
tbf xs = concatMap files xs ++ tbf (concatMap directories xs)
files :: Tree a -> [a]
files (File a) = [a]
files (Directory _ _) = []
directories :: Tree a -> [Tree a]
directories (File _) = []
directories (Directory _ ys) = ys
main = (traverseBF <$> makeTheTree "/usr/local") >>= mapM_ (print . length . filter (=='/'))