Haskell function which check whether a given value is in a tree - haskell

I m trying to create a function which check the whether a given value is in a tree, this what a got so far
data Tree = Null |
Node Int Tree Tree
deriving (Show)
testTree = Node 20 (Node 3 (Node 12 Null Null) (Node 7 Null Null))
(Node 8 (Node 4 (Node 6 Null Null) Null) Null)
isMember :: Int->Tree -> Bool
isMember x (Null) = False
isMember x(Node n st1 st2) = x == n
It didn't give me any error but I wanted to check the subtree as well

You just need to call isMember recursively on each subtree, as needed.
isMember :: Int -> Tree -> Bool
isMember x Null = False
isMember x (Node n st1 st2) = x == n || isMember x st1 || isMember x st2

You can make Tree a polymorphic type and make it an instance of Foldable. With the DeriveFoldable extension [ghc-doc], then you can make use of elem :: (Eq a, Foldable f) => a -> f a -> Bool to find out if the tree contains a given element:
{-# LANGUAGE DeriveFoldable #-}
data Tree a
= Null
| Node a (Tree a) (Tree a)
deriving (Foldable, Show)
Then your isMember is thus a special case of elem:
isMember :: Int -> Tree Int -> Bool
isMember = elem
For example:
Prelude> elem 5 testTree
False
Prelude> elem 20 testTree
True
Prelude> elem 4 testTree
True
Prelude> elem 7 testTree
True
Prelude> elem 9 testTree
False

Related

Can uniplate's `universeBi` be used to retrieve nodes in a breadth-first fashion?

Is it possible to use Uniplate's universeBi to get the output in breadth-first-order? It appears the results are returned in a depth-first fashion. I'm wondering how I can use uniplate to retrieve the universeBi in a breadth-first fashion.
To illustrate, consider the following toy program:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Generics.Uniplate.Data
data A = A B Int deriving (Data, Typeable)
data B = B Int deriving (Data, Typeable)
val :: A
val = A (B 1) 2
ints :: [Int]
ints = universeBi val
I get:
*Main> ints
[1,2]
But this is depth-first, as 1 is obtained from the B node. I'd rather get it in the breadth-first order, i.e., receive [2,1]. Is this achievable in uniplate?
You can dig into the structure of the Str returned by biplate:
layers :: Str a -> [[a]]
layers Zero = []
layers (One x) = [[x]]
layers (Two f x) = catLayers (layers f) ([] : layers x)
where catLayers [] ys = ys
catLayers xs [] = xs
catLayers (x : xs) (y : ys) = (x ++ y) : catLayers xs ys
layersBi :: Biplate from to => from -> [[to]]
layersBi = layers . fst . biplate
breadthBi :: Biplate from to => from -> [to]
breadthBi = concat . layersBi
So now
breadthBi (A (B 1) 2) :: [Int]
-- = [2, 1]
and
data Tree a = Branch (Tree a) a (Tree a) | Leaf deriving (Data, Typeable)
-- 4
-- 2 6
-- 1 3 5 7
example = Branch (Branch (Branch Leaf 1 Leaf) 2 (Branch Leaf 3 Leaf)) 4 (Branch (Branch Leaf 5 Leaf) 6 (Branch Leaf 7 Leaf))
(layersBi :: Data a => Tree a -> [[a]]) example
-- = [[],[4],[2,6],[1,3,5,7]]
I'm not sure if it's actually guaranteed that Str exactly reflects the structure of the data type, but it appears to. You could instead cook something out of the Data primitives if you have to.

Haskell using map to call function with more than one parameter

Let's say we have the following code representing binary trees where decodeInt searches the tree for an integer:
import Text.Show.Functions
data BinTree a b = Leaf b | Node a (BinTree a b) (BinTree a b) deriving Show
example :: BinTree (Int -> Bool) Char
example = Node (\x -> x > 4) (Node (\x -> x * x == x) (Leaf 'g') (Node (\x -> x == 0)
(Leaf 'u') (Leaf 'l'))) (Node (\x -> x >= 7) (Leaf 'f') (Leaf 'i'))
countInnerNodes :: BinTree a b -> Int
countInnerNodes (Node a b c) = 1 + countInnerNodes b + countInnerNodes c
countInnerNodes (Leaf x) = 0
decodeInt :: BinTree (Int -> Bool) b -> Int -> b
decodeInt (Leaf b) p = b
decodeInt (Node x y z) p = if (x(p) == True) then decodeInt z p else decodeInt y p
decode :: BinTree (Int -> Bool) b -> [Int] -> String
decode x [] = "empty list"
decode x xs = ??????
How can I use map to get a result like this when calling decode?
decode Tree [1,2,3,4]
= [decodeInt Tree (1), decodeInt Tree (2),
decodeInt Tree (3), decodeInt Tree (4)]
/edit: Followup
Let's also say we would like to create a function like the following
mapTree (\x -> ’e’) example
mapTree should return a BinTree just like example with the only difference being that the Char of every Leaf has been replaced with an 'e'. How do I accomplish that? I've started Haskell yesterday so I'm quite new to functional programming.
decodeInt :: BinTree (Int -> Bool) b -> Int -> b, so assuming t :: BinTree (Int -> Bool) b, then decodeInt t :: Int -> b. You map that function over your list of Ints.
decode t xs = let y = map (decodeInt t) xs
in ...
You'll still have to figure out how to convert y to the String value that decode is expected to return.
A bit too late but maybe this helps :
decode :: BinTree (Int -> Bool) b -> [Int] -> [b]
decode _ [] = []
decode x (y:ys) = decodeInt x y .... maybe you have an idea how to continue here ;)

