F#是否有三元?:运算符?

Tim*_*ith 32 f# conditional-operator

我正在学习来自C#的F#,我刚刚尝试编译一个类似的表达式

let y = Seq.groupBy (fun x -> (x < p ? -1 : x == p ? 0: 1))
Run Code Online (Sandbox Code Playgroud)

但请参阅'表达式中的意外整数文字'.F#有三元运算符吗?如果没有,我应该用什么呢?

Gus*_*Gus 51

是的,它被称为 if .. then .. else

实际上在F#中,一切都是表达式,甚至是一个if .. then .. else 块.

在C#中 var x = true ? 0 : 1;

在F#中 let x = if true then 0 else 1

所以在你的情况下:

let y = Seq.groupBy (fun x -> if x < p then -1 else if x = p then 0 else 1)
Run Code Online (Sandbox Code Playgroud)

你可以稍微缩短一下 elif

let y = Seq.groupBy (fun x -> if x < p then -1 elif x = p then 0 else 1)
Run Code Online (Sandbox Code Playgroud)

F#中特别考虑的另一个选择是模式匹配:

let f p x =
    match x with
    | x when x < p -> -1
    | x when x = p ->  0
    | _ -> 1

let y = Seq.groupBy (f p)
Run Code Online (Sandbox Code Playgroud)

但在你的特殊情况下,我会使用if .. then .. elif ..然后.

最后请注意,测试相等运算符=不像==C#中那样.

  • @Enigmativity实际上它属于他们两个.if表达式可以有零个或多个elif分支,因此`如果是a x elif b则y else z`是单个`if`表达式.另一方面,`if a then else else if else then else c`是一个`if`表达式,其中`then`分支本身是第二个`if`表达式.将其与`if a then if if b then x else y else z`进行比较,后者不编译.对于`then`分支包含一个`if`表达式,`if`表达式需要在括号中:`if a then(如果b则接x,否则为y),否则为z`.这与C#条件运算符形成对比. (3认同)

Chr*_*ard 7

如果你想保存打字,你可以定义你自己的

let (?=) (q: bool) (yes: 'a, no: 'a) = if q then yes else no
Run Code Online (Sandbox Code Playgroud)

请注意,您不能在运算符中使用 : 因此 ?= 是您可以获得的最近的。

用法:也许 ?= ("true", "false")

  • 小心:无论条件如何,这都会急切地评估真假面!也就是说,`if true then printf "a" else printf "b"` 只会打印 `a`,但是 `true ?= (printf "a", printf "b")` 会打印 `ab`! (12认同)

小智 6

您还可以使用模式匹配功能使用警卫来实现此功能:

    let y = Seq.groupBy  (function |x when x < p -> -1
                                   |x when x = p -> 0
                                   |_ -> 1)
Run Code Online (Sandbox Code Playgroud)

模式匹配可能看起来更长的三元运算符,但是当逻辑变得更复杂时,它们更容易阅读.