0

特定のインターフェイスを実装するすべてのクラスで機能する型パラメーター化メソッドの一般的な、おそらく遅い実装を持つコードを記述したいと思いますが、必要に応じて、サブクラスがこのメソッドをより効率的な実装で特殊化できるようにします。

ただし、次のコードはまったく機能しません

class A(val i:Int)

class B {
    def f[T](t:T) = println(t.toString)
}

class C extends B { 
    override def f[A](a:A) = println(a.i * a.i) 
}

クラス C の A を、型パラメーターが A のみの場合に関数をオーバーライドするものとしてではなく、型パラメーターとして扱うためです。

実行時に一致を使用せずに必要なコードを記述する方法はありますか?

4

1 に答える 1

0

あなたがしようとしているのはこれです:

scala> class A(val i: Int)
defined class A

scala> class B { 
     |   def f[T](t: T) = println(t.toString)
     | }
defined class B

scala> class C extends B { 
     |   override def f[T <: A](a: T) = println(a.i * a.i) 
     | }
<console>:10: error: overriding method f in class B of type [T](t: T)Unit;
 method f has incompatible type
         override def f[T <: A](a: T) = println(a.i * a.i) 

しかし、型システムが言うように、これは間違っています。ここでは、リスコフの置換原則に違反しています。

代わりにできることはT、クラスレベルの型パラメーターまたは抽象型のメンバーを作成することです。次に、以下に示すように、サブクラスでそれを制約できます。

scala> class B {
     |   type T
     |   def f(t: T) = println(t.toString)
     | }
defined class B

scala> class C extends B {
     |   type T = A
     |   override def f(a: T) = println(a.i * a.i)
     | }
defined class C

scala> (new C).f(new A(11))
121

あなたはそれ以上の情報を提供していないので、これがあなたの特定のケースでうまくいくかどうかはわかりません。

編集:

物事を具体化する1つの方法は、型クラスを使用することです。コード:(これは予想よりも複雑であることが判明しました。)

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

case class A(i: Int)

case object B

trait F[-A] {
  def f(a: A): Unit
}

trait FLowPriorityImplicits {
  implicit object FAny extends F[Any] {
    def f(a: Any) = println(a.toString)
  }
}

trait FImplicits extends FLowPriorityImplicits {
  implicit object FA extends F[A] {
    def f(a: A) = println(a.i * a.i)
  }
}

object F extends FImplicits

def f[A](x: A)(implicit f: F[A]) = f.f(x)

// Exiting paste mode, now interpreting.

defined class A
defined module B
defined trait F
defined trait FLowPriorityImplicits
defined trait FImplicits
defined module F
f: [A](x: A)(implicit f: F[A])Unit

scala> f(B)
B

scala> f(A(2))
4
于 2012-10-28T10:49:37.827 に答える