我正在学习有关 Scala 的更多信息,但在理解 http://www.scala-lang.org/node/135 中的匿名函数示例时遇到了一些麻烦。 .我复制了下面的整个代码块:
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 函数的应用感到困惑
def modN(n: Int)(x: Int) = ((x % n) == 0)
在示例中,它使用一个参数调用
modN(2) and modN(3)
modN(n: Int)(x: Int) 的语法是什么意思?
由于它是用一个参数调用的,我假设它们不是两个参数,但我无法真正弄清楚 mod 函数如何使用来自 nums 的值。
最佳答案
这是函数式编程中的一件有趣的事情,称为 currying .基本上,Moses Schönfinkel 和后来的 Haskell Curry(虽然 Schonfinkeling 听起来很奇怪......)提出了调用多个参数的函数的想法,比如 f(x,y)
与调用链 {g(x)}(y)
相同或 g(x)(y)
在哪里 g
是一个产生另一个函数作为其输出的函数。
以函数 f(x: Int, y: Int) = x + y
为例.调用 f(2,3)
会产生 5
,正如预期的那样。但是当我们 curry 这个函数时会发生什么 - 将它重新定义为 f(x:Int)(y: Int)
并将其称为 f(2)(3)
.第一个电话,f(2)
产生一个取整数 y
的函数并添加 2
给它-> 因此f(2)
有类型 Int => Int
并且等价于函数g(y) = 2 + y
.第二次通话f(2)(3)
调用新生成的函数 g
带有参数 3
,因此评估为 5
,正如预期的那样。
查看它的另一种方法是逐步执行 f(2)(3)
的缩减(函数式程序员称之为 beta-reduction - 它就像逐行步进的函数式方式)。调用(注意,以下不是真正有效的 Scala 语法)。
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。我希望这一切都是有意义的——我试图给出一些背景,说明为什么
modN(3)
通话很有意义:)
关于syntax - 匿名 Scala 函数语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1550821/