When I compile the following code with GHC (using the -Wall flag):
module Main where
data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show)
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right)
| x == a = Node a left right
| x < a = Node a (insert x left) right
| x > a = Node a left (insert x right)
main :: IO()
main = do
let nums = [1..10]::[Int]
print . foldr insert EmptyTree $ nums
GHC complains that pattern matching in insert is non-exhaustive:
test.hs|6| 1:
|| Warning: Pattern match(es) are non-exhaustive
|| In an equation for `insert': Patterns not matched: _ (Node _ _ _)
Why is GHC issuing this warning? It is pretty obvious that the pattern GHC complains about is handled in insert x (Node a left right).
It's because the pattern matching is incomplete. There's no guarantee that one of x==a, x<a, or x>a holds. For instance, if the type is Double and x is NaN then none of them are True.
Riccardo is correct, GHC doesn't infer that your guards can't possibly all be false. So accept his answer please.
I'm going to digress and talk about coding style.
Your motivation for not using otherwise may have been that it looks unsightly:
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right)
| x == a = Node a left right
| x < a = Node a (insert x left) right
| otherwise = Node a left (insert x right)
Looking at this code, a human reader must confirm to themselves that the final guard accepts precisely those cases where x > a.
We could instead write it like this:
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right) = case x `compare` a of
EQ -> Node a left right
LT -> Node a (insert x left) right
GT -> Node a left (insert x right)
The Ordering type returned by compare has only the three values EQ, LT, and GT, so GHC can confirm that you've covered all possibilities, and a human reader can easily see that you've covered them correctly.
This is also more efficient code: we call compare once, instead of calling == and then probably calling < as well.
Now I'm going to digress some more and talk about laziness.
You've probably also written a function similar to this:
contains :: (Ord a) => a -> Tree a -> Bool
contains _ EmptyTree = False
contains x (Node a left right) = case x `compare` a of
EQ -> True
...
When x == a, you need to know that the tree uses the Node constructor, and that its first argument is equal to x. You don't need to know what either of the subtrees are.
But now look back at my definition of insert above. When the tree it's given is a Node, it always returns a Node whose first argument is always a. But it doesn't state that up front: instead it evaluates x `compare` a.
We can rewrite insert to perform the comparison as late as possible:
insert :: (Ord a) => a -> Tree a -> Tree a
insert x EmptyTree = Node x EmptyTree EmptyTree
insert x (Node a left right) = Node a newLeft newRight
where comparison = x `compare` a
newLeft = if comparison == LT then insert x left else left
newRight = if comparison == GT then insert x right else right
Now we return the Node a bit as soon as possible --- even if the comparison throws an error! --- and we still perform the comparison once at most.
GHC is not able to infer whether your three guards in the insert x (Node a left right) cover all possible cases, and consequently there will be no body to be associated with insert x (Node a left right). Try replacing the last condition x > a with otherwise (a synonim for True).
In this specific case however, it's true that the guards do not cover all cases, see augustss' example about double numbers.
Related
So I have a tree defined as follows:
data Tree = Node Tree Int Tree | Leaf Int
The Int for a Node in this case is the value at that Node. I am trying to check that a tree is balanced, and that the tree is increasing as it's traversed left to right.
To do so I have a recursive function that takes a (Node left x right) and checks that the difference in height of left and right (the nodes below it) is no more than one. I then call balanced again for left and right.
Is it possible to access the Int value of left and right?
Yes, you can write a function that returns the integer at the top node:
getInt (Node _ i _) = i
getInt (Leaf i) = i
E.g.
Prelude> getInt $ Leaf 42
42
Prelude> getInt $ Node (Leaf 42) 123 (Leaf 1337)
123
Of course you can, instead of put variables like left and right, use the constructors again:
Edit, I forget the case of Leaf, it has also an int:
data Tree = Node Tree Int Tree | Leaf Int
exampleSumNodes (Node left x right) = (treeToInt left) + x + (treeToInt right)
treeToInt (Node _ n _) = n
treeToInt (Leaf n ) = n
Im trying to write a little program that can check whether a given number appears in a Tree. This is my code:
import Prelude
data Tree = Node Int [Tree]
Tree happytree = Node 5 [Node 1 [Node 6 []],Node 8 [],Node 2 [Node 1 [],Node 4 []]]
contains1 :: [Tree] -> Int -> Bool
contains1 [] x = False
contains1 (a:as) x = contains a x || contains1 as x
contains :: Tree -> Int -> Bool
contains (Node x []) y = x==y
contains (Node x as) y = x==y || contains1 as y
Im getting the error message
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
What is this supposed to mean?
I was wondering if somebody could give me an advice how to write my contains function without writing the help function contains1.
Thanks in advance
You get the error from the declaration Tree happytree = .... It seems a C-style habit snuck into your code and you tried to declare the constant with a type in the wrong way.
It's just happytree = ... and the compiler deduces the type. If you want to specify it explicitly, you do it like with the functions and write happytree :: Tree on a separate line.
As for getting rid of contains1, it's testing whether any of the trees in the list contains the value, so you can get rid of it this way:
contains :: Tree -> Int -> Bool
contains (Node x []) y = x==y
contains (Node x as) y = x==y || any (`contains` y) as
I'm using section syntax here for the partially applied contains; you could instead write a lambda \a -> contains a y.
While Sebastian's answer tells you the problem (type declarations belong in their own lines), note that the error message stems from the following:
data Id Int = Id Int
Id x = Id 5
This is perfectly valid, since you're binding with a pattern Id x. It's similar to
(x:_) = [5..]
However, in order to do this, you need a data constructor, e.g. something that can create a value, like Node, whereas Tree is a type constructor, it creates (or in this case is) types. That's why you end up with that rather cryptic error message:
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
Either way, you can fix this by removing Tree from Tree happytree.
For your other question, use any:
contains :: Tree -> Int -> Bool
contains (Node x as) y = x == y || any (`contains` y) as
Note that elem-like functions (on lists elem :: Eq a => a -> [a] -> Bool) usually take the predicate first and the container last, which makes the application of contains easier:
contains :: Int -> Tree -> Bool
contains y (Node x as) = x == y || any (contains y) as
I am new to Haskell and I am trying to build a tree which holds integers and every element in the left subtree is <= node value.
This is the code that I have written so far but I don't know how to do the recursion inside. I would appreciate it if you could give me some guidance.
data Tree = Leaf | Node Int Tree Tree
deriving (Eq, Show, Read, Ord)
insert :: Int -> Tree -> Tree
insert x (Tree n i t1 t2) =
From what I understand is that I have to check each node of tree and see if there is an int to it and then recursively search the subtrees.
Please help
thanks
EDIT:
I managed to do something but it seems that the new nodes fail to be created or I am checking it wrong, this is the new code:
data Tree = Leaf | Node Int Tree Tree
deriving (Eq, Show, Read, Ord)
insert :: Int -> Tree -> Tree
insert x Leaf = Node x Leaf Leaf
insert x (Node i t1 t2)
| x <= i = insert x t1
| otherwise = insert x t2
To check it I write:
let tree = insert 5 (insert 10 ( insert 11 ( insert 12 (insert 15 tree))))
But when I write in the ghci:
tree
I get:
Node 5 Leaf Leaf
When you are inserting into a node, you are returning what would be inserted into one side of the Node, not a new Node with the data inserted into one side of it. Only at the Leaf level are you making a new node.
insert :: Int -> Tree -> Tree
insert x Leaf = Node x Leaf Leaf
insert x (Node i t1 t2)
| x <= i = Node i (insert x t1) t2
| otherwise = Node i t1 (insert x t2)
The problem with your recursive case for Node is that although you call insert to make a new sub tree on either the left or the right, you don't rebuild the parent tree afterwards, you just return the new sub tree.
For example the first case should be Node i (insert x t1) t2, and similarly for the second case.
Assume I have a binary tree:
data Bst a = Empty | Node (Bst a) a (Bst a)
I have to write a function that searches for a value and returns the number of its children. If there is no node with this value, it returns -1. I was trying to write both BFS and DFS, and I failed with both.
Pattern matching is your friend. Your Bst can either be Empty or a Node, so at the toplevel, your search function will be
search Empty = ...
search (Node left x right) = ...
Can an Empty tree possibly contain the target value? With a Node the target value, if present, will be either the node value (x above), in the left subtree, in the right subtree—or perhaps some combination of these.
By “return[ing] the number of its children,” I assume you mean the total number of descendants of the Bst rooted at a Node whose value is the target, which is an interesting combination of problems. You will want another function, say numChildren, whose definition uses pattern matching as above. Considerations:
How many descendants does an Empty tree have?
In the Node case, x doesn’t count because you want descendants. If only you had a function to count the number of children in the left and right subtrees …
Here is a way to do this. Breath-first search can actually be a bit tricky to implement and this solution (findBFS) has aweful complexity (appending to the list is O(n)) but you'll get the gist.
First I have decided to split out the finding functions to return the tree where the node element matches. That simplifies splitting out the counting function. Also, it is easier to return the number of elements than the number of descendants and return -1 in case not found, so the numDesc functions rely on the numElements function.
data Tree a = Empty
| Node a (Tree a) (Tree a)
numElements :: Tree a -> Int
numElements Empty = 0
numElements (Node _ l r) = 1 + numElements l + numElements r
findDFS :: Eq a => a -> Tree a -> Tree a
findDFS _ Empty = Empty
findDFS x node#(Node y l r) | x == y = node
| otherwise = case findDFS x l of
node'#(Node _ _ _) -> node'
Empty -> findDFS x r
findBFS :: Eq a => a -> [Tree a] -> Tree a
findBFS x [] = Empty
findBFS x ((Empty):ts) = findBFS x ts
findBFS x (node#(Node y _ _):ts) | x == y = node
findBFS x ((Node _ l r):ts) = findBFS x (ts ++ [l,r])
numDescDFS :: Eq a => a -> Tree a -> Int
numDescDFS x t = numElements (findDFS x t) - 1
numDescBFS :: Eq a => a -> Tree a -> Int
numDescBFS x t = numElements (findBFS x [t]) - 1
module Main where
import Data.List
import Data.Function
type Raw = (String, String)
icards = [("the", "le"),("savage", "violent"),("work", "travail"),
("wild", "sauvage"),("chance", "occasion"),("than a", "qu'un")]
data Entry = Entry {wrd, def :: String, len :: Int, phr :: Bool}
deriving Show
-- French-to-English, search-tree section
entries' :: [Entry]
entries' = map (\(x, y) -> Entry y x (length y) (' ' `elem` y)) icards
data Tree a = Empty | Tree a (Tree a) (Tree a)
tree :: Tree Entry
tree = build entries'
build :: [Entry] -> Tree Entry
build [] = Empty
build (e:es) = ins e (build es)
ins :: Entry -> Tree Entry -> Tree Entry
...
find :: Tree Entry -> Word -> String
...
translate' :: String -> String
translate' = unwords . (map (find tree)) . words
so i'm trying to design function ins and find but i am not sure where to start.any ideas?
I have no idea by which criteria the tree should be sorted, so I use just wrd. Then it would look like:
ins :: Entry -> Tree Entry -> Tree Entry
ins entry Empty = Tree entry Empty Empty
ins entry#(Entry w _ _ _) (Tree current#(Entry w1 _ _ _) left right)
| w == w1 = error "duplicate entry"
| w < w1 = Tree current (ins entry left) right
| otherwise = Tree current left (ins entry right)
How to get there?
As always when using recursion, you need a base case. Here it is very simple: If the tree is empty, just replace it by a node containing your data. There are no children for the new node, so we use Empty.
The case if you have a full node looks more difficult, but this is just due to pattern matching, the idea is very simple: If the entry is "smaller" you need to replace the left child with a version that contains the entry, if it is "bigger" you need to replace the right child.
If both node and entry have the same "size" you have three options: keep the old node, replace it by the new one (keeping the children) or throw an error (which seems the cleanest solution, so I did it here).
A simple generalization of Landei's answer:
ins :: Ord a => a -> Tree a -> Tree a
ins x Empty = Tree x Empty Empty
ins x (Tree x' l r) = case compare x x' of
EQ -> undefined
LT -> Tree x' (ins x l) r
GT -> Tree x' l (ins x r)
For this to work on Tree Entry, you will need to define an instance of Ord for Entry.