「名前渡し引数 ≠ lazy だぞー!!! 名前渡しは再計算されるから、間に合わなくなっても知らんぞー!!!」
お題は竹内関数と呼ばれているもの。
Scala2.9にて。
object Main extends App { def tarai(x: => Int, y: => Int, z: => Int): Int = { if (x <= y) y else tarai( tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y) ) } println(tarai( { println("call"); 100 }, { println("call"); 50 }, { println("call"); 0 } )) }
出力
call call call call call /* 略(かなり長い) */ call call call call call 100
こうすればOK。
object Main extends App { def tarai(nx: => Int, ny: => Int, nz: => Int): Int = { lazy val x = nx lazy val y = ny lazy val z = nz if (x <= y) y else tarai( tarai(x - 1, y, z), tarai(y - 1, z, x), tarai(z - 1, x, y) ) } println(tarai( { println("call"); 100 }, { println("call"); 50 }, { println("call"); 0 } )) }
出力
call call call 100