我用下面的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