生成First n Primes(Haskell)

时间:2016-03-02 18:03:24

标签: list haskell primes lazy-evaluation counting

我有这个功能:

generatePrimes :: Integral a => a -> [a]
generatePrimes n = [i | i <- [2..], isPrime i]

我正在尝试获得第一个 n 素数。我知道我可以使用main函数调用take中的函数(并获取列表的第一个 n 元素),但我希望能够拥有当函数到达 n primes(函数内部)时,函数停止,以便在main中调用它时,例如:

generatePrimes 8

它将显示仅包含前8个素数的列表。

2 个答案:

答案 0 :(得分:4)

您所提问题的答案只是将take移至generatePrimes的定义中,因此:

generatePrimes :: Integral a => Int -> [a]
generatePrimes n = take n [i | i <- [2..], isPrime i]

如果您保留与问题中完全相同的类型签名非常重要,则可以使用take中提供的Data.List的更多多态版本:

import Data.List
generatePrimes :: Integral a => a -> [a]
generatePrimes n = genericTake n [i | i <- [2..], isPrime i]

(实际上,此实现具有更通用的类型generatePrimes :: (Integral a, Integral i) => i -> [a]。)

然而,这是anti-modular in the presence of lazy evaluation;你应该控制消费者而不是生产者消费了多少清单。

答案 1 :(得分:0)

打印第一个 n 个质数的另一种实现可以通过模式匹配来完成。给定一个输入范围为 2 n 的列表,函数 isPrime 返回所有为质数的值。

isPrime [p] = if null ([x | x <- [2.. p - 1], mod p x == 0])
              then show p 
              else ""

isPrime (p:ps) = if null ([x | x <- [2.. p - 1], mod p x == 0])
                 then show p ++ ", " ++ isPrime(ps)
                 else "" ++ isPrime(ps)

要执行第一个 n 个数字,我们可以使用范围,只需键入:isPrime[2..n]。我们认为2是第一个素数。