最近のSOの質問で述べたように、私はプロジェクトオイラーの問題を経験してF#を学んでいます。
私は今、次のように見える問題3に対する機能的な答えを持っています:
let rec findLargestPrimeFactor p n =
if n = 1L then p
else
if n % p = 0L then findLargestPrimeFactor p (n/p)
else findLargestPrimeFactor (p + 2L) n
let result = findLargestPrimeFactor 3L 600851475143L
ただし、への異なる呼び出しにつながる可能性のある実行パスが2つあるfindLargestPrimeFactor
ため、末尾再帰用に最適化できるかどうかはわかりません。だから私は代わりにこれを思いついた:
let rec findLargestPrimeFactor p n =
if n = 1L then p
else
let (p', n') = if n % p = 0L then (p, (n/p)) else (p + 2L, n)
findLargestPrimeFactor p' n'
let result = findLargestPrimeFactor 3L 600851475143L
への末尾呼び出しにつながるパスは1つしかないためfindLargestPrimeFactor
、実際に末尾再帰用に最適化されると思います。
だから私の質問:
- 2つの異なる再帰呼び出しがある場合でも、最初の実装を末尾再帰用に最適化できますか?
- 両方のバージョンを末尾再帰用に最適化できる場合、一方が他方よりも優れている(より「機能的」、高速など)のでしょうか。