Haskell - 无法在无限序列中推导出(a~Integer)

时间:2014-05-21 21:27:06

标签: haskell

powers_of :: (Integral a) => a -> [Integer]
powers_of n = sequence
where
    sequence = 1 : next sequence
    next (first : rest) = (n * first) : next rest

这让我:

Could not deduce (a ~ Integer)
from the context (Integral a)
  bound by the type signature for
             powers_of :: Integral a => a -> [Integer]
  at Triangle.hs:(10,1)-(13,61)
  `a' is a rigid type variable bound by
      the type signature for powers_of :: Integral a => a -> [Integer]
      at Triangle.hs:10:1
Expected type: [Integer]
  Actual type: [a]
In the expression: sequence
In an equation for `powers_of':
    powers_of n
      = sequence
      where
          sequence = 1 : next sequence
          next (first : rest) = (n * first) : next rest

当我摆脱Integral类型类并使签名只是Integer -> [Integer]时,一切都很好。为什么是这样?是类型推理系统的某种失败吗?

2 个答案:

答案 0 :(得分:6)

绝对不是推理系统的失败。它是推理系统的成功。

它观察到(*) :: Num a => a -> a -> a。它观察到(*)的第一个参数必须与powers_of的参数统一起来。它观察到(*)的结果必须与powers_of的结果列表的元素类型统一。

这三件事一起说明powers_of的参数类型必须与结果列表的元素类型相同。

错误消息告诉您它没有任何上下文来证明aInteger是相同的类型,它是函数键入check所需的类型。 / p>

答案 1 :(得分:3)

您的类型签名应为:

powers_of :: (Integral a) => a -> [a]

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

1的类型为Num a => a(*)Num a => a -> a -> a,因此您可以提供任何Num实例并生成该类型的列表。

无法将Num的实例隐式转换为Integer。如果需要,您可以明确地这样做:

powers_of :: (Integral a) => a -> [Integer]
powers_of n = sequence
  where
    sequence = 1 : next sequence
    next (first : rest) = ((fromIntegral n) * first) : next rest