柯里化和多参数列表有什么区别? [英] What's the difference between currying and multiple parameter lists?

查看:56
本文介绍了柯里化和多参数列表有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无论在哪里,我都能看到术语多参数列表和柯里化可互换使用.我在几十个 stackoverflow 问题中看到了它,甚至在 scala-lang.org 上.例如,此页面的标题是咖喱".还有第一句话?方法可以定义多个参数列表."

Everywhere I look, I see the terms multiple parameter lists and currying used interchangably. I see it in dozens of stackoverflow questions, and even on scala-lang.org. This page, for example, has the title "Currying". And the first sentence? "Methods may define multiple parameter lists."

然而,一些知识渊博的人在看到多个参数列表和柯里化等同时会感到恼火.我发布了对这个问题的回答,但当我看到 Randall Schulz发表评论,因为我担心我可能会在不经意间传播错误信息.我的理解是,具有多个参数列表的函数必然是柯里化函数,但该函数柯里化也可以通过其他方式实现(这个问题列出了四种方法),但我不确定这就是整个故事.我想真正了解其中的区别.

And yet some very knowledgeable people get annoyed when they see multiple parameter lists and currying equated. I posted an answer to this question but then deleted it when I saw Randall Schulz's comment because I was afraid I might be inadvertently spreading misinformation. My understanding was that a function with multiple parameter lists is necessarily a curried function, but that function currying can be achieved in other ways as well (the top answer to this question lists four ways), but I'm not sure that's the whole story. I want to really understand the distinction.

我知道在 stackoverflow 上有很多非常类似的问题,但我还没有找到一个准确说明区别的问题.关于多个参数列表和柯里化,我需要了解什么才能准确地谈论它们?

I know there are a lot of very similar questions to this one on stackoverflow, but I haven't found one that precisely spells out the difference. What do I need to understand about multiple parameter lists and currying in order to speak accurately about them?

推荐答案

我希望您不介意我从 Haskell 示例开始,因为 Haskell 是一种比 Scala 简单得多的语言.在 Haskell 中,所有函数都是数学意义上的函数——它们接受一个参数并返回一个值.Haskell 也有元组,你可以编写一个看起来有点像它接受多个参数的函数,作为一个从元组到任何东西的函数.例如:

I hope you don't mind if I start with a Haskell example, since Haskell is a vastly simpler language than Scala. In Haskell all functions are functions in the mathematical sense—they take one argument and return one value. Haskell also has tuples, and you can write a function that looks a little like it takes multiple parameters, as a function from a tuple to whatever. For example:

Prelude> let add = (\(x, y) -> x + y) :: (Int, Int) -> Int
Prelude> add (1, 2)
3

现在我们可以curry这个函数来得到一个Int->类型的函数.内部 ->Int 而不是 (Int, Int) ->整数:

Now we can curry this function to get a function with type Int -> Int -> Int instead of (Int, Int) -> Int:

Prelude> let curriedAdd = curry add

这允许我们部分应用函数,例如:

This allows us to partially apply the function, for example:

Prelude> let add3 = curriedAdd 3
Prelude> add3 1
4

所以我们有一个很好的柯里化定义——它是一个函数,它接受一个带有元组(特别是一对)作为参数的函数,并返回一个函数,该函数将元组中的第一个类型作为参数并返回一个函数从对中的第二个类型到原始返回类型.这只是一种冗长的说法:

So we have a nice clean definition of currying—it's a function that takes a function with a tuple (specifically a pair) for an argument and returns a function that takes as an argument the first type in the pair and returns a function from the second type in the pair to the original return type. Which is just a wordy way to say this:

Prelude> :t curry
curry :: ((a, b) -> c) -> a -> b -> c

好的,现在是 Scala.

Okay, now for Scala.

在 Scala 中,您还可以使用带有元组参数的函数.Scala 也有接受多个参数的函数"(Function2 及以上).这些是(令人困惑的)不同种类的动物.

In Scala you can also have functions that take a tuple argument. Scala also has "functions" that take more than one argument (Function2 and up). These are (confusingly) different kinds of animals.

Scala 也有方法,它们不同于函数(尽管它们可以通过eta 扩展或多或少地自动转换为函数).方法可以有多个参数,或元组参数,或多个参数列表.

Scala also has methods, which are different from functions (although they can be converted to functions more or less automatically via eta expansion). Methods can have multiple parameters, or tuple parameters, or multiple parameter lists.

那么,在这种情况下,说我们正在柯里化是什么意思?

So what does it mean to say we're currying something in this context?

从字面上看,柯里化是您使用 Function2(及更高版本)执行的操作:

Most literally, currying is something you do with a Function2 (and up):

scala> val add: Function2[Int, Int, Int] = (x: Int, y: Int) => x + y
add: (Int, Int) => Int = <function2>

scala> val curriedAdd = add.curried
curriedAdd: Int => (Int => Int) = <function1>

scala> val add3 = curriedAdd(3)
add3: Int => Int = <function1>

这与我们在 Haskell 案例中看到的大致相同,不同之处在于我们柯里化了一个带有多个参数的函数,而这在 Haskell 中是不存在的.

This is about the same as what we saw in the Haskell case, except that we're currying a function with multiple arguments, which is something that doesn't properly exist in Haskell.

现在我很确定这是 curry 一词实际出现在 Scala 标准库中的唯一上下文(不包括 Function 伴随对象),但考虑到 Scala 在方法、函数等概念上造成的巨大混乱(不要误会我的意思——我喜欢 Scala,但这部分语言完全是一场灾难),对我来说申请似乎很合理也可以在以下上下文中使用该词:

Now I'm pretty sure this is the only context in which the word curry actually appears in the Scala standard library (not counting the accompanying uncurried on the Function companion object), but given the enormous mess that Scala makes of the idea of methods, functions, etc. (don't get me wrong—I love Scala, but this part of the language is a complete disaster), it seems pretty reasonable to me to apply the word in the following context as well:

def add(x: Int, y: Int) = x + y
def curriedAdd(x: Int)(y: Int) = add(x, y)

在这里,我们将一个接受两个参数的方法变成了一个具有多个参数列表的方法——每个参数列表只接受一个参数(最后一部分很重要).

Here we've turned a method that takes two parameters into a method with multiple parameter lists—each of which only takes a single parameter (this last part is important).

事实上语言规范也在这个上下文,将以下内容描述为单一的柯里化函数定义":

And in fact the language specification also uses the term in this context, describing the following as "a single, curried function definition":

def func(x: Int)
        (y: Int) = x + y

(这当然令人困惑,因为这是一个方法,而不是一个函数.)

(Which is of course confusing as hell, since this is a method, not a function.)

所以总结一下:多个参数列表是在Scala中实现柯里化的一种方式,但并非所有具有多个参数列表的方法都是柯里化的——只有每个参数列表只有一个参数的方法.无论如何,所有术语都很糊涂,所以不要太担心是否正确.

So to sum up: multiple parameter lists are one way to implement currying in Scala, but not all methods with multiple parameter lists are curried—only ones where each parameter list has a single parameter. And all the terminology is pretty mushy, anyway, so don't worry too much about getting it right.

这篇关于柯里化和多参数列表有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