Теперь я понимаю, что первую строчку кода можно сократить до второй. Это первый раз, когда я сталкиваюсь с этим, и я не могу найти документацию о том, как называется оператор. Является ли это абстрактным понятием, которое можно использовать и для других целей?
let contains optValue value =
Option.exists (fun v -> v >= value) optValue
let contains optValue value =
Option.exists ((>=) value) optValue
Да, ты прав. " = " - это инфиксный оператор. Добавляя круглые скобки вокруг него, вы можете сделать его префиксным оператором. Если вы хотите добавить это в качестве ответа, я приму это.
Между прочим, эти две функции не делают одно и то же. Либо функция выбора во второй версии должна быть (=) value
, либо лямбда в первой версии fun v -> value >= v
, чтобы они были идентичными.
Вам уже сказали, что второй пример должен был быть (=)
, чтобы ваши две функции были эквивалентны, поэтому я не буду вдаваться в подробности. Но я хочу предупредить вас, что использование оператора >=
таким образом может работать не так, как вы ожидаете. Основная причина связана с тем, как F# выполняет частичное применение, и https://fsharpforfunandprofit.com/series/thinking-functionally.html является лучшим справочником для этого. (Соответствующие части — это статьи о каррировании и частичном применении, но вы захотите прочитать их целиком по порядку, так как последующие статьи основаны на концепциях, описанных в предыдущих статьях).
Теперь, если вы читали эти статьи, вы знаете, что F# допускает частичное применение функций: если у вас есть функция с двумя параметрами f a b
, но вы вызываете ее только с одним параметром f a
, результатом будет функция, которая ожидает параметр b
, и когда он получает это, он выполняет f a b
. Когда вы заключаете оператор в круглые скобки, F# рассматривает его как функцию, поэтому, когда вы выполняете (>=) value
, вы получаете функцию, ожидающую второго параметра x
, а затем оценивающую (>=) value x
. И когда F# оценивает (op) a b
, какой бы ни был оператор, это то же самое, что и a op b
, поэтому (>=) value x
совпадает с value >= x
.
И это то, что поначалу сбивает с толку большинство людей. Потому что, когда вы читаете Option.exists ((>=) value) optValue
, вы, естественно, хотите прочитать это как «Содержит ли вариант что-то большее или равное value
»? Но на самом деле он говорит: «Содержит ли опция значение x
такое, что value >= x
истинно?», т. е. что-то меньше или равноvalue
.
Таким образом, простые правила частичного применения, применяемые последовательно, могут привести к неожиданным результатам с операторами больше или меньше, или фактически с любым оператором, который не является коммутативным. Помните об этом, и если вы хотите использовать частичное приложение с некоммутативными операторами, дважды проверьте свою логику.
Это просто оператор больше или равно как функция, хотя для того, чтобы быть эквивалентным первому, вы должны использовать
=
, т.е.Option.exists ((=) value) optValue