什么是"咖喱"?

时间:2020-03-05 18:45:31  来源:igfitidea点击:

我在几篇文章和博客中都看到过关于咖喱函数的引用,但我找不到很好的解释(或者至少有一个合理的解释!)

解决方案

回答

咖喱化是指将一个包含多个参数的函数分解为一系列包含该参数的函数的情况。这是JavaScript中的示例:

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

add(3, 4); // returns 7

这个函数接受两个参数a和b并返回它们的总和。现在,我们将使用此函数:

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

这是一个接受一个参数a的函数,并返回接受另一个参数b的函数,该函数返回它们的总和。

add(3)(4);

var add3 = add(3);

add3(4);

第一条语句返回7,就像add(3,4)语句一样。第二条语句定义了一个名为add3的新函数,该函数会将3加到其参数中。这就是某些人所谓的关闭。第三条语句使用add3操作将3加到4,结果再次产生7.

回答

Currying是一种可应用于函数的转换,以使它们比以前少使用一个参数。

例如,在F中,我们可以这样定义一个函数:

let f x y z = x + y + z

在这里,函数f接受参数x,y和z并将它们求和,这样:

f 1 2 3

返回6.

因此,根据我们的定义,我们可以为f定义curry函数:-

let curry f = fun x -> f x

其中'fun x-> f x'是Lambda函数,等效于C#中的x => f(x)。该函数输入我们要咖喱的函数,并返回一个带有单个参数的函数,并返回将第一个参数设置为输入参数的指定函数。

使用前面的示例,我们可以得到f的咖喱:-

let curryf = curry f

然后,我们可以执行以下操作:

let f1 = curryf 1

它为我们提供了与f1 y z = 1 + y + z等价的函数f1. 这意味着我们可以执行以下操作:

f1 2 3

返回6.

此过程通常与"部分功能应用程序"混淆,可以这样定义:

let papply f x = f x

尽管我们可以将其扩展为多个参数,即:-

let papply2 f x y = f x y
let papply3 f x y z = f x y z
etc.

部分应用程序将使用该函数和参数,并返回一个需要一个或者多个更少参数的函数,并且如前两个示例所示,该函数直接在标准Ffunction定义中实现,因此我们可以实现以前的结果:-

let f1 = f 1
f1 2 3

这将返回结果6.

综上所述:-

currying和部分函数应用程序之间的区别在于:

Currying具有一个函数,并提供一个接受单个参数的新函数,并返回将其第一个参数设置为该参数的指定函数。这使我们可以将具有多个参数的函数表示为一系列单参数函数。例子:-

let f x y z = x + y + z
let curryf = curry f
let f1 = curryf 1
let f2 = curryf 2
f1 2 3
6
f2 1 3
6

局部函数应用程序更直接,它接受一个函数和一个或者多个参数,然后返回将前n个参数设置为指定的n个参数的函数。例子:-

let f x y z = x + y + z
let f1 = f 1
let f2 = f 2
f1 2 3
6
f2 1 3
6

回答

curried函数是重写了几个参数的函数,这样它可以接受第一个参数,并返回一个可以接受第二个参数的函数,依此类推。这允许几个自变量的功能部分地应用其某些初始自变量。

回答

在函数的代数中,处理带有多个参数(或者等效的一个是N元组的参数)的函数有些微不足道-但是,正如Moses Sch?nfinkel(以及独立的Haskell Curry)证明的那样,它并不需要:全部我们需要的是带有一个参数的函数。

那么如何处理自然表达为" f(x,y)"的东西呢?好吧,我们将其等同于f(x)(y)-f(x),称其为" g"是一个函数,然后将该函数应用于y`。换句话说,我们只有带有一个参数的函数-但其中一些函数会返回其他函数(也带有一个参数;-)。

像往常一样,维基百科对此有一个很好的总结条目,其中包含许多有用的指针(可能包括与我们喜欢的语言有关的指针;-)以及更为严格的数学处理。

回答

我发现本文及其引用的文章对更好地理解curring很有用:
http://blogs.msdn.com/wesdyer/archive/2007/01/29/currying-and-partial-function-application.aspx

正如其他人提到的那样,这只是拥有一个参数函数的一种方式。

这很有用,因为我们不必假设要传入多少个参数,因此我们不需要2个参数,3个参数和4个参数函数。

回答

这是一个具体的例子:

假设我们有一个计算作用在物体上的重力的函数。如果我们不知道公式,可以在这里找到。此函数将三个必需参数作为参数。

现在,在地球上,我们只想计算该星球上物体的力。用功能语言,我们可以将地球质量传递给功能,然后对其进行部分评估。我们会得到的是另一个仅包含两个参数并计算地球上物体的重力的函数。这称为"咖喱"。

回答

这是Python中的一个玩具示例:

>>> from functools import partial as curry

>>> # Original function taking three parameters:
>>> def display_quote(who, subject, quote):
        print who, 'said regarding', subject + ':'
        print '"' + quote + '"'

>>> display_quote("hoohoo", "functional languages",
           "I like Erlang, not sure yet about Haskell.")
hoohoo said regarding functional languages:
"I like Erlang, not sure yet about Haskell."

>>> # Let's curry the function to get another that always quotes Alex...
>>> am_quote = curry(display_quote, "Alex Martelli")

>>> am_quote("currying", "As usual, wikipedia has a nice summary...")
Alex Martelli said regarding currying:
"As usual, wikipedia has a nice summary..."

(只需通过+使用串联,以避免非Python程序员分心。)

编辑添加:

参见http://docs.python.org/library/functools.html?highlight=partial#functools.partial,
这也显示了Python实现此方法的部分对象与函数的区别。