Converting rose trees to different binary tree types - haskell

I am completely lost on how to do some tree conversions in Haskell. I need to go from a rose tree defined as:
data Rose a = Node a [Rose a] deriving (Eq, Show, Ord)
to a binary tree which is defined as:
data Btree a = Empty | Fork a (Btree a) (Btree a) deriving (Eq, Show, Ord)
In my class I was given a function that is similar, but using a different definition of the binary tree. For that function the rose tree is defined the same and the binary tree is defined as:
Btree a = Leaf a | Fork (Btree a) (Btree a)
with the function from rose tree to binary tree defined as:
toB :: Rose a -> Btree a
toB (Node x xts) = foldl Fork (Leaf x) (map toB xts)
toB (Node x []) = foldl Fork (Leaf x) []
I have the answer but I don't know how to convert it so that it works with the new definition of Btree.

When I did something like this, I considered the "left" subtree to be the first child, and the "right" subtree to be the siblings of the node. This means that you convert the tree like so:
h h
/|\ /
/ | \ /
b d e ==> b->d->e
/ \ / \ / /
a c f g a->c f->g
h is still the root, but in the second diagram / is the left subtree and -> is the right. Leaves have no left subtree, but might have siblings (right subtrees). The root has no right subtree, but might have children (left subtree). Internal nodes have both.
Does that help?

Try to write a function converting from the first to the second definition of the binary tree. Then convB . toB is your new function! Now, systematically create a new function that acts directly as a fusion of the two, by inlining one into the other, and you'll get a straightforward and elegant solution.

Related

Haskell trees: how to get binary tree with leaf as any type?

Created a binary tree structure, values can be either a node with 2 branches, a leaf or empty. I've not specifically defined leaf to be a certain type so I can create trees with all leaves as integers or all as string, but how can I get it so that it accepts a mix of the 2 types, so a tree with leaves as integers aswell as strings?
data Tree a = Empty | Leaf a | Node a (Tree a) (Tree a)
Example of what I want: a node with 2 leaves, leaf1 = "a string" leaf2 = 5
My current problem is that leaf1 and leaf2 need to be same type so both either integers or both strings. I get an error If I do a mix.
Practically you can't create trees in Haskell that can contain any type. However, you can define custom types with multiple constructors like this:
data Val a b = Int a | String b deriving (Show, Eq)
You then use the Val type to create trees containing two types:
data Tree a = Leaf a | Node a (Tree a) (Tree a) deriving (Show, Eq)
let v = Node (String "eh") (Leaf (Int 12)) (Leaf (Int 123))
:t v
v :: Num a => Tree (Val a String)

Data type for Tree in Haskell

