[英]Scala Syntax Help Currying
I came across some code in scala in a similar form like this: 我在scala中以类似的形式遇到了一些代码,如下所示:
def test1(f : Int => Int)(x : Int) = x + f(x)
def test2(f : Int => Int)(x : Int) = f(x)
test2(test1(x => 2*x))(2)
I'm confused, so function test1 takes a function and a Int as parameters, and returns a function, right? 我很困惑,所以函数test1将一个函数和一个Int作为参数,然后返回一个函数,对吗? Then how can
test1(x => 2*x)
be valid and returns a function to test2? 那么
test1(x => 2*x)
如何有效并将函数返回给test2? Apparently it takes 2 asthe integer parameter, but why? 显然,它需要2作为整数参数,但是为什么呢? How does the statement
test2(test1(x => 2*x))(2)
expand? 语句
test2(test1(x => 2*x))(2)
扩展?
Thanks in advance. 提前致谢。
function test1 takes a function and a Int as parameters, and returns a function, right?
函数test1将一个函数和一个Int作为参数,然后返回一个函数,对吗?
No, it only takes a function as its argument and returns a function. 不,它仅将函数作为参数并返回一个函数。 The returned function then takes an int as the argument and returns an int.
然后,返回的函数将int作为参数并返回int。
Then how can test1(x => 2*x) be valid and returns a function to test2?
那么test1(x => 2 * x)如何有效并将函数返回给test2?
I hope that's clear now. 我希望现在很清楚。
How does the statement test2(test1(x => 2*x))(2) expand?
语句test2(test1(x => 2 * x))(2)如何扩展?
test1
is called with x => 2*x
as the argument and returns a function. 使用
x => 2*x
作为参数调用test1
并返回一个函数。 Then test2
is called with that returned function as its argument and returns another function. 然后以返回的函数作为参数调用
test2
并返回另一个函数。 Then that other function is called with 2
as its argument. 然后使用
2
作为参数调用另一个函数。
This: 这个:
test2(test1(x => 2*x))(2)
expands to this: 扩展为:
test2(y => test1(x => 2*x)(y))(2)
Scala's methods with multiple argument lists can act a lot like curried functions in other languages, but in fact are implemented as methods that requires all of their parameters, and this does show through in the syntax. Scala具有多个参数列表的方法可以像其他语言中的咖喱函数一样工作,但实际上是作为需要其所有参数的方法实现的,这确实在语法中得以体现。 For example if you put this into the REPL:
例如,如果将其放入REPL中:
test1(x => 2*x)
It will complain about missing arguments. 它将抱怨缺少论据。 What this syntax does allow is "eta-expansion", where a method is converted into a function.
此语法允许的是“ eta扩展”,其中方法被转换为函数。 If you write:
如果您写:
val func: Int => Int = test1(x => 2*x) _
You can get a function that represents test1
partially applied. 您可以获得代表部分应用的
test1
的函数。 Scala will do eta-expansion automatically if the context requires it, which is what happens with test2(test1(x => 2*x))(2)
. 如果上下文需要,Scala将自动执行eta扩展,这就是
test2(test1(x => 2*x))(2)
。 Note that test1
itself never returns a function, but the compiler will build a function based on it when required. 请注意,
test1
本身从不返回函数,但编译器将在需要时基于该函数构建函数。
However, if you define test1
like: 但是,如果您像这样定义
test1
:
def test1(f : Int => Int) = (x : Int) => x + f(x)
Then the compiler will accept test1(x => 2*x)
without the _
. 然后,编译器将接受不带
_
test1(x => 2*x)
。 Also, in the underlying implementation there will be only one class implementing the closure retured by test1
, whereas with the original definition every partial application of test1
causes a new class to be created for it. 同样,在基础实现中,只有一个类实现由
test1
处理的闭包,而对于原始定义, test1
每个部分应用都会为其创建一个新类。 On the other hand, it is less efficient when given both parameters, because the closure is always created. 另一方面,给定两个参数时效率较低,因为总是创建闭包。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.