Haskell中的参数化类型和相等性

时间:2012-12-16 19:46:39

标签: haskell equality typeclass

我在Haskell中实现了一个union-find数据结构。

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

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仅考虑具有已定义的相等关系的类型?

2 个答案:

答案 0 :(得分: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_classhttp://en.wikipedia.org/wiki/Ad-hoc_polymorphism

答案 1 :(得分:3)

为了增加Vladislav的优秀答案,当遇到我不确定类型的问题时,我经常省略类型并通过将代码加载到GHCi中来利用Haskell的类型推理功能,并且(以下方式: ))要求Haskell告诉我它推断出了什么。也就是说,把这段代码与你的代码完全相同,除了没有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

除了阿尔法替换之外,正是弗拉迪斯拉夫所给出的。