I'm going through the problems in the Haskell O'Reilly book. The problem I am working on is
Using the binary tree type that we defined earlier in this chapter,
write a function that will determine the height of the tree. The height
is the largest number of hops from the root to an Empty. For example, the
tree Empty has height zero; Node "x" Empty Empty has height one;
Node "x" Empty (Node "y" Empty Empty) has height two; and so on.
I'm writing my code in a file called ch3.hs. Here's my code:
36 data Tree a = Node a (Tree a) (Tree a)
37 | Empty
38 deriving (Show)
39
40 --problem 9:Determine the height of a tree
41 height :: Tree -> Int
42 height (Tree node left right) = if (left == Empty && right == Empty) then 0 else max (height left) (height right)
opening ghci in the terminal and typing :load ch3.hs. When I do that I get the following error:
Prelude> :load ch3.hs
[1 of 1] Compiling Main ( ch3.hs, interpreted )
ch3.hs:42:7: Not in scope: data constructor `Tree'
Failed, modules loaded: none.
I expect that the Tree data constructor should be there, because I defined it in the lines above the height method. But when I try to load the file, I'm told that the data constructor is not in scope. I appreciate your help and explanation of why this error occurs. Thanks, Kevin
Change
to
That means the pattern matching works on the constructors of the algebraic data type (ADT).
Tree
is not a constructor, it is the name of the ADT.Btw, you have to comment out your function signature declaration to compile the code because it contains an error.
You can then check the inferred type via
in ghci or hugs.
Your code is wrong, on several levels. It looks like you misunderstood algebraic data types.
Tree
is always aTree
of a specific type - which you calleda
in its declaration, and which may be any type (since you didn't constraint it). Soheigth
has to take aTree
of some type - aTree SomeType
, too. You can and should use the most generic type forSomeType
, i.e. a type variable likea
.Node a (Tree a) (Tree a)
orEmpty
- to match against, not against the type as a whole. Soheight (Node ...)
would match aNode
,height (Empty)
would match aEmpty
, andheight (Tree ...)
would try to match a constructor namedTree
, but there is none. That's the error message you recieve.==
) with a Constructor. It would actually work if you wrotederiving (Show, Eq)
. But you should use pattern matching to determine if you reached anEmpty
Node
, notEmpty
- you should add a clause forEmpty
.height
- which can, in turn, only return 0 or the max of their childrens'height
, etc ad infinitum. You have to increment the result at each level ;)You pattern-match against constructors, i.e. the cases, of your
Tree
ADT.Tree
is just what sums them all up.It's much more straightforward like this, and, most of all, correct: