2012-11-19 39 views
1

對於數據的方便分析數據的樹輸出我想使用這對於下面的代碼庫:庫進行分析

data SomeType = A [String] Int | B | C Int deriving (Eq, Ord, Show) 

main = do 
    let theData = A ["a", "b", "c"] 9 : C 3 : B : [] 
    putStr $ treeString theData -- `treeString` is the implied library function 

會產生類似以下的輸出:

- A: 
| - - a 
| | - b 
| | - c 
| - 9 
- C: 
| - 3 
- B 

有沒有這樣的圖書館?或者,也許更好的方法來解決這個問題?

回答

4

Data.TreedrawTreedrawForest功能類似的格式,所以你可以寫一個函數來你的數據結構轉換爲Tree String,然後使用drawTree

import Data.Tree 

data SomeType = A [String] Int | B | C Int deriving (Eq, Ord, Show) 

toTree :: SomeType -> Tree String 
toTree (A xs n) = Node "A" [Node "*" (map (flip Node []) xs), Node (show n) []] 
toTree B  = Node "B" [] 
toTree (C n) = Node "C" [Node (show n) []] 

main = do 
    let theData = A ["a", "b", "c"] 9 : C 3 : B : [] 
    putStr $ drawTree (Node "*" (map toTree theData)) 

輸出:

* 
| 
+- A 
| | 
| +- * 
| | | 
| | +- a 
| | | 
| | +- b 
| | | 
| | `- c 
| | 
| `- 9 
| 
+- C 
| | 
| `- 3 
| 
`- B 
+0

謝謝!輸出非常好,但toTree實現看起來像純粹的樣板。沒有更通用的解決方案嗎? –

+1

@NikitaVolkov:你可能可以用泛型做些事情,但是你會想要像列表或字符串這樣的特殊情況,以便它們不會呈現爲巨大的「(:)」節點樹。 – hammar

+0

發現如何做到這一般。看到我的答案 –

1

添加到哈馬爾的答案。這裏有一個如何做一個通用的轉換Data.Tree

import Data.Tree 
import Data.Generics 
import Control.Applicative 

dataTree = fix . genericTree 
    where 
    genericTree :: Data a => a -> Tree String 
    genericTree = dflt `extQ` string 
     where 
     string x = Node x [] 
     dflt a = Node (showConstr (toConstr a)) (gmapQ genericTree a) 
    fix (Node name forest) 
     | name == "(:)" 
     , a : b : [] <- forest 
     = Node "*" $ (fix a) : (subForest $ fix b) 
     | otherwise = Node name $ fix <$> forest 

但是這對一個人的數據類型的工作,他們必須有Data一個實例,它可以很容易地通過添加{-# LANGUAGE DeriveDataTypeable #-}編譯和製造型來實現來自TypeableData像這樣:

data SomeType = A [String] Int | B | C Int | D [[String]] 
    deriving (Typeable, Data)