Haskell - Creating a list by using functions - haskell

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]

Related

Return the Branch in a Data Tree Haskell

I am trying to return the branches in a Data Tree. Currently my code only returns the first branch.
data DTree a = Leaf a | Branch a (DTree a) (DTree a) deriving (Show)
get_b :: DTree Int -> [Int]
get_branches (Branch x _ _) = [x]
get_branches (Branch _ l r) = get_branches r ++ get_branches l
Example output
ghci > get_branches (Branch 2 (Leaf 3) (Branch 1 (Leaf 9) (Leaf 5)))
[2]
Perhaps this is something youre looking for?
get_branches :: DTree Int -> [Int]
get_branches (Branch x l r) = [x] ++ get_branches r ++ get_branches l
get_branches (Leaf x) = [x]
There is no base case for your function. So use the pattern 'Leaf'.
Additionally, the patterns (Branch x _ _) (Branch _ l r) are the same pattern, except with (Branch _ l r) you get the left and right branch.
Haskell will perform pattern matching from top to bottom. Since a Branch &hellip … … is matched by the first clause it will never trigger the second clause. Furthermore your program does not cover the Leaf case.
If you want to construct a list of values in the inodes (the Branches), then we can work with:
get_branches :: DTree a -> [a]
get_branches (Leaf _) = []
get_branches (Branch x l r) = x : get_branches r ++ get_branches l
here we first return the value of the branch, and then the values of the branches of the subtrees (first the left subtree and then the right subtree). For example with:
get_branches :: DTree a -> [a]
get_branches (Leaf _) = []
get_branches (Branch x l r) = get_branches r ++ x : get_branches l
this will result in a lot of appending, which is linear in the size of the first list. We can prevent this by making calls where we pass a recursive call as tail, so:
get_branches :: DTree a -> [a]
get_branches = go []
where go tl (Leaf _) = tl
go tl (Branch x l r) = go (x : go tl r) l

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

How to define a state monad?

