只是玩延續。目標是創建將接收另一個函數作爲參數的函數,以及執行量 - 和將應用參數給定次數的返回函數。爲什麼scala不會進行尾部呼叫優化?
實現看起來相當明顯
def n_times[T](func:T=>T,count:Int):T=>T = {
@tailrec
def n_times_cont(cnt:Int, continuation:T=>T):T=>T= cnt match {
case _ if cnt < 1 => throw new IllegalArgumentException(s"count was wrong $count")
case 1 => continuation
case _ => n_times_cont(cnt-1,i=>continuation(func(i)))
}
n_times_cont(count, func)
}
def inc (x:Int) = x+1
val res1 = n_times(inc,1000)(1) // Works OK, returns 1001
val res = n_times(inc,10000000)(1) // FAILS
但有沒有問題 - 這個代碼失敗,StackOverflow的錯誤。爲什麼這裏沒有tail-call優化?
我在Eclipse中使用Scala的插件運行它,它在scala.runtime.BoxesRunTime.boxToInteger(來源不明) 在Task_Mult $$ anonfun $ 1返回螺紋 異常 「主要」 java.lang.StackOverflowError的 .Apply(Task_Mult.scala:25) at Task_Mult $$ anonfun $ n_times_cont $ 1 $ 1.apply(Task_Mult.scala:18)
ps
F#代碼,這幾乎是直接翻譯,工作沒有任何問題
let n_times_cnt func count =
let rec n_times_impl count' continuation =
match count' with
| _ when count'<1 -> failwith "wrong count"
| 1 -> continuation
| _ -> n_times_impl (count'-1) (func >> continuation)
n_times_impl count func
let inc x = x+1
let res = (n_times_cnt inc 10000000) 1
printfn "%o" res
的可能重複(http://stackoverflow.com/questions/105834/does -the-jvm-prevent-tail-call-optimizations) – 2013-05-14 09:29:05