我正在尝试编写一个函数filterTree
,它将使用给定条件过滤掉RoseTree中的元素:
data RoseTree a = RoseTree a [RoseTree a]
deriving (Show, Functor)
extractChild :: RoseTree a -> RoseTree a
extractChild (RoseTree _ (x:[])) = x
extractChild rTree = rTree
filterTree :: ( a -> Bool ) -> RoseTree a -> RoseTree a
filterTree condition rTree@(RoseTree a list) =
if (condition $ a)
then (extractChild rTree)
else (RoseTree a (filterTreeList condition list))
filterTreeList :: (a -> Bool) -> [RoseTree a] -> [RoseTree a]
filterTreeList condition [] = []
filterTreeList condition (x:xs) = [filterTree condition x] ++ (filterTreeList condition xs)
但它并不像预期的那样有效。由于某种原因,它不会过滤掉满足条件的嵌套元素。例如,如果我运行
filterTree (==2) (RoseTree 1 [ RoseTree 2 [ RoseTree 3 [] ]])
然后它运行良好返回RoseTree 1 [RoseTree 3 []]
。但是如果我用另一个满足条件的嵌套元素运行它
filterTree (==2) (RoseTree 1 [ RoseTree 2 [ RoseTree 3 [RoseTree 2 [RoseTree 1[]]] ]])
然后它返回错误的结果,列表中有第二个匹配元素:RoseTree 1 [RoseTree 3 [RoseTree 2 [RoseTree 1 []]]]
为什么会发生这种情况的任何想法?
答案 0 :(得分:2)
以下内容适用于您提供的示例。
请注意,如果节点与过滤条件匹配且没有一个子节点,它将循环。
filterTree :: ( a -> Bool ) -> RoseTree a -> RoseTree a
filterTree condition rTree@(RoseTree a list) =
if (condition $ a)
then filterTree condition (extractChild rTree)
else (RoseTree a (filterTreeList condition list))