繁体   English   中英

获取玫瑰树中节点的父节点

[英]Get parent node of the node in a rose tree

我正在尝试使用以下代码获取玫瑰树中节点的父节点:

{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE DeriveFunctor     #-}
{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}

module Main where

import GHC.Generics (Generic)

data RoseTree a = RoseTree { value :: a, children :: [RoseTree a]}
                   deriving (Show, Generic, Functor)

type Timestamp = Integer

type Tree = RoseTree Timestamp 

getParentNode :: Timestamp -> Tree -> Maybe Timestamp 
getParentNode node tree@(RoseTree _ []) = Nothing
getParentNode node tree@(RoseTree rootNode (x:xs)) =
  if node == value x then Just rootNode else case getParentNode node x of 
    Nothing -> case getParentNodeForList node (children x) of 
      Nothing -> getParentNodeForList node xs
      Just parent -> Just parent
    Just parent -> Just parent 

getParentNodeForList :: Timestamp -> [Tree]-> Maybe Timestamp
getParentNodeForList node [] = Nothing
getParentNodeForList node (x:xs) = case getParentNode node x of 
  Nothing -> case getParentNodeForList node (children x) of 
    Nothing -> getParentNodeForList node xs
    Just parent -> Just parent
  Just parent -> Just parent 


main :: IO ()
main = do
  let tree = RoseTree 1623839394 [RoseTree 1623839395 [], RoseTree 1623839396 [], RoseTree 1623839397 []]
  putStrLn $ show $ getParentNode 1623839397 tree

对于这种情况, Nothing是空的。 我不懂为什么。 我在getParentNodegetParentNodeForList中涵盖了所有可能的遍历情况(至少看起来是这样,它显然不起作用)。

任何帮助表示赞赏。

我认为问题是getParentNode应该在getParentNode node (RoseTree rootNode xs)上递归,所以整个 function 会变成:

getParentNode :: Timestamp -> Tree -> Maybe Timestamp 
getParentNode node tree@(RoseTree _ []) = Nothing
getParentNode node tree@(RoseTree rootNode (x:xs)) =
  if node == value x then Just rootNode else case getParentNode node x of 
    Nothing -> case getParentNodeForList node (children x) of 
      Nothing -> getParentNode node (RoseTree rootNode xs)
      Just parent -> Just parent
    Just parent -> Just parent 

就个人而言,我会使用asum来更简洁地编写它:

getParentNode node (RoseTree x xs)
  | node `elem` map value xs = pure x
  | otherwise = asum (map (getParentNode node) xs)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM