2015-07-06 24 views
5

Ho scritto questo codice per pretty-stampa di un albero: uscitaPosso derivare parzialmente 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) 

Esempio:

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

Ora vorrei fare questa l'implementazione per show. Questo approccio è vicino, ma non riesco a trovare un modo per chiamare il built-in show:

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

(In questo esempio, ho potuto solo fare con A, B, e C. Ma nel codice vero e proprio, ci sono molti tipi di nodi.)

risposta

8

L'unico modo che posso vedere per fare questo è separare in due tipi.

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

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

La tua definizione di 'Tree' dà un tipo di dati nettamente diverso rispetto alla definizione originale di 'Tree'. Qualcosa come "albero dei dati a = albero a [albero a] | Foglia a' corrisponderebbe più strettamente all'originale. – user2407038

+0

@ user2407038 Bene, 'Leaf x' è approssimativamente come' Albero x [] ', ma certo ... – MathematicalOrchid

1

seguito reponse di MathematicalOrchid, il modo migliore per farlo è con un nuovo tipo, ma qui c'è un modo migliore per organizzare i tipi:

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 
Problemi correlati