primes
只是一个列表。它的第一个元素是 2,其余元素取自(部分)函数过滤的奇数列表primeFactors
。
primeFactors
,但是,使用primes
. 这不是循环吗?
不完全的。因为 Haskell 是懒惰的,primeFactors
不需要primes
一次所有的值,只需要小于或等于其参数平方根的值(p:ps
匹配反对primes
,但我们只需要ps
if p*p <= n
),并且这些素数都是由以前调用primeFactors
.
例如,跟踪对 的前几次调用primeFactors
。为简洁起见,让b = (==1) . length . primeFactors
.
primeFactors 3 == factor 3 primes
-- only unpack as much of primes as we need for the next step
== factor 3 (2:filter b [3,5..])
-- because 2*2 > 3, that's only one level
== [3]
因此,既然b [3]
是真的,我们知道 3 是 的下一个元素primes
。那是,primes = 2:3:filter b [5,7..]
primeFactors 5 == factor 5 primes
== factor 5 (2:3:filter b [3,5..])
-- 2*2 > 5 is false, as is 5 `mod` 2 == 0, so
== factor 5 (3:filter b [3,5..])
-- 3*3 > 5, so
== [5]
并且b [5]
是真的,5
的下一个元素也是如此primes
。
primeFactors 7 == factor 7 primes
== factor 7 (2:3:5:filter b [3,5..])
== factor 7 (3:5:filter b [3,5..])
-- 3*3 > 7
== [7]
并且b [7]
是真的,7
的下一个元素也是如此primes
。(似乎所有内容都添加到了primes
,不是吗?再打一次电话primeFactors
将表明情况并非如此)
primeFactors 9 == factor 9 primes
== factor 9 (2:3:5:7:filter b [3,5..])
-- 2*2 > 9 and 9 `mod` 2 == 0 are false
== factor 9 (3:5:7:filter b [3,5..])
-- 3*3 > 9 is false, but 9 `mod` 3 == 0 is true, so
== 3 : factor (9 `div` 3) (3:5:7:filter b [3,5..])
== 3 : factor 3 (3:5:7:filter b [3,5..])
-- 3*3 > 3 is false, but 3 `mod` 3 == 0, so
== 3 : [3] == [3,3]
但是因为b [3,3]
是假的,9
所以不是的元素primes
。所以现在我们有
primes = 2:3:5:7:filter b [3,5..])
追踪这一点是一个漫长而乏味的过程,但你应该有一种primes
始终保持“领先”的感觉primeFactors
;primes
这种需求的要素primeFactors
总是由较早的对primeFactors
.