匿名 Scala 函数语法 [英] Anonymous Scala function syntax
问题描述
我正在学习更多关于 Scala 的知识,但我在理解 http://www.scala-lang.org/node/135.我复制了下面的整个代码块:
I'm learning more about Scala, and I'm having a little trouble understanding the example of anonymous functions in http://www.scala-lang.org/node/135. I've copied the entire code block below:
object CurryTest extends Application {
def filter(xs: List[Int], p: Int => Boolean): List[Int] =
if (xs.isEmpty) xs
else if (p(xs.head)) xs.head :: filter(xs.tail, p)
else filter(xs.tail, p)
def modN(n: Int)(x: Int) = ((x % n) == 0)
val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
println(filter(nums, modN(2)))
println(filter(nums, modN(3)))
}
我对 modN 函数的应用感到困惑
I'm confused with the application of the modN function
def modN(n: Int)(x: Int) = ((x % n) == 0)
在这个例子中,它是用一个参数调用的
In the example, it's called with one argument
modN(2) and modN(3)
modN(n: Int)(x: Int) 的语法是什么意思?
What does the syntax of modN(n: Int)(x: Int) mean?
因为它是用一个参数调用的,所以我假设它们不是两个参数,但我真的无法弄清楚 mod 函数如何使用来自 nums 的值.
Since it's called with one argument, I'm assuming they're not both arguments, but I can't really figure out how the values from nums get used by the mod function.
推荐答案
这是函数式编程中的一个有趣的东西,叫做 咖喱.基本上,Moses Schönfinkel 和后来的 Haskell Curry(尽管 Schonfinkeling 听起来很奇怪……)提出了调用多个参数的函数的想法,比如 f(x,y)
与链相同调用 {g(x)}(y)
或 g(x)(y)
其中 g
是产生另一个函数的函数它的输出.
This is a fun thing in functional programming called currying. Basically Moses Schönfinkel and latter Haskell Curry (Schonfinkeling would sound weird though...) came up with the idea that calling a function of multiple arguments, say f(x,y)
is the same as the chain of calls {g(x)}(y)
or g(x)(y)
where g
is a function that produces another function as its output.
以函数f(x: Int, y: Int) = x + y
为例.正如预期的那样,对 f(2,3)
的调用将产生 5
.但是当我们对这个函数进行柯里化时会发生什么 - 将它重新定义为 f(x:Int)(y: Int)
并将其称为 f(2)(3)
.第一次调用 f(2)
产生一个函数,它接受一个整数 y
并将 2
添加到它 -> 因此 f(2)
的类型为 Int =>Int
等价于函数 g(y) = 2 + y
.第二次调用 f(2)(3)
使用参数 3
调用新生成的函数 g
,因此计算结果为 5
,正如预期的那样.
As an example, take the function f(x: Int, y: Int) = x + y
. A call to f(2,3)
would produce 5
, as expected. But what happens when we curry this function - redefine it as f(x:Int)(y: Int)
and call it as f(2)(3)
. The first call, f(2)
produces a function taking an integer y
and adding 2
to it -> therefore f(2)
has type Int => Int
and is equivalent to the function g(y) = 2 + y
. The second call f(2)(3)
calls the newly produced function g
with the argument 3
, therefore evaluating to 5
, as expected.
另一种查看它的方法是逐步完成f(2)(3)
的归约(函数式程序员称之为beta 归约——它就像逐行逐行的函数式方法)调用(注意,以下不是真正有效的 Scala 语法).
Another way to view it is by stepping through the reduction (functional programmers call this beta-reduction - it's like the functional way of stepping line by line) of the f(2)(3)
call (note, the following is not really valid Scala syntax).
f(2)(3) // Same as x => {y => x + y}
|
{y => 2 + y}(3) // The x in f gets replaced by 2
|
2 + 3 // The y gets replaced by 3
|
5
所以,在讲完所有这些之后,f(x)(y)
可以被看作只是下面的 lambda 表达式 (x: Int) =>{(y: Int) =>x + y}
- 这是有效的 Scala.
So, after all this talk, f(x)(y)
can be viewed as just the following lambda expression (x: Int) => {(y: Int) => x + y}
- which is valid Scala.
我希望这一切都有意义 - 我试图给出一些为什么modN(3)
调用有意义的背景:)
I hope this all makes sense - I tried to give a bit of a background of why the modN(3)
call makes sense :)
这篇关于匿名 Scala 函数语法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!