Reputation: 623
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
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
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