Beginning Haskell - getting "not in scope: data constructor" error - haskell

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
height (Tree node left right)
to
height (Node node left right)
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
:t height
in ghci or hugs.

Your code is wrong, on several levels. It looks like you misunderstood algebraic data types.
The type signature is wrong, a Tree is always a Tree of a specific type - which you called a in its declaration, and which may be any type (since you didn't constraint it). So heigth has to take a Tree of some type - a Tree SomeType, too. You can and should use the most generic type for SomeType, i.e. a type variable like a.
When pattern matching, you name a specific constructor - Node a (Tree a) (Tree a) or Empty - to match against, not against the type as a whole. So height (Node ...) would match a Node, height (Empty) would match a Empty, and height (Tree ...) would try to match a constructor named Tree, but there is none. That's the error message you recieve.
You never ever compare (via ==) with a Constructor. It would actually work if you wrote deriving (Show, Eq). But you should use pattern matching to determine if you reached an Empty
Which leads to: You're only matching Node, not Empty - you should add a clause for Empty.
Also, your function still returns 0 for all inputs if you fix all the above issues. You never return anything but 0 or the max of the childrens' 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:
height Empty = 0
height (Node _ l r) = 1 + max (height l) (height r)

Related

Haskell max from parameterized binary search tree

I have this function to get min value from my BST, type Int:
maxBST :: BST Int -> Int
maxBST Nil = -1000000
maxBST (Node left value right) = max (maxBST left) (max value (maxBST right))
Now I want to remake this function so that it also works for parameterized BST, like this:
maxBST :: (Ord t) => BST t -> t
maxBST Nil = //?
maxBST (Node left value right) = max (maxBST left) (max value (maxBST right))
The problem here is to find the correct //? value, so that it's minimum for type t. Do you have any suggestion for this?
The fundamental problem here is that your type signature (like that of maximum) is a lie. You cannot guarantee to produce the maximal element from a data structure that may contain no elements. A special sentinel value can paper over this issue in some cases, but even in those cases it breaks down if you look carefully. What is the minimum element of Node Nil -2000000 Nil? This is a nonempty tree, so you should be able to get its maximum, but your implementation returns -1000000 instead, as though the tree were empty!
One thing you could try that would do a better job of sweeping the problem under the rug would be to add a Bounded constraint, so that you could use minBound as the "neutral" element. Then at least you don't get erroneous results as in my example, but you still can't tell an empty tree from a tree containing only the minimum.
Better is to adjust your type signature to tell the truth. You can return Maybe t instead of just t, using Nothing to indicate "sorry, this tree was empty". As for implementation, you can just the the obvious brute-force thing of pattern-matching on the recursive calls - it's clunky, but it works.
Better still, though, would be to implement Foldable for your tree type (a good idea in any case), so that you can take advantage of its toList. Presuming that you have done so, this maximum function becomes easy:
maxBST t = case toList t of
[] -> Nothing
xs -> Just $ maximum xs
I agree with #amalloy's answer, that returning a Maybe type is the best approach here.
However, there is another approach if you are determined to always return an "actual value" and have it be a sensible "minimum" for the type. And that is to alter the type signature so that the elements of the tree must be of a type that is an instance of Bounded as well as Ord. This would be:
maxBST :: (Ord t, Bounded t) => BST t -> t
maxBST Nil = minBound
maxBST (Node left value right) = max (maxBST left) (max value (maxBST right))
Note that, although this will work on Int, it won't be identical to your original function, because the minBound for Int is much less than -1000000.
Don't goto nil, just destructure left and right and see if both of them are nil and handle the cases
maxBST Nil = error "your function shouldn't reach here"
maxBST (Node Nil value Nil) = value
maxBST (Node left#(Node _ _ _) value Nil) = max (maxBST left) value
maxBST (Node Nil value right#(Node _ _ _)) = max value (maxBST right)

Function to measure size of a binary tree

When i tried to size (N a (left a) (right a)) instead of size (N a left right), i was told by ghci that this line conflicts when the definition. I am not sure why because in my data signature, it is N a (Tree a) (Tree a). size is a function to count the number of nodes in a bin tree.
data Tree a = Nil | N a (Tree a) (Tree a) deriving (Show, Read, Eq)
size :: Tree Int -> Int
size Nil = 0
size (N _ left right) = 1 + size left + size right
When i tried to size (N a (left a) (right a)) instead of size (N a left right)
left and right in this case are expressions of type Tree Int.
a is not a known variable or type in this context.
In case the definition is updated to size (N a left right), then a is a bound expression of type Int.
To help you see what’s going on, you could write your match internal nodes to name the left and right subtrees and their respective values with
size (N _ left#(N a _ _) right#(N b _ _)) = 1 + size left + size right
Section 3.17.1 “Patterns” describes what is happening with the at signs, which allow the programmer to name the left and right subtrees.
Patterns of the form var#pat are called as-patterns, and allow one to use var as a name for the value being matched by pat.
The broad approach is inelegant for a number of reasons.
left and right are already constrained to be of type Tree because of the declaration of the Tree algebraic datatype.
Much worse, you’d also have to define the other three cases of size for either one or two Nil arguments.
Section 3.17.2 Informal Semantics of Pattern Matching outlines the cases for how the language handles patterns. Of especial note to you in the context of this question are
1. Matching the pattern var against a value v always succeeds and binds var to v.
and
5. Matching the pattern con pat1 … patn against a value, where con is a constructor defined by data, depends on the value:
If the value is of the form con v1 … vn, sub-patterns are matched left-to-right against the components of the data value; if all matches succeed, the overall match succeeds; the first to fail or diverge causes the overall match to fail or diverge, respectively.
If the value is of the form con′ v1 … vn, where con is a different constructor to con′, the match fails.
If the value is ⊥, the match diverges.
The first is how you want to do it and how you wrote it in your question, by binding the left and right subtree to variables. Your first attempt looked vaguely like binding to a constructor, and that’s why you got a syntax error.
Haskell pattern matching can be more sophisticated, e.g., view patterns. For learning exercises, master the basics first.

Haskell binary tree max int?

I'm trying to write a haskell function that will return the max int inside a binary tree of integers. My binary tree is defined as follows:
data Tree = Node Int Tree Tree | Leaf Int
deriving (Eq,Show)
The way I understand it this declaration is saying that for the 'Tree' data type, it can either be a single leaf int, or be a subtree containing two more trees.
So my maxInt function will look something like this ( I think )
maxInt :: Tree -> Int --maxInt function receives Tree, returns int
maxInt --something to detect if the Tree received is empty
--if only one node, return that int
--look through all nodes, find largest
and so when my function is given something like
maxInt (Node 5 (Leaf 7) (Leaf 2)) , the correct value for maxInt to return would be 7.
I'm new to haskell and don't really know where to start with this problem, I would really appreciate some guidance. Thank you
Let me start it for you:
maxInt :: Tree -> Int
maxInt (Leaf x) = ?
maxInt (Node x l r) = ?
You may find it helpful to use the standard function max, which takes two arguments and returns their maximum:
max 3 17 = 17
To begin with, we have this datatype:
data Tree = Node Int Tree Tree | Leaf Int
deriving (Eq,Show)
That means, we have two constructors for things of type Tree: either we have a Leaf with a single Int value, or we have a Node which allows us to represent bigger trees in a recursive fashion.
So, for example we can have these trees:
Leaf 0
And more complex ones:
Node 3 (Leaf 0) (Leaf 4)
Recall that this tree representation have information both in the leaves and in the nodes, so for our function we will need to take that into account.
You guessed correctly the type of the function maxInt, so you are halfway through!
In order to define this function, given we have a custom defined datatype, we can be confident in using pattern-matching.
Pattern-matching is, putting it simple, a way to define our functions by equations described by, on the left side, one element of our datatype (either Leaf or Node, in our case) and on the right side, the result value. I'd recommend you to learn more about pattern-matching here: pattern matching in Haskell
Hence, we start our function by its type, as you correctly guessed:
maxInt :: Tree -> Int
As we have seen earlier, we will use pattern-matching for this. What would be the first equation, that is, the first pattern-matching case for our function? The simplest tree we have given our datatype is Leaf value. So we start with:
maxInt (Leaf n) = n
Why n as a result? Because we don't have any other value than n in the tree and therefore it's the maximum.
What happens in a more complex case?
maxInt (Node n leftTree rightTree) = ...
Well... we can think that the maximum value for the tree (Node n leftTree rightTree) would be the maximum among n, the maximum value of leftTree and rightTree.
Would you be encouraged to write the second equation? I strongly recommend you to first read the chapter of the book I just linked above. Also, you might want to read about recursion in Haskell.

How to find the node that holds the minimum element in a binary tree in Haskell?

I'm trying to solve a similar problem (find the shortest list in a tree of lists) and I think that solving this problem would be a good start.
Given a data type like
data (Ord a, Eq a) => Tree a = Nil | Node (Tree a) a (Tree a)
How to find the node that holds the minimum element in the binary tree above?
Please not that this is not a binary search tree.
I'm trying to think recursively: The minimum is the minimum between the left, right subtrees and the current value. However, I'm struggling to translate this to Haskell code. One of the problems that I am facing is that I want to return the tree and not just the value.
Here's a hint:
You can start by defining, as an auxiliary function, a minimum between only two trees. Nodes are compared according to ther value, ignoring the subtrees, and comparing Nil to any tree t makes t the minimum (in a sense, we think of Nil as the "largest" tree). Coding this can be done by cases:
binaryMin :: Ord a => Tree a -> Tree a -> Tree a
binaryMin Nil t = t
binaryMin t Nil = t
binaryMin (Node l1 v1 r1) (Node l2 v2 r2) = ???
Then, the minimum subtree follows by recursion, exploiting binaryMin:
treeMin :: Ord a => Tree a -> Tree a
treeMin Nil = Nil
treeMin (Node left value right) = ???
where l = treeMin left
r = treeMin right
Note: class constraints on datatype declarations are no longer supported in Haskell 2010, and generally not recommended. So do this instead:
data Tree a = Nil
| Node (Tree a) a (Tree a)
Think recursively:
getMinTree :: Ord a => Tree a -> Maybe (Tree a)
getMinTree = snd <=< getMinTree'
getMinTree' :: Ord a => Tree a -> Maybe (a, Tree a)
getMinTree' Nil = ???
getMinTree' (Node Nil value Nil) = ???
getMinTree' (Node Nil value right) = ???
getMinTree' (Node left value Nil) = ???
getMin' (Node left value right) = ???
Note also: there is no need for an Eq constraint. Since Eq is a superclass of Ord, an Ord constraint implies an Eq constraint. I don't think you're even likely to use == for this.
You have the correct understanding. I think you should be fine when you can prove the following:
Can the tree with min be Nil
The tree with min probably has the min value at the root
So instead of just comparing the values, you might need to pattern-match the subtrees to get the value of the root node.
You didn't mention what the type of the function is. So, let's suppose it looks like so:
findmin :: Tree a -> Tree a
Now, suppose you already have a function that finds min of the tree. Something like:
findmin Nil = Nil -- no tree - no min
findmin (Node l x r) = case (findmin ..., findmin ...) of
-- like you said, find min of the left, and find min of the right
-- there will be a few cases of what the min is like on the left and right
-- so you can compare them to x
some case -> how to find the min in this case
some other case -> how to find min in that other case
Perhaps, you will need to know the answers to the first two questions.
It is so hard to give an answer short of giving away the actual code, since your thinking is already correct.

Haskell add value to tree

Im trying to make a funciton which allows me to add a new value to a tree IF the value at the given path is equal to ND (no data), this was my first attempt.
It checks the value etc, but the problem, is i want to be able to print the modified tree with the new data. can any one give me any pointers? I have also tried making a second function that checks the path to see if its ok to add data, but im just lost to how to print out the modified tree?
As iuliux points out, your problem is that you are treating your BTree as though it were a mutable structure. Remember functions in haskell take arguments and return a value. That is all. So when you "map over" a list, or traverse a tree your function needs to return a new tree.
The code you have is traversing the recursive tree and only returning the last leaf. Imagine for now that the leaf at the end of the path will always be ND. This is what you want:
add :: a -> Path -> Btree a -> Btree a
add da xs ND = Data da
add _ [] _ = error "You should make sure this doesn't happen or handle it"
add da (x:xs) (Branch st st2) =
case x of
L -> Branch (add da xs st) st2
R -> Branch st (add da xs st2)
Notice how in your original code you discard the Branch you pattern match against, when what you need to do is return it "behind you" as it were.
Now, on to the issue of handling situations where the leaf you arrive it is not a ND constructor:
This type of problem is common in functional programming. How can you return your recursive data structure "as you go" when the final result depends on a leaf far down the tree?
One solution for the trickiest of cases is the Zipper, which is a data structure that lets you go up down and sideways as you please. For your case that would be overkill.
I would suggest you change your function to the following:
add :: a -> Path -> Btree a -> Maybe (Btree a)
which means at each level you must return a Maybe (Btree a). Then use the Functor instance of Maybe in your recursive calls. Notice:
fmap (+1) (Just 2) == Just 3
fmap (+1) (Nothing) == Nothing
You should try to puzzle out the implementation for yourself!
I'm no expert in Haskell, but functional programming only works with functions. So kind of anything is a function.
Now, your function takes some input and returns something, not modifing the input. You have to retain the returned tree somewhere and that will be your new tree, the one with inserted element in it
We really need to see the Path and Error data types to answer your question, but you can print out your trees using the IO Monad:
main :: IO()
main = do let b = Branch ND (Branch (Data 1) (Data 2))
let b1 = add 10 [L] b --actual call depends on definition of Path
(putStrLn . show) b1

Resources