Использование Data.Tree
я могу определить дерево, как это:Propagate значения вверх Data.Tree в Haskell
mkTree :: T.Tree Double
mkTree = T.Node 0 [ T.Node 4 []
, T.Node 0 [T.Node 5 [], T.Node 4 []]
, T.Node 0 [T.Node 2 [], T.Node 1 []]
]
Что бы перевести так:
0.0
|
+- 4.0
|
+- 0.0
| |
| +- 5.0
| |
| `- 4.0
|
`- 0.0
|
+- 2.0
|
`- 1.0
теперь я хочу, чтобы преобразовать дерево так что каждый T.Node
теперь содержит сумму (или какой-либо другой функции) своих детей:
16.0
|
+- 4.0
|
+- 9.0
| |
| +- 5.0
| |
| `- 4.0
|
`- 3.0
|
+- 2.0
|
`- 1.0
проблема в том, что я не могу получить доступ к дочерним узлам узла, используя fmap
. То, что я до сих пор их функции:
propagate :: Num a => T.Tree a -> T.Tree a
propagate (T.Node x []) = T.Node x []
propagate (T.Node _ ts) = T.Node (sum $ map gather ts) (map propagate ts)
gather :: Num a => T.Tree a -> a
gather (T.Node n []) = n
gather (T.Node _ ts) = sum $ map gather ts
Но это кажется слишком сложным, особенно, если я заменить sum
с другой функцией. Может быть, есть лучший способ сделать это, используя Foldable
или Traversable
?
Вам может понравиться [dual-tree] (http://hackage.haskell.org/package/dual-tree) (используя ['Sum'] (https://hackage.haskell.org/package/base -4.8.2.0/docs/Data-Monoid.html # t: Sum) моноида в качестве аннотации восходящего движения). –