Sumation of tree - haskell

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

Related

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)

Relationships in a Tree (Haskell)

Binary trees with values in the leaves and nodes are defined by:
data Tree a = Leaf a
| Node a (Tree a) (Tree a)
deriving (Eq, Show)
For example,
10
/ \
/ \
8 2
/ \ / \
3 5 2 0
exTree :: Tree Int
exTree = N 10 (N 8 (H 3) (H 5))
(N 2 (H 2) (H 0))
Well, I need a function called RelationshipBinaryTree, which generates a list of tuples, whose first component is an x and its second the father. In this tree,
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree exTree = [(10,8),(8,3),(8,5),(10,2),(2,2),(2,0)]
Also, I need to define it in the Data.Tree hackage (https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Tree.html)
I hope you can help me because I don't understand trees and graphs very well.
I have tried this
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree (L _) = []
relationshipBinaryTree (N _ (Tree i) (Tree d)) = relationshipBinaryTree (N _) ++ relationshipBinaryTree (Tree i) ++ relationshipBinaryTree (Tree d)
You want to use Data.Tree, but Data.Tree isn't even about binary trees, but about multi way trees (a.k.a. rose trees). However, if you had a function value :: Tree a -> a, then of course you could map it to the children of a rose tree and combine the result with the value.
Now, there exists a function that does that in Data.Tree, it's called rootLabel. And there is another function to geht the children of a node, it's called subForest.
That comes from the definition of Tree in Data.Tree:
Node
rootLabel :: a -- label value
subForest :: Forest a -- zero or more child trees
So we could define for rose trees:
fatherChild :: Tree a -> [(a, a)]
fatherChild t = map mkPair children ++ concatMap fatherChild children
where mkPair child = (rootLabel t, child)
children = subForest t
Example:
fatherChild (Node 3 [Node 8 [], Node 4 []])
> [(3,8),(3,4)]
Your example:
fatherChild (Node 10 [Node 8 [Node 3 [], Node 5 []], Node 2 [Node 2 [], Node 0 []]])
> [(10,8),(10,2),(8,3),(8,5),(2,2),(2,0)]
Now, this doesn't answer your question about binary trees, but I would like to leave that to you as an exercise, because it will be very similar (except if you get stuck). (And please don't use rose trees as binary trees, because there is no type safety to ensure that there are always two children.)
A simple way to do it is by getting the value with an auxiliary function and then do the recursion:
data Tree a = Leaf a
| Node a (Tree a) (Tree a) deriving (Eq, Show)
exTree :: Tree Int
exTree = Node 10 t1 t2
t1 = Node 8 (Leaf 3) (Leaf 5)
t2 = Node 2 (Leaf 2) (Leaf 0)
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree (Leaf _) = []
relationshipBinaryTree (Node v i d) = [(v, getVal i), (v, getVal d)] ++ relationshipBinaryTree i ++ relationshipBinaryTree d
getVal (Node v _ _) = v
getVal (Leaf v) = v
relationshipBinaryTree exTree
=> [(10,8),(10,2),(8,3),(8,5),(2,2),(2,0)]

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]

Haskell Tree to List - preorder traversal

Given the following tree structure in Haskell:
data Tree = Leaf Int | Node Int Tree Tree deriving Show
How can I get Haskell to return a list of the data in pre-order?
e.g. given a tree:
Node 1 (Leaf 2) (Leaf 3)
return something like:
preorder = [1,2,3]
You could aim to a more general solution and make your data type an instance of Foldable.
There is a very similar example at hackage, but that implements a post-order visit.
If you want to support pre-order visits you will have to write something like this:
import qualified Data.Foldable as F
data Tree a = Leaf a | Node a (Tree a) (Tree a) deriving Show
instance F.Foldable Tree where
foldr f z (Leaf x) = f x z
foldr f z (Node k l r) = f k (F.foldr f (F.foldr f z r) l)
With this, you'll be able to use every function that works on Foldable types, like elem, foldr, foldr, sum, minimum, maximum and such (see here for reference).
In particular, the list you are searching for can be obtain with toList. Here are some examples of what you could write by having that instance declaration:
*Main> let t = Node 1 (Node 2 (Leaf 3) (Leaf 4)) (Leaf 5)
*Main> F.toList t
[1,2,3,4,5]
*Main> F.foldl (\a x -> a ++ [x]) [] t
[1,2,3,4,5]
*Main> F.foldr (\x a -> a ++ [x]) [] t
[5,4,3,2,1]
*Main> F.sum t
15
*Main> F.elem 3 t
True
*Main> F.elem 12 t
False
Use pattern matching
preorder (Leaf n) = [n]
preorder (Node n a b) = n:(preorder a) ++ (preorder b)
Ok, sorry about the late reply, but I got this working as follows:
preorder(Leaf n) = [n]
preorder(Node n treeL treeR) = [n] ++ preorder treeL ++ preorder treeR'code'
This however does not work for me still
preorder (Leaf n) = [n]
preorder (Node n a b) = n:(preorder a) ++ (preorder b)

Tree Traversal in 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.

Resources