我在Haskell中真的很新,我正在尝试创建一个霍夫曼树,直到最后我都无法弄明白。
我对树的定义如下:data HuffTree = Node Int HuffTree HuffTree | Leaf (Int, Char)
到目前为止,我有一个函数insTree :: HuffTree -> HuffTree -> HuffTree
,它在树中插入带有子树的Node并返回新树。一个函数makePair :: HuffTree -> HuffTree -> HuffTree
,它接受两棵树,并使一棵新树具有原始两棵树的子树,并且值为前两棵树中值的总和。以及从每个节点返回值的函数value :: HuffTree -> Int
。
我的问题是函数makeHuffTree :: [(Int, Char)] -> HuffTree
看起来像这样:
makeHuffTree :: [(Int, Char)] -> HuffTree
makeHuffTree lst = merge leafList
where
leafList = map (\ ((x,c)) -> Leaf (x,c)) lst
merge [] = []
merge [t] = [t]
merge (t1 : t2 : tree) = insTree (makePair t1 t2) tree
我知道这个功能有问题,但我不知道如何处理它。我得到的错误是:
Couldn't match expected type `[a0]' with actual type `HuffTree'
In the return type of a call of `insTree'
In the expression: insTree (makePair t1 t2) tree
In an equation for `merge':
merge (t1 : t2 : tree) = insTree (makePair t1 t2) tree
你能否提示如何解决这个问题?
答案 0 :(得分:7)
merge
的结果是什么类型的?
如果是HuffTree
,则merge [t] = [t]
行是荒谬的。如果不是,则makeHuffTree lst = merge leafList
行是荒谬的。
行merge (t1 : t2 : tree) = insTree (makePair t1 t2) tree
无论如何都是荒谬的,因为tree
是一个列表而insTree
应该是HuffTree
,而不是列表。
我不熟悉霍夫曼树构建算法。但我认为:
merge [] = []
,因为没有对应于空列表的有效树。merge [t]
应该返回t
。我无法确定这一点,但我只是遵循这些类型。merge (t1 : t2 : tree)
应该返回insTree (makePair t1 t2) (merge tree)
。我再次关注这些类型。如果您对此感到困惑,请记住,在模式(a:b:cs)
中,只有a
和b
是列表的元素; cs
是列表的其余部分,这只是另一个列表。我的观点是:始终遵循类型。你应该能够指出任何表情并说“啊哈,你是T型!”。然后你可以指出那个接受该表达式的函数,并指责“什么哎呀,你不能有这种类型的论证!”(通过编译,通常,编译器通常很乐意借给你一个长手指,就像它有用的错误消息一样)。 然后你认为“我有什么可以根据 值来制作所需类型的值?”,只应用正确的函数来修复有问题的参数,这就是它。哦,如果你没有任何合适的功能,你可以写一个。