コンテキスト暗黙の変換を使用すると無限ループに陥るのはなぜですか?
object Fibonacci {
final val Threshold = 30
def fibonacci(n: Int)(implicit implementation: Fibonacci): Int = implementation match {
case f: functional.type if n > Threshold => fibonacci(n)(imperativeWithLoop)
case f: imperativeWithRecursion.type => f(n)
case f: imperativeWithLoop.type => f(n)
case f: functional.type => f(n)
}
sealed abstract class Fibonacci extends (Int => Int)
object functional extends Fibonacci {
def apply(n: Int): Int =
if (n <= 1) n else apply(n - 1) + apply(n - 2)
}
object imperativeWithRecursion extends Fibonacci {
def apply(n: Int) = {
@scala.annotation.tailrec
def recursion(i: Int, f1: Int, f2: Int): Int =
if (i == n) f2 else recursion(i + 1, f2, f1 + f2)
if (n <= 1) n else recursion(1, 0, 1)
}
}
implicit object imperativeWithLoop extends Fibonacci {
def apply(n: Int) = {
def loop = {
var res = 0
var f1 = 0
var f2 = 1
for (i <- 2 to n) {
res = f1 + f2
f1 = f2
f2 = res
}
res
}
if (n <= 1) n else loop
}
}
}
例
object Main extends App { // or REPL
import Fibonacci._
println(fibonacci(6)(imperativeWithRecursion)) // 8
println(fibonacci(6)(imperativeWithLoop)) // 8
println(fibonacci(6)(functional)) // 8
println(fibonacci(6)) // 8
println(fibonacci(40)(functional)) // 102334155
}
説明 私はスカラ座で遊んと、このコードで終わりました。これは、コンパイルし、実行されますが、...
質問:
1)
case f: functional.type => f(n)
と
case `functional` => functional(n)
との差額(readbility、パフォーマンス、既知のバグ、何が)あります
これはもっと議論の場であると思われるので、私は事実だけに興味がありません。意見は歓迎されます。
2)fibonacci
メソッドの最初の行を見てください。ここでは、次のとおりです。
case f: functional.type if n > Threshold => fibonacci(n)(imperativeWithLoop)
私は2番目のパラメータリスト(imperativeWithLoop)
のままにすると、コードがコンパイルされますが、私はそれを実行すると無限ループに入ります。なぜ誰が知っていますか?デフォルトの実装imperativeWithLoop
はコンパイラに認識されています(エラーは生成されません)。ではなぜ暗黙のうちに呼び出されないのですか? (私はそうではないと仮定します)
Thx、私は今それを得ると思います。このような場合、コンパイラの警告や何かがうまくいくでしょう。 – agilesteel