如果要匹配的类型也采用类型参数

时间:2017-04-15 10:11:34

标签: scala

我想将一系列向量作为矩阵处理。显然,我们需要区分两个案例。它是行向量序列还是列向量序列。但是矢量本身可以是任何分数类型。所以我试过这个:

implicit class MatrixEvent[K: Ordering, V: Fractional, T <: VectorEvent[K, V]](x: Seq[T])(implicit tag: TypeTag[T]) {
    lazy val mx = tag.tpe match {
      case t if t =:= typeOf[ColumnVectorEvent[K, V]] =>
        x.zipWithIndex.foldLeft(new Array2DRowRealMatrix(x(0).vector.getRowDimension, x.length))({case (mx, (vec, idx)) => {
          mx.setColumnVector(idx, vec.vector.getColumnVector(0))
          mx
        }})
      case t if t =:= typeOf[RowVectorEvent[K, V]] =>
        x.zipWithIndex.foldLeft(new Array2DRowRealMatrix(x.length, x(0).vector.getColumnDimension))({case (mx, (vec, idx)) => {
          mx.setRowVector(idx, vec.vector.getRowVector(0))
          mx
        }})
    }
  }

但scala编译器不太喜欢这个:

Error:(52, 29) No TypeTag available for ColumnVectorEvent[K,V]
      case t if t =:= typeOf[ColumnVectorEvent[K, V]] =>

1 个答案:

答案 0 :(得分:2)

我看到你要做的是什么,但是为什么你会在选择隐含时使用运行时逻辑和匹配类型?除非我遗漏了什么。

让我们假设您的ADT看起来像这样:

trait VectorEvent[K, V]
trait ColumnVectorEvent[K, V] extends VectorEvent[K, V]
trait RowEvent[K, V] extends VectorEvent[K, V]
trait Compute[T <: VectorEvent[K, V], K, V] {
  def compute(ev: T): Array2DRowRealMatrix
}

object Compute {
  implicit def rowEventCmp[K, V]: Compute[RowEvent[K, V], K, V]] = {
   new Compute {
     def compute: Array2DRowRealMatrix = {
       x.zipWithIndex.foldLeft(new Array2DRowRealMatrix(x(0).vector.getRowDimension, x.length))({case (mx, (vec, idx)) => {
      mx.setColumnVector(idx, vec.vector.getColumnVector(0))
      mx
    }})
     }
   }
  }
  implict def columnVectorEvent[K, V] = ...
}

最后,您可以利用类型类实例。 Scala将知道默认情况下如何查看Compute的伴随对象以搜索这些含义。

implicit class MatrixEvent[
  K: Ordering,
  V: Fractional,
  T <: VectorEvent[K, V]
](x: Seq[T])(implicit ev: Compute[T, K, V]) {
    lazy val mx = ev.compute
  }