我试图为霍夫曼树数据结构实现Eq
和Ord
,但我遇到了几个"定义不明确"和范围相关的错误。我一直在遵循上的树示例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
派生了Eq
和Ord
,因此不必自己定义它们。如果您在这里想要自定义实例,则不要派生它们。除此之外,您需要将Ord
实例的定义修改为
instance Ord (Tree a) where
a <= b = freq a <= freq b
对于CCD_ 16具有相同的定义。这里不需要进行模式匹配,特别是因为Tree
是一个类型构造函数,但只能使用数据构造函数进行模式匹配。Leaf
和Internal
在这里是数据构造函数,所以它们可以在上进行模式匹配。您也需要为Eq
实例修复此问题,但解决方案类似。