Pull to refresh

Comments 24

В общем, может оказаться полезным в случае работы в группой методов, требующих постоянного проталкивания одних и тех-же параметров. И отличающихся только парочкой.
Хороший пример про логгер, спасибо. Как раз думал над тем, как именно решить эту проблему неуказывания источника.
Насколько я понял принципиальная разница в том, что партиал функция возвращает результат принимая меньше параметров (кешируя дополнительные), а каррированая возвращает функцию, которая возвращает функцию… (повторить n раз)… которая возвращает результат.
Спасибо за перевод.
У меня сразу появилась мысль: а нельзя ли сделать currying или partial function application ещё более универсальными, используя именованные параметры из C# 4.0? То есть, чтобы оба следующих вызова работали одинаково:

curried(a: 1)(b: 2)(c: 3);
curried(c: 3)(b: 2)(a: 1);

Но, наверное, это невозможно.
Это думаю невозможно изза:
return a => b => c => function(a, b, c);
Но ведь поменяв порядок аргументов вы получите то же самое(вам не нужны именованые аргументы):
curried(1)(2)(3);
curried(3)(2)(1);
Ведь это ничто иное как:
curried(1) -Ю вернёт объект ссылку на функцию к которой будет применёна параметр (2) и результатом будет опять ссылка на функцию к которой будет применён параметр (3).
Так вот зачем functools.partial в Python! Спасибо)
Делать хитрые map'ы с ним особо удобно.
По ссылке Jon Skeet Facts порадовал топовый коммент:
Who the hell is Jon Skeet?
частичное применение преобразует функцию с N параметрами в функцию с N-1 параметрами

Если уж быть более формальным то в N-k
Ппц, столько текста, я чуть в транс не ушел…
Что? Я серьезно!
Всю статью можно записать как

fcurry = curry(f, 1)
fpartial = partial(f, 1)

Обычный вызов:
f(1, 2, 3, 4)

Каррирование:
fcurry(2)(3)(4)

Частичное применение:
fpartial(2, 3, 4)
По поводу (бес)полезности каррирования на практике, в котором сомневается автор.
Скорее всего в C# оно действительно бесполезно, поскольку требует утомительного написания кода и не даёт особых преимуществ. В других языках дело обстоит иначе. Например, в OCaml сама сигнатура функции SampleFunction будет записана как:
val sample_function : int -> int -> int -> string = <fun>

Ничего не напоминает? Да, это то же самое «a => b => c => function(a, b, c)», которое пришлось писать руками на C#. То есть, любая объявленная функция получается изначально каррированной, и создание логгера выглядит примерно так:
(* принимаем на вход имя файла, тип сообщения и сообщение *)
# let logger filename level message = (* здесь логика вывода сообщения в файл *);;
val logger : string -> int -> string -> unit = <fun>
# let business_logger = logger "business.log";; (* Функция, которая принимает уже только два параметра и пишет в лог*)
val business_logger : int -> string -> unit = <fun>

А вот частичное применение выглядит уже не таким удобным, его ещё надо написать (и оно тоже работает через каррирование):
# let partial_apply func x = func x;; (* Функция, которая применяет параметр x в качестве первого параметра *)
val partial_apply : ('a -> 'b) -> 'a -> 'b = <fun>
# let business_logger = partial_apply logger "business.log";;
val business_logger : int -> string -> unit = <fun>

Согласитесь, совсем не так удобно смотрится.
Это всего лишь вопрос обмазанности синтаксическим сахаром того или иного языка. К примеру в языке с нормальной поддержкой частичного применения вполне можно описать случай:
//Фиксируем 1 и 3 параметры
def infoLogger = logger("some.log", _, LogLevel.Info, _); 
infoLogger(LogCategory.GUI, "message");
infoLogger(LogCategory.DB, "other message");

В таких случаях карринг уже не выглядит таким уж удобным.
Напрасно автор статьи выбрал функцию с тремя параметрами, уже на четырех получается гораздо интереснее.
Для пущего эффекта можно так же употреблять термин «шейнфинкелинг».
UFO just landed and posted this here
Вы уже выбрали подходящий перевод или замену термина «currying»?
Я бы назвал «Расщепление функции» или просто транслитерировал название в «Карринг»
В русском языке есть два суффикса для заимствованных слов, обозначающих какое-либо действие: «ов» и «иров». Multiplexing — мультиплексирование, juggling — жонглирование, currying — каррирование.
Не буду спорить, согласен.
Стоило отметить или где-то добваить, что автор метода — Haskell Brooks Curry, создатель языков Haskell, Brooks и Curry :-)
Всё-таки не «создатель языков», а «в его честь были названы языки». Но результаты его исследований во многом используются в этих языках, это да.
PS. В частности, он придумал саму концепцию карринга.
Sign up to leave a comment.

Articles