最明顯的方法:
type Num = {
def +(a: Num): Num
def *(a: Num): Num
}
def pyth[A <: Num](a: A, b: A)(sqrt: A=>A) = sqrt(a * a + b * b)
// usage
pyth(3, 4)(Math.sqrt)
這是可怕的原因有很多。首先,我們有遞歸類型的問題,Num
。只有在您將-Xrecursive
選項設置爲某個整數值(5對數字來說可能綽綽有餘)的情況下編譯此代碼時,才允許這樣做。其次,類型Num
是結構化的,這意味着它定義的成員的任何用法都將被編譯成相應的反射調用。溫和地說,這個版本的pyth
是低效率的,運行速度比常規實現低幾十萬分之一秒。雖然如果您想要定義pyth
爲任何類型,它定義了+
,*
,並且存在sqrt
函數,但無法繞過結構類型。
最後,我們談到最根本的問題:它太複雜了。爲什麼要用這種方式來實現這個功能呢?實際上,它唯一需要應用的類型是真正的Scala數字。因此,最簡單的做法如下:
def pyth(a: Double, b: Double) = Math.sqrt(a * a + b * b)
所有問題都解決了!由於隱式轉換的奇蹟,此函數可用於Double
,Int
,Float
類型的值,即使是奇怪的類型如Short
。雖然這種功能的確在技術上比我們的結構型版本更不靈活,但它更加高效且顯着更具可讀性。我們可能已經失去了計算定義爲+
和*
的不可預見類型的Pythagrean定理的能力,但我認爲你不會錯過這個能力。
現在我終於知道爲什麼結構類型不會讓我這樣做:http://article.gmane.org/gmane.comp.lang.scala/7013 – 2010-12-02 12:02:20