我有这个功能:
generatePrimes :: Integral a => a -> [a]
generatePrimes n = [i | i <- [2..], isPrime i]
我正在尝试获得第一个 n 素数。我知道我可以使用main
函数调用take
中的函数(并获取列表的第一个 n 元素),但我希望能够拥有当函数到达 n primes(函数内部)时,函数停止,以便在main
中调用它时,例如:
generatePrimes 8
它将显示仅包含前8个素数的列表。
答案 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是第一个素数。