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


当前回答

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

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

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

其他回答

这里有一个具体的例子:

假设你有一个计算作用在物体上的引力的函数。如果你不知道公式,你可以在这里找到。这个函数接受三个必要的形参作为参数。

现在,在地球上,你只想计算这个星球上物体的力。在函数式语言中,你可以把地球的质量传递给函数,然后对它进行部分计算。你会得到另一个函数,它只接受两个参数,并计算地球上物体的引力。这叫做咖喱。

如果你理解了部分,你就成功了一半。partial的思想是将参数预先应用到一个函数,并返回一个只需要剩余参数的新函数。当这个新函数被调用时,它包括预加载的参数以及提供给它的任何参数。

在Clojure +中是一个函数,但要明确一点:

(defn add [a b] (+ a b))

您可能已经意识到inc函数只是简单地将1加到它传递的任何数字上。

(inc 7) # => 8

让我们自己使用partial来构建它:

(def inc (partial add 1))

Here we return another function that has 1 loaded into the first argument of add. As add takes two arguments the new inc function wants only the b argument -- not 2 arguments as before since 1 has already been partially applied. Thus partial is a tool from which to create new functions with default values presupplied. That is why in a functional language functions often order arguments from general to specific. This makes it easier to reuse such functions from which to construct other functions.

现在想象一下,如果语言足够聪明,能够自省地理解add需要两个参数。当我们向它传递一个参数时,如果函数部分应用了我们代表它传递的参数,并理解我们可能打算稍后提供另一个参数呢?然后,我们可以在不显式使用partial的情况下定义inc。

(def inc (add 1)) #partial is implied

这是一些语言的表现方式。当希望将函数组合成更大的转换时,它特别有用。这将把人们引向传感器。

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

有一个“咖喱在理性ml”的例子。

let run = () => {
    Js.log("Curryed function: ");
    let sum = (x, y) => x + y;
    Printf.printf("sum(2, 3) : %d\n", sum(2, 3));
    let per2 = sum(2);
    Printf.printf("per2(3) : %d\n", per2(3));
  };

下面是JavaScript中的一个curry示例,这里的multiply返回用于将x乘以2的函数。

const multiply = (presetConstant) => {
  return (x) => {
    return presetConstant * x;
  };
};

const multiplyByTwo = multiply(2);

// now multiplyByTwo is like below function & due to closure property in JavaScript it will always be able to access 'presetConstant' value
// const multiplyByTwo = (x) => {
//   return presetConstant * x;
// };

console.log(`multiplyByTwo(8) : ${multiplyByTwo(8)}`);

输出

multiplyByTwo(8): 16