如何使用Haskell和非二叉树(例如this question)来达到Data.Tree
中所示的相同结果?考虑到记录let lastAttack = null;
// ...
if (self.pressingAttack) {
let now = new Date();
if (!lastAttack || now - lastAttack > 3000) {
self.shootBullet(self.mouseAngle);
lastAttack = now;
}
}
用于存储数据,而记录NodeData { nodeID :: String , parentID :: String, value :: a }
对于树类型,树将是:
Data.Tree
现在如何根据节点的子节点的Node $ NodeData "id" "parent" (value :: a) (children :: Forest (NodeData a)) :: Tree (NodeData a)
及其自身的值来更新value
?输入表将是列表value
。 [NodeData]
和id可以成为NodeData
的实例,但不能成为Eq
的实例。
答案 0 :(得分:4)
我认为没有特别聪明的单通解决方案。您只需要轻咬一下子弹,然后执行两次遍历:一次遍历创建Map Id [Node]
形式的索引,列出每个节点的所有子节点。然后,第二遍将消耗该索引,并将其重构为Forest a
。请注意,它不是Tree a
,因为根本没有价值可言,而且因为我们都知道有多个根。
import qualified Data.Map.Lazy as M
import qualified Data.Tree as T
newtype Id = Id Int deriving (Eq, Show, Ord)
data Node a = Node {id, parent :: Id, value :: a} deriving Show
input :: [Node String]
input = [ Node (Id 1) (Id 0) "1"
, Node (Id 2) (Id 1) "1.1"
, Node (Id 3) (Id 0) "2"
, Node (Id 4) (Id 2) "1.1.1"
, Node (Id 5) (Id 3) "2.1"
, Node (Id 6) (Id 1) "1.2"
]
index :: [Node a] -> M.Map Id [Node a]
index m = M.fromListWith (++) $ do
n@(Node this parent v) <- m
pure (parent, [n])
recombine :: M.Map Id [Node a] -> T.Forest a
recombine m = go (Id 0) -- Implied root, but a more thorough solution would be explicit
where go root = [ T.Node v (go idx)
| Node idx p v <- M.findWithDefault [] root m
]
在这之后,我们有了想要的树:
> putStr . T.drawForest . recombine . index $ input
2
|
`- 2.1
1
|
+- 1.2
|
`- 1.1
|
`- 1.1.1