问题描述
我正在研究符号代数系统。我目前正在研究如何从二叉分析树执行多项式加法/乘法。稍后我会认为这是一个普通戒指。
解析在这里不相关——这旨在成为解析的输出。形成的解析树。如果这里有什么可以改进的地方,我当然也很高兴了解这一点。
我“感觉”这个树结构可以折叠/压碎,但我不太清楚如何去做。我相信我可以一起破解一些东西,但由于我仍在学习 Haskell,我想了解更高级的用户会做什么。
以下是相关代码背景。
我的两个相关数据声明是:
data Op = Add | Mul
data Tree a = Leaf a | Node Op [Tree a] [Tree a]
这是我的测试示例之一:
-- 3*(x+2)*(x+(5*4))
test = Node Mul [
Node Mul
[Leaf "3"]
[Node Add
[Leaf "x"]
[Leaf "2"]
]
]
[Node Add
[Leaf "x"]
[Node Mul
[Leaf "5"]
[Leaf "4"]
]
]
这是一种典型的递归树类型,其中一个节点包含一个操作以及左树和右树的列表。计算通过以下操作进行。注意:它们现在都是字符串操作。我需要它们尽可能通用(但稍后会添加进一步的结构,如乘法交换性)。
prod :: [Tree [a]] -> [Tree [a]] -> [Tree [a]]
prod ls rs = [Leaf (l ++ r) | (Leaf l) <- ls,(Leaf r) <- rs]
add :: [Tree [a]] -> [Tree [a]] -> [Tree [a]]
add l r = l ++ r
opOnLeaf :: Op -> [Tree [a]] -> [Tree [a]] -> [Tree [a]]
opOnLeaf op l r
| op == Add = add l r
| op == Mul = prod l r
operate :: Tree [a] -> [Tree [a]]
operate (Node op [Node op2 l2 r2] [Node op3 l3 r3]) = operate (Node op (operate (Node op2 l2 r2)) (operate (Node op3 l3 r3)))
operate (Node op [Node op2 l2 r2] r) = operate (Node op (operate (Node op2 l2 r2)) r)
operate (Node op l [Node op2 l2 r2]) = operate (Node op l (operate (Node op2 l2 r2)))
operate (Node op l r) = opOnLeaf op l r
我认为 operate
中的变量名很糟糕,但我想确保它首先起作用。让它变得丑陋也使它更加突出。这实际上是在对我大喊大叫,让我找到更好的方法。
现在,我想使用 fold 或 foldMap,但我遇到了在每个操作(即 (*)
和 (+)
)中都有不同幺半群的问题。而这只是开始——我将添加其他几个操作。所以我需要像“可变幺半群”之类的东西,或者可能是其他一些地图,其操作是首先获取幺半群。我不确定。
查询:给定这个二叉树,每个节点有多个操作,如何折叠结构?有没有更好的方法可以将其编写为可折叠的实例或其他结构?我还打算添加其他几个二进制操作。理想情况下,我想要一个可以无限扩展的结构。我假设一旦解决了 2,我们就可以有效地解决 n。
Tree drawing corresponding to test example
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)