(Kestrel) K-комбинатор: почему он полезен?

Я недавно занимался F# (мой опыт работы с C#) и читаю сайт http://fsharpforfunandprofit.com/, который я считаю очень полезным.

Я попал на http://fsharpforfunandprofit.com/posts/defining-functions/ где находится раздел о комбинаторах. Я понимаю их все (хотя Y-образный комбинатор или Птица-шалфей винты с моей стороны!) За исключением пустельги. Скотт Влашин дает определение (в F#) как:

let K x y = x

Я не могу понять на всю жизнь ситуацию, в которой это было бы полезно. Сначала я подумал, что его можно использовать как оператор цепочки, чтобы вы могли передать значение в функцию, а затем вернуть исходное значение. Я сам раньше писал такого оператора, но, как вы можете видеть, это не то же самое:

let (>|) x f = f x; x

Если мы частично применяем комбинатор K (со значением 5), то мы возвращаем функцию, которая игнорирует ее аргумент и вместо этого возвращает 5. Опять же, бесполезно.

(K 5) = fun y -> 5

Кто-нибудь может дать мне простой пример того, где это может быть использовано, пожалуйста?

1 ответ

Решение

Вот очень простой пример:

Предположим, у меня есть структура, например список, в котором я могу отображать функции.

let K x y = x

let lst = [3;5;13;2]

Я могу отобразить математические функции следующим образом:

let plus5  = lst |> List.map ((+)5) // instead of writing List.map (fun x -> 5 + x)
// val plus5 : int list = [8; 10; 18; 7]

let times3 = lst |> List.map ((*)3) // instead of writing List.map (fun x -> 3 * x)
// val times3 : int list = [9; 15; 39; 6]

Что если я хочу отобразить постоянную функцию?

let tens = lst |> List.map (K 10) // instead of writing List.map (fun x -> 10)
// val tens : int list = [10; 10; 10; 10]

Учитывая, что в FP вы обычно передаете функции в качестве аргументов, комбинатор K позволяет вам указать постоянную функцию с помощью нескольких нажатий клавиш.

Другие вопросы по тегам