我有一个简单的函数,并得到如下所示的编译错误:
fac::[int] -> int
fac [] = 0
fac (x:[]) = x
fac ([xs]) = sum [xs]
编译错误:
No instance for (Num int) arising from the literal `0'
Possible fix:
add (Num int) to the context of
the type signature for fac :: [int] -> int
In the expression: 0
In an equation for `fac': fac [] = 0
代码有什么问题?
答案 0 :(得分:12)
类型签名错误。 int
(小写i
)是一个“类型变量”,这意味着此函数应该是任何类型[sometype] -> sometype
的多态。相反,您可能希望Int
(大写I
)引用一个位长的有符号整数,这取决于您的编译器和平台。
另一个问题,一个常见的错误,是最后一个模式永远不会匹配,因为它指定了一个包含一个元素的列表。也就是说,x:[]
是单个元素列表,其中名称x
绑定到元素。类似地,[xs]
是单个元素列表(xs:[]
的语法糖),其中xs
绑定到一个元素。
答案 1 :(得分:5)
首先,您希望类型Int
带有大写字母。
fac :: [Int] -> Int
接下来,您的图案重叠。匹配[xs]
的任何内容也匹配x:[]
,反之亦然。它看起来像你想匹配
fac xs = sum xs
...仅仅是fac = sum
。
答案 2 :(得分:1)
只需要添加其他答案的一件事:如果您确实希望fac
处理所有数字类型,则可以将Num
约束添加到类型签名中,如错误消息所示。在这种情况下,最好使用比int
更难混淆的类型变量:
fac :: Num a => [a] -> a