2013-06-22 48 views
4

我有一個重載的方法定義如下:斯卡拉超載高階函數會導致錯誤類型

def g(f:() ⇒ Double): Object = null 
def g(f: Double ⇒ Double): Object = null 
def g(f: (Double, Double) ⇒ Double): Object = null 

def h(f: (Double, Double) ⇒ Double): Object = null 

雖然h(math.max _)作品如預期,稱g(math.max _) 給我的錯誤「重載方法......不能應用到((Int,Int)=> Int)「。看來編譯器選擇了Int版本math.max而不是Double版本。

如何以math.max作爲參數調用我的重載方法g?如果沒有下劃線,我可以致電g(math.max),這將是額外的好處。

回答

3

您已經遇到了編譯器使用的啓發式,以避免類型的指數級複雜搜索。當方法被重載時,它會根據參數的類型嘗試消除歧義。不幸的是,參數也是重載。它沒有嘗試可能性,而是抓住了想到的第一個,但它不起作用。

您可以通過提出正確的方式誘騙到搜索更多:

g(math.max(_,_)) 

Notationally它現在清楚的是,它在尋找一個Function2和編譯器 - 即使的max所有版本必須Function2 ! - 足以讓編譯器搜索匹配項(並且它與DoubleDouble匹配)。

1

紀要公佈之後,我發現這個解決方案:

g(math.max: ((Double, Double) => Double)) 

我仍然好奇,爲什麼Scala有在第一種情況下的問題。

+0

正如Rex指出的,'max'是一種重載方法,有四種選擇。顯然只有最大值(Double,Double)有效,但推理者不夠聰明。 – pedrofurla