Is there some directory walker in Haskell?
Asked Answered
E

4

19

Is there some recursive directory walker in Haskell so I could write something like

listing <- walkDir "/tmp"

I would not like to write my own. I can install some dependency from cabal but I want it to be cross platform (at least Linux and Windows).

Elinorelinore answered 8/11, 2012 at 21:12 Comment(1)
I wrote the dir-tree package which should allow a lazy walkDir to be defined pretty easily I would guess, e.g. with toList provided by the Foldable instance.Kahl
R
13

Here is one way to list all Haskell files in a directory tree, using directory-tree that is not in a hidden directory (whose name starts with '.'):

import Data.Traversable (traverse)
import System.Directory.Tree (
    AnchoredDirTree(..), DirTree(..),
    filterDir, readDirectoryWith
    )
import System.FilePath (takeExtension)

listFilesDirFiltered = do
    _:/tree <- readDirectoryWith return "C:\\devmy\\code"
    traverse print $ filterDir myPred tree
    return ()
  where myPred (Dir ('.':_) _) = False
        myPred (File n _) = takeExtension n == ".hs"
        myPred _ = True

main = listFilesDirFiltered

Works on both Windows and Linux.

Recency answered 15/11, 2012 at 11:47 Comment(2)
It's just a constructor defined in the library: hackage.haskell.org/packages/archive/directory-tree/0.11.0/doc/…Acrefoot
I like this library a little better than the accepted answer - it's simpler and has less dependencies, yet still just as powerful. It's also compatible with lens, yet doesn't depended on the (huge) lens library if you're not using it. Here's a link to the main hackage page: directory-tree [EDIT: but don't get me wrong; FilePather is also excellent]Wallache
C
7

I have a recursive definition for traversing a directory using filepath package:

import Control.Monad
import System.Directory
import System.FilePath
import System.Posix.Files

-- | Traverse from 'top' directory and return all the files by
-- filtering out the 'exclude' predicate.
traverseDir :: FilePath -> (FilePath -> Bool) -> IO [FilePath]
traverseDir top exclude = do
  ds <- getDirectoryContents top
  paths <- forM (filter (not.exclude) ds) $ \d -> do
    let path = top </> d
    s <- getFileStatus path
    if isDirectory s
      then traverseDir path exclude
      else return [path]
  return (concat paths)
Curarize answered 23/5, 2014 at 6:59 Comment(1)
Thank you @StephaneRolland.Curarize
E
5

http://hackage.haskell.org/package/FilePather has that sort of recursive directory walking functionality.

Encroach answered 8/11, 2012 at 21:16 Comment(2)
Is there some tutorial for that library? It does not look like easy one.Elinorelinore
I made use of it in github.com/singpolyma/imapmd, but only used the docs as presented on hackage.Encroach
C
2

The filemanip package provides powerful and elegant functions for that. For example it provides a fold function that will recursively call your function down a directory tree. As an example i used it here to recursively list files in a directory starting from the oldest

Consortium answered 22/5, 2014 at 22:10 Comment(1)
@Elinorelinore There are some examples in the source code but it's certainly true that Haskell libraries tend to be under-documented in terms of practical, tutorial advice. I often find I get more out of messing around in ghci than reading the docs.Paulsen

© 2022 - 2024 — McMap. All rights reserved.