我的任务是创建一个素数列表,但仅包含以下信息:
- 列表必须是无限的
- 我必须检查n > 1
的素数
- 如果有一个变量2 <= k < n-2
,它除n
,那么它就不是素数,如果它没有除n
,它就是
- 没有功能!
所以我开始写这样的代码:
primes = [n| n<-[2,3..],k<-[2,3..], if (k>=2) && (k<=(n-2))
then if n `mod` k /= 0 then n else return ()
else return () ]
但后来出现以下错误:“无法将预期类型'Bool'与实际类型匹配”
这是因为return ()
,但我不知道如何替换此return
。
我希望得到帮助。
答案 0 :(得分:3)
假设你有一个功能:
isPrime :: Int -> Bool
返回True表示素数,否则返回False。然后你可以定义:
primes = [ n | n <- [2..], isPrime n ]
使用函数all
,您可以像这样写isPrime
:
isPrime n = all (\a -> mod n a /= 0) [2..n-1]
如果all f xs
应用于f
的每个成员为True,则 xs
会返回True。因此n
对于[2..n-1],mod n a /= 0
中的所有元素都是素数,即a不能除n。
all
函数的更多示例:
all even [2,4,10,12] -- True
all (\x -> x > 0) [4,-5,6] -- False
all (\xs -> length xs > 0) [ [3], [4,5], [-4] ] -- True
all (\x -> x*x < 0) [] -- True
您可以使用标准模板在列表上进行递归来自己提出all
的定义:
all f [] = ...
all f (x:xs) = ...
答案 1 :(得分:0)
它应该 2&lt; = k &lt; = n-2 ,否则4将是素数( &lt; 强>)。
没有函数,可以写成
[n | n<-[2..], []<-[[i | i<-[2..div n 2], rem n i==0]]] -- or, even,
[n | n<-[2..], []<-[[j | i<-[2..n-2], j<-[i*i, i*i+i..n], j==n]]] -- no `i` dividing `n`
最后的代码片段非常引人注目,因为它既是试验分区,也是Eratosthenes的筛子,仅通过添加工作(当通过重新排列和共享重复计算发现并消除计算冗余时成为真正的筛子)。
特别针对您的问题,return
在那里不合适。列表推导中的测试表达式只是Bool
类型的表达式。 False
结果表示拒绝当前生成的值; True
表示接受 - 因此包含在结果列表中。
另一件事是,重复生成的值的重复失败测试意味着无限循环,适用于k
以上n-2
的所有值(由k<-[2..]
生成结束)您的测试(k>=2) && (k<=(n-2))
将始终失败(并导致生成下一个k
,然后生成下一个n-2
,以及下一个... {)。
我们使用[2..n-2]
完全停止k
之后的生成,而不是测试,因此测试条件总是按构造保持 - 并且它会失败,这些值首先,options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });
根本没有生成。