Мое ограниченное понимание таково:
1) Применение частичной функции
Частичное применение функции - это процесс возврата функции, которая принимает меньшее количество аргументов. Если вы предоставите 2 из 3 аргументов, он вернет функцию, которая принимает аргумент 3-2 = 1. Если вы предоставите 1 из 3 аргументов, он вернет функцию, которая принимает 3-1 = 2 аргумента. Если бы вы хотели, вы могли бы даже частично применить 3 из 3 аргументов, и это вернуло бы функцию, которая не принимает аргументов.
Так дана следующая функция:
f(x,y,z) = x + y + z;
При связывании 1 с x и частичном применении этого к вышеуказанной функции f(x,y,z)
вы получите:
f(1,y,z) = f'(y,z);
Где: f'(y,z) = 1 + y + z;
Теперь, если бы вы связали y с 2 и z с 3 и применили частично, f'(y,z)
вы получите:
f'(2,3) = f''();
Где f''() = 1 + 2 + 3
:;
Теперь в любой момент, вы можете оценить f
, f'
или f''
. Так что я могу сделать:
print(f''()) // and it would return 6;
или же
print(f'(1,1)) // and it would return 3;
2) Карри
Карри с другой стороны - это процесс разбиения функции на вложенную цепочку функций с одним аргументом. Вы никогда не можете предоставить более 1 аргумента, это один или ноль.
Итак, с учетом той же функции:
f(x,y,z) = x + y + z;
Если вы его каррируете, вы получите цепочку из 3 функций:
f'(x) -> f''(y) -> f'''(z)
Где:
f'(x) = x + f''(y);
f''(y) = y + f'''(z);
f'''(z) = z;
Теперь, если вы звоните f'(x)
с x = 1
:
f'(1) = 1 + f''(y);
Вам возвращается новая функция:
g(y) = 1 + f''(y);
Если вы звоните g(y)
с y = 2
:
g(2) = 1 + 2 + f'''(z);
Вам возвращается новая функция:
h(z) = 1 + 2 + f'''(z);
Наконец, если вы звоните h(z)
с z = 3
:
h(3) = 1 + 2 + 3;
Вы вернулись 6
.
3) Закрытие
Наконец, Closure - это процесс сбора функции и данных в единый блок. Закрытие функции может принимать от 0 до бесконечного числа аргументов, но оно также знает о данных, которые ему не передаются.
Опять же, учитывая ту же функцию:
f(x,y,z) = x + y + z;
Вместо этого вы можете написать закрытие:
f(x) = x + f'(y, z);
Где:
f'(y,z) = x + y + z;
f'
закрыт на x
. Это означает, что f'
можно прочитать значение х внутри f
.
Так что, если вам нужно позвонить f
с x = 1
:
f(1) = 1 + f'(y, z);
Вы получите закрытие:
closureOfF(y, z) =
var x = 1;
f'(y, z);
Теперь, если вы звонили closureOfF
с y = 2
и z = 3
:
closureOfF(2, 3) =
var x = 1;
x + 2 + 3;
Который вернется 6
Заключение
Карринг, частичное применение и замыкания несколько похожи в том, что они разбивают функцию на несколько частей.
Карринг разлагает функцию нескольких аргументов на вложенные функции отдельных аргументов, которые возвращают функции отдельных аргументов. Нет смысла каррировать функцию с одним или несколькими аргументами, так как это не имеет смысла.
Частичное приложение разлагает функцию нескольких аргументов на функцию меньших аргументов, чьи пропущенные аргументы были заменены предоставленным значением.
Закрытие разлагает функцию на функцию и набор данных, где переменные внутри функции, которые не были переданы, могут заглянуть внутрь набора данных, чтобы найти значение, к которому необходимо привязаться, когда его попросят оценить.
Что смущает во всем этом, так это то, что они могут быть использованы для реализации подмножества других. Таким образом, по сути, все они немного детали реализации. Все они обеспечивают одинаковое значение в том смысле, что вам не нужно собирать все значения заранее, и в этом вы можете повторно использовать часть функции, поскольку вы разложили ее на дискретные блоки.
раскрытие
Я ни в коем случае не эксперт в этой теме, я только недавно начал изучать их, и поэтому я даю свое текущее понимание, но в нем могут быть ошибки, которые я предлагаю вам указать, и я исправлю как / если Я нахожу любой.