我是Haskell编程的新手,无法理解以下列表理解的扩展方式。
primes = sieve [2..]
sieve (p:xs) = p : sieve [x | x <-xs, x `mod` p /= 0]
有人可以纠正我
sieve
扩展的工作原理:sieve
中进行模式匹配,因此p
将与2
中的x
和[3..]
关联。 x<-3
,但是在没有短路的情况下,如何仅用3
调用筛子。 我不明白的另一件事是递归在这里如何工作。
我认为很明显,如果可以一次扩展上述步骤的前几个数字,直到
5
。 最佳答案
让我们做一些方程式推理。
primes = sieve [2..]
sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]
[2..]
是[2, 3, 4, 5, ...]
的语法糖,因此primes = sieve [2, 3, 4, 5, 6, ...]
内联
sieve
一次:primes = 2 : sieve [x | x <- [3, 4, 5, 6, 7, ...], x `mod` 2 /= 0]
首先,
x
获得值3
,该值通过mod 2
过滤器primes = 2 : sieve (3 : [x | x <- [4, 5, 6, 7, ...], x `mod` 2 /= 0])
再次内联
sieve
(我将x
重命名为y
以避免混淆)primes = 2 : 3 : sieve [y | y <- [x | x <- [4, 5, 6, 7, ...], x `mod` 2 /= 0],
y `mod` 3 /= 0]
现在
x = 4
使mod 2
过滤器失败,但x = 5
通过了它。所以primes = 2 : 3 : sieve [y | y <- 5 : [x | x <- [6, 7, 8, ...], x `mod` 2 /= 0],
y `mod` 3 /= 0]
这个
y = 5
也通过了mod 3
过滤器,所以我们现在有了primes = 2 : 3 : sieve (5 : [y | y <- [x | x <- [6, 7, 8, ...], x `mod` 2 /= 0],
y `mod` 3 /= 0])
再扩展一次
sieve
(用z
代替y
)可以使我们primes = 2 : 3 : 5 : sieve [z | z <- [y | y <- [x | x <- [6, 7, 8, ...],
x `mod` 2 /= 0],
y `mod` 3 /= 0],
z `mod` 5 /= 0]
并且扩展以相同的方式继续进行。