directory-tree-0.2.0: A simple directory-like tree datatype, with useful IO functions

MaintainerBrandon Simmons <>




Provides a simple data structure mirroring a directory tree on the filesystem, as well as useful functions for reading and writing file and directory structures in the IO monad.

Errors are caught in a special constructor in the DirTree type.

Defined instances of Functor, Traversable and Foldable allow for easily operating on a directory of files. For example, you could use Foldable.foldr to create a hash of the entire contents of a directory.

The AnchoredDirTree type is a simple wrapper for DirTree to keep track of a base directory context for the DirTree.

Please send me any requests, bugs, or other feedback on this module!


Data types for representing directory trees

data DirTree a Source

the String in the name field is always a file name, never a full path. The free type variable is used in the File constructor and can hold Handles, Strings representing a file's contents or anything else you can think of. We catch any IO errors in the Failed constructor. an Exception can be converted to a String with show.




name :: FileName
contents :: [DirTree a]


name :: FileName
file :: a


name :: FileName
err :: IOException

data AnchoredDirTree a Source

a simple wrapper to hold a base directory name, which can be either an absolute or relative path. This lets us give the DirTree a context, while still letting us store only directory and file NAMES (not full paths) in the DirTree. (uses an infix constructor; don't be scared)


FilePath :/ (DirTree a) 


type FileName = StringSource

an element in a FilePath:

High level IO functions

readDirectory :: FilePath -> IO (AnchoredDirTree String)Source

build an AnchoredDirTree, given the path to a directory, opening the files using readFile.

readDirectoryWith :: (FilePath -> IO a) -> FilePath -> IO (AnchoredDirTree a)Source

same as readDirectory but allows us to, for example, use ByteString.readFile to return a tree of ByteStrings.

writeDirectory :: AnchoredDirTree String -> IO ()Source

write a DirTree of strings to disk. clobbers files of the same name. doesn't affect files in the directories (if any already exist) with different names:

writeDirectoryWith :: (FilePath -> a -> IO ()) -> AnchoredDirTree a -> IO ()Source

writes the directory structure to disc, then uses the provided function to write the contents of Files to disc.

Lower level functions

zipPaths :: AnchoredDirTree a -> DirTree (FilePath, a)Source

tuple up the complete filename with the File contents, by building up the path, trie-style, from the root. The filepath will be relative to the current directory. This allows us to, for example, mapM_ 'uncurry writeFile' over a DirTree of strings.

build :: FilePath -> IO (AnchoredDirTree FilePath)Source

builds a DirTree from the contents of the directory passed to it, saving the base directory in the Anchored* wrapper. Errors are caught in the tree in the Failed constructor. The file fields initially are populated with full paths to the files they are abstracting.

openDirectory :: FilePath -> IOMode -> IO (AnchoredDirTree Handle)Source

a simple application of readDirectoryWith openFile:

writeJustDirs :: AnchoredDirTree a -> IO ()Source

writes the directory structure (not files) of a DirTree to the anchored directory. can be preparation for writing files:

Utility functions

Handling failure

successful :: DirTree a -> BoolSource

True if there are no Failed constructors in the tree

anyFailed :: DirTree a -> BoolSource

True if any Failed constructors in the tree

failures :: DirTree a -> [DirTree a]Source

returns a list of Failed constructors only:

failedMap :: (FileName -> IOException -> DirTree a) -> DirTree a -> DirTree aSource

maps a function to convert Failed DirTrees to Files or Dirs


free :: AnchoredDirTree a -> DirTree aSource

strips away base directory wrapper: