我正在编写一个实现任意对象的二维矩阵的 Scala 类。我需要这个类比嵌套的对象对更专业IndexedSeq
,但是扩展一个集合类是多余的,所以我正在编写自己的。为了从我的矩阵类中的方法返回正确的类型,我使用了隐式构建器习语,但在运行时我得到一个我不明白的“找不到参数的隐式值”错误。
我的矩阵类的精简版本如下所示。
trait MatrixBuilder[V, M <: Matrix[V]] {
def apply(values: IndexedSeq[IndexedSeq[V]]): M
}
abstract class Matrix[V](values: IndexedSeq[IndexedSeq[V]]) extends Function2[Int, Int, V] {
def apply(row: Int, col: Int): V = values(row)(col)
def set[M <: Matrix[V]](row: Int, col: Int, value: V)(implicit builder: MatrixBuilder[V, M]): M =
builder(values.updated(row, values(row).updated(col, value)))
}
case class IntMatrix(values: IndexedSeq[IndexedSeq[Int]]) extends Matrix[Int](values)
object IntMatrix {
def apply(n: Int) = new IntMatrix(IndexedSeq.fill(n, n)(0))
implicit object IntMatrixBuilder extends MatrixBuilder[Int, IntMatrix] {
def apply(values: IndexedSeq[IndexedSeq[Int]]) = IntMatrix(values)
}
}
我希望该set
函数设置指定的单元格,然后返回正确类型的新矩阵。所以我希望IntMatrix(2).set(0,0,5)
返回一个IntMatrix
在除 (0,0) 之外的所有单元格中都为零的对象,它应该有一个 5。相反,我在运行时收到以下错误。
error: could not find implicit value for parameter builder: MatrixBuilder[Int,M]
IntMatrix(2).set(0,0,5)
我在这里做错了什么?
正如pedrofurla在下面指出的那样,如果您首先运行该行,则该代码确实可以在 REPL 中运行import IntMatrix._
。并且查看集合文档,使用构建器的源代码中似乎有类似的导入语句。我尝试在我的IntMatrix
班级中添加一个。
case class IntMatrix(values: IndexedSeq[IndexedSeq[Int]]) extends Matrix[Int](values) {
import IntMatrix._
}
但这没有效果。(事实上,我的 IDE IntelliJ 将此标记为未使用的导入语句。)
为了比较,我从上面逐字链接的集合文档中复制了 RNA 序列示例。该import RNA._
行没有被标记为多余的,并且所有操作都返回正确的类型。如果答案是我需要添加一个import IntMatrix._
,我不知道该放在哪里。