I want to be able to specify an element and the tree and the function should give me a list of directions and if the element is not contained it should not return an error but rather a "Nothing" made by Maybe.
data BTree a = Nil | Node a ( BTree a) ( BTree a) deriving Show
data Direction = L | R deriving (Show , Eq)
getPath :: (Ord a) => a -> BTree a -> Maybe [Direction]
getPath y (Node x lt rt)
| (Node x lt rt) == Nil = Nothing
| y == x = Just []
| y < x = Just (L:(getPath y lt))
| otherwise = Just (R:(getPath y rt))
But with this code i am getting an error:
* Couldn't match expected type: [Direction]
with actual type: Maybe [Direction]
* In the second argument of `(:)', namely `(getPath y lt)'
In the first argument of `Just', namely `(L : (getPath y lt))'
In the expression: Just (L : (getPath y lt))
|
57 | | y < x = Just (L:(getPath y lt))
* Couldn't match expected type: [Direction]
with actual type: Maybe [Direction]
* In the second argument of `(:)', namely `(getPath y rt)'
In the first argument of `Just', namely `(R : (getPath y rt))'
In the expression: Just (R : (getPath y rt))
|
58 | | otherwise = Just (R:(getPath y rt))
It would be great if someone could help me.
>Solution :
The reason Just (L : getPath y lt) does not work is because getPath y lt is a Maybe [Direction], not a [Direction], hence it is not a list, and you thus can not prepend this with L or R.
You can make use of fmap :: Functor f => (a -> b) -> f a -> f b to perform a mapping on the item wrapped in the Just data constructor, and fmap f Nothing will return Nothing.
You thus can implement this as:
getPath :: Ord a => a -> BTree a -> Maybe [Direction]
getPath Nil = Nothing
getPath y (Node x lt rt)
| y == x = Just []
| y < x = fmap (L:) (getPath y lt)
| otherwise = fmap (R:) (getPath y rt)
The condition (Node x lt rt) == Nil can never be True: you should pattern match on Nil, and in that case return Nothing.