Haskell 递归函数中的中间结果
我想写一个函数,它能找到从2到100的所有素数。当一个数Haskell 递归函数中的中间结果,haskell,Haskell,我想写一个函数,它能找到从2到100的所有素数。当一个数n除以2..n-1中的所有数时,我可以通过查看余数来测试一个数是否为素数 然而,我只想测试我已经找到的素数。这就是我编写递归函数的过程,但我不知道如何用我已经计算出的素数替换[2..t-1](我猜是递归函数的中间结果)。我该怎么做 primes = go [2..100] where go l@(t:ts) | all (\x -> t `rem` x /= 0) [2..t-1] =
n
除以2..n-1
中的所有数时,我可以通过查看余数来测试一个数是否为素数
然而,我只想测试我已经找到的素数。这就是我编写递归函数的过程,但我不知道如何用我已经计算出的素数替换[2..t-1]
(我猜是递归函数的中间结果)。我该怎么做
primes = go [2..100]
where
go l@(t:ts)
| all (\x -> t `rem` x /= 0) [2..t-1] = t:(go ts)
| otherwise = go ts
go [] = []
main = print primes
这里有一种可能的方法:
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
还要注意,我们需要引导
素数
,这样第一个素数就不会从以前的素数中计算出来,这样takeWhile
就可以工作了。您可以通过尾部递归来实现这一点。您可以随身携带已计算的素数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)
| all(\x->(t`rem`x)/=0)(takeWhile(\x->x*x)我的一次尝试几乎是一样的,但我不断得到发生检查:无法构造无限类型:a1~[a1]
错误。唯一的区别是你在t:ps
周围有。()
成功了!非常感谢!我想Haskell会记住已经用素数计算过的素数,这样你就可以不重新计算而直接求平方根了?@TomTom是的,没错。
| all (\x -> (t `rem` x) /= 0) (takeWhile (\x -> x*x <= t) ps) = go ts (t:ps)