I wrote the below code to construct a tree with given vertex given a list of connections between vertices.
type Connection = (Int,Int)
data Tree = Leaf Int | Node Int [Tree] deriving (Eq,Read,Show)
makeTree :: Int -> [Connection] -> Tree
makeTree x [] = Leaf x
makeTree indx connections = Node indx otherTrees where
otherTrees = [makeTree i cx | i <- directConnections, let cx = removeConnectionsTo indx connections]
directConnections = map (\(x,y) -> if (x == indx) then y else x) $ filter (\(x,y) -> x == indx || y == indx) connections
removeConnectionsTo :: Int -> [Connection] -> [Connection]
removeConnectionsTo indx = filter (\(x,y) -> x /= indx && y /= indx)
For some reason, the inputs below give me surprisingly different results:
makeTree 1 [(1,2),(1,3)] gives me Node 1 [Leaf 2,Leaf 3]
makeTree 1 [(1,2),(1,5),(2,3),(2,4),(5,6),(5,7)] gives me Node 1 [Node 2 [Node 3 [],Node 4 []],Node 5 [Node 6 [],Node 7 []]]
I am running GHCi, version 7.4.1 on OS X 10.8.2.
I don’t understand why I get Leaf twice in the first example (correct) but node with empty subtree lists in the second example (incorrect).
A quick fix would be to just check if
otherTreesis empty before deciding whether to build aLeafor aNode, e.g.To understand what is happening here, let’s add a little instrumentation:
Now load it up into GHCi, and let’s see what the recursive calls are:
As you can see, the list in the second argument is not empty which is why it doesn’t match the first case of your function, so you’ll either need to add some additional checks as in my example, or make sure that you filter out the rest of the connections.