Каррування або каррінг (англ. currying) в інформатиці — метод обчислення функції від багатьох аргументів, перетворенням її в послідовність функцій одного аргумента. Це перетворення було введено і отримало свою назву від свого поширювача, Гаскеля Каррі.
Операція каррування є функцією вищого порядку, оскільки, вона приймає і повертає функцію.
Карровані функції можуть використовуватись у всіх мовах програмування, що підтримують замикання. Хоча не карровані функції обчислюються швидше, оскільки не потребують часткового застосування та створення замикання.
Визначення
Для функції двох змінних , каррування — це операція .
Тобто, має аргумент і повертає функцію однієї змінної .
Часткове застосування функції
Каррування — це не є зменшення кількості аргументів функції за допомогою їх фіксації, це побудова послідовності функцій одного аргумента, кожна з яких повертає наступну.
Для функції , каррування — це послідовність функцій .
Знаходження значення функції — це , а при обчисленні значення каррованої функції , для кожного аргумента, при його підстановці отримуємо нову функцію, в яку підставляємо наступний аргумент і т. д.
Тобто, , повертає функцію одного аргумента (яка в свою чергу теж повертає функцію), а не функцію двох аргументів.
Математична точка зору
В теоретичній інформатиці є такий аналітичний апарат, як лямбда-числення, який можна застосувати тільки для функцій однієї змінної. З точки зору теорії множин, каррування — це відповідність між множинами та …
Приклади
#include<functional> auto curry = ([](int x)->std::function<int(int)>{ return [x](int y)->int { return x+y; }; }); int a = curry(4)(5); // 9 auto curry_4 = curry(4); int b = curry_4(5); // 9
C# (3.0)
Func<int, Func<int, int>> curry = (x => (y => x + y)); curry(4)(5); // 9
Curry = fun(A) -> fun(B) -> A + B end end. (Curry(3))(4). % => 7
let add a b = a + b //'a -> 'a -> 'a let addOne = add 1 //'a -> 'a let x = addOne 10 // 11
(defun curry(x) (lambda (y) (+ x y))) ((curry 2) 3) ; повертає 5 ; через особливості семантики вертає помилку (на відміну від Scheme)... (funcall (curry 2) 3) ; повертає 5
curry x = (\y -> x + y) -- також можна написати curry = (+) curry 2 3 -- повертає 5
! curry - turn a binary function into a function producing a function. !(Named after Haskell B. Curry) ! e.g. curry f x y = f(x, y) dec curry : (alpha # beta -> gamma) -> alpha -> beta -> gamma; --- curry f <= lambda x => lambda y => f(x, y); curry (+) 1; >> lambda y => 1 + y: num->num (curry (+) 1) 2; >>3: num
function curry(x){ return function(y){ return x + y; } } curry(4)(5); // повертає 9
Починаючи з версії ECMAScript 5 можливий код:
const curry = (fn,x) => (y) => fn(x,y); const add = (x,y) => x+y; curry(add,4)(5); // повертає 9
Lisp Scheme
; визначення (define (curry x) (lambda (y) (+ x y))) ; виклик (let ((curr (curry 4))) (curr 5)) ;результат 9 ; або так ((curry 4) 5)
let curry x = function y -> x + y;; (* val curry : int -> int -> int = <fun> *) let a = curry 4 5;; (* - : int = 9 *)
OCaml є мовою із сімейства ML, в мовах цього сімейства приведення багатомісної функції в карроване представлення виконується автоматично:
let curry x y = x + y;; (* val curry : int -> int -> int = <fun> *) let a = curry 4;; (* val a : int -> int = <fun> *) a 5;; (* - : int = 9 *)
curry = lambda fn, x: lambda y: fn(x, y) add = lambda x, y: x + y curry(add, 4)(5) # => 9
sub curry { my $x = shift; return sub { return $x + shift } } curry(4)->(5); # 9
Починаючи з PHP 5.3, в якому було додано замикання.
function curry($x) { return function ($y) use ($x) { return $x + $y; }; } $a = curry(5); $b = $a(10); // 15
def curry(x) Proc.new{|y| x + y} end curry(1).call(2) # => 3
def curry(x: Int)(y: Int) = x + y // curry: (Int)(Int)Int f = curry(4)_ f(5) // Int = 9
Приклад реалізації з використанням блоків (blocks):
typedef int (^Add)(int y); Add curry(int x) { return Block_copy(^(int y) { return x + y; }); } int res = curry(5)(6); NSLog(@"%i",res); >>11
package main func main() { curry := func(x int) func(int) int { return func(y int) int { return x+y } } print(curry(2)(3)) // 5 }
curry = @(x)@(y)x+y; a = curry(5); disp(a(6)); % 11
F = {(Y) = {(X)=X+Y}}, write(F(2)(3)), % 5
t(A, B):- A > B, !. call(call(t, 3), 0). % true
Див. також
Примітки
- . Архів оригіналу за 7 жовтня 2014. Процитовано 3 жовтня 2014.
Ця стаття потребує додаткових для поліпшення її . (квітень 2020) |
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет