I have a Haskell exam in three days, so I thought I should practice a little and pulled up past exams, one of which features the following Tree datatype:
data Tree a = Leaf1 a | Leaf2 a a | Node (Tree a) (Maybe (Tree a)) deriving (Eq, Ord, Show)
It didn't seem that challenging at first, but then I realized I have to write a Traversable instance for this Tree. Dealing with the leaves were easy enough:
instance Traversable Tree where
traverse f (Leaf1 a) = Leaf1 <$> f a
traverse f (Leaf2 a b) = Leaf2 <$> f a <*> f b
However, I started running into problems with the Node.
traverse f (Node t Nothing) = Node <$> traverse f t <*> Nothing
traverse f (Node l (Just r)) = Node <$> traverse f l <*> Just (traverse f r)
Naturally, these don't work, and I can't wrap my head around what should come after the second <*>. I tried using holes, but the messages given to me by ghci didn't help much (I get that the problem is with types, but I have no idea how I'm supposed to fix it).
Here's the error message I got when I tried to compile it:
* Couldn't match type `f' with `Maybe'
`f' is a rigid type variable bound by
the type signature for:
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Tree a -> f (Tree b)
at exam.hs:92:3-10
Expected type: f (Maybe (Tree b))
Actual type: Maybe (Maybe (Tree b))
* In the second argument of `(<*>)', namely `Nothing'
In the expression: Node <$> traverse f t <*> Nothing
In an equation for `traverse':
traverse f (Node t Nothing) = Node <$> traverse f t <*> Nothing
* Relevant bindings include
f :: a -> f b (bound at exam.hs:94:12)
traverse :: (a -> f b) -> Tree a -> f (Tree b)
(bound at exam.hs:92:3)
|
94 | traverse f (Node t Nothing) = Node <$> traverse f t <*> Nothing
| ^^^^^^^
Could someone please give me some pointers or a possible fix for this issue?