F# 筛选“列表选项”并将其转换为“列表”?
我有下面的代码,它将为这些可以解析的URL返回F# 筛选“列表选项”并将其转换为“列表”?,f#,F#,我有下面的代码,它将为这些可以解析的URL返回DownloadLink的seq type DownloadLink = { Url: string; Period: DateTime } nodes |> Seq.map (fun n -> let url = n.Attributes.["href"].Value match url with | Helper.ParseRegex "[a-zA-Z](?<period>\d{4})\.t
DownloadLink
的seq
type DownloadLink = { Url: string; Period: DateTime }
nodes |> Seq.map (fun n ->
let url = n.Attributes.["href"].Value
match url with
| Helper.ParseRegex "[a-zA-Z](?<period>\d{4})\.txt" [period] ->
{ Url = url; Period = period }
| _ ->
printfn "Cannot parse %s" url // Error
)
基本问题是如果你有
match x with
|true -> A
|false -> B
A
和B
的类型必须相同
实际上,有一个内置函数,它使用您想到的Some
组合映射和过滤器-使用Seq
nodes |> Seq.choose (fun n ->
let url = n.Attributes.["href"].Value
match url with
| Helper.ParseRegex "[a-zA-Z](?<period>\d{4})\.txt" [period] ->
Some ({ Url = url; Period = period })
| _ ->
printfn "Cannot parse %s" url // Error
None
)
nodes>Seq.choose(乐趣n->
让url=n.Attributes。[“href”].Value
将url与匹配
|Helper.ParseRegex“[a-zA-Z](?\d{4})\.txt”[period]>
一些({Url=Url;Period=Period})
| _ ->
printfn“无法分析%s”url//错误
没有一个
)
除了Seq.choose
,您还可以使用序列表达式很好地解决这个问题-您可以使用yield
在一个分支中返回结果,但不必在另一个分支中生成值:
seq { for n in nodes do
let url = n.Attributes.["href"].Value
match url with
| Helper.ParseRegex "[a-zA-Z](?<period>\d{4})\.txt" [period] ->
yield { Url = url; Period = period }
| _ ->
printfn "Cannot parse %s" url }
seq{for n in nodes do
让url=n.Attributes。[“href”].Value
将url与匹配
|Helper.ParseRegex“[a-zA-Z](?\d{4})\.txt”[period]>
收益{Url=Url;Period=Period}
| _ ->
printfn“无法分析%s”url}
另外,我不建议将副作用(打印)作为处理代码的一部分。如果要报告错误,最好返回一个选项(或定义一个类型,该类型为Success
或Error of string
),以便将错误报告与处理分开。谢谢<代码>顺序。选择
在这里非常有用。否则,我想先创建seq选项
,过滤掉None
项,然后从seq
重新映射回seq
。谢谢。很高兴知道还有其他方法可以做这件事。最后,我希望记录错误(在数据库表或文本文件中,可能也是成功的)。在F#中实现日志记录(这也是一个副作用)的最佳方法是什么?我认为在序列表达式中进行日志记录是精细的-打印是用户可见的副作用,因此更好地处理它更有意义,但是日志记录更多的是出于内部目的——所以我认为当它作为其他计算的一部分完成时(这就是日志记录的要点:-)不会有问题。我计划从这个github项目中使用异步日志记录。处理打印和日志记录是否良好?
seq { for n in nodes do
let url = n.Attributes.["href"].Value
match url with
| Helper.ParseRegex "[a-zA-Z](?<period>\d{4})\.txt" [period] ->
yield { Url = url; Period = period }
| _ ->
printfn "Cannot parse %s" url }