【问题标题】:Implementing a recursive function that recursively executes another function实现递归执行另一个函数的递归函数
【发布时间】:2017-11-26 09:22:52
【问题描述】:

我试图组合一个链接分析器,它通过网站 html 代码并返回包含相同基本 url 的所有链接(指同一站点的网页),我目前已将这段代码放在一起。 (本人是初学者,业余代码请多包涵^^):

import Network.HTTP
import Data.List
import Data.Char

htmlLinks link = do
  content <- simpleHTTP (getRequest link) >>= fmap (take 10000) . getResponseBody
  let string = content
  let tags = splitOn "<" string
  let links = filter (isInfixOf "href") tags
  let filtered = filter (isInfixOf link) links
  let url = map (splitOn "\"") filtered
  let final = map (filter (isInfixOf "http")) url
  let urlString = map (\(h:_) -> h)final
  let result = nub urlString
  --let result = map head $ group $ sort urlString
  return result

此函数遍历代码并返回我想要的具有相同基本 url 的所有链接的列表。现在我想浏览该列表的每个元素并对它们应用相同的功能,这样我也可以获得每个网站上的链接,最终为我提供给定网站结构的所有网页。所以对于递归函数,我尝试了这个:

linkScanner result = linkRec [] result where
  linkRec acc [] = acc
  linkRec acc (h:t) = linkRec ((htmlLinks h) : acc) t 

这基本上采用链接列表将 htmlLinks 应用于每个元素并将其结果添加到我的累加器,在本例中是一个空列表。现在我的问题是我找不到一种方法来组合这两个函数,以便它们可以使用给定的 URL 执行并为我提供我需要的所有链接的列表。我也有类型冲突,因为 htmlLinks 是 IO[String] 类型,递归函数需要 [String] 导致错误..

我正在寻找一些关于如何解决这个问题的建议或一些我可以用来达到我想要的结果的技巧。非常感谢任何和所有帮助!

【问题讨论】:

  • 为了补充一点,ResponseBody 的 fmap(取 10000)仅用于测试,以便我可以使用较小的 html 代码。之后会被删除。

标签: haskell recursion types html-parsing


【解决方案1】:

你可能想要类似的东西

linkScanner result = linkRec [] result where
linkRec acc [] = return acc
linkRec acc (h:t) = do
   x <- htmlLinks h
   linkRec (x : acc) t 

(将以相反的顺序返回列表)或

linkScanner = traverse htmlLinks -- or the analogous with mapM

顺便说一句,您应该真正将类型注释添加到顶级绑定。很难想象会发生什么。

【讨论】:

  • 所以代码本身可以使用 IO 字符串吗?因为这似乎是一个问题/错误。我的意思是 linkScanner 函数。感谢您的帮助!
  • @M.O 应该的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
  • 2015-03-01
相关资源
最近更新 更多