You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell遍历二叉树收集Monoid值的函数重构后出错,原因是什么?

你重构后的代码存在两个明确错误:

错误1:节点模式匹配的子树顺序写反

你定义的BinTree类型中,NodeBT的参数顺序为 值 -> 左子树 -> 右子树,但在collectBT'的模式匹配中你写的是NodeBT val rt lt,直接把左子树赋值给了rt变量、右子树赋值给了lt变量,左右子树完全颠倒,自然遍历顺序不符合预期。

错误2:递归调用的函数名写错

你在collectBT'中定义递归逻辑时写的是recursion = collectBT ord f,这里调用的是你最初版本的旧函数collectBT,而不是重构后的新函数collectBT',逻辑完全串接错误。


修正后的可正常运行代码

combineInOrder :: Monoid m => TravOrder -> m -> m -> m -> m
combineInOrder Inorder = \val lt rt -> lt <> val <> rt
combineInOrder Preorder = \val lt rt -> val <> lt <> rt
combineInOrder Postorder = \val lt rt -> lt <> rt <> val

collectBT' :: Monoid m => TravOrder -> (a -> m) -> BinTree a -> m
collectBT' ord f EmptyBT = mempty
collectBT' ord f (NodeBT val lt rt) = -- 修正子树顺序
    let recursion = collectBT' ord f -- 修正递归调用的函数名
    in combineInOrder ord (f val) (recursion lt) (recursion rt)

用你给出的测试树验证,以中序遍历转列表为例:
collectBT Inorder (:[]) (NodeBT 1 (NodeBT 2 EmptyBT EmptyBT) (NodeBT 3 EmptyBT EmptyBT)) 和修正后的collectBT'返回结果一致,均为[2,1,3],符合预期。

内容的提问来源于stack exchange,提问作者Red_Black

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 13:54:06