中间产生递归函数

时间:2016-01-02 12:00:37

标签: haskell

我正在尝试编写一个能找到2到100之间所有素数的函数。我可以通过查看数字{@ 1}}除以所有数字时的余数来测试数字是否为素数在n

然而,我只想测试我已经找到的素数。这是我编写递归函数的程度,但我不知道如何用我已经计算出的素数代替2..n-1(我猜测我的递归函数的中间结果)。我怎么能这样做?

[2..t-1]

2 个答案:

答案 0 :(得分:6)

这是一种可能的方式:

primes = 2 : go [3..]
    where
        go (t:ts)
            | all (\x -> t `rem` x /= 0) (takeWhile (\x->x*x<=t) primes)  = t:(go ts)
            | otherwise = go ts

在这里,我们使用primes的已计算部分,直到t的平方根。请注意,我们不需要在primes中指定上限,它只会生成一个无限列表,您可以在以后进行切割:

print $ take 1000 primes

另请注意,我们需要引导primes,以便不会从先前的素数计算第一个素数,以便takeWhile可以工作。

答案 1 :(得分:3)

你可以用尾递归来做到这一点。你携带已计算的素数ps的地方。

primes = go [2..100] []
    where go (t:ts) ps
            | all (\x -> (t `rem` x) /= 0) ps = go ts (t:ps)
            | otherwise = go ts ps
          go [] ps = ps

请注意,素数现在已反转。连接它们比附加它更快。

您还可以限制分割数量:

| all (\x -> (t `rem` x) /= 0) (takeWhile (\x -> x*x <= t) ps) = go ts (t:ps)

如果速度很重要,也可以使用Int,因为它是未装箱的。