[Haskell-cafe] Paths to tree
John Ky
newhoggy at gmail.com
Mon Jan 29 06:10:47 EST 2007
Hi,
I've written some code and was wondering if there was a better way to write
it in terms of readability, brevity and/or efficiency.
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. Siblings with the same name are merged.
For instance:
prettyPrint $ mergeForest $ pathsToForest [["a", "b", "c"], ["c", "b",
"a"], ["a", "b", "d"]]
gives:
a
b
d
c
c
b
a
Thanks
-John
import Data.Tree
import Control.Monad
data ArcData = ArcData
{ name :: String
} deriving Show
type ArcTree = Tree ArcData
type ArcForest = Forest ArcData
pathsToForest :: [[String]] -> ArcForest
pathsToForest paths = mergeForest $ concat $ map pathToTree paths
mergeForest :: ArcForest -> ArcForest
mergeForest [] = []
mergeForest (x:xs) = merge x (mergeForest xs)
where
merge :: ArcTree -> ArcForest -> ArcForest
merge tree [] = [tree]
merge tree (y:ys) =
if sameTreeName tree y
then
merge
tree
{ subForest = mergeForest ((subForest tree) ++ (subForest y))
}
ys
else
(y:merge tree ys)
treeName :: ArcTree -> String
treeName tree = name $ rootLabel $ tree
sameTreeName :: ArcTree -> ArcTree -> Bool
sameTreeName treeLeft treeRight = treeName treeLeft == treeName treeRight
pathToTree :: [String] -> ArcForest
pathToTree [] = []
pathToTree (name:subpath) =
[ Node
{ rootLabel = ArcData { name = name }
, subForest = pathToTree subpath
}
]
prettyPrint' :: ArcForest -> [String]
prettyPrint' [] = []
prettyPrint' (x:xs) =
[name $ rootLabel $ x] ++ (map (" " ++) (prettyPrint' $ subForest x))
++
prettyPrint' xs
prettyPrint :: ArcForest -> IO ()
prettyPrint forest = do
forM_ (prettyPrint' forest) putStrLn
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20070129/0055719d/attachment.htm
More information about the Haskell-Cafe
mailing list