Instance show with Tree data structure - haskell

I am new at haskell and I want to instance Tree a with the class show.
data Tree a = Null
|Node (Tree a) a (Tree a)
instance Show (Tree a) where
show Null = ""
show Node ((Tree l) (v) (Tree r)) = "|"--I don´t know how i can do this step
Thanks for your help.

Apply show recursively:
data Tree a = Null | Node (Tree a) a (Tree a)
instance Show a => Show (Tree a) where
show Null = "Null"
show (Node l v r) = "(" ++ show l ++ " " ++ show v ++ " " ++ show r ++ ")"

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

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 No instance arising from a use of 'print'

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))

Class Instances and ambiguous occurence in Haskell

Here is the code:
data Tree t = NilT
| Node t (Tree t) (Tree t)
instance Show (Tree t) where
show NilT = ""
show Node t l r = (show t) ++ ", " ++ (show l) ++ ", " ++ (show r)
how to use "show" in "t show" with the default setting and use "show" with the tree data with the definition given by myself?
In order to use show t, you must add the constraint Show t to your instance definition.
instance Show t => Show (Tree t) where
show NilT = ""
show (Node t l r) = show t ++ ", " ++ show l ++ ", " ++ show r
You were also missing parenthesis around your pattern Node t l r, and I removed the parenthesis around the calls to show, as they were redundant since function application already has the highest precedence.
Just a side note: There is a function Data.List.intersperse for putting a value between list elements.
show (Node t l r) = concat $ intersperse ", " [show t, show l, show r]
Or shorter, as hammar pointed out:
show (Node t l r) = intercalate ", " [show t, show l, show r]
Unfortunately you can't write map show [t, l, r], as the list elements need to have a unique type.

Resources