使用Scala的构建器惯用法时,运行时“无法找到参数的隐式值”错误

时间:2013-01-26 23:39:43

标签: scala builder implicit

我正在编写一个实现任意对象的二维矩阵的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._,我无法确定将其放在哪里。

1 个答案:

答案 0 :(得分:1)

这个小代码在这里工作:

scala> import IntMatrix._
import IntMatrix._

scala> IntMatrix(2).set(0,0,5)
res1: Mat.IntMatrix = <function2>

隐式参数由调用站点中的编译器填充,因此它们必须在调用范围set中可用。