Reputation: 1065
I have the following data type for my tree.
data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving ( Show )
I'd like to print a representation of a given tree using a left to right depth first traversal.
For the moment, I've decided to go with pattern matching.
showt :: Tree a -> [Char]
showt ( Leaf a ) = [a]
...
When I try to run it using GHCi, here's the error I get
• Couldn't match expected type ‘Char’ with actual type ‘a’
‘a’ is a rigid type variable bound by
the type signature for:
showt :: forall a. Tree a -> [Char]
at 2016.hs:31:10
• In the expression: a
In the expression: [a]
In an equation for ‘showt’: showt (Leaf a) = [a]
• Relevant bindings include
a :: a (bound at 2016.hs:32:14)
showt :: Tree a -> [Char] (bound at 2016.hs:32:1)
I don't see where the problem comes from. Haskell should infer the type, no?
Upvotes: 1
Views: 225
Reputation: 476659
Well it is not because a data Tree a = ... deriving Show
, that it means that a
is a Char
.
It only means that Haskell has automatically added an type instance:
instance Show a => Show (Tree a) where
-- ...
So as you can see, it adds a type constraint: a
must be an instance of Show
in order for Tree a
to be an instance of Show
. So our first conclusion is a
can still be of any type.
Furthermore, even if a
is an instance of Show
, it does not mean that it is a String
(or Char
). It only means that there are some functions available like show :: (Show a) => a -> String
.
So there some options here:
you add a type constraint, and use show
:
showt :: Show a => Tree a -> [Char]
showt ( Leaf a ) = show a
--- ...
you restrict yourself to trees of type String
(or type Char
):
showt :: Tree Char -> [Char]
showt ( Leaf a ) = [a]
--- ...
Finally Haskell can infer the type of a function, but here you provide an explicit type signature. If you however omit the signature, you let Haskell derive it automatically:
Prelude> let showt ( Leaf a ) = [a]
Prelude> :t showt
showt :: Tree t -> [t]
Upvotes: 3