Tree Traversal in Haskell - haskell

Here is a peice of code to traverse a tree which is not working:
data Tree = Leaf Int | Node Int Tree Tree deriving Show
preorder(Leaf n) = [n]
preorder(Node n t0 t1) = [n] ++ (preorder t0) ++ (preorder t1)
inorder(Leaf n) = [n]
inorder(Node n t0 t1) = (inorder t0) ++ [n] ++ (inorder t1)
postorder(Leaf n) = [n]
postorder(Node n t0 t1) = (postorder t0) ++ (postorder t1) ++ [n]
I have been asked to execute the following:
Node 8 (Node 3 (Leaf 5) (Leaf 2)) (Node 1 (Leaf 9) (Leaf 6))
When I execute the above statement it returns back as it is, when it should return:
preorder t = [8,3,5,2,1,9,6]
inorder t = [5,3,2,8,9,1,6]
postorder t =[5,2,3,9,6,1,8]
How can I fix this?

What you have given:
Node 8 (Node 3 (Leaf 5) (Leaf 2)) (Node 1 (Leaf 9) (Leaf 6))
is a value of type Tree. You can give this value a name by creating a binding or definition for it. If you're working in a source file, you can just do
myTree = Node 8 (Node 3 (Leaf 5) (Leaf 2)) (Node 1 (Leaf 9) (Leaf 6))
or give it a type signature:
myTree :: Tree -- this is the type signature
myTree = Node 8 (Node 3 (Leaf 5) (Leaf 2)) (Node 1 (Leaf 9) (Leaf 6))
If you're working in the interpreter, ghci, you can use let to create a new definition:
Prelude> let myTree = Node 8 (Node 3 (Leaf 5) (Leaf 2)) (Node 1 (Leaf 9) (Leaf 6))
Your task seems to be to evaluate each of the functions postorder, inorder and preorder when given this tree. If you're in a source file, you'll want to save the result in a definition:
inOrderResult :: [Int]
inOrderResult = inorder myTree
(Note that we passed in myTree as an argument to the function inorder.) And if you're working with ghci, just typing
Prelude> inorder myTree
will print the result to the terminal.

Related

How to merge two trees in Haskell

Assuming I am using a tree structured using the following:
data Tree a = LEAF a | NODE a (Tree a) (Tree a)
deriving (Show, Read, Eq)
How would I go about creating a function capable of adding together the values found at each equivalent node/leaf w/out importing any libraries (leaving me with the Prelude library), and is compatible with
function :: Num a => Tree a -> Tree a -> Tree a
As an example, assume the input is
left = NODE 1 (NODE 2 (NODE 3 (LEAF 4) (LEAF 5)) (LEAF 6)) (NODE 7 (LEAF 8) (LEAF 9))
right = NODE 1 (NODE 2 (LEAF 3) (LEAF 6)) (NODE 7 (NODE 8 (LEAF 10) (LEAF 11)) (LEAF 9))
merge_trees left right
Then the output should be
NODE 2
(NODE 4 (NODE 6 (LEAF 4) (LEAF 5)) (LEAF 12))
(NODE 14 (NODE 16 (LEAF 10) (LEAF 11)) (LEAF 18))
Any and all help would be appreciated.
This is really quite straightforward if we think through the different combinations of arguments to merge_trees.
A leaf and another leaf.
A leaf on the left and a node on the right.
A node on the left and a leaf on the right.
A node on the left and a node on the right.
The first case is very simple.
merge_trees (LEAF a) (LEAF b) = LEAF (a + b)
The second and third cases only require us to add the value of the leaf to the value of the node, and return the rest of the node unchanged.
merge_trees (LEAF a) (NODE b l r) = NODE (a + b) l r
merge_trees (NODE b l r) (LEAF a) = NODE (a + b) l r
The last option takes the most work but is fundamentally straightforward. We add the values of both nodes, and construct a new node with that value and the results of recursively applying merge_trees to the corresponding branches of both nodes.
merge_trees (NODE a l r) (NODE b l' r') = NODE v l'' r''
where
v = a + b
l'' = merge_trees l l'
r'' = merge_trees r r'
Prelude> left = NODE 1 (NODE 2 (NODE 3 (LEAF 4) (LEAF 5)) (LEAF 6)) (NODE 7 (LEAF 8) (LEAF 9))
Prelude> right = NODE 1 (NODE 2 (LEAF 3) (LEAF 6)) (NODE 7 (NODE 8 (LEAF 10) (LEAF 11)) (LEAF 9))
Prelude> merge_trees left right
NODE 2 (NODE 4 (NODE 6 (LEAF 4) (LEAF 5)) (LEAF 12)) (NODE 14 (NODE 16 (LEAF 10) (LEAF 11)) (LEAF 18))

