爲了幫助我學習Haskell,我正在解決Project Euler上的問題。解決了每個問題後,我檢查了我的解決方案與Haskell wiki,試圖學習更好的編碼實踐。這裏是the solution到problem 3:爲什麼這個Haskell代碼片段不是無限遞歸的?
primes = 2 : filter ((==1) . length . primeFactors) [3,5..]
primeFactors n = factor n primes
where
factor n (p:ps)
| p*p > n = [n]
| n `mod` p == 0 = p : factor (n `div` p) (p:ps)
| otherwise = factor n ps
problem_3 = last (primeFactors 317584931803)
我的這個天真的解讀是,primes
中的primeFactors
,這是在primes
定義的定義。因此,評估primeFactors 9
將遵循以下過程:
- 評估
factor 9 primes
。 - 詢問
primes
爲其第一個元素,即2. - 詢問
primes
的下一個元素。 - 作爲此過程的一部分,請評估
primeFactors 3
。 - 詢問
primes
爲其第一個元素,即2. - 詢問
primes
的下一個元素。 - 作爲此過程的一部分,請評估
primeFactors 3
。 - ...
換句話說,步驟2-4將重複無限。很明顯,我錯了,算法終止。我在這裏犯了什麼錯誤?
因爲,如這裏的答案說,'直到素的平方超過被測試的數目primeFactors'只訪問'primes',該代碼相當於'素數= 2:[N |所有((> 0).rem n)$ takeWhile((<= n)。(^ 2))素數]這顯然是非循環的。 –