Advertisement
ot32em

Walk Directory in Haskell v230113

Jan 12th, 2023 (edited)
2,022
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 1.28 KB | Source Code | 0 0
  1. import System.Environment ( getArgs )
  2. import System.Directory
  3.     ( doesDirectoryExist, doesFileExist, listDirectory )
  4. import System.FilePath ( (</>), takeExtension )
  5. import Control.Monad ( filterM, forM_ )
  6.  
  7. -- [helper]
  8. splitFD :: [FilePath] -> IO([FilePath], [FilePath])
  9. splitFD items = do
  10.     files <- filterM doesFileExist items
  11.     dirs <- filterM doesDirectoryExist items
  12.     return (files, dirs)
  13.  
  14. -- [helper] list qualified path by `prepending src dir`
  15. listDirectoryPath :: FilePath -> IO [FilePath]
  16. listDirectoryPath src = do
  17.     names <- listDirectory src
  18.     return $ (src </>) <$> names
  19.  
  20. -- [main] walkDir with maxDepth
  21. walkDirSafe :: Int -> (FilePath -> Bool) -> FilePath -> IO [FilePath]
  22. walkDirSafe 0 _ _ = return []
  23. walkDirSafe maxDepth p src = do
  24.     paths <- listDirectoryPath src
  25.     (files, dirs) <- splitFD paths
  26.     let thisFiles = filter p files
  27.     thatFilesList <- walkDirSafe (maxDepth - 1) p `mapM` dirs
  28.     return $ thisFiles ++ mconcat thatFilesList
  29.  
  30. -- [main] no maxDepth limit walkDir
  31. walkDir :: (FilePath -> Bool) -> FilePath -> IO [FilePath]
  32. walkDir = walkDirSafe (-1)
  33.  
  34. -- [client example]
  35. main :: IO ()
  36. main = do
  37.     args <- getArgs
  38.     let src = head args
  39.     result <- walkDir (\x -> takeExtension x == ".txt") src
  40.     forM_ result print
  41.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement