Haskell中素数的生成

Haskell中素数的生成,haskell,primes,Haskell,Primes,在过去的几天里,我一直在学习Haskell,通过向您学习Haskell。我一直在尝试完成一些项目Euler问题,其中一些需要素数。然而,我编写的函数试图生成一些(在本例中,素数低于20000)输出不正确。当我运行它时,GHCi返回'[1',,并且似乎没有终止。我使用的代码是: sieve :: (Integral a) => a -> [a] -> [a] sieve 20000 list = list sieve n (x:xs) = sieve (n+1) $ x:(fil

在过去的几天里,我一直在学习Haskell,通过向您学习Haskell。我一直在尝试完成一些项目Euler问题,其中一些需要素数。然而,我编写的函数试图生成一些(在本例中,素数低于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
。我知道这个函数可能效率低下,我主要是就我一定犯过的语法/过程错误寻求帮助。
谢谢你

你过滤掉了每个数字的倍数,而不仅仅是质数。你想用
x
而不是
n
来检查整除性。(事实上,我不确定你是否需要
sieve
函数中的
n
;只要让你的
primesto20000
函数生成适当的输入列表,并传递它即可。)

你过滤掉的是每个数字的倍数,而不仅仅是质数。你想用
x
而不是
n
来检查可除性。(事实上,我不确定您是否需要
sieve
函数中的
n
;只需让您的
primesto20000
函数生成适当的输入列表,然后传递即可。)

您的代码中有两个问题:

  • 因为它的时间复杂性(我猜是二次的),它不能在合理的时间内完成,而且它似乎只是挂起。如果用200替换20000,它将完成,但结果将是
    [1]
  • 另一个问题是,对于每个
    n
    ,您希望过滤所有可被
    n
    整除且大于
    n
    的数字。如果没有此条件,您将过滤
    n
    本身,结果是过滤掉所有数字
更正后的版本可能如下所示(具有参数化限制):

limit::积分a=>a
限额=20000
筛::(积分a)=>a->[a]->[a]
筛n列表| n==极限
=列表
筛n(x:xs)
=筛子(n+1)$x:(过滤器过滤器xs)
哪里
--过滤所有可被'n'整除的内容,但不过滤'n'本身。

filt q=(q代码中有两个问题:

  • 因为它的时间复杂性(我猜是二次的),它不能在合理的时间内完成,而且它似乎只是挂起。如果用200替换20000,它将完成,但结果将是
    [1]
  • 另一个问题是,对于每个
    n
    ,您希望过滤所有可被
    n
    整除且大于
    n
    的数字。如果没有此条件,您将过滤
    n
    本身,结果是过滤掉所有数字
更正后的版本可能如下所示(具有参数化限制):

limit::积分a=>a
限额=20000
筛::(积分a)=>a->[a]->[a]
筛n列表| n==极限
=列表
筛n(x:xs)
=筛子(n+1)$x:(过滤器过滤器xs)
哪里
--过滤所有可被'n'整除的内容,但不过滤'n'本身。

filt q=(q我不确定为什么这个函数似乎没有终止,但我可以理解为什么它只输出1,不是因为你过滤掉了素数及其导数吗?我打算附加素数(即列表中的第一个数字)使用过滤函数之前的x:x,它只作用于列表的其余部分,xs。我该怎么做?@kimitsudesa作为旁注,这不是一个筛子。它只是一个试除法素数生成器。顺便说一句,你可能想检查一下你是否关心后面的性能。你使用的算法比试除法更糟糕。我不确定为什么这个函数似乎没有终止,但我可以理解为什么它只输出1,不是因为你过滤掉了素数及其导数吗?我打算附加素数(即列表中的第一个数字)使用过滤函数之前的x:x,它只作用于列表的其余部分,xs。我该怎么做?@kimitsudesa作为旁注,这不是一个筛子。它只是一个试除法素数生成器。顺便说一句,你可能想检查你是否关心后面的性能。你使用的算法比试除法更糟糕。我刚刚试过使用q
mod
x,它导致函数终止,但只返回[1]尝试将列表
[2..20000]
作为输入传递给它。我认为第一步是过滤掉所有内容。我只是尝试使用q
mod
x,它导致函数终止,但只返回[1]尝试传递列表
[2..20000]
作为输入。我认为第一步是过滤掉所有内容。谢谢,看到Haskell代码的好例子非常有帮助谢谢,看到Haskell代码的好例子非常有帮助
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]