I want to define a State monad that manages errors (in a sense like Maybe): if an error/problem occurs during the "do" computation, it is signal led and propagated by >>=.
The error should also contain a string describing it.
After, i want to apply this monad to mapTreeM, using for map a function that assumes states as numbers and a tree containing numbers, and at each visiting step updates the current state by adding to it the value of the current leaf; the resulting tree must contain a pair with the old leaf value and the state at the visiting instant. Such visit must fail if the state becomes negative during the computation, and succeed if it is positive.
e.g. Given this tree: Branch (Branch (Leaf 7) (Branch (Leaf (-1)) (Leaf 3))) (Branch (Leaf (-2)) (Leaf 9))
We obtain a tree (considering the initial state 0): Branch (Branch (Leaf (7,7)) (Branch (Leaf (-1,6)) (Leaf (3,9)))) (Branch (Leaf (-2,7)) (Leaf (9,16)))
If we put -18 in the second leaf, we should obtain an erroneous value signaling that we reached a negative state (-11).
I did a thing like this to print the tree without managing errors...i haven't understood how to do it.
The following is my code:
module Main where
-- State monad
newtype State st a = State (st -> (st, a))
instance Monad (State state) where
return x = State(\s -> (s,x))
State f >>= g = State(\oldstate ->
let (newstate, val) = f oldstate
State newf = g val
in newf newstate)
-- Recursive data structure for representing trees
data Tree a = Leaf a | Branch (Tree a) (Tree a)
deriving (Show,Eq)
-- Utility methods
getState :: State state state
getState = State(\state -> (state,state))
putState :: state -> State state ()
putState new = State(\_ -> (new, ()))
mapTreeM :: (Num a) => (a -> State state b) -> Tree a -> State state (Tree b)
mapTreeM f (Leaf a) =
f a >>= (\b -> return (Leaf b))
mapTreeM f (Branch lhs rhs) = do
lhs' <- mapTreeM f lhs
rhs' <- mapTreeM f rhs
return (Branch lhs' rhs')
numberTree :: (Num a) => Tree a -> State a (Tree (a,a))
numberTree tree = mapTreeM number tree
where number v = do
cur <- getState
putState(cur+v)
return (v,cur+v)
-- An instance of a tree
testTree = (Branch
(Branch
(Leaf 7) (Branch (Leaf (-1)) (Leaf 3)))
(Branch
(Leaf (-2)) (Leaf (-20))))
runStateM :: State state a -> state -> a
runStateM (State f) st = snd (f st)
main :: IO()
main = print $ runStateM (numberTree testTree) 0
Can I propose an alternative solution to your problem? While Monads are good for many things, what you want to do can be done with a simple function that
keeps track of errors.
My function transferVal below is an example of such function.
The function transferVal traverses the
Tree from left to right while keeping the last value found. If an error occurs, the function returns the error and stops traversing the Tree.
Instead of using Maybe, it is often better to use Either <error_type> <result_type> to get a more clear error if something goes wrong. In my example, I use ([ChildDir],a) where [ChildDir] contains the
"direction" of the incriminated node and a is the erroneous value that triggered the error. The function printErrorsOrTree is an example of how you can use the output of transferVal and main contains 4 examples of which the first three are correct and the last one triggers the error that you was expecting.
module Main where
import Data.List (intercalate)
import Control.Monad (mapM_)
data Tree a = Leaf a | Branch (Tree a) (Tree a)
deriving (Show,Eq)
-- given a Branch, in which child the error is?
data ChildDir = LeftChild | RightChild
deriving Show
-- an error is the direction to get to the error from the root and the
-- value that triggered the error
type Error a = ([ChildDir],a)
-- util to append a direction to an error
appendDir :: ChildDir -> Error a -> Error a
appendDir d (ds,x) = (d:ds,x)
transferVal :: (Ord a,Num a) => Tree a -> Either (Error a) (Tree (a,a))
transferVal = fmap fst . go 0
where go :: (Ord a,Num a) => a -> Tree a -> Either (Error a) (Tree (a,a),a)
go c (Leaf x) = let newC = x + c
in if newC < 0
then Left ([],newC)
else Right (Leaf (x,newC),newC)
go c (Branch t1 t2) = case go c t1 of
Left e -> Left $ appendDir LeftChild e
Right (newT1,newC) -> case go newC t2 of
Left e -> Left $ appendDir RightChild e
Right (newT2,newC') -> Right (Branch newT1 newT2,newC')
printErrorsOrTree :: (Show a,Show b) => Either (Error a) (Tree b) -> IO ()
printErrorsOrTree (Left (ds,x)) = putStrLn $ "Error in position " ++ (intercalate " -> " $ map show ds) ++ ". Error value is " ++ show x
printErrorsOrTree (Right t) = putStrLn $ "Result: " ++ show t
main :: IO ()
main = mapM_ runExample
[(Leaf 1)
,(Branch (Leaf 1) (Leaf 2))
,(Branch (Branch (Leaf 7) (Branch (Leaf (-1)) (Leaf 3))) (Branch (Leaf (-2)) (Leaf 9)))
,(Branch (Branch (Leaf 7) (Branch (Leaf (-11)) (Leaf 3))) (Branch (Leaf (-2)) (Leaf 9)))]
where runExample orig = do
let res = transferVal orig
print orig
printErrorsOrTree res
By making your Tree datatype an instance of Traversable, you can use mapM (from Data.Traversable) to map an action over a Tree. You can also layer the StateT monad transformer atop the Either monad to provide error handling.
import Control.Monad.State
import Control.Applicative
import Control.Monad.Error
import Data.Monoid
import Data.Foldable
import Data.Traversable
import qualified Data.Traversable as T
-- our monad which carries state but allows for errors with string message
type M s = StateT s (Either String)
data Tree a = Leaf a | Branch (Tree a) (Tree a)
deriving (Show,Eq)
-- Traversable requires Functor
instance Functor Tree where
fmap f (Leaf a) = Leaf (f a)
fmap f (Branch lhs rhs) = Branch (fmap f lhs) (fmap f rhs)
-- Traversable requires Foldable
instance Foldable Tree where
foldMap f (Leaf a) = f a
foldMap f (Branch lhs rhs) = foldMap f lhs `mappend` foldMap f rhs
-- Finally, we can get to Traversable
instance Traversable Tree where
traverse f (Leaf a) = Leaf <$> f a
traverse f (Branch lhs rhs) = Branch <$> traverse f lhs <*> traverse f rhs
testTree = (Branch
(Branch
(Leaf 7) (Branch (Leaf (-1)) (Leaf 3)))
(Branch
(Leaf (-2)) (Leaf (-20))))
numberTree :: (Num a, Ord a) => Tree a -> M a (Tree (a,a))
numberTree = T.mapM number where
number v = do
cur <- get
let nxt = cur+v
-- lift the error into the StateT layer
when (nxt < 0) $ throwError "state went negative"
put nxt
return (v, nxt)
main :: IO ()
main =
case evalStateT (numberTree testTree) 0 of
Left e -> putStrLn $ "Error: " ++ e
Right t -> putStrLn $ "Success: " ++ show t

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