Haskell'任何'功能 - 素性检查

时间:2011-12-17 22:41:47

标签: haskell

我正在尝试在Haskell中定义is_prime函数。任何人都可以指出使用任何功能的问题?

另外,我知道下面的代码是天真的,但我正在学习语言,所以从babysteps开始。

is_prime 0 = False
is_prime 1 = False
is_prime 2 = True
is_prime n = any [n `mod` k == 0 | k <- [2.. sqrt n]]

2 个答案:

答案 0 :(得分:7)

any的类型为(a -> Bool) -> [a] -> Bool,因此它接受谓词和集合。所以你应该重写你的最后一个案例,例如

is_prime n = not $ any (\k -> n `mod` k /= 0)
                       [2 .. ceiling $ sqrt $ fromIntegral n]

fromIntegral是必要的,因为sqrt的类型为Floating a => a -> an是整数。随后,如果没有ceiling,则any的第二个参数将为Floating t => [t]。这会破坏,因为在非整数类型上调用类型为mod的{​​{1}}是非法的。

如果你想寻找其他一些实现,我可以推荐例如this discussion

答案 1 :(得分:0)

在我看来,接受的答案是错误的,因为如果is_prime是素数,False函数实际返回n,这就是原因。

  1. any function data一旦遇到True data function data中的此类元素,就会返回True
  2. \k -> mod n k /= 0如果应用于除以某个常量True的数字,则返回n
  3. 因此,any会返回True如果给定列表中有一个数字除以我们要检查的素数n的数字如果,则False
  4. 因此,is_prime会返回True以查看 可以被列表[2 .. ceiling $ sqrt $ fromIntegral n]中的任何数字整除的任何数字,例如,4显然不是是素数。
  5. 话虽如此,正确的解决方案应如下所示:

    is_prime n = not $ any (\k -> n `mod` k == 0) [2 .. ceiling $ sqrt $ fromIntegral n]
    

    这是因为如果不是是2和n之间任意数字的倍数,则sqrt n为素数。