I’ve read up a little on Manifests and the erasure-avoidance techniques required to allow Scala to do things like “new Array[Array[T]]”, but I’m a little stumped with this one….
I’ve got a method that sort of tabulates up a bunch of rows in an array like a spreadsheet. For example imagine a 2D array like this:
11, 5, 4
8, 3, 7
2, 1, 4
I wrote a method that sums up the columns of that array and spits out a 1D array like [21, 9, 15]
I want to genericize it beyond just Ints (like Doubles or Floats maybe), and when I add a parameter and manifest I get a compile error.
Here’s the code
def sumGrid[T](grid: Array[Array[T]])(implicit m: ClassManifest[T]): Array[T] = {
val sum = new Array[T](grid(0).size)
for(i <- 0 until grid.size) {
for(j <- 0 until grid(0).size) {
sum(j) = sum(j) + grid(i)(j)
}
}
sum
}
Here’s the compile error:
[ERROR] ...scala/euler/GridOperations.scala:126: error: type mismatch;
[INFO] found : T
[INFO] required: String
[INFO] sum(j) = sum(j) + grid(i)(j)
[INFO] ^
[ERROR] one error found
What’s going on here? Why is String “required”?
Because you use the
+operator which is always defined for strings. Any type can be converted to String (toStringis always defined) and thus it will work for any typeT.But you could add some constraints on
Tto ensure it corresponds to the arithmetic operation. For instance, you can use implicits to get aNumericobjects defining the addition for typeT: