2

我在 Haskell 中实现了一个联合查找数据结构。

我想使用参数化类型,但是当我尝试比较用作参数的对象时遇到了一个小问题。

data UnionFindElement valueType =
    RootElement valueType |
    ElementWithParent valueType (UnionFindElement valueType)

holds :: UnionFindElement valueType -> valueType -> Bool
holds (RootElement v) value = v == value

似乎没有定义平等。

No instance for (Eq valueType)
  arising from a use of `=='
In the expression: v == value

如何限制 valueType 仅考虑具有已定义相等关系的类型?

4

2 回答 2

4

holds :: (Eq valueType) => UnionFindElement valueType -> valueType -> Bool

(Eq valueType) =>手段valueType来自类Eq(等价值),并且构造的存在正是为了能够限制泛型参数的类型。

请注意,这也适用于数据声明和其他几个地方。您可以在http://en.wikibooks.org/wiki/Haskell/Classes_and_types#Type_constraints了解更多信息

对于更一般的概述,http ://en.wikipedia.org/wiki/Type_class和http://en.wikipedia.org/wiki/Ad-hoc_polymorphism

于 2012-12-16T19:58:34.097 回答
3

为了补充 Vladislav 的出色答案,当遇到我不确定类型的问题时,我经常省略类型并通过将代码加载到 GHCi 中来利用 Haskell 的类型推断功能和(恭敬地:))询问Haskell 告诉我它推断了什么。也就是说,将这段代码(除了没有明确的 for 类型外,与您的代码完全相同holds)放入 GHCi:

data UnionFindElement valueType =
    RootElement valueType |
    ElementWithParent valueType (UnionFindElement valueType)

holds (RootElement v) value = v == value

并检查类型:

ghci> :t holds
holds :: Eq a => UnionFindElement a -> a -> Bool

除了 alpha 替换之外,这正是 Vladislav 给出的。

于 2012-12-17T12:43:36.363 回答