Syntax 匿名Scala函数语法
我正在学习更多关于Scala的知识,在理解中的匿名函数示例时遇到了一些困难。我复制了下面的整个代码块:Syntax 匿名Scala函数语法,syntax,scala,anonymous-function,Syntax,Scala,Anonymous Function,我正在学习更多关于Scala的知识,在理解中的匿名函数示例时遇到了一些困难。我复制了下面的整个代码块: 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)
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中的值。在该示例中,modN返回一个函数,该函数按特定的N进行mods。这样做可以省去您的麻烦:
def mod2(x:Int): Boolean = (x%2) == 0
def mod3(x:Int): Boolean = (x%3) == 0
这两对参数限定了可以停止向方法传递参数的位置。当然,即使方法只有一个参数列表,也可以使用占位符来实现同样的效果
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, _)))
您正在部分应用ModN函数。部分函数应用是函数式语言的主要特征之一。有关更多信息,请查看这些关于和样式的文章。这是函数式编程中的一件有趣的事情。基本上,摩西·舍芬克尔(Moses Schönfinkel)和后来的哈斯克尔·库里(Haskell Curry,Schonlinking听起来很奇怪……)提出了这样一个想法:调用多个参数的函数,比如
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
,因此计算结果与预期一致
查看它的另一种方法是逐步执行f(2)(3)
调用的缩减(函数式程序员称之为beta缩减-类似于逐行执行的函数式缩减)(注意,以下不是真正有效的Scala语法)
因此,在所有这些讨论之后,f(x)(y)
可以被看作是下面的lambda表达式(x:Int)=>{(y:Int)=>x+y}
——这是有效的Scala
我希望这一切都是有意义的-我试着给出一点背景信息,说明为什么
modN(3)
调用有意义:)感谢您的详细回复。在使用占位符的第二个示例中,您能否解释最后一个:Int是用于什么的,即:def modN(n:Int)(x:Int):Int与def modN(n:Int)(x:Int)是否只是占位符可以使用和不能使用时的语法差异,编译器抱怨modN的参数数量不正确,这是因为modN(x,y)
不是调用函数的有效方式(Scala不自动进行无毛刺处理,即从f(x)(y)
转换为f(x,y)
)。因此,在本例中调用modN
的正确方法是modN(2)(41;
。另外,小的挑剔-返回类型modN
不正确,它应该是modN(n:Int)(x:Int):Boolean=(x%n)==0
。或者,您可以让类型推断器进行推断。:)我更新了第二个示例以减少错误。谢谢你的解释,弗拉维,解释得很好。我将您的更改为接受的答案(加上您修复了上一个示例中的错误)。从现在起我只使用这个词-D
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