I've been playing around with binary trees in Haskell, and I am attempting to implement a dfs variant that returns the path (composed of left and rights) from the root node to the node containing the value searched for. I think it would be best to return a Maybe Directions
type.
Here is what has been implemented so far.
data Tree a = Empty | Node a (Tree a) (Tree a)
deriving (Show, Eq)
data Direction = L | R
deriving (Show)
type Directions = [Direction]
inTree :: (Eq a) => a -> Tree a -> [Direction]
inTree val (Node x l r)
| val == x = []
| l /= Empty = L:(inTree val l)
| r /= Empty = R:(inTree val r)
| otherwise =
but I have no idea how to have it traverse the entire tree. I feel as though I might be thinking too imperatively.
Your idea to use Maybe Direction
is good. I would rewrite your function as follows:
inTree :: (Eq a) => a -> Tree a -> Maybe [Direction]
inTree val Empty = Nothing
inTree val (Node x l r)
| val == x = Just []
| otherwise = (fmap (L:) (inTree val l)) <|> (fmap (R:) (inTree val r))
fmap
ing a function f
on a Maybe
results in Nothing
if the original value is Nothing
and Just (f v)
if it's Just v
. In our case if the recursive call found the value (so it's returning a path Just [Direction]
) we append the Direction
we took at the current node.
The <|>
operator comes from the Alternative
instance of Maybe
. It's a left biased choice on maybes. Here we use it to pick the subtree which returned Just [Direction]
(if there was any).
A good exercise is to modify the code so that it returns all the paths to the x
s in the tree.