Haskell玫瑰树路径枚举:实现带路径坐标的Event提取函数
实现coords函数的解决方案
看起来你需要实现一个遍历自定义Tree类型、收集事件及其路径坐标的函数,我来帮你一步步搞定这个问题!
首先先明确你的Tree类型定义(我补充了Event的示例定义,你可以替换成实际的Event类型):
data Event = Event String -- 替换成你的Event实际定义即可 deriving (Show) data Tree = Empty | Leaf Event | Split String [(String, Tree)] deriving (Show)
核心思路
要实现coords :: Tree -> [(Event,[Int])],我们需要递归遍历树结构,同时追踪当前到达节点的路径坐标。核心规则如下:
- 遇到
Empty分支直接忽略,不产生任何结果 - 遇到
Leaf Event时,记录当前的完整路径坐标 - 遇到
Split节点时,给每个子分支分配从0开始的索引(作为路径的一部分),递归处理每个子树后拼接结果
完整实现
我们可以借助一个辅助函数go来维护当前路径,主函数只需要初始化空路径即可:
coords :: Tree -> [(Event, [Int])] coords tree = go [] tree where -- 辅助函数:接收当前路径和子树,返回对应的(Event, 路径)列表 go :: [Int] -> Tree -> [(Event, [Int])] go _ Empty = [] -- 空分支直接忽略,返回空列表 go currentPath (Leaf event) = [(event, currentPath)] -- 叶子节点,返回当前路径 go currentPath (Split _ branches) = -- 给每个分支加上索引,递归处理后拼接所有结果 concatMap (\(branchIdx, (_, subTree)) -> go (currentPath ++ [branchIdx]) subTree) (zip [0..] branches)
测试示例
用你给出的例子验证一下:
-- 构造测试树:Split节点包含一个Leaf分支和一个Empty分支 testTree :: Tree testTree = Split "some-str" [("str2", Leaf (Event "my-event")), ("str3", Empty)] -- 调用coords testTree,输出结果: -- [(Event "my-event", [0])]
完全符合你的预期,Empty分支被自动忽略了。
代码细节解释
zip [0..] branches:给每个子分支分配从0开始的整数索引,这个索引就是路径中的坐标值currentPath ++ [branchIdx]:将当前分支的索引追加到已有路径后面,形成到达子树的完整路径concatMap:遍历所有分支的递归结果,将它们拼接成一个列表,自动过滤掉Empty分支返回的空列表
内容的提问来源于stack exchange,提问作者D.Dog
相关产品推荐
相关产品推荐

