尝试为自定义树数据结构定义Eq时出现定义不明确的错误



我试图为霍夫曼树数据结构实现EqOrd,但我遇到了几个"定义不明确"和范围相关的错误。我一直在遵循上的树示例https://www.haskell.org/tutorial/classes.html

import Data.List
data Tree a = Leaf a Int | Internal (Tree a) (Tree a) Int deriving (Eq, Ord)
instance (Eq a) => Eq (Tree a) where
(Leaf a ac) == (Leaf b bc) = (a == b) && (ac == bc)
(Internal (Tree a1) (Tree a2) ac) == (Internal (Tree b1) (Tree b2) bc) = 
                    (a1 == b1) && (a2 == b2) && (ac == bc)
_ == _ = False
instance Ord (Tree a) where
Tree a <= Tree b = (freq a) <= (freq b)
freq :: Tree a -> Int
freq (Leaf _ c) = c
freq (Internal _ _ c) = c

我不知道什么是模棱两可的。它说==可能来自Prelude或我的代码。但是,我的==只为我的Tree定义,所以我不确定发生了什么。请帮助我理解并纠正这个问题。

问题在于缩进。您需要使用==<=缩进所有行。编译器将instance (Eq a) => Eq (Tree a) where视为一个块,然后将树上==的定义视为完全独立的代码块。缩进这个和你的Tree a <= Tree b = ...行,应该可以开始了。否则,看起来你是在源代码的顶层定义==,Haskell很乐意让你这么做

由于您已经为Tree派生了EqOrd,因此不必自己定义它们。如果您在这里想要自定义实例,则不要派生它们。除此之外,您需要将Ord实例的定义修改为

instance Ord (Tree a) where
    a <= b = freq a <= freq b

对于CCD_ 16具有相同的定义。这里不需要进行模式匹配,特别是因为Tree是一个类型构造函数,但只能使用数据构造函数进行模式匹配。LeafInternal在这里是数据构造函数,所以它们可以在上进行模式匹配。您也需要为Eq实例修复此问题,但解决方案类似。

最新更新