繁体   English   中英

无法从上下文 (…) 中推断出 (Eq 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]

您需要通过在签名中提及它来告诉编译器aEq类型 class 的实例。

表达方式

x == (head xs)

需要在xs的成员上定义== ,这意味着a必须是类型类Eq的实例。 将函数的类型签名更改为

deleteDuplicates :: Eq a => [a] -> [a]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM