I've found such code in the book "Real World Haskell", p68
data Tree a = Node a (Tree a) (Tree a)
| Empty
deriving (Show)
nodeAreSame (Node a _ _) (Node b _ _)
| a == b = Just a
nodeAreSame _ _ = Nothing
My question is: What job did the Just data constructor do? When I delete it, I will get error message such like
(in ghci)
......
<Main *> nodeAreSame (Node 3 Empty Empty) (Node 3 Empty Empty))
<interactive>:1:16:
No instance for (Num (Maybe a))
......
But when I try to compare the type difference between "Just" and "No Just" version:
nodeAreSameJust :: (Eq t) => Tree t -> Tree t -> Maybe t
nodeAreSameNoJust :: (Eq a) => Tree (Maybe a) -> Tree (Maybe a) -> Maybe a
So what is the key point here? Does it means when I put a var with type a in the node, the function will not output a node with type a, so it get an error?
In fact, the absence of Just does not make it ill-typed.
Here's the deal. The code
nodeAreSame (Node a _ _) (Node b _ _)
| a == b = a
nodeAreSame _ _ = Nothing
is well-typed provided that a and b are of type Maybe t for some t, since that's the type of Nothing. Thus the type system makes this inference.
Now, when you have a numeric literal like 3, it is inferred to be of type Num s => s until you actually commit it to a particular data type (like Int or Double).
So when it puts these two facts together, it presumes the following:
Num (Maybe t) => 3 :: Maybe t.
As there is no instance for Num (Maybe t), it complains at that point, before getting a chance to complain that 3 :: Maybe t makes no sense.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With