Tree to a list of possible paths (values) - haskell

Given a tree data structure defined as
data Tree = Node Int Tree Tree | Leaf
How can one transform it into a list of values along all paths?
For example Node 1 (Node 2 Leaf Leaf) (Node 3 Leaf Leaf) should translate to [[1,2], [1,3]].

You have a recursive data structure, so you should expect a recursive solution. The first step in such a solution is to identify the base cases. For this problem, there is the obvious base case: Leaf. We probably also want to treat Node x Leaf Leaf as a base case to avoid duplicate paths.
Now let's write down the type signature. This should make it clear what our base cases should produce.
paths :: Tree -> [[Int]]
For Leaf the sensible thing to do is return a list containing an empty list since a Leaf is representing an empty path.
paths Leaf = [[]]
For Node x Leaf Leaf, we can return a list consisting of a list containing x.
paths (Node x Leaf Leaf) = [[x]]
The next part requires the most thought. We need to consider what to do with the non-base case Node x left right. The strategy here is to assume that we have the result of paths left and paths right and then decide what we need to do with x. We're building paths, so we need to tack x onto the front of all the left paths and the right paths. We also need to combine the two lists into a single list.
paths (Node x left right) = map (x:) (paths left ++ paths right)
And that's it. Of course, now you might want to see if there's a more efficient way to implement it, or if there's a common pattern here instead (i.e. can we write this as a fold?).

The answer here is very simple, so for a Tree structure such as the one you provided, if we have:
data Tree = Node Int Tree Tree | Leaf
We would need a nested function within our function, basically a function which returns a list from a branch, this way we can have the first argument of the Tree (the trunk or initial value) separated from values of either of the branches, but I'm sure there is a more efficient implementation, so here it is:
traverse :: Tree a -> [[Int]] -- Do not use "a" in the return type
traverse Leaf = [[]]
traverse (Node value left right) = [value] ++ treeToList left : [value] ++ treeToList right : []
where treeToList Leaf = []
treeToList (Node a left right) = [a] ++ treeToList left ++ treeToList right
returns
> traverse (Node 2 (Node 3 Leaf Leaf) (Node 4 Leaf Leaf))
> [[2,3],[2,4]]
Be careful with the return type as Tree a denotes that a is polymorphic but the constructor Node takes only values of type Int, denoting the returned list can only be of type Int.

Related

Find all the partial paths in a tree

I am trying to create a Haskell function that generates a list containing all the partial paths of a tree, given the tree implementation data Tree a = Empty | Node a (Tree a) (Tree a). For example, if I have a tree
tree = Node 5 (Node 3 Empty Empty ) (Node 2 Empty Empty )
I want to get
[[],[5],[5,3],[5,2]]
How could I make such a function?
First let us consider the type of this function, it must be Tree a -> [[a]].
So what can we do given a node Node x left right? We have the path that is just the node itself - this is just [x], as well as the paths that go through this node to the left- and right sub tree. The paths going throu the left and right sub tree are just what we get if we apply our function to left and right respectively. We now just need to add x to the start of each of those paths and we do that by calling map(x:) paths. (And for an empty one we should get an empty list as there is no path.)
data Tree a = Empty | Node a (Tree a) (Tree a)
tree = Node 5 (Node 3 Empty Empty ) (Node 2 Empty Empty )
pp :: Tree a -> [[a]]
pp (Node x left right) = [[x]] ++ map(x:)(pp left) ++ map(x:)(pp right)
pp Empty = []
Now this has one flaw that the empty path is not considered as a partial path by this function. But we can easily amend that by adding it and wrapping it in another function:
partialPaths :: Tree a -> [[a]]
partialPaths t = [[]] ++ pp t
main = print $ partialPaths tree
Try it online!

How do I print a list of nodes at a specific level of a general tree?

