Help In Declaring Variable Number Of Arguments - haskell

High Guys,
I have to define a polymorphic datatype for a tree that can have multiple nodes. Each node can have any number of children and a vlaue. This type will always have at least one node. I am new in Haskell so am asking how can i declare the node to have variable number of arguments.
This is what i have now. This is a tree that can have a Node or a node with value (a) and two tree children. Instead of two tree children, i want them to be any number of tree children. (Analoog as java variable number of arguments "arg...")
data Tree a = Node a | Node a (Tree a) (Tree a) deriving (Show)
Thanks for your help
EDIT
A little question::: How can i declare this node with variable arguments in a functions
parameter(header/signature). I have to implement a function called
"contains" which will check if a Node contains a specific element.
contains :: Tree a -> b -> Bool
contains (Node val [(tree)]) = ......
Is the second line correct ?

it would be:
data Tree a = Node a | Node a [(Tree a)] deriving (Show)
but in addition there is a second problem that this should be
data Tree a = Leaf a | Branch a [(Tree a)] deriving (Show)
or such as the parts of a union must have different names as otherwise you couldn't use pattern matching
Leaf and Branch are data constructors so:
Branch 1 [Leaf 3, Branch 6 [Leaf 5]]
is an example of a Tree
contains :: Tree a -> a -> Boolean
contains (Leaf a) b = a == b
contains (Branch a c) b = a == b || any (map (\t -> contains t b) c)
or such

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.

Converting rose trees to different binary tree types

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.

Resources