因此,我列出了一个质数列表,以帮助我使用简单的尝试除法来学习haskell(在我对语言有所了解之前,不要花哨的东西)。我正在尝试使用以下代码:
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) primes]
加载没有错误。然而:
>take 2 primes
[2ERROR - C stack overflow
我用嵌套列表推导尝试了同样的事情。没用我猜想我要进行太多的递归调用,但是如果我只计算一个素数,那就不应该了。在我看来,懒惰的评估应该做到,这样
take 2 primes
可以执行以下操作:primes = 2 : [ 3 | all (\p -> (mod 3 p) /= 0) [2] ]
哪个不需要那么多的计算-
mod 3 2 == True
,所以all (\p -> (mod 3 p) /= 0) == True
,这意味着take 2 primes == [2, 3]
,对吗?我不明白为什么这行不通。希望更精通函数式编程黑魔法的人可以帮助我...如果有任何区别,这是在HUGS上。
编辑-我能够提出这个解决方案(不是很漂亮):
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) (takeWhile (<= (ceiling (sqrt (fromIntegral x)))) primes)]
EDIT2-通过HUGS或GHCi进行解释时,该程序可以正常工作,但是当我尝试使用GHC进行编译时,它会输出
test: <<loop>>
。有人知道是什么问题吗? 最佳答案
拥抱不应该这样做,但是代码还是被破坏了,所以没关系。考虑:
primes = 2 : [ x | x <- [3..], all (\p -> (mod x p) /= 0) primes]
您如何确定3是否为质数?好吧,
mod 3 2 == 0
?否。mod 3 ??? == 0
吗?糟糕!素数在二之后的下一个元素是什么?我们不知道,我们正在尝试对其进行计算。一旦测试了所有小于x
的p elem
素数,就需要添加一个加3(或其他任何sqrt x
)的排序约束。关于haskell - Haskell递归列表理解导致C堆栈溢出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5199388/