EMZETT.
Login

Currying

Kurz: Currying zerlegt eine Funktion mit mehreren Parametern in eine Kette von Funktionen mit je einem Parameter: f(a, b, c) wird zu f(a)(b)(c).

Genauer: Der Name erinnert an den Logiker Haskell Curry. Die Technik erlaubt Teilanwendung (partial application): Man gibt nur einen Teil der Argumente an und erhält eine neue, spezialisierte Funktion. In Haskell, OCaml und F# sind alle Funktionen automatisch curryt; in anderen Sprachen baut man es mit Closures nach.

Im Detail

const addiere = (a) => (b) => a + b;
const plus10 = addiere(10);
console.log(plus10(5));          // 15
console.log(addiere(1)(2));      // 3
 
const rechne = (op) => (a) => (b) => op(a, b);
const mal = rechne((x, y) => x * y);
console.log([1, 2, 3].map(mal(10)));   // [10, 20, 30]
from functools import partial
 
def potenz(basis, exponent):
    return basis ** exponent
 
quadrat = partial(potenz, exponent=2)
zweierpotenz = partial(potenz, 2)
print(quadrat(7))          # 49
print(zweierpotenz(10))    # 1024
addiere :: Int -> Int -> Int
addiere a b = a + b
 
plus10 :: Int -> Int
plus10 = addiere 10

Wozu?

  • Wiederverwendung: Aus einer allgemeinen Funktion entstehen mit wenig Aufwand spezialisierte.
  • Komposition: Funktionen mit einem Parameter lassen sich leichter verketten (map(plus10), |>-Pipelines).
  • Konfiguration: Erst Einstellungen übergeben, später die Daten.

Currying ist nicht dasselbe wie Teilanwendung: Currying ist die Umformung, Teilanwendung das Festlegen einiger Argumente; beides geht oft Hand in Hand.

Siehe auch: Higher-Order-Funktion, Lambda-Ausdruck, Closure