我在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仅考虑具有已定义的相等关系的类型?
答案 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_class和http://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
除了阿尔法替换之外,正是弗拉迪斯拉夫所给出的。