0

我目前正在阅读Real World Haskell这本书,本书中的一个练习要求读者使用 实现文件名匹配**,这与 相同*,但也一直在文件系统中的子目录中查找。下面是我的带有注释的代码片段(目前有很多重复),再往下你可以找到有关代码的更多信息。我认为贴出的代码足以解决问题,这里不需要列出整个程序。

case splitFileName pat of
        ("", baseName) -> do -- just the file name passed
            curDir <- getCurrentDirectory
            if searchSubDirs baseName -- check if file name has `**` in it
              then do 
                  contents <- getDirectoryContents curDir
                  subDirs <- filterM doesDirectoryExist contents
                  let properSubDirs = filter (`notElem` [".", ".."]) subDirs
                  subDirsNames <- forM properSubDirs $ \dir -> do
                                      namesMatching (curDir </> dir </> baseName) -- call the function recursively on subdirectories
                  curDirNames <- listMatches curDir baseName -- list matches in the current directory
                  return (curDirNames ++ (concat subDirsNames)) -- concatenate results into a single list
              else listMatches curDir baseName
        (dirName, baseName) -> do // full path passed
            if searchSubDirs baseName
              then do
                  contents <- getDirectoryContents dirName
                  subDirs <- filterM doesDirectoryExist contents
                  let properSubDirs = filter (`notElem` [".", ".."]) subDirs
                  subDirsNames <- forM properSubDirs $ \dir -> do
                                      namesMatching (dirName </> dir </> baseName) -- call the function recursively on subdirectories
                  curDirNames <- listMatches dirName baseName -- list matches in the passed directory
                  return (curDirNames ++ (concat subDirsNames)) -- concatenate results into a single list

附加信息:

pat是我正在寻找的模式(例如*.txtC:\\A\[a-z].*)。

splitFileName是将文件路径拆分为目录路径和文件名的函数。如果我们只指定一个文件名,元组的第一个元素将为空pat

searchSubDirsTrue如果文件名中有则返回**

listMatches返回与目录中的模式匹配的文件名列表,替换***.

namesMatching是我发布其摘录的函数的名称。

为什么它不起作用?

当我只传递文件名时,程序只在当前目录和第一级子目录中搜索它。当我传递完整路径时,它仅在指定目录中搜​​索。看起来 case(dirName, baseName)没有正确递归。我一直在查看代码一段时间,但我无法弄清楚问题出在哪里。

笔记

如果需要更多信息,请在评论中告诉我,我会在问题中添加任何必要的内容。

4

1 回答 1

2

这里有一个问题:

              contents <- getDirectoryContents dirName
              subDirs <- filterM doesDirectoryExist contents

getDirectoryContents仅返回目录的叶子名称,因此您dirName必须/contents调用doesDirectoryExist.

于 2015-10-17T13:36:58.900 回答