【问题标题】:Partial application of curried constructors in ScalaScala 中柯里化构造函数的部分应用
【发布时间】:2014-06-26 18:42:54
【问题描述】:

考虑以下几点:

class A(foo: Int)(bar: Int)(baz: Int)
object A{
    def apply(foo: Int)(bar: Int)(baz: Int) = new A(foo)(bar)(baz)
}

使用 apply 方法,我可以执行以下操作:

scala> A(1)(2)(3)
res12: Script.A = Script$A@7a6229e9

scala> A(1)_
res13: Int => (Int => Script.A) = <function1>

为什么我不能执行以下操作:

scala> new A(1)_
<console>:21: error: missing arguments for constructor A in class A
              new A(1)_
              ^

我是否遗漏了一些语法方面的东西?我认为构造函数只是类上的方法,因此在需要时应该将它们提升为函数(很像上面的 apply 方法)

【问题讨论】:

  • 根据你使用它的方式,定义你的构造函数 uncurried 可能更容易,然后使用.curried。见this answer
  • 希望 Scala 的未来版本能够消除这些警告并变得更加一致......

标签: scala currying


【解决方案1】:

在应该创建该类实例的类上调用 new(在您的情况下为 A),但您尝试对 new A(1) _ 执行的操作是为承包商创建一个没有完整数据的 A 类实例,这本质上是不合逻辑的。但是编写A(1) _ 是正确且合乎逻辑的,因为在这种情况下,您将一个方法提升为一个函数(来自伴随对象的apply 方法),该函数已经拥有创建该类实例的所有数据。

【讨论】:

  • new A() 不是在底层调用伴随对象中的 apply 方法吗?
  • 我对此表示怀疑; apply 方法并不总是被定义,即使是这样,它也会在我的情况下导致无限循环,因为我定义 apply 是根据 new A()()()
  • @goral 不,如果你有一个case class,就会调用生成的apply 方法,然后像val inst = CaseClass(params) 这样的东西会调用生成的应用方法,但你也可以调用new CaseClass(params) ,它会简单地调用类承包商。
  • 请注意,您(几乎)可以写成new A(1)(_)(_),因为您正在完全指定构造函数的参数。不幸的是,编译器无法处理它,您需要识别类型,例如new A(1)(_: Int)(_: Int)
  • @DanGetz 哦,整洁。虽然在这种情况下它似乎创建了一个非咖喱函数:scala&gt; new A(1)(_:Int)(_:Int) res41: (Int, Int) =&gt; Script.A = &lt;function2&gt;
猜你喜欢
  • 2012-03-14
  • 2012-12-27
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多