2015-09-28 77 views
1

我正在学习specs2测试框架,通过下面的一些例子。Scala使用部分应用程序的匿名函数语法?

我注意到下面的匿名函数的语法重复:

val upper = (_: String).toUpperCase 

这相当于更传统的/一般

val upper = (s: String) => s.toUpperCase 

虽然语法简单大方,但它的不是很familiar (easy)

有人能指导我了解第一种语法的工作原理/派生方法吗?我很确定它与某种部分申请有关,但不能完全推理。

也是在Scala中经常使用的语法? (我还在这里学习的绳索:])

编辑::

我已经找到了循环模式使用这样的语法是特设多态(简单地说,重载方法/功能),其中参数传递函数的类型决定了哪个函数被调度。

例如,

def f(g: Int => String): String = g(10) 
def f(g: String => String): String = g("hello") 
f((_: Int).toString + " beers") // 10 beers 
f((_: String) + " world") // hello world 

这种模式是在图书馆等重复ScalaCheck

回答

2

该语法根据参数顺序指示您正在创建函数的编译器,其参数的类型为String,该参数插入使用_的地方。如果您有:

val f = (_:String).length + (_:Int) 

它会创建一个函数(String, Int) => Int,哪里哪里正在使用的每个_马克参数。顺序很重要!他们必须以相同的顺序使用你想要的功能的参数是

如果类型已经定义声明val时,你可以在函数体中忽略它们:

val f: (String, Int) => Int = _.length + _ 
+0

你的最后一句话让一切明确。 '如果声明val时已经定义了类型,则可以在函数体中省略它们'。尽管我很熟悉使用'_'来传递匿名函数给combinators,但是这个语法看起来令人毛骨悚然,因为它创建的函数没有预定义的类型。谢谢! –