I am trying to convert postfix expression to binary tree. My function takes as argument a list of tokens (strings).
Everytime I give the function any input, debugger writes a message: Non-exhaustive patterns in function "add".
My idea was: read a token after token and determine, if it is an operator or an operand. If it is operand, don't save any node to the tree and store the number to the stack. Otherwise I create a node with an operator, pop symbols from stack, set them as children of new node and push the operator to stack.
If the list of strings is empty, functions print the binary tree.
Would someone explain to me, why the function gives non-exhaustive patterns error and how can I fix the function?
data Tree = Leaf String | Empty | Node Tree String Tree deriving (Show)
add :: Tree -> [String] -> [Tree] -> Tree
add (Node l v p) [] stack = (Node l v p)
add Empty (x:xs) []
| x `elem` ["*","-","+"] = add (Leaf x) xs [Leaf x]
| otherwise = add Empty xs [Leaf x]
add Empty (x:xs) (a:b:bs)
| x `elem` ["*","-","+"] = add (Node b x a) xs (Leaf x:a:b:bs)
| otherwise = add Empty xs (Leaf x:a:b:bs)
add (Leaf x) token (a:b:bs)
| x `elem` ["*","-","+"] = add (Node b x a) token (Leaf x:bs)
| otherwise = Leaf x
add (Node l v p) (x:xs) (a:b:bs)
| x `elem` ["*","-","+"] = add (Node b x a) xs (Leaf x:bs)
| otherwise = add (Node l v p) xs (Leaf x:a:b:bs)
parse :: String -> Tree
parse input = add Empty (words (toPostfix input)) []
I've managed to reproduce the error by simple example:
add Empty ["10", "1", "+"] []
The program successfully adds Leaf "10" to the stack, but can't add Leaf "1" to the stack, because the add is called with the following args:
add Empty ["1", "+"] [Leaf "10"]
But it doesn't match any pattern, because add Empty (x:xs) (a:b:bs) expects the third argument to have two Tree elements and a list. Therefore, a pattern that matches third argument as a list with one element is needed. For example, adding:
add Empty (x:xs) [a] = add Empty xs (Leaf x:[a])
fixes the error and prints the following:
Node (Leaf "10") "+" (Leaf "1")
Hope it'll help you to continue with the task, unless you've already solved it :)
Related
I defined selectionSort function as below, sorting an empty list just results in an empty list and sorting a non-empty list is cons of minimum element and sorted version of rest of the list.
selectionSort :: Ord a => [a] -> [a]
selectionSort xs
| null xs = []
| otherwise = minElem : (selectionSort ys)
where
(minElem, ys) = minf xs
where
minf [x] = (x, [])
minf (x:xs) = let (m ,ms) = minf xs in
if x <= m then (x, xs)
else (m, x:ms)
minf takes a non-empty list and returns a tuple of minimum value and rest of the list.
When i compile this function with -W flag, I get this warning
warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for `minf': Patterns not matched: []
|
24 | minf [x] = (x, [])
| ^^^^^^^^^^^^^^^^^^...
It is straight forward that the function minf is never applied to an empty list, because those cases are caught in null xs = []. Is there any way to inform GHC that the particular case is impossible without using other types (NonEmpty list type) or Maybes
Usually the idea is to "design" types in such way that the number of "impossible patterns" is very small (and prefereably zero).
As a poor man solution, you can rewrite the signature of the function from:
foo :: [a] -> b -- [a] is a non-empty list
to:
foo :: a -> [a] -> b -- head and tail as input
So in this context we can rewrite your function to:
selectionSort :: Ord a => [a] -> [a]
selectionSort [] = []
selectionSort (x:xs) = minElem : selectionSort ys
where (minElem, ys) = minf x xs
minf z [] = (z, [])
minf z za#(z2:zs) = let (m, ms) = minf z2 zs in
if z <= m then (z, za)
else (m, z:ms)
So we here use the first parameter as the head of the list, and the second as the tail. Since the list contains at least one element, this means that the tail can be empty, and hence we can do pattern matching. As a result, we can still use the -Wincomplete-patterns flag to check if all patterns are covered and thus we still have some guarantees by the compiler.
In case you still have no means to design the types properly, you can for example add the pattern and raise a (validation) error:
minf [] = error "Impossible: minf only works with a non-empty list"
Given a Tree :
data Tree a = Empty | Node a [Tree a] deriving Show
I am trying to get the maximum element so I've tried:
maxElem:: (Ord a) => Tree a -> Int
maxElem Empty = error "maxElem on empty Tree"
maxElem (Node a []) = a
maxElem (Node a x ) = maximum [ maxElem h | h<-x]
But I get an error and I don't find it.
There are three potential problems here:
if a tree contains one or many Emptys, it will error. So a Node 1 [Node 4 [], Empty, Node 2 [Node 5 []]], will raise an error since there is an Empty in the tree, and we will eventually call maxElem on that Empty whereas we can ignore the Empty and thus return 5;
you also do not take a into account when you calculate the maximum of a Node with children, whereas the a can be the maximum as well;
the result is an a as well, not per se an Int.
There are in fact two cases here:
1. the Empty tree, that raises an error; and
2. the maximum of a Node x cs is the maximum of x and the maxElem of the children, ignoring the Emptys.
So we can write it as:
maxElem:: Ord a => Tree a -> a
maxElem Empty = error "maxElem on Empty"
maxElem (Node x cs) = maximum (x : map maxElem [c | c#(Node _ _) <- cs])
Or we can write the map maxElem in the list comprehension:
maxElem:: Ord a => Tree a -> a
maxElem Empty = error "maxElem on Empty"
maxElem (Node x cs) = maximum (x : [maxElem c | c#(Node _ _) <- cs])
So the base case is the same, but the case of Node x cs calculates the maximum of a list with x as head, and map MaxElem as tail, but not on all children, but only the children that match the Node _ _ pattern. Since this list contains at least one element x, maximum can not error on the empty list, and we calculate only maxElem on Node instances.
I am trying to construct a tree from pre/postoreder traversals . My tree type is below:
data Tree = Emptytree | Node Integer [Tree]
I am new in functional programming. So I come across with some difficulties while tying construct my base cases and recursion.My function will be something like this:
ListToTree :: [Integer] -> [Integer] -> Tree
I construct some algorithms but I can not make it to fit to Language requirements.
My algorithm is quite simple:I take each element of first list (preorder traversal list) then I check it position in the second list. Let me give an example:
1
/ \
2 5
/ \
3 4
Preorder of this Tree traversal is as you know [1,2,3,4,5]
Postorder of this Tree traversal is as you know [3,4,2,5,1]
Firstly I look to the first element of first list it is 1 then I look it is position it in 2nd list it is last so I add this to my tree. Then I check next element of tree it is 2 in the second list it on the left of 1 it means it is child of it. Then 3 is on the left of 2 (in the second list) it means it is also the son of 2 then i look to 4 it is on the left of 2 it is son of 2, and lastly 5 it is on the left of 1 it is child of one (because it is on the right of 2 it is not a child of 2).
I tried to implement it . I write helper function which determines if Node has a child or not. I use also counter in my function So actually my function is like this:
ListToTree :: Integer -> [Integer] -> [Integer] -> Tree
{-First Stands for counter ,2nd preorder, 3rd postorder-}
MY base condition are:
1. is about if list are Emptytree return Emptytree
2. is about if counter== length-1 return Node element [Emptytree]
My main problematic part is in my recursive part:
ListToTree counter a b
| hasChild b counter == 1 = Node ( Element ) [ListToTree (1+counter) a b]
| hasChild b counter == 0 = Node ( Element ) [Emptytree]
{-My problematic part if node has no Child what I must change here-}
{-Or what are your suggestions-}
I need help in improving my algorithm Any kind of help or comments will be highly appreciated.
The beautiful thing about haskell is that you don't usually need a counter. It is usually sufficient to just do patter matching.
I will give the solution for [Tree] since that requires less cases. If you want a solution for a single Tree you can just introduce some cases in a wrapper function.
listToTree :: [Integer] -> [Integer] -> [Tree]
listToTree [] [] = []
listToTree (x:xs) ys = go where
fstSubTreePost = takeWhile (/=x) ys -- all the elems of 1. subtree except x
fstSubTreeLength = length fstSubTreePost
fstSubTreePre = take fstSubTreeLength xs
-- this will recursively compute the first subtree
fstTree = Node x (listToTree fstSubTreePre fstSubTreePost)
-- the next line will recursively compute the rest of the subtrees
rest = listToTree (drop fstSubTreeLength xs) (drop (fstSubTreeLength+1) ys)
go = fstTree : rest
Given the pre-order and post-order are [Integer], there may be zero or one or many trees that returns these traversals. For instances the traversals [1,1,1] and [1,1,1] have two possible trees. With 'mLast' and 'splits' helper function, it is possible to define a short 'listToTrees' which handles possible 'Forest' parsings. Then it is easy to define 'listToTree' as a special case that produces possible single 'Tree' parsings.
module PPT where
import Data.List
data Tree a = Emptytree | Node a (Forest a)
deriving Show
-- | A list of sibling trees, in left to right order
type Forest a = [Tree a]
-- | Returns a list of all valid trees that produce the given pre-order and post-order traversals.
--
-- If the input cannot be parsed into a Tree then results is an empty list.
listToTree :: [Integer] -> [Integer] -> [Tree Integer]
listToTree [] [] = [Emptytree] -- base case
listToTree [] _ = [] -- detect length mismatch
listToTree (x:xs) yAll = case mLast yAll of
Just (ys, y) | x==y -> map (Node x) (listToTrees xs ys) -- pre-order start == post-order end
_ -> []
-- | Given pre-order and post-order traversals of a forest, return a list of possible parsings.
listToTrees :: [Integer] -> [Integer] -> [Forest Integer]
listToTrees [] [] = [ [] ] -- base case
listToTrees [] _ = [] -- detect length mismatch
listToTrees (x:xs) ys = concatMap build (splits x ys) -- for each copy of 'x' in ysAll
where
build (belowX', _x', rightOfX') =
let (belowX, rightOfX) = splitAt (length pre) xs
in [ Node x kids : sibs
| kids <- listToTrees belowX belowX'
, sibs <- listToTrees rightOfX rightOfX' ]
-- | Safely split a non-empty into the initial portion and the last portion
mLast :: [a] -> Maybe ([a], a)
mLast [] = Nothing
mLast ys = Just (init ys, last ys)
-- | At each position for the given element 'x', split the input list 'ys' into (pre, x, post)
-- portions. The output has a tuple for each copy of 'x' in the input list 'ys'.
--
-- This could be better optimized to avoid (++), or changed to a zipper
splits :: Eq a => a -> [a] -> [ ([a], a, [a]) ]
splits x ysIn = unfoldr go ([], ysIn)
where
go (pres, ys) =
case span (x /=) ys of
(_, []) -> Nothing
(pre, x':post) -> Just ((pres ++ pre, x', post), (pres++pre++[x'], post))
-- | test1 has a single possible parsing
test1 :: ([Integer], [Integer])
test1 = ( [1, 2, 3, 4, 5]
, [3, 4, 2, 5, 1] )
-- | test2 has two possible parsings
test2 :: ([Integer], [Integer])
test2 = ( [1, 2, 1, 2]
, [2, 1, 2, 1] )
main :: IO ()
main = do
mapM_ print (uncurry listToTree test1)
mapM_ print (uncurry listToTree test2)
Working on a function that given a SuffixTree as input, outputs the list of integers in that suffix tree. For example. getIndices tree1 = [2,4,1,3,5,0] . The order of the list of integers does not matter. I am getting the error, on the second last line of the function: "Couldn't match expected type 'SuffixTree' with actual type '[SuffixTree]'". I have thought about this for a long time now and have had no luck. Any help would be greatly appreciated.
data SuffixTree = Leaf Int | Node [ ( String, SuffixTree ) ]
deriving (Eq,Ord,Show)
text1 :: String
text1 = "banana"
tree1 :: SuffixTree
tree1 = Node [("banana",Leaf 0),
("a",Node [("",Leaf 5),
("na",Node [("",Leaf 3),
("na",Leaf 1)])]),
("na",Node [("",Leaf 4),
("na",Leaf 2)])]
------------------------------------------------------------------
getIndices :: SuffixTree -> [ Int ]
getIndices sufTree = getIndices' sufTree []
where getIndices' :: SuffixTree -> [Int] -> [Int]
getIndices' (Node ((_, Node xs):ys)) c
| Node xs == Node [] = c
| otherwise = getIndices' ((Node xs):([Node ys])) c
getIndices' (Node ((_,Leaf i):xs)) c = getIndices' (Node xs) (i:c)
Your getIndices' utility function is declared to take a SuffixTree, but in the otherwise case you're passing it (Node xs:[Node ys]) which has type [SuffixTree].
Given that all you want to do is to collect up the integers in the tree, perhaps your otherwise case just needs to call getIndices' twice:
| otherwise = getIndices' (Node xs) (getIndices' (Node ys) c)
Your code also has some other problems. If you compile with warnings (-Wall) the compiler will warn you about incomplete pattern matches. Your code also fails at runtime because of them.
The incompleteness is because getIndices' doesn't cover all possible kinds of SuffixTree. You also need to fill in cases for getIndices' (Leaf Int) and getIndices' (Node []).
Also, your existing case for | Node xs == Node [] within the Node ((_, Node xs):ys case then becomes redundant: it'll be handled by the recursive call to getIndices' from the otherwise case and then the new Node [] case. You might also think about how to simplify the two cases you have already into a single case.
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.