Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 递归函数中的中间结果_Haskell - Fatal编程技术网

Haskell 递归函数中的中间结果

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] =

我想写一个函数,它能找到从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] = 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)