check if tree is a subtree of another tree

I am trying to check out if tree is a subtree of another tree. Here is my data for Tree:
data Tree a = Empty | Node a (Tree a)(Tree a) deriving Show
tree1 :: Tree Int
tree1 = Node 1
(Node 2
(Node 4 Empty Empty)
(Node 5 Empty
(Node 8 Empty Empty))
)
(Node 3
(Node 6 Empty
(Node 9 Empty Empty))
(Node 7 Empty Empty)
)
tree2 :: Tree Int
tree2 = Node 2
(Node 4 Empty Empty)
(Node 5 Empty
(Node 8 Empty Empty))
And finally def of unfulfilled function:
isSubTree :: Eq a => Tree a -> Tree a -> Bool
isSubTree _ Empty = False
isSubTree Empty _ = False
isSubTree (Node a l r) (Node b ll rr) |
| otherwise = False
I need a hint how to fulfill first guardian - should i use elem or any other basic function? If I would want to find any specific element in tree I would use code below, so should I somehow modify that code?
treeMember x (Node a l r) |x `elem` [a] = True
|otherwise = treeMember x l || treeMember x r
A tree t1 is a (non-strict) subtree of a tree t2 given the two trees are equal, or t1 is a subtree of one of the (direct) children of t2.
We can let Haskell implement an instance for the Eq typeclass with:
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Eq, Show)
So now we can implement a check with:
isSubtree :: Eq a => Tree a -> Tree a -> Bool
isSubtree t1 t2 | t1 == t2 = True
isSubtree t1 (Node _ c1 c2) = …
isSubtree _ _ = False
where you still need to fill in the … part. I leave this as an exercise.

Relationships in a Tree (Haskell)

