I wrote this program that recursively prints all the files and directories starting at the current directory:
import Data.Tree (Tree (..))
import System.Directory (doesDirectoryExist, getCurrentDirectory, getDirectoryContents)
main :: IO ()
main = do
currentDirectory <- getCurrentDirectory
tree <- tree currentDirectory "."
printTree 0 tree
printTree :: Int -> Tree FilePath -> IO ()
printTree indent tree = do
putStrLn $ (replicate indent ' ' ++ rootLabel tree)
mapM_ (printTree $ indent + 2) (subForest tree)
treeHelper :: FilePath -> IO [Tree FilePath]
treeHelper path =
let filter' = filter (`notElem` [".", ".."]) in
do
contents <- getDirectoryContents path
trees <- mapM (tree path) (filter' contents)
return trees
tree :: FilePath -> FilePath -> IO (Tree FilePath)
tree parent path =
let fullPath = (parent ++ "/" ++ path) in
do
isDirectory <- doesDirectoryExist fullPath
case isDirectory of
False -> return $ Node path []
True -> treeHelper fullPath >>= (return . Node (path ++ "/"))
If you run it, it might print something like this:
./
dist/
build/
autogen/
cabal_macros.h
Paths_Tree.hs
tree/
tree
tree-tmp/
Main.hi
Main.o
package.conf.inplace
setup-config
Setup.lhs
tree.cabal
Tree.hs
I think this is pretty nifty. It's a toy program, so I purposefully left out stuff like error checking and symlink handling and etc. How would you improve this program? Am I duplicating functionality available in a library? Are there places where the code could be tighter? Is my Haskell style not up to snuff?