7

Scala 2.8 语言规范§6.26.5 Eta Expansion 中,它声明我们需要一个最大子表达式,但是,找不到它的定义。有人可以澄清一下吗?

4

1 回答 1

4

考虑以下:

def list1 = { println("1st list!"); List(1, 2, 3) }
def list2 = { println("2nd list!"); List(4, 5) }
def empty = { println("Empty string!"); "" }

接着:

scala> val foo = (list1 ++ list2).foldLeft(empty) _
Empty string!
1st list!
2nd list!
foo: ((String, Int) => String) => String = <function1>

(list1 ++ list2).foldLeft(empty)是方法类型的表达式,list1 ++ list2并且empty是它的最大子表达式,它们实际上是它的最大组成表达式。我们_用来强制 eta 扩展,但在某些情况下这不是必需的。

list1 ++ list2例如,我们不希望每次使用 function 时都被求值是有道理的,foo这就是第 6.26.5 节中描述的转换所完成的——它确保子表达式在之前被求值和保存一次函数被创建。

如果我们用 开始 REPL -print,我们会看到以下内容(为清晰起见重新格式化):

$read$$iw$$iw.this.foo = {
  <synthetic> val eta$0$1: String = $line5.$read$$iw$$iw.empty();
  <synthetic> val eta$1$1: List = $line3.$read$$iw$$iw.list1().++(
    $line4.$read$$iw$$iw.list2(),
    immutable.this.List.canBuildFrom()
  ).$asInstanceOf[List]();
  {
    (new anonymous class anonfun$1(eta$0$1, eta$1$1): Function1)
  }
};

如果您想知道在给定情况下究竟是什么构成子表达式,这是一种简单的检查方法 - 只需查找以 . 开头的行<synthetic> val

于 2014-01-07T19:41:32.770 回答