2

私は現在持っています:

class X[+T: Numeric](val x: T)
abstract class M[N: Numeric, T <: X[N]] { // <- I'd like to remove N.
  def apply(x: Int): T
  final def row = (1 to 10).map(this(_))
}

私はこのように使用します:

class Y(x: Double, val y: Double) extends X[Double](x)
class Z extends M[Double, Y] {           // <- So that this is simpler.
  def apply(x: Int) = new Y(0.0, 0.0)
}

それはこのように動作します:

object testapp {
  // row is properly polymorphic, allowing access to Y.y
  def main(args: Array[String]): Unit = (new Z).row.map(r => println(r.y))
}

Z次のように使用できるように、よりシンプルにしたいM

class Z extends M[Y] {
  def apply(x: Int) = new Y(0.0, 0.0)
}

または、さらに良い:

class Z extends M[Double] {           // i.e. Meaning apply can return
  def apply(x: Int) = new Y(0.0, 0.0) // any subclass of X[Double]
}

これが、このポイントに到達するための私の要点の反復です。

4

2 に答える 2

2

型パラメーターと型メンバーの 3 番目の方法は、両方を使用することです。

型メンバーの利点は、子クラスのシグネチャを汚染しないことです。型メンバーは、不要な場合 (具象クラスであっても) 抽象のままにすることができます。必要に応じて、下位クラスのみが定義する必要があります。

  import scala.collection.immutable.IndexedSeq
  class X[+T: Numeric](val x: T)
  abstract class M[+A: Numeric] {
    type W <: X[A]
    def apply(x: Int): W
    final def row: IndexedSeq[W] = (1 to 10) map apply
    def sumx: A = {  // in terms of the underlying Numeric
      val n = implicitly[Numeric[A]]
      n fromInt (0 /: row)((s,w) => s + (n toInt w.x))
    }
  }

  class Y(x: Double, val y: Double) extends X[Double](x)
  class Z extends M[Double] {
    type W = Y
    def apply(x: Int) = new Y(0.0, 0.0)
  }

  def main(args: Array[String]): Unit = (new Z).row foreach (Console println _.y)
于 2012-12-16T09:23:47.643 に答える
1

ここでは本当に必要ありませんでしclass Mた:

class X[+T: Numeric](val x: T)
def row[W <: X[_]](c: => Int => W) = (1 to 10).map(c)

class Y(x: Double, val y: Double) extends X[Double](x)
def z = row(_ => new Y(0.0, 0.0))

def main(args: Array[String]): Unit = z.map(r => println(r.y))

を保持したい場合はM、同じアイデアを使用します。

class X[+T: Numeric](val x: T)
abstract class M[W <: X[_]] {
    def apply(x: Int): W
    final def row = (1 to 10).map(this(_))
}

class Y(x: Double, val y: Double) extends X[Double](x)
class Z extends M[Y] {
  def apply(x: Int) = new Y(0.0, 0.0)
}

def main(args: Array[String]): Unit = (new Z).row.map(r => println(r.y))
于 2012-12-16T02:46:41.803 に答える