我用下面的Sieve of Eratosthenes实施来到不工作:Haskell代码排除号码埃拉托色尼的筛预期
sieve :: (Integral a) => [a] -> [a]
sieve [] = []
sieve (p:ps) = p:[x | x <- sieve ps, (rem x p) /= 0]
primes :: (Integral a) => [a]
primes = sieve [2..100]
调用primes
从gchi
打印:
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
添加出发的optimization step标记号码p,我结束了以下代码:
sieve :: (Integral a) => [a] -> [a]
sieve [] = []
sieve (p:ps) = p:[x | x <- sieve ps, x > p^2, (rem x p) /= 0]
primes :: (Integral a) => [a]
primes = sieve [2..100]
但它产生以下输出:
[2]
我是新来的Haskell所以我有问题要理解为什么加入x > p^2
正在产生这样的结果。
您可以通过解释Haskell如何评估表达式来发现我的错误吗?
这不是Eratosthenes的筛子。这是一种[试验分区]形式(http://en.wikipedia.org/wiki/Trial_division),速度很慢。要获得更好的功能筛网,请参阅紧密基于Eratosthenes的[O'Neill筛网](https://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf)。 – dfeuer
我很担心这种实现的缓慢,这就是为什么我要跳过第一个“p^2”数字,但是当我通过答案学习时,它并不是那种方式。感谢您的论文链接。 – higuaro
奥尼尔的实际实施比文中的实施要复杂一点(也好多了)。它在'NumberSieves'包中的[Math.Sieve.ONeill](https://hackage.haskell.org/package/NumberSieves-0.1.1/docs/Math-Sieve-ONeill.html)中。 – dfeuer