Instance show tree in haskell - 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

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 of Show list for a custom datatype

I have defined a (Matrix) datatype, as a 2D list:
newtype Matrix a = M [[a]]
and an instance for Show, as follows:
instance Show a => Show (Matrix a) where
show (M a) = intercalate "\n" (map (unwords . map show) a) ++ "\n"
Which behaves like so:
> mat = M [[3,1,8],[6,3,0],[6,8,8]]
> mat
3 1 8
6 3 0
6 8 8
However, I'd like to handle how it prints lists, because the default behaviour looks a bit weird. How do I specify this? I've tried something like these:
instance Show a => Show ([Matrix a]) where
show mat = case mat of
[M a] -> intercalate "\n" (map (unwords . map show) a) ++ "\n"
(m:ms) -> show m ++ "\n" ++ show ms
instance Show a => Show (Matrix a) where
show (M a) = intercalate "\n" (map (unwords . map show) a) ++ "\n"
show (m:ms) = show m ++ "\n" ++ show ms
But I just get syntax errors. I tried googling the issue, but I couldn't find anything (Perhaps I used the wrong keywords?)
Thanks in advance.
EDIT:
Desired input and output:
mat1 = M [[1,2],[3,4]]
mat2 = M [[1,2],[3,4]]
> [mat1, mat2]
1 2
3 4,
1 2
3 4
This is exactly what the showList method is for:
instance Show a => Show (Matrix a) where
show (M a) = intercalate "\n" (map (unwords . map show) a) ++ "\n"
showList (m:ms) = shows m . ("\n" ++) . showList ms
Note that this doesn't handle empty lists, though, so you also need
showList [] = id
(or whatever you want it to show for empty lists.)

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

Displaying binary tree in Haskell

data BinTree a = Empty | Node a (BinTree a) (BinTree a)
deriving (Show)
I'm trying to figure out a way to display a binary tree in a manner such that for each level I go down in the tree, I want to add an additional * next to the name of the node and have them all separated by \n.
For example:
let x = Node "Parent" (Node "childLeft" (Node "grandChildLeftLeft" Emp Emp) Emp) (Node "childRight" Emp Emp)
putStrLn $ displayTree x
should return:
"Parent"
*"childLeft"
**"grandChildLeftLeft"
*"childRight"
My function (only prints up to one *):
displayTree :: Show a => BinTree a -> String
displayTree Emp = ""
displayTree (Node head Emp Emp) = (show head)
displayTree (Node head left Emp) = (show head) ++ "\n*" ++ displayTree left
displayTree (Node head Emp right) = (show head) ++ "\n*" ++ displayTree right
displayTree (Node head left right) = (show head) ++ "\n*" ++ displayTree left ++ "\n*" ++ displayTree right
My displayTree function would print:
"Parent"
*"childLeft"
*"grandChildLeftLeft"
*"childRight"
I want "grandChildLeftLeft" to have ** next to it instead of just *.
Any suggestions?
NOTE: I don't want to change the parameters that are passed into the function, so it should stay as displayTree :: Show a => BinTree a -> String
I think this is what you want:
module Main (main) where
data BinTree a = Empty | Node a (BinTree a) (BinTree a)
deriving (Show)
showTree :: Show a => BinTree a -> Int -> String
showTree (Empty) _ = []
showTree (Node t l r) n = replicate n '*' ++ show t ++ "\n" ++ showTree l (n+1) ++ showTree r (n+1)
main :: IO ()
main = do
let x = Node "Parent" (Node "childLeft" (Node "grandChildLeftLeft" Empty Empty) Empty) (Node "childRight" Empty Empty)
putStrLn $ showTree x 0
Note the accumulator n which changes the indent level with each recursive call.
http://ideone.com/lphCoV
"Parent"
*"childLeft"
**"grandChildLeftLeft"
*"childRight"
Why not pass in the depth to the displayTree function?
displayTree :: Show a => BinTree a -> String
displayTree = displayTree' ""
displayTree' str Emp = ""
displayTree' str (Node head Emp Emp) = str ++ (show head)
displayTree' str (Node head left Emp) = str ++ (show head) ++ "\n" ++ displayTree' (str ++ "*") left
displayTree' str (Node head Emp right) = str ++ (show head) ++ "\n" ++ displayTree' (str ++ "*") right
displayTree' str (Node head left right) = str ++ (show head) ++ "\n" ++ displayTree' (str ++ "*") left ++ "\n" ++ displayTree (str ++ "*") right
Also, here's it refactored to be kinda more readable:
displayTree :: Show a => BinTree a -> String
displayTree = displayTree' ""
displayTree' str Empty = ""
displayTree' str (Node h l r) = hstr ++ lstr ++ rstr
where
hstr = str ++ (show head) ++ "\n"
lstr = makeTreeStr l
rstr = makeTreeStr r
makeTreeStr Empty = ""
makeTreeStr tree = displayTree' (str ++ "*") tree ++ "\n"

Resources