I am given the following tree definition and functions:
data Tree a = Node a [Tree a] deriving (Eq, Read, Show)
treeRoot :: Tree a -> a
treeRoot (Node a _) = a
treeSubtrees :: Tree a -> [Tree a]
treeSubtrees (Node _ subtrees) = subtrees
I need to create a function 'nodesAtLevel' that takes two arguments: a tree and an integer n >= 0. The function needs to return a list of all the nodes at the given level n. The root of the tree is level 0. I am very new to Haskell, and yes, this is part of a homework assignment, so if you could help walk me through the thought process of completing this, it would be greatly appreciated! I currently have the definition of the 'nodesAtLevel' function written as follows:
nodesAtLevel :: Int -> Tree a -> [a]
Ok, let's to this step by step (leaving you with some holes for now):
nodes at level 0
as I understand it you are suppost to only return the roots value here (of course in a list)
so what goes in the ... here?
nodesAtLevel 0 (Node a subtrees) = ...
nodes at deeper levels
well the structure is nicely recursive so we probably want to use recursion.
So let's go recursively deeper one level deeper (decreasing the way we have left to go - aka our n)
But there is a slight problem: nodesAtLevel acts on a single node but we only have a list of nodes left (the subtrees) .. so what to do?
Well maybe we should do something for each of the subtrees/subnodes - so we need to find the right function f here (hint you probably want to map and concat the results ...):
nodesAtLevel n (Node a subtrees) = f (nodesAtLevel (n-1)) subtrees
what can that f be? Can you guess it? Maybe you can write it yourself if not?
Additional Hint:
maybe you should first find out what type f has - because then you might be even able to use Hoogle to find a good fit.
If you use a newer GHC version you an let the compiler do the work if you write
nodesAtLevel n (Node _ subtrees) = _f (nodesAtLevel (n-1)) subtrees
where _f is a hole - now if you load this in GHCi it will give you a
Found hole ‘_f’ with type: ....
error with lot's of additional information ;)
so just find ... and f and this should work ;)
BTW you can use the functions you already have instead of pattern matching again as I did, but I feel it's easier to see the result this way - so if you follow this path you don't need to use treeSubtrees or treeRoot
solution
... = [a]
f = concatMap
so one possible way to do it is this:
nodesAtLevel :: Int -> Tree a -> [a]
nodesAtLevel 0 (Node a _) = [a]
nodesAtLevel n (Node _ subtrees) = concatMap (nodesAtLevel (n-1)) subtrees

Non-exhaustive patterns in function internals

