我对何时替换咖喱函数及其对程序性能的影响有疑问。
具体来说,给出以下代码:
def curriedFun(f: Stuff => OtherStuff)(stuff: Stuff) = ...
def normalFun(stuff: Stuff): OtherStuff = ...
...
listOfListsOfStuff: List[Stuff] = ...
val otherStuff: List[OtherStuff] =
listOfListsOfStuff.map(curriedFun(normalFun))
我的疑问与代码块的最后一次调用有关,尤其是map
与curried函数的交互方式。特别是:
val substitutedFun = curriedFun(normalFun)
val otherStuff: List[OtherStuff] =
listOfListsOfStuff.map(substitutedFun)
otherStuff
列表中的每个元素替换一次?我的直觉告诉我应该等同于预先替换功能(第一个选项),但是我真的不明白为什么,而且我也不知道在哪里看...
答案 0 :(得分:3)
方法的参数是在调用该方法之前计算的(除非参数是按名称)。因此,map
的参数是在调用map
之前计算出来的。
因此,在这种情况下,curriedFun(normalFun)
被计算一次以提供一个函数,然后将该函数传递给map
。 map
然后将此功能应用于listOfListsOfStuff
的每个元素。 map
的参数由咖喱函数生成的事实与执行顺序无关。
答案 1 :(得分:2)
我个人认为scala -print
通常对此类问题很有用。例如,创建以下Main.scala
文件
// Main.scala
def foo(i: Int)(j: String): String = j
List("hello", "world").map(foo(42))
然后执行scala -print Main.scala
,其输出类似于
def foo(i: Int, j: String): String = j;
def $anonfun$new$1(j: String): String = anon$1.this.foo(42, j);
new collection.immutable.::("hello", new collection.immutable.::("world", scala.collection.immutable.Nil)).$asInstanceOf[List]().map({
((j: String) => anon$1.this.$anonfun$new$1(j))
});
在执行$anonfun$new$1
之前,我们看到的curry被解析为map
函数一次。