Give a tree where value of each node holds the sum of child nodes

trying to figure out how to make a tree where the value of each node holds the sum of child nodes
data Tree a = LEAF a | NODE a (Tree a) (Tree a)
deriving (Show, Read, Eq)
addNode:: Num a => Tree a -> Tree a
addNode(NODE x (LEAF a) (LEAF b)) = (NODE (a+b) (LEAF a) (LEAF b))
addNode(NODE x left right) = (NODE x (addNode(left)) (addNode(right)))
tree1 = NODE 1
(NODE 2 (NODE 3 (LEAF 4) (LEAF 5)) (LEAF 6))
(NODE 7 (LEAF 8) (LEAF 9))
When I run the code I got:
addNode tree1
NODE 1 (NODE 2 (NODE 9 (LEAF 4) (LEAF 5)) *** Exception: testTree.hs:(105,1)-(106,89) Non-exhaustive patterns in function addNode
Can't figure out what's the cause, any help is much appreciated
We can generate a function that generates a 2-tuple where the first item is the sum of the tree, and the second item, the Tree itself:
addNode' :: Num a => Tree a -> (a, Tree a)
addNode' l#(LEAF x) = (x, l)
addNode' (NODE _ a b) = (sab, NODE sab ta tb)
where (sa, ta) = addNode' a
(sb, tb) = addNode' b
sab = sa + sb
We thus should both take the LEAF and the NODE into account. Likely we need to calculate the sum recursively of the subtrees, and sum these up in the node, therefore it is more efficient to use a 2-tuple here, to store the result of the sum thus far.
then we can define an addNode function that unpacks the 2-tuple and returns only the last element:
addNode :: Num a => Tree a -> Tree a
addNode = snd . addNode'
This thus will produce a tree like:
Prelude> addNode tree1
NODE 32 (NODE 15 (NODE 9 (LEAF 4) (LEAF 5)) (LEAF 6)) (NODE 17 (LEAF 8) (LEAF 9))
You where so close, you just need the base case, the LEAF:
data Tree a = LEAF a | NODE a (Tree a) (Tree a) deriving (Show, Read, Eq)
addNode:: Num a => Tree a -> Tree a
addNode (LEAF x) = LEAF x
addNode(NODE x left right) = NODE ((sumT left) + (sumT right)) (addNode left) (addNode right)
sumT :: Num a => Tree a -> a
sumT (LEAF a) = a
sumT (NODE _ left right) = (sumT left) + (sumT right)
t1 = NODE 1 t4 t3
t2 = NODE 3 (LEAF 4) (LEAF 5)
t3 = NODE 7 (LEAF 8) (LEAF 9)
t4 = NODE 2 t2 (LEAF 6)
NODE 1 (NODE 2 (NODE 3 (LEAF 4) (LEAF 5))
(LEAF 6))
(NODE 7 (LEAF 8) (LEAF 9))
$> addNode t1
NODE 32 (NODE 15 (NODE 9 (LEAF 4) (LEAF 5))
(LEAF 6))
(NODE 17 (LEAF 8) (LEAF 9))
(In general function that work on a particular type - e.g. Tree - have to pattern match on every value constructor from that type or else Haskell will rise non-exhaustive pattern match error)

Sumation of tree

So for this problem I tried to take the sum of all leaves in a tree. But it's shooting an error every time. I am providing a snippet of the code I wrote.
Sample case
t1 =NODE 1 (NODE 2 (NODE 3 (LEAF 4) (LEAF 5)) (LEAF 6)) (NODE 7 (LEAF 8) (LEAF 9))
Answer should be 32.
data Tree a = LEAF a | NODE a (Tree a) (Tree a) deriving (Show, Read, Eq)
tre (LEAF a) = a
tre (NODE a (Tree b) (Tree c)) = [Tree b, Tree c]
sum [] accum = []
sum list#(x:xs) accum = if tre x == Int
then sumTree xs (accum + x)
else sumTree x accum
sumTree :: Num p => Tree p -> p
sumTree p accum= let
list = tre p
in sum list accum
32
The Haskell snipet provided is not the idiomatic Haskell way of solving the problem.
You don't need the tre function => use Pattern matching on constructors of your type
You don't have to use tre x == Int let out the magic of type inference
I've provided the following snippet of the code, load it into ghci and use :i Tree and :i sumTree to understand the types
module Main where
data Tree a = Leaf a | Node a (Tree a) (Tree a) deriving (Show)
sumTree (Leaf a) = a
sumTree (Node a l r) = a + sumTree l + sumTree r
main = do
let tree = Node 5 (Node 21 (Leaf 14) (Leaf 13)) (Leaf 29)
putStrLn $ show tree
putStrLn $ show $ sumTree tree

Show Tree Haskell [duplicate]

This question already has answers here:
Haskell display Tree without Data.Tree or deriving(show)
(4 answers)
Closed 6 years ago.
Consider the following data type
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a
I'm trying to define an instance of Show (without importing any modules or using deriving) that would display the tree like so
Main*> let a = Branch "x" (Branch "y" (Leaf 4) (Leaf 7)) (Leaf 9)
Main*> a
"x"
"y"
4
7
9
So far, this is what I've come up with
findDepth (Leaf a) = 0
findDepth (Branch a (b) (c)) = 1 + (max (findDepth b) (findDepth c))
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a
instance (Show a, Show b) => Show (Tree a b) where
show (Leaf x) = show x
show (Branch a (b) (c)) =
show a ++ "\n" ++ s2 ++ show b ++ "\n" ++ s2 ++ show c ++ "\n" ++ s1
where
d = findDepth (Branch a (b) (c))
s1 = addSpace (d-1)
s2 = addSpace d
addSpace n = replicate n '\t'
Unfortunately, this indents the nodes with the lowest depth the most and the highest depth nodes the least. I know that the findDepth function should actually be giving leaf the greatest value and branch the lowest value, but can't figure out a way to write the function recursively for both arguments. Any suggestions?
Actually, there is no need for additional findDepth function - you could easily traverse through the tree and increase the depth each time you shows the children:
import Text.Printf
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a
instance (Show a, Show b) => Show (Tree a b) where
show = showAtLevel 0
where
showAtLevel l (Leaf x) = addSpace l ++ show x
showAtLevel l (Branch x (lt) (rt)) = printf "%s%s\n%s\n%s" (addSpace l) (show x) (showAtLevel (l + 1) lt) (showAtLevel (l + 1) rt)
addSpace = flip replicate '\t'
Test cases:
*Main> let a = Branch "x" (Branch "y" (Leaf 4) (Leaf 7)) (Leaf 9)
*Main> a
"x"
"y"
4
7
9
*Main> Branch "x" (Branch "y" (Leaf 4) (Branch "z" (Leaf 42) (Leaf 314))) (Leaf 9)
"x"
"y"
4
"z"
42
314
9
Here's a hint without he whole solution: Write a single function showWithDepth :: Int -> Tree -> String that passes down the "accrued depth" so far. Then you can write show = showWithDepth 0.
Note that in general you shouldn't write show instances like this, as its "semi-standard" that show instances should work essentially like the derived ones and generate something resembling valid Haskell code. (And additionally, in the presence of a Read instance, we want read . show === id.

Haskell - Creating a list by using functions

I want to do what the title says, but it keeps me showing errors. I put my code below.
data Tree a = Leaf a | Branch (Tree a) (Tree a) deriving Show
treeToList :: Tree a -> [a]
treeToList (Leaf x) = [x]
treeToList (Branch a b) = (treeToList a):(treeToList b)
It would show something like this:
treeToList Branch (Branch (Leaf 2) (Leaf 3)) (Leaf 4)
[2,3,4]
In the first pattern match you get a value of type list. Now all you have to do is concatenate them when you pattern match the Branch constructor.
treeToList :: Tree a -> [a]
treeToList (Leaf x) = [x]
treeToList (Branch a b) = (treeToList a) ++ (treeToList b)
Demo in ghci:
*Main> treeToList (Branch (Branch (Leaf 2) (Leaf 3)) (Leaf 4))
[2,3,4]

Resources