过去几天我一直在学习Haskell,通过Learn You A Haskell。我一直试图完成一些项目欧拉问题,其中一些需要素数。但是我写的试图生成一些函数(在这种情况下,质数低于20000)的函数输出不正确。当我运行它时,GHCi
会返回'[1,',似乎不会终止。我正在使用的代码是:
sieve :: (Integral a) => a -> [a] -> [a]
sieve 20000 list = list
sieve n (x:xs) = sieve (n+1) $ x:(filter (\q -> q `mod` n /= 0) xs)
primesto20000 = sieve 2 [1..20000]
然后我打电话给primesto20000
。我理解这个函数可能效率低下,我主要是要求我必须提供的语法/过程错误的帮助。
三江源
答案 0 :(得分:2)
您正在过滤每个数字的倍数,而不仅仅是素数。您希望按x
检查可分性,而不是n
。 (事实上,我不确定你在n
函数中是否需要sieve
;只需让你的primesto20000
函数生成相应的输入列表,然后传递它。)
答案 1 :(得分:2)
您的代码中存在两个问题:
[1]
。n
,您希望过滤所有可被n
整除但大于而不是n
的数字。如果没有这个条件,您可以过滤n
本身,结果是过滤掉所有数字。更正的版本可能看起来像(带参数化限制):
limit :: Integral a => a
limit = 20000
sieve :: (Integral a) => a -> [a] -> [a]
sieve n list | n == limit
= list
sieve n (x:xs)
= sieve (n+1) $ x : (filter filt xs)
where
-- filter everything divisible by `n`, but not `n` itself.
filt q = (q <= n) || (q `mod` n /= 0)
primesto20000 = sieve 2 [1..limit]