实现递归函数,递归执行另一个函数

时间:2017-06-22 22:55:02

标签: haskell recursion types html-parsing

我试图整理一个链接分析器,它通过一个网站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是Type IO [String],递归函数需要[String],这会导致错误..

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

1 个答案:

答案 0 :(得分:0)

你可能想要像

这样的东西
sed -E 's/"[^=]*=([^"]*)("|$)/\1/g'

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

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

顺便说一句,您应该在顶级绑定中添加类型注释。很难想到发生了什么。