Hi,<br><br>I&#39;ve written some code and was wondering if there was a better way to write it in terms of readability, brevity and/or efficiency.<br><br>The function concerned is pathsToForest which takes a list of paths (ie. [[String]]) and converts it into a tree structure where the individual nodes are the names in the path.&nbsp; Siblings with the same name are merged.
<br><br>For instance:<br><br>&nbsp; prettyPrint $ mergeForest $ pathsToForest [[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;], [&quot;c&quot;, &quot;b&quot;, &quot;a&quot;], [&quot;a&quot;, &quot;b&quot;, &quot;d&quot;]]<br><br>
gives:<br><br>&nbsp; a<br>&nbsp;&nbsp; b<br>&nbsp;&nbsp;&nbsp; d<br>&nbsp; &nbsp; c<br>&nbsp; c<br>&nbsp;&nbsp; b<br>&nbsp; &nbsp; a<br><br>Thanks<br><br>-John<br><br>import Data.Tree<br>import Control.Monad<br><br>data ArcData = ArcData<br>&nbsp; { name :: String<br>&nbsp; } deriving Show<br><br>
type ArcTree = Tree ArcData<br>type ArcForest = Forest ArcData<br><br>pathsToForest :: [[String]] -&gt; ArcForest<br>pathsToForest paths = mergeForest $ concat $ map pathToTree paths<br><br><br>mergeForest :: ArcForest -&gt; ArcForest
<br>mergeForest [] = []<br>mergeForest (x:xs) = merge x (mergeForest xs)<br>&nbsp; where<br>&nbsp;&nbsp;&nbsp; merge :: ArcTree -&gt; ArcForest -&gt; ArcForest<br>&nbsp;&nbsp;&nbsp; merge tree [] = [tree]<br>&nbsp;&nbsp;&nbsp; merge tree (y:ys) =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if sameTreeName tree y
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; merge<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tree<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { subForest = mergeForest ((subForest tree) ++ (subForest y))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ys<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (y:merge tree ys)<br><br>
treeName :: ArcTree -&gt; String<br>treeName tree = name $ rootLabel $ tree<br><br>sameTreeName :: ArcTree -&gt; ArcTree -&gt; Bool<br>sameTreeName treeLeft treeRight = treeName treeLeft == treeName treeRight<br><br>pathToTree :: [String] -&gt; ArcForest
<br>pathToTree [] = []<br>pathToTree (name:subpath) =<br>&nbsp; [ Node<br>&nbsp;&nbsp;&nbsp; { rootLabel = ArcData { name = name }<br>&nbsp;&nbsp;&nbsp; , subForest = pathToTree subpath<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp; ]<br><br>prettyPrint&#39; :: ArcForest -&gt; [String]<br>
prettyPrint&#39; [] = []<br>prettyPrint&#39; (x:xs) =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [name $ rootLabel $ x] ++ (map (&quot; &quot; ++) (prettyPrint&#39; $ subForest x)) ++<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prettyPrint&#39; xs<br><br>prettyPrint :: ArcForest -&gt; IO ()
<br>prettyPrint forest = do<br>&nbsp; forM_ (prettyPrint&#39; forest) putStrLn<br><br>