2017-02-13 101 views
0

我有這個類中定義:斯卡拉轉換類型參數爲Double

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 
} 

那裏現在

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

,在另一個類中,我創建對象LinearEquations(假設MLMatrix充滿雙打) :

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

有一些類型的隱式轉換我必須做,但我不知道該怎麼做。構造函數接收一個類型參數,但是當我實例化類時,我傳遞了一個Double。

在此先感謝,

+2

請發佈您的問題[MCVE]。什麼是'y'和'rows',他們在哪裏創建?另外,視圖邊界已被棄用。 –

+0

不少言論並且沒有問題。怎麼樣問一個問題?你有錯誤嗎?問題是什麼? – pedrofurla

+0

如何讀我寫的東西。你沒有看到一個錯誤?值abs不是類型參數的成員T – MLeiria

回答

0

試試這個:

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 
    } 
    } 

它編爲我

+0

這工作,但我正在尋找一個更scala的方式來做到這一點。謝謝 – MLeiria

+0

你可能想看看Spire開源數學項目: https://github.com/non/spire 它有很多很好的通用數學代碼。我自己使用它,並對它感到滿意。 –

2

代碼:

10.0.abs 

工作得益於隱式轉換鍵入RichDoublePredef定義:

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

但是在某些情況下,編譯器不能僅僅處理T,因爲有些原因。

雖然有解決這個問題的方法,例如,類型類:

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 
} 

這可以通過所有可能的T你會使用提供了新的implicits很容易地擴展。

要恢復你可以定義另一個隱含的類的語法:

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

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

這應該是你可能要傳遞到LinearEquations任何數值類型的工作。

+0

這就是我一直在尋找的東西。真棒回答!謝謝。 – MLeiria