Rod*_*gue 4 functional-programming scala anonymous-function currying higher-order-functions
我在比较两种在Scala 中定义高阶函数的方法:
def f1(elem: Int)(other: Int) = (elem == other)
def f2(elem: Int) = (other: Int) => (elem == other)
Run Code Online (Sandbox Code Playgroud)
我想知道两种方法之间的区别在于Scala如何实现它们以及哪种版本更可取?
这些实现与Scala编译器完全不同.curried版本通过取消参数来解压缩到Java方法:
def f1(elem: Int, other: Int): Boolean = elem.==(other);
Run Code Online (Sandbox Code Playgroud)
第二个版本是一个返回匿名函数(a Function1
)的方法,因此它们的签名完全不同.虽然它们通常可以在Scala代码中互换使用,但在第二个版本中生成的代码要多得多:
def f2(elem: Int): Function1 = (new <$anon: Function1>(elem): Function1);
@SerialVersionUID(value = 0) final <synthetic> class anonfun$f2$1 extends scala.runtime.AbstractFunction1$mcZI$sp with Serializable {
final def apply(other: Int): Boolean = anonfun$f2$1.this.apply$mcZI$sp(other);
<specialized> def apply$mcZI$sp(other: Int): Boolean = anonfun$f2$1.this.elem$1.==(other);
final <bridge> <artifact> def apply(v1: Object): Object = scala.Boolean.box(anonfun$f2$1.this.apply(scala.Int.unbox(v1)));
<synthetic> <paramaccessor> private[this] val elem$1: Int = _;
def <init>(elem$1: Int): <$anon: Function1> = {
anonfun$f2$1.this.elem$1 = elem$1;
anonfun$f2$1.super.<init>();
()
}
}
Run Code Online (Sandbox Code Playgroud)
在我明确希望使用对象的情况下,我只会考虑使用第二个版本Function1
.但是,我个人倾向于使用curried版本,因为你仍然可以获得第一个Function1
部分应用程序.curried版本同样强大,但Function1
在不需要时不会创建对象.
scala> f1(1) _
res1: Int => Boolean = <function1>
Run Code Online (Sandbox Code Playgroud)