andro
andro

Reputation: 949

Rose tree deconstructor

If we have a rose tree definition as follows:

data Rose a = a :> [Rose a]

then I know that :> is an infix constructor. But how do you work with elements of such a tree? How can you traverse it to visit nodes or extract subtrees or elements?

Upvotes: 2

Views: 686

Answers (2)

ThreeFx
ThreeFx

Reputation: 7360

You can pattern match on the constructor like this (for example):

find :: (Eq a) => a -> Rose a -> Bool
find item (top :> rest)
  | item == top = True
  | otherwise = any (find item) rest

Addressing your second problem: Yes you can do this without any further knowledge of functors, but it would make sense to create a functor instance because it would make your datastructure more flexible. But lets get down to business: A map which processes every node would look something like this:

myMap :: (a -> b) -> Rose a -> Rose b
myMap f (node :> rest) = f node :> map (myMap f) rest

This is pretty easy to add to the functor typeclass, because it does exactly what we want:

instance Functor Rose where
  fmap :: (a -> b) -> Rose a -> Rose b
  fmap = myMap

Upvotes: 7

Tom Ellis
Tom Ellis

Reputation: 9434

subtrees :: Rose a -> [Rose a]
subtrees (_ :> rs) = rs

label :: Rose a -> a
label (a :> _) = a

Upvotes: 1

Related Questions