10

クラスのセットが 2 つあり、最初のセットは Foo から継承し、2 番目のセットは Bar から継承するとします。

class Foo
class Baz extends Foo
class Bar
class Qux extends Bar

スコープ内に暗黙的なコンバーター型がある場合、Foo を Bar に変換する汎用の暗黙的な変換関数を作成したいと考えています。

trait Converter[A <: Foo, B <: Bar] {
  def convert(a : A) : B
}

implicit object BazToQuxConverter extends Converter[Baz, Qux] {
  def convert(a : Baz) : Qux = new Qux
}

implicit def FooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, B]) : B = converter.convert(a)

残念ながら、これは私が期待するようには機能していないようです。次の行を REPL に接続すると:

val a : Baz = new Baz
val b : Qux = a

...次のエラーが表示されます。

<console>:17: error: type mismatch;
 found   : Baz
 required: Qux
       val b : Qux = a
                     ^

これを機能させる方法はありますか?私が来ることができた最も近いものは次のとおりです。

implicit def BadFooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, _]) : B = converter.convert(a).asInstanceOf[B]

これは前の例では機能しますが、タイプ セーフではありません。

class Qax extends Bar
val a : Baz = new Baz
val b : Qax = a

これは問題なくコンパイルされますが、Qux(の結果) を( )converter.convert(a)にキャストできないため、実行時に爆発します。理想的には、スコープ内に何もないため、コンパイル時に上記の行がキャッチされるようにしたいと考えています。QaxasInstanceOf[Qax]Converter[Bax,Qax]

4

1 に答える 1

5

これは 2.11 で修正されたバグです。PR 2822以降に修正されたようです。関連するチケットはSI-3346です。

Welcome to Scala version 2.11.0-20131030-090728-c38235fd44 (OpenJDK 64-Bit Server VM, Java 1.7.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> :paste
// Entering paste mode (ctrl-D to finish)

  class Foo
  class Baz extends Foo
  class Bar
  class Qux extends Bar

  trait Converter[A <: Foo, B <: Bar] {
    def convert(a : A) : B
  }

  implicit object BazToQuxConverter extends Converter[Baz, Qux] {
    def convert(a : Baz) : Qux = new Qux
  }

  import scala.language.implicitConversions
  implicit def FooToBar[A <: Foo, B <: Bar](a : A)(implicit converter : Converter[A, B]) : B = converter.convert(a)

  val a : Baz = new Baz
  val b : Qux = a

// Exiting paste mode, now interpreting.

defined class Foo
defined class Baz
defined class Bar
defined class Qux
defined trait Converter
defined object BazToQuxConverter
import scala.language.implicitConversions
FooToBar: [A <: Foo, B <: Bar](a: A)(implicit converter: Converter[A,B])B
a: Baz = Baz@4f4db2ac
b: Qux = Qux@760d62e0
于 2013-11-04T22:58:51.840 に答える