Does F# have the ternary ?: operator?

2020-03-08 07:15发布

I'm learning F# coming from C# and I've just tried compiling an expression like

let y = Seq.groupBy (fun x -> (x < p ? -1 : x == p ? 0: 1))

but see 'unexpected integer literal in expression'. Does F# have a ternary operator? If not, what should I use instead?

4条回答
Root(大扎)
2楼-- · 2020-03-08 07:39

If you want to save the typing you can define your own

let (?=) (q: bool) (yes: 'a, no: 'a) = if q then yes else no

Note that you can't use : in operators so ?= is the nearest you can get.

Usage: maybe ?= ("true", "false")

查看更多
Explosion°爆炸
3楼-- · 2020-03-08 07:40

You can also implement this using pattern matching with function using guards:

    let y = Seq.groupBy  (function |x when x < p -> -1
                                   |x when x = p -> 0
                                   |_ -> 1)

Pattern matches may seem longer ternary operator but they are much easier to read when logic gets more complex.

查看更多
老娘就宠你
4楼-- · 2020-03-08 07:47

Yes, it's called if .. then .. else

In fact in F# everything is an expression, even an if .. then .. else block.

In C# var x = true ? 0 : 1;

In F# let x = if true then 0 else 1

So in your case:

let y = Seq.groupBy (fun x -> if x < p then -1 else if x = p then 0 else 1)

you can shorten it a bit with elif

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

Another option to consider in F# specially when you have more than 2 cases is pattern matching:

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

let y = Seq.groupBy (f p)

But in your particular case I would use the if .. then .. elif .. then.

Finally note that the test-equality operator is = not == as in C#.

查看更多
手持菜刀,她持情操
5楼-- · 2020-03-08 07:54

For more examples of C# expressions and statements in F# you can refer to this page. For example:

Ternary operator

C# has the ternary operator "?:" for conditional expressions:

condition ? trueVal : falseVal 

F# has the same operator, but its name is if-then-else:

if condition then trueVal else falseVal

(Note that "if" is used much less frequently in F# than in C#; in F#, many conditionalexpressions are done via pattern-matching rather than if-then-else.)

Switch statement

C# has a switch statement. It looks something like this:

switch (x) 
{ 
    case 1: 
        SomeCode(); 
        break; 
    default: 
        SomeCode(); 
        break; 
} 

In F#, this is just one of many things that pattern matching expresses more succinctly:

    match x with 
     | 1 -> SomeCode() 
     | _ -> SomeCode()  // _ is a ‘catch all’ default
查看更多
登录 后发表回答