haskell - 无法从上下文中推导出 (Eq a) (...)

标签 haskell types typeclass

我是 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]

也就是说你的函数可以处理任何类型的列表,a ,但事实并非如此!你稍后打电话:
x == (head xs)

所以你必须能够比较你的类型是否相等。这意味着签名必须是:
deleteDuplicates :: Eq a => [a] -> [a]

在这种情况下,最好删除您的显式类型签名,在 GHCi 中加载函数并发现解释器认为它应该具有的类型(通过 :t deleteDuplicates)。

更多错误

此外,您对 head 的使用有一个坏主意。 head是一个偏函数,当 xs == [] 时会失败.我建议你扩展模式匹配:
deleteDuplicates (x1:x2:xs)
    | x1 == x2 = ...
    | otherwise = x1 : deleteDuplicates (x2:xs)

还要注意对 otherwise 的修复案件。您跳过了 x2,但是如果 x2 匹配列表中的下一个元素呢?类似 [1,2,2,3]会发现 1 /= 2然后递归会得到列表 [2,3] - 哎呀!

关于haskell - 无法从上下文中推导出 (Eq a) (...),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5806930/

相关文章:

haskell - 类型类和重载,有什么联系?

haskell - "instance Show State where"不编译

c# - 如何重用相同的变量,但用于不同的类型?

haskell - 是否存在与 Bifunctor 等价的 Monoid?

Haskell IO Int 和 Int

c# - 为什么要在 Method<type>() 中指定 <type> ?以及如何使用它?

c++ - C 和 C++ 类型之间的区别 (typedef)

haskell - 即使类型实现它也不能使用 Show

scala - 在 Scala 中实现产品类型,并在其各个部分上使用通用更新功能

macos - OS X 上的 Haskell SDL