为方便分析数据,我想使用一个库,代码如下:
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
有这样的图书馆吗?或者也许是解决这个问题的更好方法?
答案 0 :(得分:4)
Data.Tree
具有类似格式的drawTree
和drawForest
函数,因此您可以编写一个函数将数据结构转换为Tree String
,然后使用{{1} }。
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))
答案 1 :(得分:1)
添加到hammar的答案。以下是如何进行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 #-}
编译指示并使类型派生自Typeable
来轻松实现和Data
一样:
data SomeType = A [String] Int | B | C Int | D [[String]]
deriving (Typeable, Data)