Text 将Seq.tryFind和x.IsSome组合在一行中

Text 将Seq.tryFind和x.IsSome组合在一行中,text,f#,find,Text,F#,Find,我正在尝试将与特定(可选)关键字相关联的数据从文件读入F#中的不可变项中 当文件中存在关键字时,我的代码执行我想要的操作: let variable1 = lines |> Seq.find(fun x -> x.Contains "keyword1") |> fun x -> x.Split(']').[1] 当关键字不存在时,Seq.find按预期中断。而不是有几行tryFind和if/then,我试图让它以F#的方式在一行中工作,但我

我正在尝试将与特定(可选)关键字相关联的数据从文件读入F#中的不可变项中

当文件中存在关键字时,我的代码执行我想要的操作:

let variable1 = 
    lines 
    |> Seq.find(fun x -> x.Contains "keyword1") 
    |> fun x -> x.Split(']').[1]
当关键字不存在时,
Seq.find
按预期中断。而不是有几行tryFind和if/then,我试图让它以F#的方式在一行中工作,但我不知道如何处理tryFind的输出,因为后续的拆分操作需要类型string,而不是来自IsSome的未知类型。如何进一步满足红色曲线对类型约束的需求

let variable1 = 
    lines 
    |> Seq.tryFind(fun x -> x.Contains "keyword1") 
    |> fun x -> if x.IsSome then x.Split(']').[1]
当您这样做时:

let variable1 = 
    lines 
    |> Seq.tryFind(fun x -> x.Contains "keyword1") 
    |>  fun x -> if x.IsSome then     x.Split(']').[1]
最后一个
x
具有类型
字符串选项
。我会做类似的事情

let variable1 = 
    lines 
    |> Seq.tryFind(fun x -> x.Contains "keyword1") 
    |> function |Some(t) -> t.Split(']').[1] |None -> "" (*need a value for the None branch*) 
当您这样做时:

let variable1 = 
    lines 
    |> Seq.tryFind(fun x -> x.Contains "keyword1") 
    |>  fun x -> if x.IsSome then     x.Split(']').[1]
最后一个
x
具有类型
字符串选项
。我会做类似的事情

let variable1 = 
    lines 
    |> Seq.tryFind(fun x -> x.Contains "keyword1") 
    |> function |Some(t) -> t.Split(']').[1] |None -> "" (*need a value for the None branch*) 

如果您只想对单个匹配执行操作,
Option.map
,正如ildjarn所述

let variable1 = 
    lines 
    |> Seq.tryFind(fun x -> x.Contains "keyword1") 
    |> Option.map (fun x -> x.Split(']')
或者,如果要对多个条目执行操作,可以使用map/choose

let variables = 
    lines 
    |> Seq.map(fun x -> if x.Contains "keyword1" then Some x else None) 
    |> Seq.choose (fun x -> x.Split(']')
在任何情况下,
if.的每个分支
then
else
的返回类型。。然后否则…
表达式需要具有相同的类型

这两个分支的公共类型是整个表达式的类型
if。。然后否则…
。这允许引用透明性,您可以始终在接受更简单表达式的情况下插入复杂表达式

这是一个很大的自由,但代价很小:你必须在两个分支中都给出一个正确类型的表达式


“例外”是指当您在定义了一些零的计算表达式中时,即使在这种情况下,两个分支都是为您提供的,而不是由您提供的。

如果您只想对单个匹配执行操作,
选项。正如ildjarn所提到的,map
是一种方法

let variable1 = 
    lines 
    |> Seq.tryFind(fun x -> x.Contains "keyword1") 
    |> Option.map (fun x -> x.Split(']')
或者,如果要对多个条目执行操作,可以使用map/choose

let variables = 
    lines 
    |> Seq.map(fun x -> if x.Contains "keyword1" then Some x else None) 
    |> Seq.choose (fun x -> x.Split(']')
在任何情况下,
if.的每个分支
then
else
的返回类型。。然后否则…
表达式需要具有相同的类型

这两个分支的公共类型是整个表达式的类型
if。。然后否则…
。这允许引用透明性,您可以始终在接受更简单表达式的情况下插入复杂表达式

这是一个很大的自由,但代价很小:你必须在两个分支中都给出一个正确类型的表达式


“异常”是指当您在一个定义了一些零的计算表达式中时,但即使在这种情况下,两个分支都是为您提供的,而不是由您提供的。

|>Option.map(…)
适合这里,使
variable1
成为
字符串选项
类型,并允许调用方从那里处理它。
>Option.map(…)
将适合这里,使
variable1
成为
字符串选项
类型,并允许调用者从那里处理它。如上复制的option.map会给我红色的曲线和错误消息“赋值左边的表达式无效”。关于为什么需要完成两个if-then分支的解释很有帮助,谢谢。@arthuritus-nicolas示例代码中的Option.map行缺少一个close paren,但Option.map仍然是最好的答案。上面复制的Option.map会给我红色的曲线和错误消息“赋值左边的表达式无效”。尽管如此,解释为什么需要完成两个if-then分支还是很有帮助的,谢谢。@arthuritus-nicolas示例代码中Option.map行缺少close paren,但Option.map仍然是最好的答案。