我在一些文章和博客中看到了curry函数的引用,但我找不到一个好的解释(或者至少一个有意义的解释!)


当前回答

正如所有其他答案一样,咖喱有助于创建部分应用函数。Javascript不提供自动咖喱的原生支持。因此,上面提供的示例可能对实际编码没有帮助。在livescript中有一些很好的例子(基本上编译成js) http://livescript.net/

times = (x, y) --> x * y
times 2, 3       #=> 6 (normal use works as expected)
double = times 2
double 5         #=> 10

在上面的例子中,当你给出较少的no of参数时,livescript会为你生成新的curried函数(double)

其他回答

curry函数是一个由几个参数重写的函数,它接受第一个参数,并返回一个接受第二个参数的函数,以此类推。这允许具有多个参数的函数部分应用它们的初始参数。

curry是Java Script的高阶函数之一。

curry是一个包含许多参数的函数,它会被重写,这样它会接受第一个参数并返回一个函数,而这个函数会使用剩余的参数并返回值。

困惑吗?

让我们看一个例子,

function add(a,b)
    {
        return a+b;
    }
add(5,6);

这类似于下面的咖喱函数,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }
var curryAdd = add(5);
curryAdd(6);

那么这个代码是什么意思呢?

现在再读一遍定义,

curry是一个包含许多参数的函数,它被重写为接受第一个参数并返回一个函数,该函数反过来使用剩余的参数并返回值。

不过,困惑吗? 让我来详细解释一下!

当你调用这个函数时,

var curryAdd = add(5);

它会返回一个这样的函数,

curryAdd=function(y){return 5+y;}

这叫做高阶函数。也就是说,依次调用一个函数返回另一个函数是高阶函数的精确定义。这是图例的最大优势,Java Script。 回到咖喱,

这一行将把第二个参数传递给curryAdd函数。

curryAdd(6);

结果是,

curryAdd=function(6){return 5+6;}
// Which results in 11

希望你能理解这里咖喱的用法。 那么,说到优点,

为什么鞭笞?

它利用了代码可重用性。 代码越少,错误越少。 你可能会问它是怎么少代码的?

我可以证明它与ECMA脚本6新的特征箭头功能。

是的!ECMA 6,为我们提供了美妙的功能,叫做箭头函数,

function add(a)
    {
        return function(b){
            return a+b;
        }
    }

借助箭头函数,我们可以将上面的函数写成如下形式:

x=>y=>x+y

酷吧?

所以,更少的代码和更少的错误!!

在这些高阶函数的帮助下,可以很容易地开发出无bug的代码。

我向你挑战!

霍普,你知道什么是咖喱。如果你有任何需要澄清的地方,请在这里评论。

谢谢,祝您愉快!

curry是指将一个N次的函数转换为N次1次的函数。函数的元数是它所需要的参数的个数。

下面是正式的定义:

 curry(f) :: (a,b,c) -> f(a) -> f(b)-> f(c)

下面是一个真实的例子:

你去自动取款机取钱。你刷你的卡,输入密码,做出选择,然后按enter键提交“金额”和请求。

这是取款的正常功能。

const withdraw=(cardInfo,pinNumber,request){
    // process it
       return request.amount
}

在这个实现函数中,我们希望一次性输入所有参数。我们将刷卡,输入密码并发出请求,然后函数将运行。如果这些步骤中有任何问题,在输入所有参数后就会发现。使用curry函数,我们可以创建更高的、纯粹的和简单的函数。纯函数将帮助我们轻松地调试代码。

这是带有咖喱功能的Atm机。

const withdraw=(cardInfo)=>(pinNumber)=>(request)=>request.amount

ATM, takes the card as input and returns a function that expects pinNumber and this function returns a function that accepts the request object and after the successful process, you get the amount that you requested. Each step, if you had an error, you will easily predict what went wrong. Let's say you enter the card and got error, you know that it is either related to the card or machine but not the pin number. Or if you entered the pin and if it does not get accepted you know that you entered the pin number wrong. You will easily debug the error.

此外,这里的每个函数都是可重用的,因此您可以在项目的不同部分使用相同的函数。

我发现这篇文章,以及它引用的文章,有助于更好地理解咖喱: http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx

正如其他人所提到的,它只是一种具有单参数函数的方法。

这很有用,因为你不需要假设有多少参数将被传入,所以你不需要2个参数,3个参数和4个参数函数。

它可以是一种用函数生成其他函数的方法。

在javascript中:

let add = function(x){
  return function(y){ 
   return x + y
  };
};

我们可以这样称呼它:

let addTen = add(10);

运行时,将10作为x传入;

let add = function(10){
  return function(y){
    return 10 + y 
  };
};

这意味着我们返回这个函数:

function(y) { return 10 + y };

所以当你打电话的时候

 addTen();

你真的在呼唤:

 function(y) { return 10 + y };

如果你这样做:

 addTen(4)

这就相当于:

function(4) { return 10 + 4} // 14

所以我们的addTen()总是给我们传入的任何东西加10。我们可以用同样的方法来构造类似的函数:

let addTwo = add(2)       // addTwo(); will add two to whatever you pass in
let addSeventy = add(70)  // ... and so on...

接下来的问题是,你到底为什么要这么做?它将一个急迫的操作x + y变成了一个可以轻松完成的操作,这意味着我们至少可以做两件事 1. 缓存昂贵的操作 2. 在功能范式中实现抽象。

想象我们的咖喱函数是这样的:

let doTheHardStuff = function(x) {
  let z = doSomethingComputationallyExpensive(x)
  return function (y){
    z + y
  }
}

我们可以调用这个函数一次,然后将结果传递给很多地方,这意味着我们只做一次计算上昂贵的事情:

let finishTheJob = doTheHardStuff(10)
finishTheJob(20)
finishTheJob(30)

我们可以用类似的方式得到抽象。