scala - 如何删除这个额外的类型参数?

标签 scala generics covariance

我目前有:

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]
}

Here are my Gist iterations达到这一点。

最佳答案

类型参数与类型成员的第三种方法是同时使用两者。

类型成员的优点是它不会污染子类的签名。如果类型成员是多余的(即使在具体类中),则可以保持抽象;如果需要,只有底层必须定义它。

  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)

关于scala - 如何删除这个额外的类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13897885/

相关文章:

scala - Maps 中的 "get"方法是否具有 Scala 中的默认值?

class - 在 Scala final case 类中使用 new

scala - 逆变为何是子类型?

具有多个接口(interface)转换的 Java 通用对象

Python Sklearn 协方差矩阵对角线条目不正确?

scala - 使用 dataframe : Collect return empty array 进行 Spark 单元测试

c# - 如何在 C# 中使用动态键创建列表字典

C# InvalidCastException 尽管基类相同

c++ - C++函数指针中的协变和逆变?

C++ 协方差意外行为