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]
时,一切都很好。为什么是这样?是类型推理系统的某种失败吗?
答案 0 :(得分:6)
绝对不是推理系统的失败。它是推理系统的成功。
它观察到(*) :: Num a => a -> a -> a
。它观察到(*)
的第一个参数必须与powers_of
的参数统一起来。它观察到(*)
的结果必须与powers_of
的结果列表的元素类型统一。
这三件事一起说明powers_of
的参数类型必须与结果列表的元素类型相同。
错误消息告诉您它没有任何上下文来证明a
和Integer
是相同的类型,它是函数键入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