为什么Scala类方法不是一等公民?

时间:2015-05-28 01:04:33

标签: function scala methods

我刚开始使用Scala并且正在修改工作表。例如:

def merp(str: String) : String = s"Merrrrrrrp $str"
val merp2 = (str: String) => s"Merrrrrrrp $str"
val merp3 = (str: String) => merp(str)
val merp4 = merp _
merp("rjkghleghe")
merp4("rjkghleghe")

相应的工作表结果:

merp: merp[](val str: String) => String
merp2: String => String = <function1>
merp3: String => String = <function1>
merp4: String => String = <function1>
res0: String = Merrrrrrrp rjkghleghe
res1: String = Merrrrrrrp rjkghleghe

例如,假设val merp5 = merp会产生错误,因为显然方法不能像函数那样成为值。但我仍然可以将方法作为参数传递。我在以下代码片段中演示了这一点,该代码段改编自a similar SO question

def intCombiner(a: Int, b: Int) : String = s"herrrrrrp $a derrrrrrp $b"
def etaAbstractor[A, B](combineFoo: (A, B) ⇒ String, a: A, b: B) = combineFoo(a, b)
etaAbstractor(intCombiner, 15, 16)

工作表结果:

intCombiner: intCombiner[](val a: Int,val b: Int) => String
etaAbstractor: etaAbstractor[A,B](val combineFoo: (A, B) => String,val a: A,val b: B) => String
res10: String = herrrrrrp 15 derrrrrrp 16
  1. 方法 - 不是一流的限制,可能是由Scala的JVM交互强加的,还是由语言设计决定的?
  2. 为什么我需要像merp3一样推出自己的eta abstractions
  3. merp4也是eta abstraction,还是偷偷摸摸的相似?
  4. 为什么我的etaAbstractor有效? Scala是否正在用intCombiner悄悄地取代intCombiner _
  5. 欢迎理论,计算机科学的答案,以及language specification中任何相关要点的指示。谢谢!

2 个答案:

答案 0 :(得分:3)

免责声明:我不是计算机科学家,但我会猜测:

  1. 方法是对象的一部分,并不存在于对象之外。你不能单独通过方法。 Closure是封装状态的另一种(等效?)方式,通过将对象方法转换为独立函数(在Scala中使用apply()方法的另一个对象),您创建了一个闭包。这个过程称为eta-expansion。 §3.3.1§6.26.5

  2. 你不必这样做。您也可以写val merp3 : (String => String) = merp§6.26.5

  3. 是的,merp4也是eta-expansion。 §6.7

  4. §6.26.2

答案 1 :(得分:2)

它与etaAbstractor一起使用的原因是编译器可以推断出需要一个函数(不是函数调用)。

如果我不得不猜测为什么在无法推断出函数类型的情况下需要下划线,我认为它可以改善常见错误类型的错误报告(获取调用的函数)。但同样,这只是猜测。

在JVM中,方法不是对象,而第一类函数必须是1。因此必须将方法装入对象以将其转换为函数。