scalascala-breezeabstract-type

Scala Abstract Typing with Tabulate


I am trying to make a generic repVec function similar to Matlab's repmat function using Scala Breeze.

First I tried:

def repVec[T](in: DenseVector[T], nRow: Int): DenseMatrix[T] =
{
    DenseMatrix.tabulate[T](nRow, in.size){case (_, j) => in(j)}
}

but this gave me the error:

Error:(112, 41) No ClassTag available for T
        DenseMatrix.tabulate[T](nRow, in.size){case (_, j) => in(j)}
                                              ^
Error:(112, 41) not enough arguments for method tabulate: (implicit evidence$15: scala.reflect.ClassTag[T], implicit evidence$16: breeze.storage.Zero[T])breeze.linalg.DenseMatrix[T].
Unspecified value parameters evidence$15, evidence$16.
        DenseMatrix.tabulate[T](nRow, in.size){case (_, j) => in(j)}
                                          ^

After doing some reading, particularily here, I tried adding an implicit TypeTag like so:

def repVec[T](in: DenseVector[T], nRow: Int)(implicit tag: TypeTag[T]): DenseMatrix[T] =
{
    DenseMatrix.tabulate[T](nRow, in.size){case (_, j) => in(j)}
}

But I got the same error.

Any thoughts as to what is going on? How is my usage different than this example (from the link) which I can build just fine?

def gratuitousIntermediateMethod[T](list:List[T])(implicit tag :TypeTag[T]) =
    getInnerType(list)

def getInnerType[T](list:List[T])(implicit tag:TypeTag[T]) = tag.tpe.toString

Edit:

Needed ClassTag and Zero, here is the full solution:

def repVec[T:ClassTag:Zero](in: DenseVector[T], nRow: Int): DenseMatrix[T] =
{
    DenseMatrix.tabulate[T](nRow, in.size)({case (_, j) => in(j)})
}

Solution

  • You need to add an implicit ClassTag, not a TypeTag. They're unrelated types (somewhat frustratingly).