正如标题所述,我试图在给定路径中找到给定的字符串。这是我到目前为止所得到的:
getRecursiveContents :: FilePath -> IO [FilePath]
getRecursiveContents topdir = do
names <- getDirectoryContents topdir
let properNames = filter (`notElem` [".", ".."]) names
paths <- forM properNames $ \name -> do
let path = topdir </> name
isDirectory <- doesDirectoryExist path
if isDirectory
then getRecursiveContents path
else return [path]
return (concat paths)
findInFile:: String -> FilePath -> IO Bool
findInFile needle filePath= do
content <- readFile filePath
return (needle `L.isInfixOf` content)
findInFolder:: (String -> Bool) -> FilePath -> String -> IO [IO Bool]
findInFolder p path needle = do
files <- getRecursiveContents path
return (map (findInFile needle) (filter p files))
find = findInFolder (\p -> takeExtension p `elem` [".py", ".xml", ".html"])
我可以:
*Main> findInFile "search_string" "./path/to/a/file"
True
哪个是完美的,但我不能对文件夹进行相同的搜索:
*Main> find "./path/to/a/folder" "search_string"
*Main>
在我的文件系统中,./path/to/a/file
位于./path/to/a/folder
下方。因此我期待同样的结果。
我做错了什么?
注意:getRecursiveContents
来自real world haskell。
答案 0 :(得分:3)
确实有效。唯一的问题是如何打印东西。当您在ghci中键入一些表达式时,它将在该表达式上调用print
。如果值的类型为IO x
,则仅当具有IO
实例时,它才会执行x
操作并打印Show
;否则它不会打印其他信息。
find "./path/to/a/folder" "search_string"
生成IO
个动作列表,其中没有Show
个实例。您可以获得find
的结果,这也是IO操作的列表,然后执行它们:
> x <- find "./path/to/a/folder" "search_string"
> sequence x
> [True, False ...
可能你最初想在你的功能中这样做。只需进行以下更改:
findInFolder:: (String -> Bool) -> FilePath -> String -> IO [Bool]
findInFolder p path needle = do
files <- getRecursiveContents path
mapM (findInFile needle) (filter p files)
现在findInFolder
可以按预期工作。