【问题标题】:Currying vs. anonymous function in ScalaScala 中的柯里化与匿名函数
【发布时间】:2017-06-30 00:53:19
【问题描述】:

我比较了在 Scala 中定义 higher-order function 的两种方式:

def f1(elem: Int)(other: Int) = (elem == other)

def f2(elem: Int) = (other: Int) => (elem == other)

第一个使用currying,第二个使用anonymous function

我想知道这两种方法在 Scala 如何实现它们以及哪个版本更可取方面有什么区别(如果有的话)?

【问题讨论】:

    标签: scala functional-programming anonymous-function higher-order-functions currying


    【解决方案1】:

    实现与 Scala 编译器完全不同。 curry 版本通过 un-currying 参数编译成 Java 方法:

    def f1(elem: Int, other: Int): Boolean = elem.==(other);
    

    第二个版本是一个返回匿名函数的方法(一个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>();
          ()
        }
      }
    

    我只会考虑在我明确希望使用Function1 对象的情况下使用第二个版本。但是,我个人倾向于使用 curried 版本,因为您仍然可以获得 Function1 并部分应用第一个。 curried 版本同样强大,但不会在您不需要 Function1 对象时创建它们。

    scala> f1(1) _
    res1: Int => Boolean = <function1>
    

    【讨论】:

    • 感谢您的回答。你如何从scala生成java代码?另外,val f3 = (_ : Int) == (_ : Int) ; f3.curried 之类的东西是否会遇到与 f2 相同的问题?
    • 您不能真正从 Scala 生成清晰的 Java 字节码(但可以生成字节码)。我使用-Xprint:jvm 在我的答案中生成代码,这是 Scala 编译器的最后阶段之一。 f3.curried 将创建 两个 匿名函数而不是一个,因此它会产生比 f2 更多的字节码。
    猜你喜欢
    • 1970-01-01
    • 2015-08-25
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多