MLeiria
MLeiria

Reputation: 623

Scala convert type parameter to Double

I have this class defined:

class LinearEquations[T <% Double](var y: MLVector[T],var rows: MLMatrix[T]) {
def largestPivot(p: Int): Int = {
    var pivot = rows(p)(p).abs //Error here: value abs is not a member of type parameter T
    //more code
}

where

type MLMatrix[T] = Array[Array[T]]

Now, in another class I'm creating the object LinearEquations (assume MLMatrix is filled with Doubles):

var rows = new MLMatrix[Double](4)//now fill with Doubles
val le = new LinearEquations(y, rows)

There's some type of implicit conversion I have to do but I'm not sure how to do it. The constructor receives a Type Parameter but when I instanciate the class I pass a Double.

thanks in advance,

Upvotes: 0

Views: 245

Answers (2)

Mateusz Kubuszok
Mateusz Kubuszok

Reputation: 27595

Code:

10.0.abs

works thanks to implicit conversion to type RichDouble defined within Predef:

@inline implicit def doubleWrapper(x: Double)   = new runtime.RichDouble(x)

However compiler cannot just treat T like Double in some cases because of reasons.

There are solutions to this problem though, e.g. type classes:

trait MathsOps[T] {

  def abs(num: T): T
}

implicit object DoubleOps extends MathOps[Double] {
   def abs(num: Double) = num.abs
}

class LinearEquations[T : MathsOps](var y: MLVector[T], var rows: MLMatrix[T]) {
def largestPivot(p: Int): Int = {
    var pivot = implicitly[MathOps[T]].abs(rows(p)(p))
    //more code
}

This could be easily extended by providing new implicits for all possible T you'd use.

To restore the syntax you could define another implicit class:

implicit class RichMathSyntax[T : MathOps](value: T) {

  def abs = implicitly[MathOps[T]].abs(value)
}

This should work for any numeric type that you might want to pass into LinearEquations.

Upvotes: 2

Sami Badawi
Sami Badawi

Reputation: 1032

Try this:

  class LinearEquations[T <% Double](var y: Array[Array[T]], var rows: Array[Array[T]]) {
    def largestPivot(p: Int): Int = {
      var pivot = rows(p)(p) //Error here: value abs is not a member of type parameter T
      val res: Double = scala.math.abs(pivot)
      //more code
      0
    }
  }

It compiled for me

Upvotes: 0

Related Questions