加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – currying和多个参数列表有什么区别?

发布时间:2020-12-16 09:33:00 所属栏目:安全 来源:网络整理
导读:我看到的地方,我看到术语多个参数列表和currying互换使用。我看到它有几十个stackoverflow问题,甚至在scala-lang.org。例如, This page有标题“Currying”。和第一句话? “方法可以定义多个参数列表”。 而有些知识渊博的人在看到多个参数列表和等同的时
我看到的地方,我看到术语多个参数列表和currying互换使用。我看到它有几十个stackoverflow问题,甚至在scala-lang.org。例如, This page有标题“Currying”。和第一句话? “方法可以定义多个参数列表”。

而有些知识渊博的人在看到多个参数列表和等同的时候会变得恼火。我发布了一个this question的答案,但是当我看到兰德尔·舒尔茨(Randall Schulz)的评论时,我删除了它,因为我害怕我可能会无意中传播错误信息。我的理解是,具有多个参数列表的功能必然是咖喱功能,但是这种功能可以以其他方式实现(最重要的答案是this question列出了四种方式),但我不知道这是完整的故事。我想真正了解这个区别。

我知道在stackoverflow中有很多非常相似的问题,但是我没有找到一个正确地说明差异的问题。我需要了解多个参数列表和调理才能准确说出他们?

解决方法

我希望你不要介意,如果我从Haskell的例子开始,因为Haskell是一个比Scala简单得多的语言。在Haskell中,所有函数都是数学意义上的函数 – 它们使用一个参数并返回一个值。 Haskell也有元组,你可以编写一个看起来像一个函数从一个元组到任何东西的函数,它需要多个参数。例如:

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

现在我们可以用这个函数来获取一个类型为Int – >的函数Int – > Int而不是(Int,Int) – >诠释:

Prelude> let curriedAdd = curry add

这允许我们部分应用该功能,例如:

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

所以我们有一个很好的清晰的currying定义 – 它是一个函数,它为一个参数带有一个元组(特别是一对)的函数,并返回一个函数,该函数将该参数中的第一个类型作为参数,并从第二个返回一个函数键入对原始返回类型。这只是一个冗长的方式来说这个:

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

好的,现在为Scala。

在Scala中,您还可以具有采用元组参数的函数。 Scala还具有多个参数(Function2和up)的“函数”。这些(混乱)不同种类的动物。

Scala还具有与功能不同的方法(尽管它们可以通过eta扩展自动转换为函数)。方法可以有多个参数或元组参数,或多个参数列表。

那么说在这个情况下我们正在骂东西呢是什么意思呢?

大多数字面上,currying是使用Function2(和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中是不正确的。

现在我很确定这是咖喱这个词实际上出现在Scala标准库中的唯一上下文(不包括在Function companion object上随附的不一致),但是考虑到Scala对方法,功能,等等(不要误会我 – 我喜欢Scala,但是这部分语言是一个完整的灾难),在下列情况下,我也应该使用这个词似乎是合理的:

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

在这里,我们已经将一个方法转换成具有多个参数列表的方法,每个参数只需要一个参数(这最后一部分很重要)。

事实上,language specification也在这个上下文中使用这个术语,将以下内容描述为“一个单一的curried函数定义”:

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

(这当然是令人困惑的,因为这是一种方法,而不是功能。)

所以总结一下:多个参数列表是在Scala中实现currying的一种方式,但并不是所有具有多个参数列表的方法都是curried-only,每个参数列表都有一个参数。无论如何,所有的术语都是非常糊糊的,所以不用担心得到正确的。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读