Haskell:update 一棵二叉树

Haskell:update a binary tree

我想实现一个映射函数 mapLeaves,该函数仅映射到二进制形式的叶子 tree.And return 更新的树。

data Tree = TNode Int [Tree] | Tleaf Int

    
         -1
        /   \
      -5     10
      / \   
    -4  30  
    / \
   13  17

t = TNode (-1) [TNode (-5)  [  TNode (-4) [ Tleaf 13, Tleaf 17] ,  Tleaf 30 ] ,Tleaf 10 ]

getListLeaves (Tleaf x)= [x]
getListLeaves (TNode x [Tleaf y])=[y]
getListLeaves (TNode x (y:ys))=  (getListLeaves y) ++ (getListLeaves (TNode x ys)) 

mapLeaves f tree = map (f) (getListLeaves tree)

mapLeaves (+3) t and get the answer [16,20,33,13]

这就是我要停止的地方,我怎样才能使这个列表成为二叉树,就像上面显示的 t 一样,叶子得到了更新,但节点仍然存在。 提前致谢。

已编辑: 为什么这是有效的,

sumLeaves :: Tree -> Int
sumLeaves (Tleaf x)=x
sumLeaves (TNode n xs)=sum (map sumLeaves xs)

但是当我将 sum 更改为 TNode n 时它不起作用,

sumLeaves :: Tree -> Int
sumLeaves (Tleaf x)=x
sumLeaves (TNode n xs)=TNode n (map sumLeaves xs)

这也是我卡住的地方,

mapLeaves :: (Int -> Int) -> Tree -> Tree
mapLeaves f (Tleaf x) = Tleaf (f x)
mapLeaves f (TNode x cs)=TNode x  (map mapLeaves f cs)

首先不要使用列表。现在“关于结构的信息”丢失了。使用递归映射树中的元素。

因此您可以将其实现为:

mapLeaves :: (Int -> Int) -> Tree -> Tree
mapLeaves f <b>(Tleaf x)</b> = …
mapLeaves f <b>(TNode x cs)</b> = TNode x (…)

需要填写部分的地方。对于 TNode 部分,您因此创建了一个新的 TNode 并以 x 作为值,然后递归树 cs.

的 children

但是建模有点奇怪。虽然 one 可以表示二叉树,但数据类型不会 强制执行 二叉树:因为 TNode 可以有零个、一个或多个 children。此外,没有 children 的 TNode 可能是一片叶子,但是您有一个额外的数据构造函数,这意味着同一棵(二叉)树可以用多种方式表示,这通常是不是个好主意。