【问题标题】:Type signature for index in HaskellHaskell中索引的类型签名
【发布时间】:2015-01-21 06:46:49
【问题描述】:

欧拉计划第 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) =&gt; a -&gt; 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) =&gt; a -&gt; a 做同样的事情。这个函数的正确类型签名是什么?

【问题讨论】:

  • 好吧,!! 的类型为 [a] -&gt; Int -&gt; a (hackage.haskell.org/package/base-4.7.0.2/docs/…);索引是固定类型Int。因此,您的函数必须具有 (Integral a) =&gt; Int -&gt; a 类型。
  • 让 ghci 告诉你 :type p007nthPrime 的类型签名是什么

标签: haskell type-signature


【解决方案1】:

(!!) 列表索引运算符只需要Ints,而您的primes 列表包含Integers,因此您的签名需要是

p007nthPrime :: Int -> Integer

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

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

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

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

【讨论】:

  • 对于Integers 和其他Integral 类型的索引,Haskell 还提供genericIndex 类型为Integral i =&gt; [a] -&gt; i -&gt; a
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-22
  • 2016-01-01
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 2014-04-15
  • 1970-01-01
相关资源
最近更新 更多