2015-07-06 2 views
5

Я написал этот код довольно-печать дерева:Могу ли я частично получить Show?

data Node = A | B | C | Tree Node [Node] 
    deriving (Show, Eq) 

printTree' :: Int -> Node -> [String] 
printTree' spaceCount (Tree node children) = (printTree' spaceCount node) 
    ++ concat (map (\child -> printTree' (spaceCount+2) child) children) 
printTree' spaceCount leaf = [(replicate spaceCount ' ') ++ (show leaf)] 

printTree :: Node -> String 
printTree node = unlines (printTree' 0 node) 

Пример вывода:

*Main> putStr $ printTree $ Tree A [Tree A [A,B,C], C] 
A 
    A 
    A 
    B 
    C 
    C 

Теперь я хотел бы сделать это для реализации show. Этот подход близок, но я не могу найти способ вызвать встроенный show:

instance Show Node where 
    show (Tree node children) = printTree (Tree node children) 
    show _ = "node... can I call the built-in show here?" 

(В этом примере, я мог бы просто иметь дело с A, B и C. Но в реальном коде, существует много типов узлов.)

ответ

8

Единственный способ, которым я могу это сделать, - разделить на два типа.

data Tree node = Tree node [Tree node] 
data Node = A | B | C deriving Show 

instance Show node => Show (Tree node) where .... 
+3

Вашего определение 'Tree' дает совершенно иной тип данные чем исходное определение «Дерево». Что-то вроде 'data Tree a = Дерево a [Дерево a] | Лист a' будет более точно соответствовать оригиналу. – user2407038

+0

@ user2407038 Ну, 'Лист x' примерно похож на' Tree x [] ', но уверен ... – MathematicalOrchid

1

После réponse MathematicalOrchid, тем лучший способ сделать это с помощью нового типа, но вот лучший способ организовать типы:

data Node = Leaf Leaf | Tree Node [Node] deriving Eq 
data Leaf = A | B | C deriving (Eq, Show) 

instance Show Node where 
    show (Tree node children) = printTree (Tree node children) 
    show (Leaf l) = show l 
Смежные вопросы