Guest User

Untitled

a guest
Jan 19th, 2019
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.71 KB | None | 0 0
  1. getFilePathBreadtFirst :: FilePath -> IO [FilePath]
  2. getFilePathBreadtFirst fp = do
  3. fileinfo <- getInfo fp
  4. res :: [FilePath] <- if isReadableDirectory fileinfo
  5. then do
  6. children <- getChildren fp
  7. lower <- mapM getFilePathBreadtFirst children
  8. return (children ++ concat lower)
  9. else return [fp] -- should only return the files?
  10. return res
  11.  
  12. getChildren :: FilePath -> IO [FilePath]
  13. getChildren path = do
  14. names <- getUsefulContents path
  15. let namesfull = map (path </>) names
  16. return namesfull
  17.  
  18. testBF fn = do -- crashes for /home/frank, does not go to swap
  19. fps <- getFilePathBreadtFirst fn
  20. putStrLn $ unlines fps
  21.  
  22. import Control.Monad
  23. import Control.Monad.Trans
  24. import Control.Monad.Trans.Maybe
  25. import Control.Monad.State.Lazy
  26. import Control.Pipe
  27. import Data.Sequence
  28. import System.FilePath.Posix
  29. import System.Directory
  30.  
  31. loop :: (Monad m) => MaybeT m a -> m ()
  32. loop = liftM (maybe () id) . runMaybeT . forever
  33.  
  34. quit :: (Monad m) => MaybeT m a
  35. quit = mzero
  36.  
  37. getUsefulContents :: FilePath -> IO [FilePath]
  38. getUsefulContents path
  39. = fmap (filter (`notElem` [".", ".."])) $ getDirectoryContents path
  40.  
  41. permissible :: FilePath -> IO Bool
  42. permissible file
  43. = fmap (p -> readable p && searchable p) $ getPermissions file
  44.  
  45. traverseTree :: FilePath -> Producer FilePath IO ()
  46. traverseTree path = (`evalStateT` empty) $ loop $ do
  47. -- All code past this point uses the following monad transformer stack:
  48. -- MaybeT (StateT (Seq FilePath) (Producer FilePath IO)) ()
  49. let liftState = lift
  50. liftPipe = lift . lift
  51. liftIO = lift . lift . lift
  52. liftState $ modify (|> path)
  53. forever $ do
  54. x <- liftState $ gets viewl
  55. case x of
  56. EmptyL -> quit
  57. file :< s -> do
  58. liftState $ put s
  59. liftPipe $ yield file
  60. p <- liftIO $ doesDirectoryExist file
  61. when p $ do
  62. names <- liftIO $ getUsefulContents file
  63. -- allowedNames <- filterM permissible names
  64. let namesfull = map (path </>) names
  65. liftState $ forM_ namesfull $ name -> modify (|> name)
  66.  
  67. printer :: (Show a) => Consumer a IO r
  68. printer = forever $ do
  69. a <- await
  70. lift $ print a
  71.  
  72. >>> runPipe $ printer <+< traverseTree path
  73. <Prints file names as it traverses the tree>
  74.  
  75. -- Demand only 'n' elements
  76. take' :: (Monad m) => Int -> Pipe a a m ()
  77. take' n = replicateM_ n $ do
  78. a <- await
  79. yield a
  80.  
  81. >> runPipe $ printer <+< take' 3 <+< traverseTree path
  82. <Prints only three files>
  83.  
  84. traverseTree :: FilePath -> Producer FilePath IO ()
  85. -- ^ traverse a tree in breadth first fashion using an external doBF function
  86. traverseTree path = (`evalStateT` empty) $ loop $ do
  87. -- All code past this point uses the following monad transformer stack:
  88. -- MaybeT (StateT (Seq FilePath) (Producer FilePath IO)) ()
  89. let liftState = lift
  90. liftPipe = lift . lift
  91. liftIO = lift . lift . lift
  92. liftState $ modify (|> path)
  93. forever $ do
  94. x <- liftState $ gets viewl
  95. case x of
  96. EmptyL -> quit
  97. file :< s -> do
  98. (yieldval, nextInputs) <- liftIO $ doBF file
  99. liftState $ put s
  100. liftPipe $ yield yieldval
  101. liftState $ forM_ nextInputs $ name -> modify (|> name)
  102.  
  103. doBF :: FilePath -> IO (FilePath, [FilePath])
  104. doBF file = do
  105. finfo <- getInfo file
  106. let p = isReadableDirectoryNotLink finfo
  107. namesRes <- if p then do
  108. names :: [String] <- liftIO $ getUsefulContents file
  109. let namesSorted = sort names
  110. let namesfull = map (file </>) namesSorted
  111. return namesfull
  112. else return []
  113. return (file, namesRes)
Add Comment
Please, Sign In to add comment