私が遭遇したプログラミングの問題の 1 つは、大きな数 (10^5 までの数) の階乗の計算に関係しています。このような単純なHaskellコードを見てきました
factorial :: (Eq x, Num x) => x -> x
factorial 0 = 1
factorial a = a * factorial (a - 1)
これは巨大な数を暗黙的に処理し、コードに関与するキャッシュがなくても何らかの形で高速に実行されます。
Javaを使用して問題を解決しようとしたとき、BigIntegerを使用して膨大な数を保持し、階乗の反復バージョンも使用する必要がありました
public static BigInteger factorialIterative(int n)
{
if(n == 0 || n == 1) return BigInteger.valueOf(1);
BigInteger f = BigInteger.valueOf(1);
for(int i = 1 ; i <= n ;i++)
f = f.multiply(BigInteger.valueOf(i));
return f;
}
上記のコードは、プログラムの設定された実行時間制限を超えました。factorial のキャッシュされた再帰バージョンも試しました
public static BigInteger factorial(int n)
{
if(cache[n] != null)
return cache[n];
else if(n == 0)
return new BigInteger("1");
else {
cache[n] = n* factorial(n - 1);
return cache[n];
}
}
これにより、メモリ不足エラーが発生しました(おそらく再帰が原因です)。
私の質問は、Haskell のような関数型プログラミング言語が、巨大な数が関係するこの種の問題を処理するのに優れているのはなぜですか? (明らかなキャッシュはありませんが)。Java コードを Haskell コードと同じくらい速く実行する方法はありますか?