Currying

Z Wikipedii, wolnej encyklopedii
Przejdź do nawigacji Przejdź do wyszukiwania

Rozwijanie funkcji (ang. currying) – operacja w funkcyjnych językach programowania polegająca na przekształceniu funkcji, która pobiera parę argumentów i zwraca wynik w funkcję, która po pobraniu argumentu zwraca funkcję, która pobiera argument i zwraca wynik . Operacja odwrotna nosi nazwę zwijanie funkcji (ang. uncurrying).

Programowanie funkcyjne (lub programowanie funkcjonalne) – filozofia i metodyka programowania będąca odmianą programowania deklaratywnego, w której funkcje należą do wartości podstawowych, a nacisk kładzie się na wartościowanie (często rekurencyjnych) funkcji, a nie na wykonywanie poleceń.Tautologia (wywodzi się od greckich słów ταυτος – ten sam i λογος – mowa) – wyrażenie, które jest prawdziwe na mocy swojej formy – budowy (dokładniej: które jest prawdziwe w każdej niepustej dziedzinie; zdanie zawsze prawdziwe). W logicznym znaczeniu zostało użyte po raz pierwszy przez Ludwika Wittgensteina (Tractatus logico-philosophicus 1922).

Podstawą dla tej operacji jest ugruntowanie systemu typów w językach funkcyjnych na rachunku lambda z typami. Taki rachunek na mocy izomorfizmu Curry’ego-Howarda jest równoważny pewnej logice intuicjonistycznej, a zatem operacja ta odpowiada tautologii logiki intuicjonistycznej:

Logika intuicjonistyczna (konstruktywna) - system logiczny oparty na filozoficznej koncepcji intuicjonizmu. Za prekursora formalizacji logiki intuicjonistycznej uważa się Arenda Heytinga.Haskell Brooks Curry (ur. 12 września 1900, zm. 1 września 1982) – amerykański matematyk. Najbardziej znany jest ze swoich prac nad logiką kombinatoryczną. Curry jest też znany z paradoksu Curry’ego i izomorfizmu Curry’ego-Howarda.

Oryginalna nazwa została zaproponowana przez Christophera Stracheya w 1967 roku, jako nawiązanie do nazwiska logika Haskella Curry’ego.

Zastosowanie w programowaniu[ | edytuj kod]

W przypadku języków programowania stosuje się rozszerzenie tego mechanizmu. Najbardziej uniwersalnym jest taki, który zwraca funkcję, która przyjmuje argumenty i zwraca funkcje dopóki suma argumentów jest mniejsza niż liczba parametrów początkowej funkcji. Natomiast gdy ich liczba przekroczy sumę parametrów, wywoływana jest pierwotna funkcja.

Przykład JavaScript

// ES5
function curry(fn) {
  var init_args = .slice.call(arguments, 1);
  var len = fn.length;
  return function() {
    var args = init_args.slice();
    function call() {
      args = args.concat(.slice.call(arguments));
      if (args.length >= len) {
        return fn.apply(null, args);
      } else {
        return call;
      }
    };
    return call.apply(null, arguments);
  };
}

// ES6
function curry(fn, ...init_args) {
  var len = fn.length;
  return function() {
    var args = init_args.slice();
    function call(...fn_args) {
      args = args.concat(fn_args);
      if (args.length >= len) {
        return fn.apply(null, args);
      } else {
        return call;
      }
    };
    return call.apply(null, arguments);
  };
}

function add(a,b,c) {
  return a+b+c;
}
var curry_add = curry(add);
console.log(curry_add(2,3,4)); // 9
console.log(curry_add(2)(3)(4)); // 9
console.log(curry_add(2,3)(4)); // 9

Przypisy[ | edytuj kod]

  1. Simpson 2020 ↓, s. 59–63.
  2. Simpson 2020 ↓, s. 68.

Bibliografia[ | edytuj kod]

  • Kyle Simpson: JavaScript funkcyjnie. Wydawnictwo Naukowe PWN, 2020. ISBN 83-01-21196-2.




  • Reklama