在 Haskell 中键入索引的签名

Type signature for index in Haskell

欧拉计划问题七:第10001个素数是多少?

这是一个接受单个参数 (10001) 和 returns 第 10001 个素数的函数。 GHCi 没有给我任何问题:

p007nthPrime x = primes !! (x - 1)
    where
        primes :: [Integer]
        primes = sieve [2..]
            where
                sieve (p:xs) = p : sieve [x|x <- xs, x `mod` p > 0]

现在,作为一个优秀的 Haskeller,我想做一个类型签名。但是,将 p007nthPrime :: (Integral a) => a -> a 放在顶部会引发此错误:

projecteuler.hs:81:29:
    Couldn't match type `Integer' with `Int'
    Expected type: Int
      Actual type: a
    In the first argument of `(-)', namely `x'
    In the second argument of `(!!)', namely `(x - 1)'
    In the expression: primes !! (x - 1)
Failed, modules loaded: none.

和插入 p007nthPrime :: (Num a) => a -> a 做同样的事情。此函数的正确类型签名是什么?

(!!)列表索引运算符只需要Ints,而你的primes列表包含Integers,所以你的签名需要

p007nthPrime :: Int -> Integer

IntInteger都是classIntegral的类型,但一个类型不能同时是IntInteger .

如果你需要参数也是Integer,我建议使用fromIntegral函数。

否则,要找出给 function/value 什么类型的签名,一个好主意是使用 GHCi 中的 :t 命令:

*Main> :t p007nthPrime
p007nthPrime :: Int -> Integer