Haskell No instance arising from a use of 'print' - haskell

I want to write a function toTree that converts a list of values to a binary tree:
data Tree a = Leaf | Branch a (Tree a) (Tree a)
tree = Branch 6 (Branch 3 Leaf Leaf) (Branch 9 Leaf Leaf)
split :: [a] -> ([a], [a])
split lst = splitAt (((length lst) + 1) `div` 2) lst
toTree :: [a] -> Tree a
toTree (x: xs) = Branch x (toTree xm) (toTree xl) where (xm, xl) = split xs
toTree [] = Leaf
I cannot figure why I get this error on toTree [1,2,3]
No instance for (Show (Tree a0)) arising from a use of `print'
In the first argument of `print', namely `it'
In a stmt of an interactive GHCi command: print it
I know this is a simple error to fix but I cannot seem to find what is causing it. How can I resolve this issue?

just add
data Tree a = Leaf | Branch a (Tree a) (Tree a)
deriving Show
the error just says that Haskell does not know how to show a value of type Tree a0 (print is using show from the Show type-class)
And the easiest way is to auto-derive it
Or you have to implement it yourself using something like this:
instance (Show a) => Show (Tree a) where
show Leaf = "leaf"
show (Branch v l r) = "(left: " ++ show l ++ ") " ++ show v ++ " (right: " ++ show r ++ ")"
where I just made something up to give you something like this:
λ> toTree [1,2,3]
(left: (left: leaf) 2 (right: leaf)) 1 (right: (left: leaf) 3 (right: leaf))

Related

I can't get to work this Instances of Show / Functor for my Forest datatype

I've started programming in haskell like 2 months ago, im fairly new so don't expect me to be some top tier expect at monads or whatever please. I have tried in so many ways to get this Forest dataType be instance of functor and show, but i really don't know how to solve the conflicts that the compiler is giving to me. Such as:
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
|
15 | show ((Tree a) : (Forest s) ) = "[" ++ show a ++ "," ++ show s ++ "]"
| ^^^^
exercici3.hs:15:23: error: Not in scope: data constructor ‘Forest’
|
15 | show ((Tree a) : (Forest s) ) = "[" ++ show a ++ "," ++ show s ++ "]"
| ^^^^^^
exercici3.hs:19:12: error:
Not in scope: data constructor ‘Tree’
Perhaps you meant ‘True’ (imported from Prelude)
|
19 | fmap ((Tree a) : (Forest s)) = [f a] ++ (fmap f s)
| ^^^^
exercici3.hs:19:23: error: Not in scope: data constructor ‘Forest’
|
19 | fmap ((Tree a) : (Forest s)) = [f a] ++ (fmap f s)
| ^^^^^^
This is the font code of the classes. I've been thinking for a long time and i can't find a resonable solution, all help is welcome , thank you!
data Tree a = Empty | Node a (Tree a) (Tree a)
data Forest a = Nil | Cons (Tree a) (Forest a)
instance Show a => Show (Tree a) where
show Empty = "()"
show (Node b (xl) (xr)) = "(" ++ show xl ++ "," ++ (show b) ++ "," ++ show xr ++ ")"
instance Functor (Tree ) where
fmap f Empty = Empty
fmap f (Node a (xl) (xr)) = Node (f a) (fmap f xl) (fmap f xr)
instance Show a => Show (Forest a) where
show Nil = []
show ((Tree a) : (Forest s) ) = "[" ++ show a ++ "," ++ show s ++ "]"
instance Functor (Forest) where
fmap f Nil = []
fmap ((Tree a) : (Forest s)) = [f a] ++ (fmap f s)
Just to be clear, the Tree datatype works just fine, its just the syntactic part of the forest that doesnt seem to work at all.
The data constructor is Cons, not (:). Then you use for example x and xs as variables, where x has type Tree a, and xs has type Forest a:
instance Show a => Show (Forest a) where
show Nil = ""
show (Cons x xs) = "[" ++ show x ++ "," ++ show xs ++ "]"
instance Functor Forest where
fmap f Nil = Nil
fmap f (Cons x xs) = Cons (fmap f x) (fmap f xs)
That being said, I don't see much reasons to define a data type Forest here, you can define this as:
type Forest a = [Tree a]

Instance show tree in haskell

I'd like to instance show function for my binary tree, constructed this way: data Tree a = Nil | Leaf a | Branch a (Tree a) (Tree a).
I'd like to achieve a representation like "tree" unix command. For instance:
The showing function would be:
> 27
>> 14
>>> 10
>>> 19
>> 35
>>> 31
>>> 42
I want to tabulate each "subtree" with a recursive function but i don't kwow how this is my actual code:
instance (Show a)=>Show (Tree a) where
show Nil = ""
show (Leaf e) = show e
show (Branch e ls rs) = show e ++ "\n\t" ++ show ls ++ "\n\t" ++ show rs
So the question is: how can i implement a recursive tabulation function, because each time i use new line and tabulate just once instead of subtree depth
You can define a helper function, let's call it showWithDepth like this:
showWithDepth :: (Show a) => Tree a -> Int -> String
showWithDepth Nil _ = ""
showWithDepth (Leaf e) depth = (replicate depth '\t') ++ show e ++ "\n"
showWithDepth (Branch e ls rs) depth = (replicate depth '\t') ++ show e ++ "\n" ++ showWithDepth ls (depth+1) ++ showWithDepth rs (depth+1)
And now we can simply define Your instance like this:
instance (Show a)=>Show (Tree a) where
show x = showWithDepth x 0

Can this implementation of in-order traversal of a binary tree be improved?

I wrote a straightforward in-order-traversal function (toList1) for a binary tree. However, I worry about its complexity (memory / time). Is there a better way to implement it?
data Tree a = Empty | Node a (Tree a) (Tree a)
toList1 :: (Tree a) -> [a]
toList1 Empty = []
toList1 (Node x lx rx) = (toList lx) ++ [x] ++ (toList rx)
Haskell's append ++ performs linearly in the length of its left argument, which means that you may get quadratic performance if the tree leans left.
One possibility would be to use difference list.
Another one would be to define a Foldable instance:
data Tree a = Empty | Node a (Tree a) (Tree a)
instance Foldable Tree where
foldr f z Empty = z
foldr f z (Node a l r) = foldr f (f a (foldr f z r)) l
then, in-order-traversal comes out naturally:
toList :: Tree a -> [a]
toList = foldr (:) []
and
\> let tr = Node "root" (Node "left" Empty Empty) (Node "right" Empty Empty)
\> toList tr
["left","root","right"]

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)

Resources