gpt4 book ai didi

haskell - 惯用的 io-streams 目录遍历

转载 作者:行者123 更新时间:2023-12-02 03:35:52 25 4
gpt4 key购买 nike

我是 discussing some code on Reddit ,这让我很好奇这将如何在 io-streams 中实现。考虑以下遍历目录结构并打印出所有文件名的代码:

import           Control.Exception         (bracket)
import qualified Data.Foldable as F
import Data.Streaming.Filesystem (closeDirStream, openDirStream,
readDirStream)
import System.Environment (getArgs)
import System.FilePath ((</>))

printFiles :: FilePath -> IO ()
printFiles dir = bracket
(openDirStream dir)
closeDirStream
loop
where
loop ds = do
mfp <- readDirStream ds
F.forM_ mfp $ \fp' -> do
let fp = dir </> fp'
ftype <- getFileType fp
case ftype of
FTFile -> putStrLn fp
FTFileSym -> putStrLn fp
FTDirectory -> printFiles fp
_ -> return ()
loop ds

main :: IO ()
main = getArgs >>= mapM_ printFiles

假设我们想要创建某种流式文件路径表示,而不是简单地打印文件。我知道这在枚举器、管道和管道中是如何工作的。但是,由于中间步骤需要获取稀缺资源(DirStream),我不确定 io-streams 的实现是什么。有人可以举例说明如何做到这一点吗?

为了比较,here's the conduit implementation ,这是通过 bracketPMonadResource 实现的。以下是如何使用管道代码来实现与上面相同的文件打印程序:

import           Control.Monad.IO.Class       (liftIO)
import Control.Monad.Trans.Resource (runResourceT)
import Data.Conduit (($$))
import Data.Conduit.Filesystem (sourceDirectoryDeep)
import qualified Data.Conduit.List as CL
import System.Environment (getArgs)

main :: IO ()
main =
getArgs >>= runResourceT . mapM_ eachRoot
where
-- False means don't traverse dir symlinks
eachRoot root = sourceDirectoryDeep False root
$$ CL.mapM_ (liftIO . putStrLn)

最佳答案

典型的风格是做这样的事情:

traverseDirectory :: RawFilePath -> (InputStream RawFilePath -> IO a) -> IO a

即一个标准的“with-”函数,具有明显的实现。

编辑:添加了一个工作示例实现:https://gist.github.com/gregorycollins/00c51e7e33cf1f9c8cc0

它并不完全复杂,但也不像我最初建议的那样微不足道。

关于haskell - 惯用的 io-streams 目录遍历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23509073/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com