2013-03-19 88 views
2

我在斯卡拉寫了這樣的功能:斯卡拉尾遞歸優化

def isSorted[T](list : List[T])(compare : (T, T) => Boolean) : Boolean = { 
    list match { 
     case Nil => true 
     case x :: Nil => true 
     case x :: rest => !compare(rest.head, x) && isSorted(rest)(compare) 
    } 
} 

我很好奇的編譯器是否優化掉的遞歸調用。遞歸調用只有發生,如果領先的比較成功。如果沒有,是否有辦法提前爆炸並仍然實現尾部遞歸優化?

+4

這就是['@ annotation.tailrec'](http://stackoverflow.com/questions/3114142/what-is-the-scala-註釋到確保尾巴遞歸功能被優化)用於 – 2013-03-19 15:20:23

+0

酷。它似乎被優化。謝謝! – 2013-03-19 15:25:18

+3

需要說明的是,'@ tailrec'不會奇蹟般地使該方法成爲尾遞歸,這使得它不是尾遞歸的錯誤。 – 2013-03-19 15:54:31

回答

3

因此,正如@omnomnom所說,您可以通過將@tailrec註釋添加到該方法來檢查是否有TCO-ed。如果編譯器無法對其進行優化,則會發出錯誤。

我們可以用一個簡單的例子驗證這一點:

@tailrec 
def fact(n : Int) : Int = fact(n - 1) * 2 

編譯器彈出,出現以下錯誤:

test.scala:6: error: could not optimize @tailrec annotated method fact: it contains a recursive call not in tail position

在程序嘗試這一點,但是,答案是...是!所以顯然編譯器很樂意優化你的尾巴呼叫:-)

+3

有趣的定義你有'事實':) – 2013-03-19 19:35:36