在Haskell中为索引键入签名

时间:2015-01-21 06:46:49

标签: haskell type-signature

项目欧拉问题7:什么是10 001本素数?

这是一个接受单个参数(10001)并返回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会做同样的事情。这个函数的正确类型签名是什么?

1 个答案:

答案 0 :(得分:6)

(!!)列表索引运算符仅需Int秒,而您的primes列表包含Integer s,因此您的签名需要

p007nthPrime :: Int -> Integer

IntInteger都是类Integral的类型,但单个类型不能同时为IntInteger

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

否则,要找出赋予函数/值的类型签名,一个好主意是在GHCi中使用:t命令:

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