import System.Directory -- find1 :: FilePath -> IO () find1 dir = do fs <- getDirectoryContents dir sequence_ [ found (dir ++ "/" ++ f) | f <- fs , f `notElem` [".",".."] ] where found file = do print file b <- doesDirectoryExist file if b then find1 file else return () -- find2 :: FilePath -> IO [FilePath] find2 dir = do fs <- getDirectoryContents dir fss <- sequence [ found (dir ++ "/" ++ f) | f <- fs , f `notElem` [".",".."] ] return (concat fss) where found file = do b <- doesDirectoryExist file if b then do fs <- find2 file return (file:fs) else return [file] -- data File = Dir String [File] | File String deriving ( Show, Eq ) type FileSystem = [File] find3 :: FilePath -> IO FileSystem find3 dir = do fs <- getDirectoryContents dir sequence [ found dir f | f <- fs , f `notElem` [".",".."] ] where found dir f = do b <- doesDirectoryExist file if b then do fs <- find3 file return (Dir f fs) else return (File f) where file = dir ++ "/" ++ f -- keepFile :: (String -> Bool) -> File -> Maybe File keepFile p (File f) | p f = Just (File f) | otherwise = Nothing keepFile p (Dir d fs) = Just (Dir d (keep p fs)) keep :: (String -> Bool) -> FileSystem -> FileSystem keep p files = [ file | file <- files, Just file' <- [keepFile p file] ]