所以我设计了以下函数来查看给定数字是否是Haskell中的素数(假设第一个素数是2):
isPrime k = length [ x | x <- [2..k], k `mod` x == 0)] == 1
即使可以被几个数字整除,它仍然存在继续评估的明显缺陷:(。当找到多个解决方案时,是否有任何理智的
另外,你会尝试哪些其他实现?我不是在这里寻找表现,我只是想看看是否还有其他更“冒险”的做法。
答案 0 :(得分:22)
快速更改代码,使评估“短路”并依赖于Haskell列表的懒惰:
isPrime k = null [ x | x <- [2..k - 1], k `mod` x == 0]
k
的第一个除数将导致列表非空,null
的Haskell实现只会查看列表的第一个元素。
你应该只需要检查sqrt(k)然而[1]:
isPrime k = null [ x | x <- [2..isqrt k], k `mod` x == 0]
当然,如果您希望进行高性能素性测试,首选库。
[1] http://www.codecodex.com/wiki/Calculate_an_integer_square_root#Haskell
答案 1 :(得分:10)
以下是haskell.org中prime numbers in haskell的最佳资源
和prime.hs github项目
答案 2 :(得分:6)
它可能不是直接相关的,但是关于在函数式语言中找到素数的主题,我发现Melissa E. O'Neill的The Genuine Sieve of Eratosthenes非常有趣。
答案 3 :(得分:4)
忽略素数问题,并关注更有效的length xs == n
方法的狭隘观点:
hasLength :: Integral count => [a] -> count -> Bool
_ `hasLength` n | n < 0 = False
[] `hasLength` n = n == 0
(_ : xs) `hasLength` n = xs `hasLength` (pred n)
isPrime k = [ x | x <- [2..k], k `mod` x == 0)] `hasLength` 1
答案 4 :(得分:4)
我喜欢这种方法:
首先使函数得到n的所有因子:
factors n = [x | x <- [1..n], mod n x == 0]
然后检查因子是否只是给定的数字和1,如果是,则数字是素数:
prime n = factors n == [1,n]
答案 5 :(得分:0)
这可能很愚蠢且效率低下(我是一个完整的 Haskell 新手),但是函数 isMyNumberPrime(在 ghci 中)似乎可以告诉您一个数字是否为素数。
factors n = [x | x <- [2..(n`div` 2)], mod n x == 0]
factormap n = fmap factors $ factors n
isMyNumberPrime n = case factormap n of [] -> True; _ -> False