2015-01-21 66 views
1

項目歐拉問題7:什麼是10 001號素數?Haskell中索引的類型簽名

這是一個函數,它接受一個參數(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] 

現在,作爲一個很好的哈斯克勒,我想做一個類型的簽名。然而,把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做同樣的事情。此功能的正確類型簽名是什麼?

+0

嘛''!!有型'[一] - > Int - > a'(http://hackage.haskell.org/package/base-4.7.0.2/docs/Prelude.html#v:-33--33-);該索引是固定類型「Int」。因此,你的函數必須具有類型'(Integral a)=> Int - > a'。 – ach 2015-01-21 06:54:30

+2

只要ghci告訴你類型簽名是用':type p007nthPrime' – ErikR 2015-01-21 07:34:56

回答

6

(!!)列表索引操作符只需要Int s左右,而您primes列表包含Integer S,所以你的簽名必須

p007nthPrime :: Int -> Integer 

兩個IntInteger是類型類Integral的,但單一的類型不能同時爲IntInteger

如果你需要的參數也是Integer,我建議使用fromIntegral函數。

否則,要找出什麼類型的簽名給一個函數/值,一個好主意是使用GHCI的:t命令:

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

用'Integer'和其他'Integral'類型索引,Haskell也提供[genericIndex] /base-4.7.0.1/docs/Data-List.html#v:genericIndex)類型'Integral i => [a] - > i - > a'。 – betaveros 2015-01-21 13:53:14