如何将Num类型类的成员视为Int

时间:2016-06-12 18:44:44

标签: haskell

这是我想写的一个功能:

missingNumber :: (Num a) => [a] -> a
missingNumber list = (sum refList) - (sum list)
  where refList = [1..n]
        n = length list

给出一个数字列表,我想总结它们并将它们与已知列表进行比较,看看是否有任何遗漏。这段代码看起来很简单,但是当我运行它时,我得到了这个(相当冗长的)错误:

Could not deduce (a ~ Int)
from the context (Num a)
  bound by the type signature for missingNumber :: Num a => [a] -> a
  at missingnumber.hs:1:18-36
  `a' is a rigid type variable bound by
      the type signature for missingNumber :: Num a => [a] -> a
      at missingnumber.hs:1:18
Expected type: [a]
  Actual type: [Int]
In the first argument of `sum', namely `refList'
In the first argument of `(-)', namely `(sum refList)'
In the expression: (sum refList) - (sum list)

我猜这种情况正在发生,因为n中的[1..n]必须是Enum类型类的实例,才能按顺序迭代。但是(假设我是正确的),我如何将a转换为两种类型?另外......不应该Int成为Num班的成员吗?

1 个答案:

答案 0 :(得分:1)

正如你所说,这应该有效:

missing :: (Num a, Foldable t) => t a -> a
missing xs = fromIntegral (sum [1..length xs + 1]) - sum xs

但仅当您的某些[1..m]

m中的数字列表中缺少一个数字时

您的版本无效,因为您声称

missingNumber :: (Num a) => [a] -> a

然后它需要适用于所有Num a - 例如Double - 但是您会将IntDouble混合(例如) - 这是您无法做到的

fromIntegral会将您保存在此处,因为它会将您的Int带回您可能拥有的任何Num afromIntegral :: (Integral c, Num d) => c -> d - 这里有c ~ Int并且d ~ a - 其中~表示类型相等)