haskell中的素数程序

时间:2014-04-17 13:57:37

标签: haskell

我正在查找Haskell中的程序,该程序测试给定数字是否为素数。

prime :: (Integral a) => a -> Bool
prime 1 = True
prime x = and [ x `mod` y /= 0 | y <- [2..(x-1)] ]

我不明白这个and的目的是什么:prime x = and [

3 个答案:

答案 0 :(得分:3)

虽然这个问题已经得到解答,但请允许我添加一些内容: 在检查and的来源时,您会得到:

and :: [Bool] -> Bool
and = foldr (&&) True

首先要注意的是and获取布尔变量列表,并返回单个布尔变量,并且表达式x mod y /= 0的计算结果为True或False(因此符合[Bool]要求)。

更重要的是要注意foldr是一个懒惰的折叠。因此,这里的惰性折叠是最佳的,因为&&是一个半严格的运算符。因此,与半严格算子组合的惰性折叠将在遇到False的第一次出现时产生短路评估。因此,在实际非素数的情况下,and将避免评估整个列表,从而节省您的时间。不要相信我的话,如果你愿意,可以定义你自己严格的and版本(使用更严格的foldl):

andStrict :: [Bool] -> Bool
andStrict x = foldl (&&) True

primeStrict :: (Integral a) => a -> Bool
primeStrict x = andStrict [x `mod` y /= 0 | y <- [2..(x-1)]]

现在运行:

prime 2000000000

注意那是怎么回事?现在这样做,但在它崩溃你的内存堆栈之前打断它:

primeStrict 2000000000

这显然比较慢,你可以打断它。这是and的作用,这就是为什么and是用foldr编写的,因此为什么会为您发布的示例代码选择它。希望这有助于作为支持性答案。

答案 1 :(得分:2)

and对列表的所有元素执行逻辑和操作。

Primes只能被一个人和他们自己整除;这意味着只要在2和x之间存在除数(没有余数),该数字就不是素数。

列表推导生成一个布尔值列表,对应于您的x是否可被上述范围内的数字整除。

一旦它们中的任何一个是假的(一个除数为零的除法),这个数字就不是素数。

考虑:

x = 7
[7 % 2 /= 0 -> True, 7 % 3 /= -> True, ...]
-- now applying and
True && True && ... && True evaluates to True

and可以表示为可以在列表上执行的更一般的操作 - 使用逻辑和 fold 。例如:and' = foldr (&&) True

答案 2 :(得分:2)

表达式

[x `mod` y /= 0 | y <- [2..(x - 1)]

Bool的列表,因为mod x y /= 0(由于反引号格式化而带有前缀表示法)返回Booland函数只对列表中的每个元素进行逻辑AND,所以

and [True, False] == False
and [True, True] == True