我正在尝试为Huffman树数据结构实现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
定义,因此我不确定发生了什么。请帮助我理解并纠正这个问题。
答案 0 :(得分:4)
问题是缩进。您需要使用==
和<=
缩进所有行。编译器将instance (Eq a) => Eq (Tree a) where
视为一个块,然后将树上==
的定义视为完全独立的代码块。缩进这个和你的Tree a <= Tree b = ...
行,它应该是好的。否则,您似乎在源代码的顶层定义了==
,Haskell很乐意让您这样做。
由于您已经为Eq
派生Ord
和Tree
,因此您不必自己定义它们。如果您想要自定义实例,那么不要派生它们。除此之外,您需要将Ord
实例的定义修改为
instance Ord (Tree a) where
a <= b = freq a <= freq b
与freq
的定义相同。您不需要在此处进行模式匹配,尤其是因为Tree
是类型构造函数,但您只能与数据构造函数进行模式匹配。 Leaf
和Internal
是数据构造函数,因此可以进行模式匹配。您还需要为Eq
实例修复此问题,但解决方案类似。