隐式解析或类型推断的局限性

时间:2013-01-23 23:26:47

标签: scala type-inference implicit-conversion

我试图理解为什么隐式解析(或类型推断)对于以下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")
}

2 个答案:

答案 0 :(得分: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")
}

答案 1 :(得分: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的类型。此外,您无法在Scala中创建类型[A] A => A的值。我真的很惊讶编译器没有推断出A类型是什么,就像你明确调用identityToIdentityWrapper时那样。