I am trying to get the parent node of the node in a rose tree using following code:
{-# 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
The output is Nothing
for this case. I do not understand why. I covered all possible cases of traversing in getParentNode
and getParentNodeForList
(at least it seems so, it doesn't work apparently).
Any help is appreciated.
I think the problem is that getParentNode
should recurse on getParentNode node (RoseTree rootNode xs)
, so the whole function would become:
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
Personally, I would make use of asum
to write it more succinctly:
getParentNode node (RoseTree x xs)
| node `elem` map value xs = pure x
| otherwise = asum (map (getParentNode node) xs)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.