У F # есть тройной?: Operator?
Я изучаю F #, исходящий из С#, и я просто попытался скомпилировать выражение типа
let y = Seq.groupBy (fun x -> (x < p ? -1 : x == p ? 0: 1))
но см. "неожиданный целочисленный литерал в выражении". У F # есть тройной оператор? Если нет, что я должен использовать вместо этого?
Ответы
Ответ 1
Да, он называется if .. then .. else
Фактически в F # все это выражение, даже блок if .. then .. else
.
В С# 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)
вы можете немного сократить его с помощью elif
let y = Seq.groupBy (fun x -> if x < p then -1 elif x = p then 0 else 1)
Другой вариант, который нужно учитывать в 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)
Но в вашем конкретном случае я бы использовал if.. then.. elif.. then.
Наконец, обратите внимание, что оператор равенства равен =
не ==
, как в С#.
Ответ 2
Вы также можете реализовать это, используя сопоставление с функцией с помощью защитных устройств:
let y = Seq.groupBy (function |x when x < p -> -1
|x when x = p -> 0
|_ -> 1)
Совпадения шаблонов могут казаться более длинными тернарными операторами, но их гораздо легче читать, когда логика становится более сложной.
Ответ 3
Дополнительные примеры выражений и операторов С# в F # можно найти на странице this. Например:
Тернарный оператор
С# имеет тернарный оператор "?:" для условных выражений:
condition ? trueVal : falseVal
F # имеет тот же оператор, но его имя - if-then-else:
if condition then trueVal else falseVal
(Обратите внимание, что "if" используется гораздо реже в F #, чем в С#; в F # многие условные выражения выполняются с помощью сопоставления шаблонов, а не if-then-else.)
Оператор switch
С# имеет оператор switch. Это выглядит примерно так:
switch (x)
{
case 1:
SomeCode();
break;
default:
SomeCode();
break;
}
В F # это всего лишь одна из многих вещей, в которой соответствие шаблонов выражается более кратко:
match x with
| 1 -> SomeCode()
| _ -> SomeCode() // _ is a ‘catch all’ default
Ответ 4
Если вы хотите сохранить ввод текста, вы можете определить свой собственный
let (?=) (q: bool) (yes: 'a, no: 'a) = if q then yes else no
Обратите внимание, что вы не можете использовать: в операторах так? = - это ближайшее, которое вы можете получить.
Использование: возможно? = ( "true", "false" )