2

我试图理解为什么以下 Scala 代码的隐式解析(或者可能是类型推断)失败。在此代码中,编译在倒数第二行失败,但在显式提供类型的行的修改版本上成功。

object O {
  trait Wrapper[-A, +B] {
    def func: A => B
  }

  object Identity

  implicit class Identity2Wrapper[A](self: Identity.type) extends Wrapper[A, A] {
    override def func: A => A = identity
  }

  // Compilation fails on the next line with error: 
  // found String("hello") 
  // required: A
  Identity.func("hello")
  // This line compiles.
  implicitly[Identity.type => Wrapper[String, String]].apply(Identity).func("hello")
}
4

2 回答 2

3

Travis Brown 似乎是对的,这是以下情况的发生:https ://issues.scala-lang.org/browse/SI-6472

作为证明,我可以使用 Travis 本人在此处给出的解决方法对其进行编译:https ://issues.scala-lang.org/browse/SI-6776

object O {
  trait Wrapper[-A, +B] {
    val funcFunc: A => B
    def func( arg: A ): B = funcFunc( arg )
  }

  private class Private
  trait BaseWrappable {
    // Dummy method (cannot ever be called, just a work around to help the compiler)
    def func( a: Private ) = ???
  }

  object Identity extends BaseWrappable

  implicit class Identity2Wrapper[A](self: Identity.type) extends Wrapper[A, A] {
    val funcFunc: A => A = identity
  }

  Identity.func("hello")
}
于 2013-01-24T09:04:06.767 回答
0

您编写的代码与以下内容相同:

class Identity2Wrapper[A](self: Identity.type) extends Wrapper[A, A] {
  override def func: A => A = identity
}

implicit def identityToIdentityWrapper[A](self: Identity.type) = new Identity2Wrapper[A](self)

请注意,在func使用调用结果之前,类型参数 A 是未绑定的。Scala 编译器不够聪明,无法向前看并确定 A 的类型。此外,您不能[A] A => A在 Scala 中创建类型的值。实际上,我很惊讶编译器不会将 A 推断为 Nothing 类型,就像您identityToIdentityWrapper显式调用时所做的那样。

于 2013-01-24T09:00:57.317 回答