【发布时间】:2014-01-07 10:52:52
【问题描述】:
在Scala 2.8 language specification, §6.26.5 Eta Expansion 中,它声明我们需要一个最大子表达式,但是找不到它的定义。有人可以澄清一下吗?
【问题讨论】:
标签: scala type-inference expansion language-specifications
在Scala 2.8 language specification, §6.26.5 Eta Expansion 中,它声明我们需要一个最大子表达式,但是找不到它的定义。有人可以澄清一下吗?
【问题讨论】:
标签: scala type-inference expansion language-specifications
考虑以下几点:
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 扩展,但在某些情况下这不是必需的。
例如,我们不希望每次使用函数 foo 时都评估 list1 ++ list2 是有道理的,这就是 §6.26.5 中描述的转换所完成的——它确保 sub - 表达式在创建函数之前被评估和保存一次。
如果我们以 -print 开始 REPL,我们会看到以下内容(为清晰起见重新格式化):
$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 开头的行。
【讨论】:
foldLeft 已经是一个函数,不需要进行这种转换。通常,最大子表达式将是调用该方法的表达式以及其他参数列表中的任何参数。