任意のオブジェクトの2次元行列を実装する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
関数が指定されたセルを設定してから、正しいタイプの新しい行列を返すようにします。したがって、(0,0)を除くすべてのセルでゼロを持つオブジェクトIntMatrix(2).set(0,0,5)
を返すことを期待しています。オブジェクトは5である必要があります。代わりに、実行時に次のエラーが発生します。IntMatrix
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._
どこに置くべきか理解できません。