Recursive directory tree printer
You can also use unfoldTree (or unfoldTreeM here) to build Data.Tree:

import Control.Monad
import System.Directory
import System.FilePath
import Data.Tree


dirTree :: FilePath -&gt; IO (Tree FilePath)
dirTree root = unfoldTreeM step (root,root)
    where step (f,c) = do
            fs &lt;- getDirectoryContents f
            ds &lt;- filterM doesDirectoryExist fs
            return (c, [(f &lt;/&gt; d, d) | d &lt;- ds, d /= "." &amp;&amp; d /= ".."])

main :: IO ()
main = do
  t &lt;- dirTree "."
  putStrLn $ drawTree t


Update: As Björn Lindqvist correctly noted in his edit suggestion, my use of doesDirectoryExist doesn't work here (it uses directory names instead of directory paths).

The correct version of dirTree would be:

dirTree :: FilePath -&gt; IO (Tree FilePath)
dirTree root = unfoldTreeM step (root,root)
    where step (p, c) = do
            isDirectory &lt;- doesDirectoryExist p
            fs &lt;- if isDirectory then getDirectoryContents p else return []
            return (c, [(p &lt;/&gt; f, f) | f &lt;- fs, f `notElem` [".", ".."]])