Binary trees with values in the leaves and nodes are defined by:
data Tree a = Leaf a
| Node a (Tree a) (Tree a)
deriving (Eq, Show)
For example,
10
/ \
/ \
8 2
/ \ / \
3 5 2 0
exTree :: Tree Int
exTree = N 10 (N 8 (H 3) (H 5))
(N 2 (H 2) (H 0))
Well, I need a function called RelationshipBinaryTree, which generates a list of tuples, whose first component is an x and its second the father. In this tree,
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree exTree = [(10,8),(8,3),(8,5),(10,2),(2,2),(2,0)]
Also, I need to define it in the Data.Tree hackage (https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Tree.html)
I hope you can help me because I don't understand trees and graphs very well.
I have tried this
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree (L _) = []
relationshipBinaryTree (N _ (Tree i) (Tree d)) = relationshipBinaryTree (N _) ++ relationshipBinaryTree (Tree i) ++ relationshipBinaryTree (Tree d)
You want to use Data.Tree, but Data.Tree isn't even about binary trees, but about multi way trees (a.k.a. rose trees). However, if you had a function value :: Tree a -> a, then of course you could map it to the children of a rose tree and combine the result with the value.
Now, there exists a function that does that in Data.Tree, it's called rootLabel. And there is another function to geht the children of a node, it's called subForest.
That comes from the definition of Tree in Data.Tree:
Node
rootLabel :: a -- label value
subForest :: Forest a -- zero or more child trees
So we could define for rose trees:
fatherChild :: Tree a -> [(a, a)]
fatherChild t = map mkPair children ++ concatMap fatherChild children
where mkPair child = (rootLabel t, child)
children = subForest t
Example:
fatherChild (Node 3 [Node 8 [], Node 4 []])
> [(3,8),(3,4)]
Your example:
fatherChild (Node 10 [Node 8 [Node 3 [], Node 5 []], Node 2 [Node 2 [], Node 0 []]])
> [(10,8),(10,2),(8,3),(8,5),(2,2),(2,0)]
Now, this doesn't answer your question about binary trees, but I would like to leave that to you as an exercise, because it will be very similar (except if you get stuck). (And please don't use rose trees as binary trees, because there is no type safety to ensure that there are always two children.)
A simple way to do it is by getting the value with an auxiliary function and then do the recursion:
data Tree a = Leaf a
| Node a (Tree a) (Tree a) deriving (Eq, Show)
exTree :: Tree Int
exTree = Node 10 t1 t2
t1 = Node 8 (Leaf 3) (Leaf 5)
t2 = Node 2 (Leaf 2) (Leaf 0)
relationshipBinaryTree :: Tree a -> [(a,a)]
relationshipBinaryTree (Leaf _) = []
relationshipBinaryTree (Node v i d) = [(v, getVal i), (v, getVal d)] ++ relationshipBinaryTree i ++ relationshipBinaryTree d
getVal (Node v _ _) = v
getVal (Leaf v) = v
relationshipBinaryTree exTree
=> [(10,8),(10,2),(8,3),(8,5),(2,2),(2,0)]

What's wrong with my isElement function (binary tree)?

I'm working on a a function that check whether an element is part of a binary tree. I've defined a type for my tree called Tree, functions to get the root element and the left and right subtrees, and a function called isElement for checking whether a value is into my tree. Unfortunately, the function only works with the root element.
The following example illustrates the incorrect results I get from my isElement function:
*Main>let tree = Node 1 Empty (Node 2 Empty (Node 3 Empty Empty))
*Main> isElement tree 2
False
*Main> isElement tree 3
False
*Main> isElement tree 1
True
This is my code:
data Tree a = Node a (Tree a) (Tree a)
|Empty
deriving (Show)
nodeValue :: Tree t -> t
nodeValue (Node x _ _) = x
rightTree :: Tree t -> Tree t
rightTree (Node _ _ x) = x
leftTree :: Tree t -> Tree t
leftTree (Node _ x _) = x
isNode :: Tree t -> Bool
isNode (Node _ _ _) = True
isNode _ = False
isElement :: (Eq t) => Tree t -> t -> Bool
isElement tree t
|isNode tree == False = False
| nodeValue(tree) == t = True
| otherwise = (isElement (leftTree(tree)) t) || (isElement (leftTree(tree)) t)
There is a mistake in the definition of your isElement function: you're calling leftTree twice, instead of calling both leftTree and rightTree. As a result, right subtrees are never explored. Amend the code accordingly,
isElement tree t
|isNode tree == False = False
| nodeValue(tree) == t = True
| otherwise = (isElement (leftTree(tree)) t) || (isElement (rightTree(tree))
and then isElement works as advertised:
λ> let tree = Node 1 Empty (Node 2 Empty (Node 3 Empty Empty))
λ> isElement tree 2
True
λ> isElement tree 3
True
λ> isElement tree 1
True
However, there is still room for improvement. You don't really need all those functions (isNode, nodeValue, etc.) to define isElement. Instead, you can do all that unpacking with pattern matching, by breaking down the definition into two equations: one corresponding to the case where the tree is empty, and another corresponding to the case where the tree is a node:
isElement :: (Eq a) => Tree a -> a -> Bool
isElement Empty _ = False
isElement (Node v l r) x = v == x || isElement l x || isElement r x
Edit: as pointed out by Luis Casillas in his comment, an additional benefit of this alternative definition is that it lends itself better (than the original definition) to exhaustiveness checking by the compiler.

Resources