我在 Haskell 方面比较缺乏经验,我想改进,所以对于我的一个学习项目,我有以下要求:
.md
. toplevel/.excluded
. .filename.md.swp
. 我到处搜索。这是我到目前为止所拥有的:
import qualified System.FilePath.Find as SFF
import qualified Filesystem.Path.CurrentOS as FP
srcFolderName = "src"
outFolderName = "output"
resFolderName = "res"
ffNotHidden :: SFF.FindClause Bool
ffNotHidden = SFF.fileName SFF./~? ".?*"
ffIsMD :: SFF.FindClause Bool
ffIsMD = SFF.extension SFF.==? ".md" SFF.&&? SFF.fileName SFF./~? ".?*"
findMarkdownSources :: FilePath -> IO [FilePath]
findMarkdownSources filePath = do
paths <- SFF.find ffNotHidden ffIsMD filePath
return paths
这行不通。 “findMarkdownSources”中的 printf 样式调试,我可以验证 filePath 是否正确,例如
"/home/user/testdata"
(打印包括“,以防万一)。列表paths
总是空的。我绝对确定我指定的目录中有markdown文件(查找/path/to/dir -name“* .md” 找到它们)。因此,我有一些具体的问题。
每个人都有大约三种独特的方式来实现我想要实现的目标,所以,我们几乎有 10 种方式来实现它......
如果它有帮助,我对基本的 haskell 相当满意,但是如果我们开始对 monad 和应用仿函数太重,你需要放慢速度(我没有使用足够的 haskell 来让这个留在我的脑海中)。不过,我发现有关 hackage 的 haskell 文档难以理解。
最佳答案
so, we're nearly at 10 ways to do it...
这是另一种方法,使用 directory 中的函数。 , filepath和 extra包,但没有太多的单子(monad)魔法:
import Control.Monad (foldM)
import System.Directory (doesDirectoryExist, listDirectory) -- from "directory"
import System.FilePath ((</>), FilePath) -- from "filepath"
import Control.Monad.Extra (partitionM) -- from the "extra" package
traverseDir :: (FilePath -> Bool) -> (b -> FilePath -> IO b) -> b -> FilePath -> IO b
traverseDir validDir transition =
let go state dirPath =
do names <- listDirectory dirPath
let paths = map (dirPath </>) names
(dirPaths, filePaths) <- partitionM doesDirectoryExist paths
state' <- foldM transition state filePaths -- process current dir
foldM go state' (filter validDir dirPaths) -- process subdirs
in go
这个想法是用户通过
FilePath -> Bool
过滤不需要的目录的功能;也是一个初始状态b
和一个转换函数 b -> FilePath -> IO b
处理文件名,更新 b
状态,可能有一些副作用。请注意,状态的类型是由调用者选择的,调用者可能会将有用的东西放在那里。如果我们只想在生成文件名时打印它们,我们可以这样做:
traverseDir (\_ -> True) (\() path -> print path) () "/tmp/somedir"
我们正在使用
()
作为一个虚拟状态,因为我们在这里并不需要它。如果我们想将文件累积到一个列表中,我们可以这样做:
traverseDir (\_ -> True) (\fs f -> pure (f : fs)) [] "/tmp/somedir"
如果我们想过滤一些文件怎么办?我们需要调整传递给
traverseDir
的转换函数所以它会忽略它们。
关于haskell - 在 Haskell 中递归搜索与名称条件匹配的所有文件的目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51712083/