如何覆盖'申请'在具有多个参数列表的函数中?

时间:2016-02-29 23:28:20

标签: scala currying

我试图创建这种类型的函数对象的实例:

trait CanGetSiblingDock[S, D]
  extends (D => String => S => Option[D])

用这个:

implicit val getSiblingDock = new CanGetSiblingDock[Situation, Dock] {
  def apply(dock: Dock)(siblingName: String)(sit: Situation): Option[Dock] = ???
}

编译器对象:

error: object creation impossible, since method apply in trait Function1 of type (v1: FARG.Dock)String => (TestFARGModel4.this.Situation => Option[FARG.Dock]) is not defined
(Note that T1 does not match FARG.Dock)
  implicit val getSiblingDock = new CanGetSiblingDock[Situation, Dock] {
                                    ^

如果我理解正确,编译器会抱怨apply的第一个参数不是Dock类型。但在我看来,它似乎是。

显然,我在某处误解了某些东西。你如何正确地使用多个参数列表创建一个Function的实例?

2 个答案:

答案 0 :(得分:1)

类似的东西:

scala> trait F extends (String => Int => Int)
defined trait F

scala> object X extends F { def apply(s: String): Int => Int = ??? }
defined object X

答案 1 :(得分:1)

A => B => C类型不是Function2[A, B, C]apply方法为def apply(a: A, b: B): C。但相反,这是Function1[A, Function1[B, C]],就像一个curried函数。如果你想要Function2,你必须写:

trait Foo extends Function2[Int, String, Boolean] {
  override def apply(a: Int, b: String): Boolean = ???
}

如果您现在需要多个参数列表,则必须重载apply

trait Foo extends Function2[Int, String, Boolean] {
  override def apply(a: Int, b: String): Boolean = ???

  def apply(a: Int)(b: String): Boolean = apply(a, b)
}

这是不可能的,因为在擦除之后,两种方法在字节码级别上看起来都是一样的。