为了帮助我学习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))素数]这显然是非循环的。 –