我在haskell中实现了一个树,我遇到了以下问题。我有正确的数据类型,我的插入和搜索方法工作。但是,在测试时我非常有限。例如,如果我在代码中声明一个树testtree
并给它一些值,当尝试插入testree
时,它实际上永远不会更新testree。请允许我解释一下。
如果我在ghci窗口insert 5 testtree
中声明,它将返回一个新树,这是testree所在的,并且5添加在正确的位置。快乐的时光。如果我尝试将另一个元素添加到testree中,它将返回原始testree添加的新元素。 5已经消失了。所以问题是我无法改变testree的原始实例,这是一个痛苦的屁股。测试我的插入方法包括创建许多树,这些树涵盖了向它们添加元素的所有可能性。如果我可以只有一棵树,我可以继续添加它将更方便。任何帮助将非常感激!下面是一个突出我的问题的样本,它是一个2-3-4树我正在实现所以我已经从中取出了很多代码,因为它不需要突出问题。
data Tree t = Empty
| Root1 t (Tree t)(Tree t)
| Root2 t t (Tree t)(Tree t)(Tree t)
deriving (Eq, Ord, Show)
leaf1 x = Root1 x (Empty) (Empty)
leaf2 x y = Root2 x y (Empty) (Empty) (Empty)
insert :: Ord t => t -> Tree t -> Tree t
insert t Empty = leaf1 t
insert t (Root1 a Empty Empty)
| t <= a = leaf2 t a
| otherwise = leaf2 a t
insert t (Root1 a left right)
| t <= a = Root1 a (insert t(left)) (right)
| otherwise = Root1 a (left) (insert t(right))
testtree = Root1 5 (Root1 3 (Empty) (Empty)) (Root1 7 (Empty) (Empty))
答案 0 :(得分:2)
欢迎来到持久数据结构的精彩世界。持久数据结构的基本定义特征是所有更新都是非破坏性的。您无法更改数据结构,只能将其用作新数据结构的基础。
这在代码维护,并行代码的性能和并发代码的正确性方面具有巨大的优势。这是一件好事。
答案 1 :(得分:2)
Haskell值是不可变的。定义testtree = ...
时,您无法更改testtree
的值。
相反,你必须做这样的事情:
tree1 = insert 5 testtree
tree2 = insert 6 tree1
tree3 = insert 7 tree2
...
请注意,如果您尝试:
testtree = insert 5 testtree
你将进入一个无限循环,因为RHS上的testtree
引用了正在定义的testtree
。