Приложение с частичной функцией для несимметричного оператора, использующего стиль без точек в F#?

Как я могу создать приложение с частичной функцией для несимметричного оператора, такого как оператор модуля, относительно первого аргумента без имен аргументов в F#? Моя первая попытка была

let mod10 = (%) 10 что, конечно, означает

mod10(x) = 10 mod x вместо желаемого

mod10(x) = x mod 10, Конечно, я мог бы написать

let mod10 x = (%)x 10 но я бы не хотел называть аргумент, так что есть какой-то заполнитель, который можно использовать, что-то вроде

let mod10 = (%)_ 10?

2 ответа

Решение

Вы можете определить flip функция, которая распространена в бессмысленном стиле:

let inline flip f x y = f y x

и используйте это так:

let (%-) = flip (%)
let mod10 = (%-) 10

или прямо так:

let mod10 = flip (%) 10

Бессмысленный стиль не всегда читабелен (как в этом примере) и не популярен в программировании на F#.

Вот решение, основанное на функциональной композиции.

let mod10 = (%) >> (|>) 10

UPD Здесь было многословное объяснение, но программисты говорят на коде, поэтому я думаю, что следующее будет описывать его намного лучше, в форме математического доказательства.

Следующие выражения равны:

let m1 x = x % 10                    
let m2 x = (%) x 10                  // x (op) y = (op) x y
let m3 x = ((%) x) 10                // f x y = (f x) y
let m4 x = 10 |>         ((%) x)     // f x = x |> f
let m5 x = ((|>) 10)     ((%) x)     // x |> f = (|>) x f
let m6 x = ((%) x)    |> ((|>) 10)   // f x = x |> f
let m7 x = (x |> (%)) |> ((|>) 10)   // (op) x = x |> (op)
let m8 x = x |> ((%)  >> ((|>) 10))  // f(x) |> g = x |> (f >> g)
let m9   =       (%)  >> ((|>) 10)   // remove formal argument
let m10  =       (%)  >>  (|>) 10    // remove unnecessary parenthesis

Альтернативный синтаксис:

let mod10_2 = (|>) 10 << (%)
Другие вопросы по тегам