我正在编写一个实现任意对象的二维矩阵的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)
在除了(0,0)之外的所有单元格中都返回一个带有零的IntMatrix
对象,它应该有一个5.而不是我在运行时得到以下错误。
error: could not find implicit value for parameter builder: MatrixBuilder[Int,M]
IntMatrix(2).set(0,0,5)
我在这里做错了什么?
如下面pedrofurla所述,如果您首先运行第import IntMatrix._
行,则代码在REPL中有效。查看collections documentation,使用构建器在源代码中似乎有类似的import语句。我尝试在我的IntMatrix
课程中添加一个。
case class IntMatrix(values: IndexedSeq[IndexedSeq[Int]]) extends Matrix[Int](values) {
import IntMatrix._
}
但这没有效果。 (事实上,我的IDE IntelliJ将此标记为未使用的import语句。)
为了进行比较,我从上面逐字链接的集合文档中复制了RNA序列示例。那里import RNA._
行没有标记为多余,所有操作都返回正确的类型。如果答案是我需要添加import IntMatrix._
,我无法确定将其放在哪里。
答案 0 :(得分:1)
这个小代码在这里工作:
scala> import IntMatrix._
import IntMatrix._
scala> IntMatrix(2).set(0,0,5)
res1: Mat.IntMatrix = <function2>
隐式参数由调用站点中的编译器填充,因此它们必须在调用范围set
中可用。