'currying'和'composition'在Javascript中是同一个概念吗?

Are 'currying' and 'composition' the same concept in Javascript?

最近我在 Javascript 一本书中读到函数组合,然后在网站上我看到有人将其称为柯里化。

它们是同一个概念吗?

组合和柯里化用于创建函数。组合和柯里化在创建新函数的方式上有所不同(通过应用 args 与链接)。

撰写:

Compose should return a function that is the composition of a list of functions of arbitrary length. Each function is called on the return value of the function that follows. You can think of compose as moving right to left through its arguments.

示例:

var compose = function(funcs) {
  funcs = Array.prototype.slice.call(arguments, 0);
  return function(arg) {
    return funcs.reduceRight(function (a, b) {
      a = a === null ? a = b(arg) : a = b(a);
      return a;
    }, null);
  };
};


var sayHi = function(name){ return 'hi: ' + name;};
var makeLouder = function(statement) { return statement.toUpperCase() + '!';};

var hello = compose(sayHi, makeLouder);
l(hello('Johhny')); //=> 'hi: JOHNNY!'

柯里化:

Currying is a way of constructing functions that allows partial application of a function’s arguments.

示例:

var addOne = add(1);
var addTwo = add(2);

var addOneToFive = addOne(5);
var addTwoToFive = addTwo(5);

l(addOneToFive); //6
l(addTwoToFive); //7

JSBin 上面的例子: https://jsbin.com/jibuje/edit?js,console

@Omarjmh 的回答很好,但在我看来,撰写示例对于学习者来说非常复杂

Are they the same concept?

没有

首先,柯里化是将一个接受多个参数的函数转换为一系列函数,每个函数接受一个参数。

// not curried
const add = (x,y) => x + y;
add(2,3); // => 5

// curried
const add = x => y => x + y;
add(2)(3); // => 5

注意应用柯里化函数的不同方式,一次一个参数。


其次,函数组合是将两个函数组合成一个函数,在应用时,returns 链接函数的结果。

const compose = f => g => x => f(g(x));

compose (x => x * 4) (x => x + 3) (2);
// (2 + 3) * 4
// => 20

这两个概念密切相关,因为它们可以很好地相互配合。通用函数组合适用于一元函数(接受一个参数的函数),柯里化函数也只接受一个参数(每个应用程序)。

// curried add function
const add = x => y => y + x;

// curried multiplication function
const mult = x => y => y * x;

// create a composition
// notice we only apply 2 of comp's 3 parameters
// notice we only apply 1 of mult's 2 parameters
// notice we only apply 1 of add's 2 parameters
let add10ThenMultiplyBy3 = compose (mult(3)) (add(10));

// apply the composition to 4
add10ThenMultiplyBy3(4); //=> 42

// apply the composition to 5
add10ThenMultiplyBy3(5); //=> 45