F#:映射到from non sequence type时,匹配表达式能否不返回序列?
我试图创建一个递归函数,该函数有条件地调用自身,目前定义如下:F#:映射到from non sequence type时,匹配表达式能否不返回序列?,f#,F#,我试图创建一个递归函数,该函数有条件地调用自身,目前定义如下: let rec crawlPage (page : String, nestingLevel : int) = HtmlDocument.Load(page) |> fun m -> m.CssSelect("a") |> List.map(fun a -> a.AttributeValue("href")) |> Seq.
let rec crawlPage (page : String, nestingLevel : int) =
HtmlDocument.Load(page)
|> fun m -> m.CssSelect("a")
|> List.map(fun a -> a.AttributeValue("href"))
|> Seq.distinctBy id
|> Seq.map (fun x -> baseUrl + x)
|> Seq.map (fun x ->
match nestingLevel with
// Compiler says it is expecting a but given seq<a> in reference to the recursive call
| _ when (nestingLevel > 0) -> crawlPage(x, (nestingLevel - 1))
| _ when (nestingLevel <= 0) -> ignore
| _ -> (* To silence warnigs.*) ignore
)
let rec crawlPage(页面:字符串,嵌套级别:int)=
HtmlDocument.Load(第页)
|>趣味m->m.CSS选择(“a”)
|>List.map(乐趣a->a.AttributeValue(“href”))
|>序号按id区分
|>Seq.map(乐趣x->baseUrl+x)
|>Seq.map(乐趣x->
将嵌套级别与
//编译器说它需要一个引用递归调用的给定seq
|当(嵌套级别>0)->爬网页面(x,(嵌套级别-1))
|_uu当(嵌套级别忽略)
|_u->(*使警告静音。*)忽略
)
这是
Seq.map(funx->…)
无法处理返回序列,或者匹配条件不能处理返回序列吗?鉴于爬网页由编译器加下划线,似乎match语句无法处理返回的seq,那么如何处理呢?规则是所有匹配分支必须返回同一类型,因此您必须:
ignore
替换为Seq.singleton x
,以指示此分支只生成x
本身
seq
转换为seq
|> Seq.map (fun x ->
match nestingLevel with
| _ when (nestingLevel > 0) -> crawlPage(x, (nestingLevel - 1))
| _ -> Seq.singleton x)
|> Seq.concat
let rec crawlPage (page : String, nestingLevel : int) = seq {
let urls =
HtmlDocument.Load(page).CssSelect("a")
|> List.map(fun a -> a.AttributeValue("href"))
|> Seq.distinctBy id
|> Seq.map (fun x -> baseUrl + x)
for x in urls do
if nestingLevel > 0 then
yield! crawlPage(x, (nestingLevel - 1))
else
yield x }
现有的帖子回答了您的具体问题,但我认为值得注意的是,您的代码片段还可以做一些其他更改。其中一些更改是出于个人喜好,但我相信它们使您的代码更简单:
- 您可以使用序列理解,它允许您使用
(以及使用yield!
)很好地处理递归调用yield
- 实际上您不需要
,因为您只有两个分支,使用普通匹配
if
- 我还要避免使用
模式,因为这里不需要它|>fun m->m.Xyz
|> Seq.map (fun x ->
match nestingLevel with
| _ when (nestingLevel > 0) -> crawlPage(x, (nestingLevel - 1))
| _ -> Seq.singleton x)
|> Seq.concat
let rec crawlPage (page : String, nestingLevel : int) = seq {
let urls =
HtmlDocument.Load(page).CssSelect("a")
|> List.map(fun a -> a.AttributeValue("href"))
|> Seq.distinctBy id
|> Seq.map (fun x -> baseUrl + x)
for x in urls do
if nestingLevel > 0 then
yield! crawlPage(x, (nestingLevel - 1))
else
yield x }