For a data type of a binary tree you can write something like this:
data Tree a = Nil | Node a (Tree a) (Tree a)
So if I do want to include trees, with Nodes having more than just two children, how could the data type possibly look like?
A lesser known technique is Left-child right-sibling where you can use the exact same type to encode trees with more than two children per node:
data Tree a
= Nil
| Node a (Tree a) (Tree a) -- value, left child, right sibling
The alternative [Tree a] does not have a performance advantage, since Haskell lists are linked lists.
You can either have a fixed branching factor:
data BinaryTree a = BTNil
| BTNode a (BinaryTree a) (BinaryTree a)
data TernaryTree a = TTNil
| TTNode a (TernaryTree a) (TernaryTree a) (TernaryTree a)
data QuadTree a = QTNil
| QTNode a (QuadTree a) (QuadTree a) (QuadTree a) (QuadTree a)
-- etc
(Note that QuadTree isn't a great name for a general tree with a branching factor of 4, since there is a specific data structure with that name.)
or you can simply use a rose tree, which stores an arbitrary list of children at each node.
data RoseTree a = RTNil | RTNode a [RoseTree a]
There is some duplication here, as RTNil is only needed to store an explicit empty tree. Leaf nodes are just RTNode a []. (Consider what difference, if any, you would assign to the values RTNode 3 [], RTNode 3 [RTNil], RTNode 3 [RTNil, RTNil], etc.)

Haskell Defining a Binary Tree

I want to define an infinite tree in Haskell using infinitree :: Tree, but want to set a pattern up for each node, defining what each node should be. The pattern is 1 more then then its parent. I am struggling on how to set up a tree to begin with, and how and where to define the pattern of each node?
Thank you
Infinite data structures can generally be defined by functions which call themselves but have no base case. Usually these functions don't need to pattern match on their arguments. For example, a list equal to [1..] can be written as
infiniteList :: [Int]
infiniteList = go 1 where
go n = n : go (n+1)
You can use the exact same technique for a tree:
data Tree a = Node (Tree a) a (Tree a) | Nil deriving (Show)
infiniteTree :: Tree Int
infiniteTree = go 1 where
go n = Node (go (2*n)) n (go (2*n+1))
This defines the infinite tree
1
/ \
2 3
/ \ / \
4 5 6 7
...
A type for infinite binary trees with no leaves:
data Tree a = Tree (Tree a) a (Tree a)
One general pattern for doing this sort of thing is called unfold. For this particular type:
unfold :: (a -> (a,b,a)) -> a -> Tree b
Can you see how to define this function and use it for your purpose?

confused about the type of the Instance of a binary tree data type of Int Nodes in Haskell

I made a binary tree data type in Haskell, according to this code:
data Tree a = EmptyTree
| Node a
(Tree a) (Tree a) deriving (Show,Eq)
and I also created a function to insert elements in the tree:
treeinsert :: (Ord a) => a -> Tree a -> Tree a
treeinsert x EmptyTree = leaf x
treeinsert x (Node a left right)
| x == a = Node x left right
| x < a = Node a (treeinsert x left) right
| x > a = Node a left (treeinsert x right)
Now, for testing I am using a list of Int elements, like this:
ghci> let nums = [8,6,4,1,7,3,5]
ghci> let numsTree = foldr treeInsert EmptyTree nums
ghci> numsTree
Node 5 (Node 3 (Node 1 EmptyTree EmptyTree) (Node 4 EmptyTree EmptyTree)) (Node 7 (Node 6 EmptyTree EmptyTree) (Node 8 EmptyTree EmptyTree))
My question is when I check the type of numsTree:
:type numsTree
numsTree :: Tree Integer
Why doesn't it just have the type of "Tree"?
I am a little confused.
(sorry for my language)
You defined the type Tree as a parametrised type. The a after Tree in the data type's definition is this parameter. This means that there is not just one Tree type, but many different ones. For example, you can have a type Tree Integer containing integers, a type Tree Bool containing booleans and a type Tree (String -> String) containing functions from string to string.
Note that it's a good thing that you can distinguish these different types. It means that when you get a value out of such a tree, you know which type of value you're going to get. If there was just one Tree type, then you wouldn't be able to find out.
Why doesn't it just have the type of "Tree"?
Because you explicitly pass the list of numbers to it which restricts the type.
If you define nTree = foldr treeInsert(in ghci prepend a let) you get the expected more general type. By the way, you may want to add Leaf a as another data constructor.

Monad instance for binary tree

I built binary tree with:
data Tree a = Empty
| Node a (Tree a) (Tree a)
deriving (Eq, Ord, Read, Show)
How can i make Monad type class instance for this tree? And can i make it on not?
i try:
instance Monad Tree where
return x = Node x Empty Empty
Empty >>= f = Empty
(Node x Empty Empty) >>= f = f x
But i can't make (>>=) for Node x left right.
Thank you.
There is no (good) monad for the type you just described, exactly. It would require rebalancing the tree and merging together the intermediate trees that are generated by the bind, and you can't rebalance based on any information in 'a' because you know nothing about it.
However, there is a similar tree structure
data Tree a = Tip a | Bin (Tree a) (Tree a)
which admits a monad
instance Monad Tree where
return = Tip
Tip a >>= f = f a
Bin l r >>= f = Bin (l >>= f) (r >>= f)
I talked about this and other tree structures a year or two back at Boston Haskell as a lead-in to talking about finger trees. The slides there may be helpful in exploring the difference between leafy and traditional binary trees.
The reason I said there is no good monad, is that any such monad would have to put the tree into a canonical form for a given number of entries to pass the monad laws or quotient out some balance concerns by not exposing the constructors to the end user, but doing the former would require much more stringent reordering than you get for instance from an AVL or weighted tree.

Resources