![](/img/trans.png)
[英]Haskell: Could not deduce (Eq a) arising from the literal ‘1’ from the context (Num a)
[英]Could not deduce (Eq a) from the context (…)
我是 Haskell 的新手。 我写了这段代码:
deleteDuplicates :: [a] -> [a]
deleteDuplicates [] = []
deleteDuplicates (x:xs)
| x == (head xs) = x : (deleteDuplicates (tail xs))
| otherwise = x : (head xs) : (deleteDuplicates (tail xs))
这个错误是什么意思,为什么会发生? 我是否不小心以某种方式比较了两种不同的类型?
set2.hs:10:3:
Could not deduce (Eq a) from the context ()
arising from a use of `==' at set2.hs:10:3-16
Possible fix:
add (Eq a) to the context of
the type signature for `deleteDuplicates'
In the expression: x == (head xs)
In a stmt of a pattern guard for
the definition of `deleteDuplicates':
x == (head xs)
In the definition of `deleteDuplicates':
deleteDuplicates (x : xs)
| x == (head xs) = x : (deleteDuplicates (tail xs))
| otherwise = x : (head xs) : (deleteDuplicates (tail xs))
您的类型签名错误:
deleteDuplicates :: [a] -> [a]
这表示您的 function 可以处理任何类型的列表a
,但事实并非如此:您稍后致电:
x == (head xs)
因此,您必须能够比较您的类型是否相等。 意味着签名必须是:
deleteDuplicates :: Eq a => [a] -> [a]
在这种情况下,最好删除显式类型签名,在 GHCi 中加载 function 并发现解释器认为它应该具有的类型(通过:t deleteDuplicates
)。
更多错误
此外,您对head
的使用是一个坏主意。 head
是部分 function 并且在xs == []
时会失败。 我建议你扩展模式匹配:
deleteDuplicates (x1:x2:xs)
| x1 == x2 = ...
| otherwise = x1 : deleteDuplicates (x2:xs)
另请注意对otherwise
情况的修复。 您正在跳过 x2,但是如果 x2 匹配列表中的下一个元素怎么办? 像[1,2,2,3]
这样的东西会发现1 /= 2
然后递归会得到列表[2,3]
- 哎呀!
编译器告诉您,仅从类型签名就无法确定a
是否为 instanceof Eq
。
deleteDuplicates :: Eq a => [a] -> [a]
您需要通过在签名中提及它来告诉编译器a
是Eq类型 class 的实例。
表达方式
x == (head xs)
需要在xs
的成员上定义==
,这意味着a
必须是类型类Eq
的实例。 将函数的类型签名更改为
deleteDuplicates :: Eq a => [a] -> [a]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.