2

次のScalaコードで暗黙の解決(またはおそらく型推論)が失敗する理由を理解しようとしています。このコードでは、コンパイルは最後から2行目で失敗しますが、型が明示的に指定されている行の変更バージョンでは成功します。

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)

呼び出しの結果が使用されるまで、型パラメーターAはバインドされていないことに注意してくださいfunc[A] A => AScalaコンパイラーは、それをはるかに先取りしてAのタイプを判別するほど賢くはありません。また、 Scalaでtypeの値を作成することはできません。コンパイラがAをタイプNoと推測しないことに実際に驚いていますidentityToIdentityWrapper。明示的に呼び出す場合とは異なります。

于 2013-01-24T09:00:57.317 に答える