Haskell - 无法获得下一个最大的素数(无法匹配类型)

时间:2015-11-08 11:13:59

标签: haskell

我有查找素数的函数,然后我想写一个函数,它接受一个数字并返回第一个更大的素数。这是我的方法:

isPrime :: (Integral a) => a -> Bool
isPrime x = and $ foldl (\acc y -> (x `mod` y /= 0):acc) [] [2..round . sqrt . fromIntegral $ (x-1)]

primes = filter isPrime [2..]

getNextPrime :: (Integral a) => a -> a
getNextPrime n = head (dropWhile (<n) primes)

但是当我尝试将其导入GHCI时,我收到此错误:

[1 of 1] Compiling Main             ( a.hs, interpreted )

a.hs:35:39:
    Couldn't match type ‘a’ with ‘Integer’
      ‘a’ is a rigid type variable bound by
          the type signature for getNextPrime :: Integral a => a -> a
          at a.hs:34:17
    Expected type: [a]
      Actual type: [Integer]
    Relevant bindings include
      n :: a (bound at a.hs:35:14)
      getNextPrime :: a -> a (bound at a.hs:35:1)
    In the second argument of ‘dropWhile’, namely ‘primes’
    In the first argument of ‘head’, namely ‘(dropWhile (< n) primes)’
Failed, modules loaded: none.

但是当我尝试插入时:

head (dropWhile (<30) primes)

它按预期返回31,其类型为Integral

我尝试编辑功能类型或明确说明例如n :: Integer但它没有帮助。我相信这将是一些微不足道的事。

由于

1 个答案:

答案 0 :(得分:0)

正如西蒙指出的那样,你需要primes上的类型签名。以下代码

primes :: (Integral a) => [a]
primes = filter isPrime [2..]

编译。 GHC尝试将没有显式多态签名(即(Integral a) => ...)的类型转换为具有单形类型的签名。在您的情况下,GHC决定将[2..]“单形化”为[Integer]。这被称为“dreaded monomorphism restriction”,其中有许多混淆的SO人员发帖。因此,编译代码的另一种方法是添加语言编译指示-XNoMonomorphismRestriction,尽管我强烈建议不要将其用于学习Haskell的人。添加类型签名是这里的方法。