2016-03-03 114 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.