Question

I don't understand why this code is impossible in Scala:

  def getColumns[T <: Array[_]] ():Array[(String,T)] ={
     Array(Tuple2("test",Array(1.0,2.0,3.0)))
  }

Compiler says:

Expression of type Array[(String,Array[Double])] doesn't conform to expected type Array[(String, T)]

I have the same error with this code:

 def getColumns[T <: Array[Double]] ():Array[(String,T)] ={
     Array(Tuple2("test",Array(1.0,2.0,3.0)))
  }

It's more clear with my complete use case, finally I have chosen an Array[AnyVal]:

class SystemError(message: String, nestedException: Throwable) extends Exception(message, nestedException) {
  def this() = this("", null)
  def this(message: String) = this(message, null)
  def this(nestedException : Throwable) = this("", nestedException)
}

class FileDataSource(path:String) {
   val fileCatch = catching(classOf[FileNotFoundException], classOf[IOException]).withApply(e => throw new SystemError(e))

   def getStream():Option[BufferedSource]={
     fileCatch.opt{Source.fromInputStream(getClass.getResourceAsStream(path))}
   }
}

class CSVReader(src:FileDataSource) {

  def lines= src.getStream().get
  val head = lines.getLines.take(1).toList(0).split(",")
  val otherLines = lines.getLines.drop(1).toList

  def getColumns():Array[(String,Array[_])] ={
    val transposeLines = otherLines.map { l => l.split(",").map {
      d => d match {
        case String => d
        case Int => d.toInt
        case Double => d.toDouble
      }}.transpose }

    head zip transposeLines.map {_.toArray}
  }
}

Can you give me some explanation or good links to understand the issues?

Was it helpful?

Solution

Because your function must be able to work with any T (any array type), however, it will always return an Array[(String,Array[Double])].

A simpler working signature would be:

def getColumns[T](): Array[(String,Array[T])]

But in the body of the function you will have to create an array of type T.

OTHER TIPS

Your function signature requires a T in the compound return type, but you give it a Array[Double]. Note that T <: Array[Double], not the other way around. The following code works:

def getColumns[T >: Array[Double]] ():Array[(String,T)] ={
 Array(Tuple2("test",Array(1.0,2.0,3.0)))
}

Shouldn't be what you want but just for elaborating the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top