【发布时间】:2021-04-15 21:36:12
【问题描述】:
我有一个典型的二叉搜索树数据类型:
data Tree a
= Empty
| Branch a (Tree a) (Tree a) deriving Show
还有变态
foldt :: b -> (a -> b -> b -> b) -> Tree a -> b
foldt empty _ Empty = empty
foldt empty branch (Branch a l r) = branch a (foldt empty branch l) (foldt empty branch r)
我尝试使用foldt 定义插入函数并得到了一些有趣的结果:
insert :: (Ord a) => a -> Tree a -> Tree a
insert x = foldt (single x) insertb
where insertb a left right
| x == a = Branch x left right
| x < a = Branch a (insert x left) right
| x > a = Branch a left (insert x right)
ghci> mytree = insert 2 (Branch 3 Empty Empty)
ghci> mytree
Branch 3 (Branch 2 (Branch 2 Empty Empty) (Branch 2 Empty Empty)) (Branch 2 Empty Empty)
ghci>
当然,传统的插入方法的行为符合预期:
insert' :: (Ord a) => a -> Tree a -> Tree a
insert' x Empty = single x
insert' x (Branch a left right)
| x == a = Branch x left right
| x < a = Branch a (insert' x left) right
| x > a = Branch a left (insert' x right)
ghci> mytree2 = insert' 2 (Branch 3 Empty Empty)
ghci> mytree2
Branch 3 (Branch 2 Empty Empty) Empty
ghci>
有没有办法用foldt 来定义insert,还是我在这里找错了树(ha)?
【问题讨论】:
-
也许
cata有可能,我不确定。但是使用para很容易,这对于这个用例来说似乎是完美的。 -
提示:
foldt empty branch应用程序不应直接生成树。它可以产生一个函数Maybe a -> Tree a,我怀疑也可以产生一对树,其中一个执行了插入,而另一个没有。从效率的角度来看,多态性肯定会更好。 -
请注意,当使用
foldt之类的东西时,您通常会尝试在其他地方避免显式递归。所以insertb中的那些insert调用有点危险。 -
@amalloy
cata和para具有相同的功率。但是,是的,它们绝对没有同等的便利性。 -
@Carl,也没有同等性能。
para为您赢得了很多分享。
标签: haskell functional-programming binary-search-tree catamorphism