2016-03-03 75 views
2

考虑显示树哈斯克尔

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a 

我试图定义显示的一个实例(没有导入任何模块或使用派生),这将显示树形像这样

Main*> let a = Branch "x" (Branch "y" (Leaf 4) (Leaf 7)) (Leaf 9) 
Main*> a 
"x" 
    "y" 
      4 
      7 
    9 
以下数据类型

到目前为止,这是我想出的

findDepth (Leaf a) = 0 
findDepth (Branch a (b) (c)) = 1 + (max (findDepth b) (findDepth c)) 
data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a 
instance (Show a, Show b) => Show (Tree a b) where 
    show (Leaf x) = show x 
    show (Branch a (b) (c)) = 
      show a ++ "\n" ++ s2 ++ show b ++ "\n" ++ s2 ++ show C++ "\n" ++ s1 
       where 
        d = findDepth (Branch a (b) (c)) 
        s1 = addSpace (d-1) 
        s2 = addSpace d 
        addSpace n = replicate n '\t' 

不幸的是,这使得节点h最深,最深的节点最少。我知道findDepth函数实际上应该给叶子最大的价值和分支最低价值,但不能找出一种方法来递归地为这两个参数编写函数。有什么建议么?

+0

如果您不认为这是其他问题的重复,请随时添加注释(不要忘记添加'@ Zeta')。这就是说,你仍然可以接受一个已发布的答案。顺便说一句,目前是否有某种Haskell讲​​座?一些最新的问题非常相似。 – Zeta

回答

4

其实,没有必要额外findDepth功能 - 你可以很容易地通过树遍历,每次增加的深度,你展示了孩子们:

import Text.Printf 

data Tree a b = Branch b (Tree a b) (Tree a b) | Leaf a 

instance (Show a, Show b) => Show (Tree a b) where 
    show = showAtLevel 0 
    where 
     showAtLevel l (Leaf x) = addSpace l ++ show x 
     showAtLevel l (Branch x (lt) (rt)) = printf "%s%s\n%s\n%s" (addSpace l) (show x) (showAtLevel (l + 1) lt) (showAtLevel (l + 1) rt) 
     addSpace = flip replicate '\t' 

测试用例:

*Main> let a = Branch "x" (Branch "y" (Leaf 4) (Leaf 7)) (Leaf 9) 
*Main> a 
"x" 
    "y" 
     4 
     7 
    9 
*Main> Branch "x" (Branch "y" (Leaf 4) (Branch "z" (Leaf 42) (Leaf 314))) (Leaf 9) 
"x" 
    "y" 
     4 
     "z" 
      42 
      314 
    9 
+0

圣牛非常感谢你 – Alec

+0

@Alec ,你总是受欢迎的! – soon

+0

是否有任何理由为什么你的四个答案(计数那些在另一个问题中)都没有使用'replicate'的递归方法,比如'show tree = unlines(map indent(go tree))where go(Leaf v)= [show a]; go(Branch vlr)= show v:indent(go l ++ go r); indent = map('\ t':)'? – Zeta

2

这里有一个提示,没有他的整个解决方案:写一个单一的功能showWithDepth :: Int -> Tree -> String,通过“累积深度”到目前为止。那么你可以写show = showWithDepth 0

注意,一般来说,你应该show情况下尚且如此,作为其“准标准”,显示情况下应主要工作就像派生的人,并产生类似的东西有效的Haskell代码。 (此外,在存在Read实例时,我们希望read . show === id.