I define Tree type as:
data Tree a = Leaf | Node a (Tree a) (Tree a)
deriving (Show, Eq)
Here are a fold function : How to write a function of type a-> b -> b -> b for folding a tree, basically same as what I using.
Now I want to write a function leafCount :: Tree a -> Integer, using fold and at most one helper function, I think I need to distinct leaf and node in different situation but I'm struggle with doing this, here is my code for now:
leafCount = fold sum (Node a left right)
where
sum left right elem = leafCount left + leafCount right + 1
There are lot of errors in this code now that I cannot figure out at all. Please give me the basic idea and the code that can improve mine.
Your immediate problem is that you are doing the pattern matching on the wrong side of the =:
leafCount (Node a left right) = fold sum left right a
where sum l r elem = leafCount left + leafCount right + 1
It's really easy actually, I forget to add the base case of the fold function when using it!
After I reading the fold stuff and ask other person, I figure this out!
Related
I am trying to use an unfold function to build trees.
Tree t = Leaf | Node (Tree t) t (Tree t)
unfoldT :: (b -> Maybe (b, a, b)) -> b -> Tree a
unfoldT f b =
case f b of
Nothing -> Leaf
Just (lt, x, rt) -> Node (unfoldT f lt) x (unfoldT f rt)
The build function needs to create a tree that has a height equal to the number provided, as well as be numbered in an in-order fashion. The base case being build 0 = Leaf and the next being build 1 = Node (Leaf 0 Leaf).
build :: Integer -> Tree Integer
My attempt at solving it:
build n = unfoldT (\x -> Just x) [0..2^n-2]
I am not entirely sure how to go about constructing the tree here.
Would love it if somebody could point me in the right direction.
Edit 1:
If I was to use a 2-tuple, what would I combine? I need to be able to refer to the current node, its left subtree and its right subtree somehow right?
If I was to use a 2-tuple, what would I combine?
I would recommend to pass the remaining depth as well as the offset from the left:
build = unfoldT level . (0,)
where
level (_, 0) = Nothing
level (o, n) = let mid = 2^(n-1)
in ((o, n-1), o+mid-1, (o+mid, n-1))
If I was to use a 2-tuple, what would I combine?
That's the key question behind the state-passing paradigm in functional programming, expressed also with the State Monad. We won't be dealing with the latter here, but maybe use the former.
But before that, do we really need to generate all the numbers in a list, and then work off that list? Don't we know in advance what are the numbers we'll be working with?
Of course we do, because the tree we're building is totally balanced and fully populated.
So if we have a function like
-- build2 (depth, startNum)
build2 :: (Int, Int) -> Tree Int
we can use it just the same to construct both halves of e.g. the build [0..14] tree:
build [0..14] == build2 (4,0) == Node (build2 (3,0)) 7 (build2 (3,8))
Right?
But if we didn't want to mess with the direct calculations of all the numbers involved, we could arrange for the aforementioned state-passing, with the twist to build2's interface:
-- depth, startNum tree, nextNum
build3 :: (Int, Int) -> (Tree Int, Int)
and use it like
build :: Int -> Tree Int -- correct!
build depth = build3 (depth, 0) -- intentionally incorrect
build3 :: (Int, Int) -> (Tree Int, Int) -- correct!
build3 (depth, start) = Node lt n rt -- intentionally incorrect
where
(lt, n) = build3 (depth-1, start) -- n is returned
(rt, m) = build3 (depth-1, n+1) -- and used, next
You will need to tweak the above to make all the pieces fit together (follow the types!), implementing the missing pieces of course and taking care of the corner / base cases.
Formulating this as an unfold would be the next step.
I have just started learning Haskell and I am trying to write a code for searching for a particular value in a binary tree and if present return true else false
This is how my tree structure looks like
data Tree = Leaf Int | Node Tree Int Tree
I am not sure how to proceed with the function to traverse through the tree and return the value. I did try BFS and DFS but I am not sure on how to return once I have got my value.
An example of how my function should look
Search 5 (Node (Node (Leaf 1) 3 (Leaf 4)) 5 (Node (Leaf 6) 7 (Leaf 9)))
A binary search could be written as follows. The type can be more generic, as we only need the items to be orderable to store / search in a binary tree.
We visit each node and either return true, or search in 1 of the child nodes.
example Node
5
/ \
3 7
lets search for 7.
We first visit the root. since 5 != 7, we test a child node. Since 7 > 5, we search in the right node, since 7 cannot appear in the left child (all values guaranteed to be lower than 5 on the left child)
If we reach a leaf, we just check if it contains the search term.
search :: Ord a => a -> BinaryTree a -> Bool
search a (Leaf b) = compare a b == EQ
search a (Node left b right)
case compare a b of
EQ -> True
LT -> search a left
GT -> search a right
I am not sure how to proceed with the function to traverse through the tree and return the value.
From that sentence, I understand you would have no problem writing a traversal yourself, but that there is a mental leap you need to take to understand how Haskell works.
You see, you never return anything in Haskell. Returning is fundamentally an imperative statement. Haskell is a declarative language, which means that writing programs is done by stating facts. That nuance can be discomforting, especially if you've been introduced to programming through learning imperative languages like C, Java, JavaScript, etc. But once you truly understand it, you will see how much more expressive and easy declarative programming is.
Because of its strong mathematical roots, in Haskell facts are stated in the form of equations, i.e. expressions where the = sign literally means the left- and right-hand side are equal (whereas in an imperative language, it would probably mean that you assign a value to a variable -- that does not exist in Haskell).
The program #Haleemur Ali wrote is in 1:1 correspondence with how you would write search using math notation:
search(x, t) = { x == y if t = Leaf y
, true if t = Node l y r and x == y
, search(x, l) if t = Node l y r and x < y
, search(x, r) if t = Node l y r and x > y
}
Indeed many times, at least as a beginner, writing Haskell is just a matter of translation, from math notation to Haskell notation. Another interpretation of Haskell programs is as proofs of theorems. Your search is a theorem saying that "if you have a tree and an integer, you can always tell if the integer is somewhere inside the tree". That's what you are telling the compiler when you write a function signature:
search :: Int -> Tree -> Bool
The compiler will only be happy if you write a proof for that theorem ... you probably guessed that the algorithm above is the proof.
An interesting observation is that the algorithm is almost dictated by the shape of the data type. Imagine you wanted to sum all the values in a tree instead:
sum(t) = { x if t = Leaf x
, x + sum(l) + sum(r) if t = Node l x r
}
Every time you want to write an algorithm over a binary tree, you will write something like the above. That is fairly mechanical and repetitive. What if later on you expand your program to deal with rose trees? Tries? You don't want to write the same algorithms and take the risk of making a mistake. One would try to come up with a function that walks down a tree and combines its values (using Haskell notation from now on):
walk :: (Int -> b) -> (b -> b -> b) -> Tree -> b
walk f g (Leaf x) = f x
walk f g (Node l x r) =
let a = walk f g l
b = walk f g r
in g (g (f x) a) b
With this function alone, you can write all manners of traversals on trees:
sum t = walk id (+) t
search x t = walk (== x) (||) t
walk is such a recurring pattern that it has been abstracted. All the data structures that expose the same pattern of recursion are said to be foldable, and the implementation is often so obvious that you can ask the compiler to write it for you, like so:
{-# LANGUAGE DeriveFoldable #-}
data Tree a = Leaf a | Node (Tree a) a (Tree a) deriving (Foldable)
There's even a definition of sum for any foldable data structure.
I want to count how many elements in a Tree "respect" a certain rule.
For example:
For the data type:
data Tree = Leaf Int | Node Tree Int Tree
and the function signature:
nSatisfy :: (Int->Bool) -> Tree -> Int
for the input:
(>0) Tree
it should return the values of the tree that are (>0).
Here's what i've tried:
nSatisfy :: (Int->Bool) -> Tree -> Int
nSatisfy condition Leaf x = if condition x then 1 else 0
nSatisfy condition (Node left x right)
|(if condition x then 1 else 0) + nSatisfy condition Tree
| otherwise = nSatisfy condition left || nSatisfy condition right
Any help?
UPDATE:
I found a much simpler way to do this:
nSatisfy :: (Int->Bool) -> Tree -> Int
nSatisfy n (Leaf x) = if n x then 1 else 0
nSatisfy n (Node left x right) = (if n x then 1 else 0) + (nSatisfy n left) + (nSatisfy n right)
That function is doing way too much at once: count, check a predicate and traverse a complex type.
I suggest to write a function
listFromTree :: Tree -> [Int]
and build your nSatisfy with listFromTree and the Prelude functions length and filter.
Edit: OP found a working answer himself, now here my code:
nSatisfy' p = length . filter p . listFromTree
listFromTree :: Tree -> [Int]
listFromTree (Leaf x) = [x]
listFromTree (Node left x right) = listFromTree left ++ [x] ++ listFromTree right
Functions that check something, i.e. a -> Bool are usually called predicate and shortened with p like in filter. n is usually an integer, not a function.
There's nothing wrong with your updated version. Luis Casillas and Franky, however, are encouraging you to think about breaking up the ideas in your code into the smallest possible pieces. This is generally the best way to deal with programming problems, for several reasons:
The human brain can only think about so much at once. If you break up the problem into different pieces or layers and only think about one at a time, you have a much better chance of solving it correctly.
You will create functions that you can reuse to solve other problems, and ways of thinking that you can reuse to solve other problems.
You will be able to test each piece of the solution separately. In this case, the problem is simple enough to test the whole solution, but in most realistic cases, waiting until you have a complete solution before you start testing will lead you down the rabbit hole of "I know it's wrong, but I don't know where".
Once you've broken your problem down into little pieces, you are much more likely to find that other people have already solved those problems. Sometime soon, your Haskell study will lead you to polymorphic data structures and functions. By generalizing your Tree type a little, you will gain the ability to use library functions like toList, fmap, and sum, building your solution from solution pieces that other people have written for you.
Well, here's a hint. You can solve this problem much more easily if you split it into three parts:
A mapTree :: (Int -> Int) -> Tree -> Tree function that applies the supplied function to every Int in the tree.
A function that tests an individual Int and returns 1 if it satisfies your condition, 0 otherwise.
A sumTree :: Tree -> Int function that sums all the Ints in a tree.
Then you can put these three parts together to solve your problem fairly easily. And what's more, mapTree and sumTree will be useful for other problems.
I'm trying to solve a similar problem (find the shortest list in a tree of lists) and I think that solving this problem would be a good start.
Given a data type like
data (Ord a, Eq a) => Tree a = Nil | Node (Tree a) a (Tree a)
How to find the node that holds the minimum element in the binary tree above?
Please not that this is not a binary search tree.
I'm trying to think recursively: The minimum is the minimum between the left, right subtrees and the current value. However, I'm struggling to translate this to Haskell code. One of the problems that I am facing is that I want to return the tree and not just the value.
Here's a hint:
You can start by defining, as an auxiliary function, a minimum between only two trees. Nodes are compared according to ther value, ignoring the subtrees, and comparing Nil to any tree t makes t the minimum (in a sense, we think of Nil as the "largest" tree). Coding this can be done by cases:
binaryMin :: Ord a => Tree a -> Tree a -> Tree a
binaryMin Nil t = t
binaryMin t Nil = t
binaryMin (Node l1 v1 r1) (Node l2 v2 r2) = ???
Then, the minimum subtree follows by recursion, exploiting binaryMin:
treeMin :: Ord a => Tree a -> Tree a
treeMin Nil = Nil
treeMin (Node left value right) = ???
where l = treeMin left
r = treeMin right
Note: class constraints on datatype declarations are no longer supported in Haskell 2010, and generally not recommended. So do this instead:
data Tree a = Nil
| Node (Tree a) a (Tree a)
Think recursively:
getMinTree :: Ord a => Tree a -> Maybe (Tree a)
getMinTree = snd <=< getMinTree'
getMinTree' :: Ord a => Tree a -> Maybe (a, Tree a)
getMinTree' Nil = ???
getMinTree' (Node Nil value Nil) = ???
getMinTree' (Node Nil value right) = ???
getMinTree' (Node left value Nil) = ???
getMin' (Node left value right) = ???
Note also: there is no need for an Eq constraint. Since Eq is a superclass of Ord, an Ord constraint implies an Eq constraint. I don't think you're even likely to use == for this.
You have the correct understanding. I think you should be fine when you can prove the following:
Can the tree with min be Nil
The tree with min probably has the min value at the root
So instead of just comparing the values, you might need to pattern-match the subtrees to get the value of the root node.
You didn't mention what the type of the function is. So, let's suppose it looks like so:
findmin :: Tree a -> Tree a
Now, suppose you already have a function that finds min of the tree. Something like:
findmin Nil = Nil -- no tree - no min
findmin (Node l x r) = case (findmin ..., findmin ...) of
-- like you said, find min of the left, and find min of the right
-- there will be a few cases of what the min is like on the left and right
-- so you can compare them to x
some case -> how to find the min in this case
some other case -> how to find min in that other case
Perhaps, you will need to know the answers to the first two questions.
It is so hard to give an answer short of giving away the actual code, since your thinking is already correct.
So I have a tree defined as
data Tree a = Leaf | Node a (Tree a) (Tree a) deriving Show
I know I can define Leaf to be Leaf a. But I really just want my nodes to have values. My problem is that when I do a search I have a return value function of type
Tree a -> a
Since leafs have no value I am confused how to say if you encounter a leaf do nothing. I tried nil, " ", ' ', [] nothing seems to work.
Edit Code
data Tree a = Leaf | Node a (Tree a) (Tree a) deriving Show
breadthFirst :: Tree a -> [a]
breadthFirst x = _breadthFirst [x]
_breadthFirst :: [Tree a] -> [a]
_breadthFirst [] = []
_breadthFirst xs = map treeValue xs ++
_breadthFirst (concat (map immediateChildren xs))
immediateChildren :: Tree a -> [Tree a]
immediateChildren (Leaf) = []
immediateChildren (Node n left right) = [left, right]
treeValue :: Tree a -> a
treeValue (Leaf) = //this is where i need nil
treeValue (Node n left right) = n
test = breadthFirst (Node 1 (Node 2 (Node 4 Leaf Leaf) Leaf) (Node 3 Leaf (Node 5 Leaf Leaf)))
main =
do putStrLn $ show $ test
In Haskell, types do not have an "empty" or nil value by default. When you have something of type Integer, for example, you always have an actual number and never anything like nil, null or None.
Most of the time, this behavior is good. You can never run into null pointer exceptions when you don't expect them, because you can never have nulls when you don't expect them. However, sometimes we really need to have a Nothing value of some sort; your tree function is a perfect example: if we don't find a result in the tree, we have to signify that somehow.
The most obvious way to add a "null" value like this is to just wrap it in a type:
data Nullable a = Null | NotNull a
So if you want an Integer which could also be Null, you just use a Nullable Integer. You could easily add this type yourself; there's nothing special about it.
Happily, the Haskell standard library has a type like this already, just with a different name:
data Maybe a = Nothing | Just a
you can use this type in your tree function as follows:
treeValue :: Tree a -> Maybe a
treeValue (Node value _ _) = Just value
treeValue Leaf = Nothing
You can use a value wrapped in a Maybe by pattern-matching. So if you have a list of [Maybe a] and you want to get a [String] out, you could do this:
showMaybe (Just a) = show a
showMaybe Nothing = ""
myList = map showMaybe listOfMaybes
Finally, there are a bunch of useful functions defined in the Data.Maybe module. For example, there is mapMaybe which maps a list and throws out all the Nothing values. This is probably what you would want to use for your _breadthFirst function, for example.
So my solution in this case would be to use Maybe and mapMaybe. To put it simply, you'd change treeValue to
treeValue :: Tree a -> Maybe a
treeValue (Leaf) = Nothing
treeValue (Node n left right) = Just n
Then instead of using map to combine this, use mapMaybe (from Data.Maybe) which will automatically strip away the Just and ignore it if it's Nothing.
mapMaybe treeValue xs
Voila!
Maybe is Haskell's way of saying "Something might not have a value" and is just defined like this:
data Maybe a = Just a | Nothing
It's the moral equivalent of having a Nullable type. Haskell just makes you acknowledge the fact that you'll have to handle the case where it is "null". When you need them, Data.Maybe has tons of useful functions, like mapMaybe available.
In this case, you can simply use a list comprehension instead of map and get rid of treeValue:
_breadthFirst xs = [n | Node n _ _ <- xs] ++ ...
This works because using a pattern on the left hand side of <- in a list comprehension skips items that don't match the pattern.
This function treeValue :: Tree a -> a can't be a total function, because not all Tree a values actually contain an a for you to return! A Leaf is analogous to the empty list [], which is still of type [a] but doesn't actually contain an a.
The head function from the standard library has the type [a] -> a, and it also can't work all of the time:
*Main> head []
*** Exception: Prelude.head: empty list
You could write treeValue to behave similarly:
treeValue :: Tree a -> a
treeValue Leaf = error "empty tree"
treeValue (Node n _ _) = n
But this won't actually help you, because now map treeValue xs will throw an error if any of the xs are Leaf values.
Experienced Haskellers usually try to avoid using head and functions like it for this very reason. Sure, there's no way to get an a from any given [a] or Tree a, but maybe you don't need to. In your case, you're really trying to get a list of a from a list of Tree, and you're happy for Leaf to simply contribute nothing to the list rather than throw an error. But treeValue :: Tree a -> a doesn't help you build that. It's the wrong function to help you solve your problem.
A function that helps you do whatever you need would be Tree a -> Maybe a, as explained very well in some other answers. That allows you to later decide what to do about the "missing" value. When you go to use the Maybe a, if there's really nothing else to do, you can call error then (or use fromJust which does exactly that), or you can decide what else to do. But a treeValue that claims to be able to return an a from any Tree a and then calls error when it can't denies any caller the ability to decide what to do if there's no a.