因此,我列出了一个质数列表,以帮助我使用简单的尝试除法来学习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/

10-08 22:05
查看更多