Does F# have the ternary ?: operator?

后端 未结 4 1593
孤独总比滥情好
孤独总比滥情好 2021-01-07 16:04

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))


        
相关标签:
4条回答
  • 2021-01-07 16:43

    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
    
    0 讨论(0)
  • 2021-01-07 16:48

    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.

    0 讨论(0)
  • 2021-01-07 16:49

    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")

    0 讨论(0)
  • 2021-01-07 17:00

    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#.

    0 讨论(0)
提交回复
热议问题