使用管道转发与嵌套序列

时间:2016-08-04 22:05:14

标签: f# seq

我是F#的新手,所以如果我使用错误的名字,我会道歉。

我正在尝试使用F#来解析看起来像这样的网页:

<!--This is simplified, in reality there are more divs, anchors etc. -->
<html>
<body> 
    <div class="pr-single"><a href="http://google.ca">Google</a></div>
    <div class="pr-single"><a href="http://apple.com">Apple</a></div>
    <div class="pr-single"><a href="http://microsoft.com">Microsoft</a></div>
</body>
</html>

我已经宣布了一个类型

type PromoterPage = FSharp.Data.HtmlProvider<"http://somewebpage.com">

现在我正在尝试获取页面上所有链接的列表。我的思考过程是:

  1. 按类名
  2. 获取所有外部div
  3. 获取所有这些div的后代
  4. 将这些后代收集到一个单一列表中
  5. 将此列表过滤为仅<a>标记
  6. 我的尝试如下:

    let GetFirst (page:PromoterPage) = 
        page.Html.Descendants()
        |> Seq.filter(fun n -> n.HasClass("pr-single"))                 //Find the divs
        |> Seq.map(fun n -> n.Descendants())                            //Get the descendants
        |> Seq.collect(fun n -> n |> Seq.where(fun m -> m.HasName("a")) //Filter and collect the anchors
    

    问题似乎是你无法嵌套Seq函数或者我不能正确地执行它。我收到错误:

    Incomplete values or function definition. If this is an expression, the body of the expression must be indented to the same column as the keyword.

    我可以按照我尝试的方式嵌套Seq函数吗?我是以错误的方式思考这个问题吗?

1 个答案:

答案 0 :(得分:5)

你错过了右括号:

|> Seq.collect(fun n -> n |> Seq.where(fun m -> m.HasName("a")))
  

我可以按照我尝试的方式嵌套Seq功能吗?

是的,将函数与lambdas中的管道嵌套完全没问题。但是,我经常将它们拉到本地函数中,因为从长远来看,它可以使代码更具可读性。