如何在 Haskell 中标记树中的节点?
How do I label nodes in a Tree in Haskell?
假设我有一个Data.Tree
持有字符:Tree Char
:
A
/ \
B C
/|\
D A F
请注意,树中可能存在重复项。我想通过存储边将这棵树存储在关系数据库中,但是由于重复项,我不能使用节点的内容作为键(注意不同级别的 A
)。
也许一个解决方案是遍历 de tree 并用唯一的 id 映射它,例如:
(1,A)
/ \
(2,B) (3,C)
/|\
(4,D)(5,A),(6,F)
现在存储边缘没有任何问题,因为我使用了 ids。
(1, null, A)
(2, 1, B)
(3, 1, C)
(4, 3, D)
(5, 3, A)
(6, 3, F)
但我看不出如何将静态树节点“映射”到无限 ID 生成器。
从功能的角度来看,您的方法是什么?请注意,我无法对分支因子的数量做出任何假设,因此我无法展平、压缩 ID 和重建树
您可以使用 State
来发送 ID,因此:
import Control.Monad.State.Lazy(State, get, put)
labelNext :: State Int Int
labelNext = do
val <- get
put (val+1)
return val
然后我们可以用以下标记树:
{-# LANGUAGE TupleSections #-}
labelTree :: Tree a -> Tree (Int, a)
labelTree tree = evalState (traverse (\a -> (,a) <$> labelNext) tree) 1
例如,这给了我们:
ghci> labelTree (Node 'A' [Node 'B' [], Node 'C' [Node 'D' [], Node 'A' [], Node 'F' []]])
Node {rootLabel = (1,'A'), subForest = [Node {rootLabel = (2,'B'), subForest = []},Node {rootLabel = (3,'C'), subForest = [Node {rootLabel = (4,'D'), subForest = []},Node {rootLabel = (5,'A'), subForest = []},Node {rootLabel = (6,'F'), subForest = []}]}]}
假设我有一个Data.Tree
持有字符:Tree Char
:
A
/ \
B C
/|\
D A F
请注意,树中可能存在重复项。我想通过存储边将这棵树存储在关系数据库中,但是由于重复项,我不能使用节点的内容作为键(注意不同级别的 A
)。
也许一个解决方案是遍历 de tree 并用唯一的 id 映射它,例如:
(1,A)
/ \
(2,B) (3,C)
/|\
(4,D)(5,A),(6,F)
现在存储边缘没有任何问题,因为我使用了 ids。
(1, null, A)
(2, 1, B)
(3, 1, C)
(4, 3, D)
(5, 3, A)
(6, 3, F)
但我看不出如何将静态树节点“映射”到无限 ID 生成器。
从功能的角度来看,您的方法是什么?请注意,我无法对分支因子的数量做出任何假设,因此我无法展平、压缩 ID 和重建树
您可以使用 State
来发送 ID,因此:
import Control.Monad.State.Lazy(State, get, put)
labelNext :: State Int Int
labelNext = do
val <- get
put (val+1)
return val
然后我们可以用以下标记树:
{-# LANGUAGE TupleSections #-}
labelTree :: Tree a -> Tree (Int, a)
labelTree tree = evalState (traverse (\a -> (,a) <$> labelNext) tree) 1
例如,这给了我们:
ghci> labelTree (Node 'A' [Node 'B' [], Node 'C' [Node 'D' [], Node 'A' [], Node 'F' []]])
Node {rootLabel = (1,'A'), subForest = [Node {rootLabel = (2,'B'), subForest = []},Node {rootLabel = (3,'C'), subForest = [Node {rootLabel = (4,'D'), subForest = []},Node {rootLabel = (5,'A'), subForest = []},Node {rootLabel = (6,'F'), subForest = []}]}]}