繁体   English   中英

匿名Scala函数语法

[英]Anonymous Scala function syntax

我正在学习更多关于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的函数式编程中是一件有趣的事情。 基本上MosesSchö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 但是当我们讨论这个函数时会发生什么 - 将它重新定义为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

查看它的另一种方法是逐步完成减少(函数式程序员称之为beta减少 - 就像逐行逐步执行的功能方式) f(2)(3)调用(注意,以下内容并非真正有效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)调用有意义的背景:)

您正在部分应用ModN功能。 部分功能应用是功能语言的主要特征之一。 有关更多信息,请查看有关CurryingPointfree样式的这些文章。

在该示例中,modN 返回一个由特定N修改的函数。它使您不必执行此操作:

def mod2(x:Int): Boolean = (x%2) == 0
def mod3(x:Int): Boolean = (x%3) == 0

两对parens分隔,您可以停止将参数传递给方法。 当然,即使方法只有一个参数列表,您也可以使用占位符来实现相同的功能。

def modN(n: Int, x: Int): Boolean = (x % n) == 0

val nums = List(1, 2, 3, 4, 5)
println(nums.filter(modN(2, _)))
println(nums.filter(modN(3, _)))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM