web-dev-qa-db-fra.com

F # a-t-il le ternaire?: Opérateur?

J'apprends F # venant de C # et je viens d'essayer de compiler une expression comme

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

mais voir "littéral entier inattendu dans l'expression". F # a-t-il un opérateur ternaire? Sinon, que dois-je utiliser à la place?

35
Tim Lovell-Smith

Oui, ça s'appelle if .. then .. else

En fait en F # tout est une expression, même un if .. then .. else bloquer.

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

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

Donc dans votre cas:

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

vous pouvez le raccourcir un peu avec Elif

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

Une autre option à considérer dans F # spécialement lorsque vous avez plus de 2 cas est la correspondance de motifs:

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

let y = Seq.groupBy (f p)

Mais dans votre cas particulier, j'utiliserais le if .. alors .. Elif .. alors.

Notez enfin que l'opérateur d'égalité de test est = ne pas == comme en C #.

54
Gus

Vous pouvez également implémenter cela en utilisant une correspondance de modèle avec une fonction utilisant des gardes:

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

Les correspondances de motifs peuvent sembler un opérateur ternaire plus long mais elles sont beaucoup plus faciles à lire lorsque la logique devient plus complexe.

6
Turkka Mannila

Si vous souhaitez enregistrer la saisie, vous pouvez définir la vôtre

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

Notez que vous ne pouvez pas utiliser: dans les opérateurs donc? = Est le plus proche que vous pouvez obtenir.

Utilisation: peut-être? = ("True", "false")

5
Chris Woodward

Pour plus d'exemples d'expressions et d'instructions C # en F #, vous pouvez vous référer à la page this . Par exemple:

Opérateur ternaire

C # a l'opérateur ternaire "?:" Pour les expressions conditionnelles:

condition ? trueVal : falseVal 

F # a le même opérateur, mais son nom est if-then-else:

if condition then trueVal else falseVal

(Notez que "si" est utilisé beaucoup moins fréquemment en F # qu'en C #; en F #, de nombreuses expressions conditionnelles sont effectuées via la correspondance de modèle plutôt que si-alors-autre.)

Instruction switch

C # a une instruction switch. Cela ressemble à ceci:

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

En F #, ce n'est qu'une des nombreuses choses que la correspondance de motifs exprime plus succinctement:

    match x with 
     | 1 -> SomeCode() 
     | _ -> SomeCode()  // _ is a ‘catch all’ default
4
MeanGreen