I am currently working on Problem 62
I have tried the following code to solve it:
data Tree a = Empty | Branch a (Tree a) (Tree a)
deriving (Show, Eq)
internals :: Tree a -> [a]
internals (Branch a Empty Empty) = []
internals (Branch a b c) = [a]++(internals b)++(internals c)
internals (Branch a b Empty) = [a]++(internals b)
internals (Branch a Empty c) = [a]++(internals c)
Which basically says:
If both the children are empty don't include that list element in the list of internals.
If both children are non-empty, that node (a) is an internal include it, and keep checking to see any of a's children are also internal.
If one of the children is non-empty, that node is internal, and recursively keep checking if the child is also an internal node.
In GHCi I have ran the following:
> let tree4 = Branch 1 (Branch 2 Empty (Branch 4 Empty Empty)) (Branch 2 Empty Empty)
> internals tree4
and get the following runtime error:
[1,2*** Exception: Untitled.hs:(6,1)-(12,49): Non-exhaustive patterns in function internals
I don't understand why this thing is non-exhaustive, I thought it would go to branch 1, notice it's children are non-empty, then go down both branch 2s and find out one branch is empty, one is not, stop at the one that is, and keep going down the one that isn't, until branch "4", and end it there. It sort of does, I do get 1, 2 in the list, but why is it not exhaustive?
Thanks in advanced.
Thank you for the help Tikhon changed my function to this:
data Tree a = Empty | Branch a (Tree a) (Tree a)
deriving (Show, Eq)
internals :: Tree a -> [a]
internals (Branch a Empty Empty) = []
internals (Branch a b Empty) = [a]++(internals b)
internals (Branch a Empty c) = [a]++(internals c)
internals (Branch a b c) = [a]++(internals b)++(internals c)
The other answer doesn't actually solve the reason for the error message, it does resolve one problem though (the fact that the order of patterns is significant).
The error message is Non-exhaustive patterns, which means that internals is being called with a value that doesn't match any of the patterns (this value is Empty). As Tikhon said, it is because Branch a b c matches all Branches, so the later patterns are never used and an Empty can slip through. We can see what happens if we trace the execution of internals (Branch 1 (Branch 2 Empty Empty) Empty) (assume strict-ish evaluation, it makes the exposition simpler):
internals (Branch 1 (Branch 2 Empty Empty) Empty) =>
[1] ++ internals (Branch 2 Empty Empty) ++ internals Empty =>
[1] ++ [] ++ internals Empty =>
[1] ++ internals Empty =>
[1] ++ ???
The proper fix will mean that can't happen, i.e. one that converts internals from a partial function (undefined for some input values) to a total function (defined for all input). Total functions are much much nicer than partial ones, especially in Haskell, where the type system gives the programmer the ability to mark "partial" functions as such at compile time (e.g. via Maybe or Either).
We can think about the recursion from the bottom-up, i.e. work out the base cases:
the empty tree has no internal nodes
a tree that is a single node has no internal nodes
We recur on any tree that doesn't satisfy either of these; in which case, the current node is an internal node (so add that to the list), and there might be internal nodes in the children, so check them too.
We can express this in Haskell:
internals :: Tree a -> [a]
internals Empty = []
internals (Branch a Empty Empty) = []
internals (Branch a b c) = [a] ++ internals b ++ internals c
This has the added bonus of making the code neater and shorter: we don't have to worry about the details of the children in the recursion, there is a base case that handles any Emptys.
The order of patterns matters. Since Branch a b c matches everything that isn't just Empty, including something like Branch a b Empty, your third and fourth cases never get hit.
This should fix it:
internals :: Tree a -> [a]
internals (Branch a Empty Empty) = []
internals (Branch a b Empty) = [a] ++ internals b
internals (Branch a Empty c) = [a] ++ internals c
internals (Branch a b c) = [a] ++ internals b ++ internals c

Writing a function to compute the left spine of a tree

I'm needing some help in figuring out how to create a leftSpine function in Haskell.
Basically, it is supposed to take all the left most leafs and put them into a list, but whenever I run my code I get an empty list. Any help would be appreciated.
Here is my code.
data Tree x = Leaf | Node (Tree x) x (Tree x)
deriving Show
leftSpine :: Tree x -> [x]
leftSpine Leaf = []
leftSpine (Node lt x rt) = (leftSpine lt)
And here is my code to test it.
leftSpine (Node (Node (Node Leaf 1 Leaf) 2 (Node Leaf 3 Leaf))
4
(Node (Node Leaf 5 Leaf) 6 (Node Leaf 7 Leaf)))
It should equal [4,2,1] but it just comes up as [].
leftSpine :: Tree x -> [x]
leftSpine Leaf = []
leftSpine (Node lt x rt) = x:leftSpine lt
You weren't actually putting anything into the list. The difference is the x:leftSpine lt instead of leftSpine lt.
Your code plainly says that the result is always the empty list.
The first case says that the left spine of a leaf is the empty list. Ok so far.
The second case says that the left spine of a node is exactly the left spine of the node's left child.
So if we want to find the left spine of a tree, we'll just keep chasing down the left children of the nodes we reach, knowing that the answer is exactly equal to the left spine of the next left child. Either we eventually find a leaf, and our result is the empty list, or the tree is infinite and we never return a result at all. There is nothing in your code that could ever return anything else.
The key to writing a recursive function of this kind is to figure out what the answer is for the base case (Leaf, here), and then for the non-base cases (Node, here) you need to figure out how to combine the sub-solutions with the local information here to generate a full solution.
In this case the left spine of a Leaf is easy, as there's no data at all. So then how would you combine the information from Node lt x rt with leftSpine lt to get the left spine of the whole tree?

I need to create haskell function, which returns all possible binary trees, given a list of integers

As the title says, I need this:
getAllTrees :: [Int] -> [Tree Int]
getAllTrees xs = undefined
where tree is
data Tree x
= Null
| Leaf x
| Node (Tree x) x (Tree x)
I will appreciate any help, even the smallest clue :)
Thanks
I usually find it easiest to use the list monad for these kinds of problems. We can define getAllTrees by reasoning as follows:
The only tree of zero items is Null:
getAllTrees [] = return Null
There is also only one tree of one element, namely a Leaf:
getAllTrees [x] = return $ Leaf x
When we have more than one element, we can split the list in all possible ways to determine how we should branch, and then recursively generate the sub-trees from each list. Let's say we have a function splits :: [a] -> [([a], [a])] that returns all ways of splitting a list, for example:
> splits [1..3]
[([],[1,2,3]),([1],[2,3]),([1,2],[3]),([1,2,3],[])]
We can then define the final case of getAllTrees by using the list monad. This allows us to write code which sort of looks like like we're focusing on only one case, and the monad will give us all the combinations.
getAllTrees xs = do
(left, x : right) <- splits xs
Node <$> getAllTrees left <*> pure x <*> getAllTrees right
The first line splits the input list and takes the first item from the second part as the middle element. The case when the second part is empty doesn't match the pattern, so it gets discarded since that's how the list monad handles pattern match failures.
The second line uses applicative syntax to say that we want the result to be a list of nodes, made from all combinations of sub-trees from the left list, the fixed middle element x, and all sub-trees from the right list.
All that remains then is to implement splits. Looking at the example above, it's easy to see that we can just take the inits and tails of the list and zip them together:
splits xs = zip (inits xs) (tails xs)
Time for a quick sanity check in the interpreter:
> mapM_ print $ getAllTrees [1..3]
Node Null 1 (Node Null 2 (Leaf 3))
Node Null 1 (Node (Leaf 2) 3 Null)
Node (Leaf 1) 2 (Leaf 3)
Node (Node Null 1 (Leaf 2)) 3 Null
Node (Node (Leaf 1) 2 Null) 3 Null
> length $ getAllTrees [1..5]
42
Looks like we're done! Some key lessons:
Try to think about the small cases first, and build up from there.
The list monad is useful for code that needs to generate all combinations of things.
You don't have to do everything at once. Dealing with the list splitting separately made the code much simpler than it would have been otherwise.

Resources