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
相关产品推荐
相关产品推荐

