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

Pie*_*ter 4 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))
Run Code Online (Sandbox Code Playgroud)

这个错误意味着什么,为什么会发生?我是不是意外地比较了两种不同的类型?

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))
Run Code Online (Sandbox Code Playgroud)

Tho*_*son 18

您的类型签名是错误的:

deleteDuplicates :: [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

这说明你的函数可以在任何类型的列表上工作a,但事实并非如此!你以后打电话:

x == (head xs)
Run Code Online (Sandbox Code Playgroud)

所以你必须能够比较你的类型是否相等.签名必须是:

deleteDuplicates :: Eq a => [a] -> [a]
Run Code Online (Sandbox Code Playgroud)

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

更多错误

另外,你使用head那里有一个坏主意. head是一个部分功能,将失败xs == [].我建议你扩展模式匹配:

deleteDuplicates (x1:x2:xs)
    | x1 == x2 = ...
    | otherwise = x1 : deleteDuplicates (x2:xs)
Run Code Online (Sandbox Code Playgroud)

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