Haskell max from parameterized binary search tree - haskell

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)

Related

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.

Nil Value for Tree a -> a in Haskell

So I have a tree defined as
data Tree a = Leaf | Node a (Tree a) (Tree a) deriving Show
I know I can define Leaf to be Leaf a. But I really just want my nodes to have values. My problem is that when I do a search I have a return value function of type
Tree a -> a
Since leafs have no value I am confused how to say if you encounter a leaf do nothing. I tried nil, " ", ' ', [] nothing seems to work.
Edit Code
data Tree a = Leaf | Node a (Tree a) (Tree a) deriving Show
breadthFirst :: Tree a -> [a]
breadthFirst x = _breadthFirst [x]
_breadthFirst :: [Tree a] -> [a]
_breadthFirst [] = []
_breadthFirst xs = map treeValue xs ++
_breadthFirst (concat (map immediateChildren xs))
immediateChildren :: Tree a -> [Tree a]
immediateChildren (Leaf) = []
immediateChildren (Node n left right) = [left, right]
treeValue :: Tree a -> a
treeValue (Leaf) = //this is where i need nil
treeValue (Node n left right) = n
test = breadthFirst (Node 1 (Node 2 (Node 4 Leaf Leaf) Leaf) (Node 3 Leaf (Node 5 Leaf Leaf)))
main =
do putStrLn $ show $ test
In Haskell, types do not have an "empty" or nil value by default. When you have something of type Integer, for example, you always have an actual number and never anything like nil, null or None.
Most of the time, this behavior is good. You can never run into null pointer exceptions when you don't expect them, because you can never have nulls when you don't expect them. However, sometimes we really need to have a Nothing value of some sort; your tree function is a perfect example: if we don't find a result in the tree, we have to signify that somehow.
The most obvious way to add a "null" value like this is to just wrap it in a type:
data Nullable a = Null | NotNull a
So if you want an Integer which could also be Null, you just use a Nullable Integer. You could easily add this type yourself; there's nothing special about it.
Happily, the Haskell standard library has a type like this already, just with a different name:
data Maybe a = Nothing | Just a
you can use this type in your tree function as follows:
treeValue :: Tree a -> Maybe a
treeValue (Node value _ _) = Just value
treeValue Leaf = Nothing
You can use a value wrapped in a Maybe by pattern-matching. So if you have a list of [Maybe a] and you want to get a [String] out, you could do this:
showMaybe (Just a) = show a
showMaybe Nothing = ""
myList = map showMaybe listOfMaybes
Finally, there are a bunch of useful functions defined in the Data.Maybe module. For example, there is mapMaybe which maps a list and throws out all the Nothing values. This is probably what you would want to use for your _breadthFirst function, for example.
So my solution in this case would be to use Maybe and mapMaybe. To put it simply, you'd change treeValue to
treeValue :: Tree a -> Maybe a
treeValue (Leaf) = Nothing
treeValue (Node n left right) = Just n
Then instead of using map to combine this, use mapMaybe (from Data.Maybe) which will automatically strip away the Just and ignore it if it's Nothing.
mapMaybe treeValue xs
Voila!
Maybe is Haskell's way of saying "Something might not have a value" and is just defined like this:
data Maybe a = Just a | Nothing
It's the moral equivalent of having a Nullable type. Haskell just makes you acknowledge the fact that you'll have to handle the case where it is "null". When you need them, Data.Maybe has tons of useful functions, like mapMaybe available.
In this case, you can simply use a list comprehension instead of map and get rid of treeValue:
_breadthFirst xs = [n | Node n _ _ <- xs] ++ ...
This works because using a pattern on the left hand side of <- in a list comprehension skips items that don't match the pattern.
This function treeValue :: Tree a -> a can't be a total function, because not all Tree a values actually contain an a for you to return! A Leaf is analogous to the empty list [], which is still of type [a] but doesn't actually contain an a.
The head function from the standard library has the type [a] -> a, and it also can't work all of the time:
*Main> head []
*** Exception: Prelude.head: empty list
You could write treeValue to behave similarly:
treeValue :: Tree a -> a
treeValue Leaf = error "empty tree"
treeValue (Node n _ _) = n
But this won't actually help you, because now map treeValue xs will throw an error if any of the xs are Leaf values.
Experienced Haskellers usually try to avoid using head and functions like it for this very reason. Sure, there's no way to get an a from any given [a] or Tree a, but maybe you don't need to. In your case, you're really trying to get a list of a from a list of Tree, and you're happy for Leaf to simply contribute nothing to the list rather than throw an error. But treeValue :: Tree a -> a doesn't help you build that. It's the wrong function to help you solve your problem.
A function that helps you do whatever you need would be Tree a -> Maybe a, as explained very well in some other answers. That allows you to later decide what to do about the "missing" value. When you go to use the Maybe a, if there's really nothing else to do, you can call error then (or use fromJust which does exactly that), or you can decide what else to do. But a treeValue that claims to be able to return an a from any Tree a and then calls error when it can't denies any caller the ability to decide what to do if there's no a.

How do you match against the type "Either a b"?

The purpose for this particular portion of code is to make the size function more efficient than simply counting all the elements in elems. I've settled on summing the two types that make up the list, but I can't seem to create the signature of the size function.
instance (Finite a, Finite b) => Finite (Either a b) where
elems = combineLists [Left x | x <- elems] [Right x | x <-elems]
size ??? = (size a) + (size b)
From Prelude, we know that Either a b = Left a | Right b.
The first thing I tried was to match Either, but of course it is a type, so that doesn't work. Next, I tried ((Left a) | (Right b)), but no go on that either. Nothing else seems to match the type Either a b.
I was able to get size (Left a) to compile, but since it's missing the b component, I receive the error:
Ambiguous type variable `b' in the constraint:
`Finite b' arising from a use of `size' at <interactive>:1:0-12
which of course makes sense in the context, but I really have no clue how to match Either a b.
Anybody have any thoughts?
Something of type Either a b is either a Left a or a Right b, so you have two cases that can be handled separately:
size (Left x) = size x
size (Right x) = size x
The error about the ambiguous type variable is a separate issue.
If you just type something like size (Left 1) into the interpreter, the system can't deduce what the "right" type of that Left 1 value would be. It could be Either Int anything and as long as it is not known what type that anything is, it cannot be checked if it is in class Finite (which is required by size).
You can avoid that problem by specifying an explicit type signature:
size (Left 1 :: Either Int String)
The trouble seems to be that you need a dummy argument for size, but you can't pass dummies for both types a and b in a single Either a b. Perhaps you can use the elems to get a dummy of each type:
size _ = (size . head) (elems :: [a]) + (size . head) (elems :: [b])
I think the core issue you are having is that you want a type that represents a datum from each of two other types at the same time. Either a b can only be one of a or b at a give time.
A simple data type that represents both an a and a b at the same time is a 2-tuple. The type signature for such a thing is (a, b), which is also the expression for creating one, and hence pattern maching one:
> :type (4,5)
(4,5) :: (Num t, Num t1) => (t, t1)
> let f (a, b) = 2*a + b
> f (4,5)
13
You should consider writing your first line with a 2-tuple, like so:
instance (Finite a, Finite b) => Finite (a, b) where
What does this Finite (a, b) represent? What would the member function definitions be?

Resources