编程 haskell 代码:素数列表
programming haskell code: List of primes
我的任务是创建一个素数列表,但只包含以下信息:
-列表必须是无限的
-我必须检查 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 () ]
但随后出现如下错误:"Couldn't match expected type ‘Bool’ with actual type"
是因为 return ()
,但我不知道如何替换这个 return
。
希望得到帮助。
假设你有一个函数:
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
returns 如果应用于 xs
的每个成员的 f
为真,则为真。所以 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) = ...
应该是2 <= k <= n-2,否则4就是素数(加上<)。
没有函数,可以写成
[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`
最后一个代码片段非常出色,因为它既是试验划分又是仅通过加法工作的埃拉托色尼筛法(当通过重新排列和共享重复计算来发现和消除计算冗余时成为真正的筛法)。
具体针对您的问题,return
不合适。列表理解中的测试表达式只是 Bool
类型的表达式。 False
结果表示拒绝当前生成的值; True
表示接受——因此包含在结果列表中。
另一件事是,重复生成的值的重复测试失败意味着无限循环,当n-2
以上的k
的所有值(由[生成=17=] 没有结束)你的测试 (k>=2) && (k<=(n-2))
将 总是失败 (并导致生成下一个 k
,下一个,再下一个.. .).
我们没有测试,而是在 n-2
之后完全停止生成,使用 [2..n-2]
,因此测试条件始终保持 通过构造 — 并且它是会失败,首先根本不会生成 k
的那些值。
我的任务是创建一个素数列表,但只包含以下信息:
-列表必须是无限的
-我必须检查 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 () ]
但随后出现如下错误:"Couldn't match expected type ‘Bool’ with actual type"
是因为 return ()
,但我不知道如何替换这个 return
。
希望得到帮助。
假设你有一个函数:
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
returns 如果应用于 xs
的每个成员的 f
为真,则为真。所以 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) = ...
应该是2 <= k <= n-2,否则4就是素数(加上<)。
没有函数,可以写成
[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`
最后一个代码片段非常出色,因为它既是试验划分又是仅通过加法工作的埃拉托色尼筛法(当通过重新排列和共享重复计算来发现和消除计算冗余时成为真正的筛法)。
具体针对您的问题,return
不合适。列表理解中的测试表达式只是 Bool
类型的表达式。 False
结果表示拒绝当前生成的值; True
表示接受——因此包含在结果列表中。
另一件事是,重复生成的值的重复测试失败意味着无限循环,当n-2
以上的k
的所有值(由[生成=17=] 没有结束)你的测试 (k>=2) && (k<=(n-2))
将 总是失败 (并导致生成下一个 k
,下一个,再下一个.. .).
我们没有测试,而是在 n-2
之后完全停止生成,使用 [2..n-2]
,因此测试条件始终保持 通过构造 — 并且它是会失败,首先根本不会生成 k
的那些值。