Как показать все элементы рекурсивного типа данных (Tree) в Haskell - PullRequest
0 голосов
/ 12 октября 2019

У меня есть небольшая проблема, когда мне нужно написать экземпляр show, который может печатать каждый элемент внутри моих рекурсивных данных дерева:

-- | A binary tree representing a series-parallel graph
data SpTree a
    -- | Leaf node
    = LeafNode a
    -- | Series composition
    | SeriesNode a (SpTree a) (SpTree a)
    -- | Parallel composition
    | ParallelNode a (SpTree a) (SpTree a)

-- | An SP-tree can be shown
--
-- >>> show $ LeafNode 1
-- "Leaf 1"
-- >>> show $ SeriesNode 1 (LeafNode 2) (LeafNode 3)
-- "Ser 1 (Leaf 2) (Leaf 3)"
-- >>> show $ ParallelNode 1 (LeafNode 2) (LeafNode 3)
-- "Par 1 (Leaf 2) (Leaf 3)"
instance Show a => Show (SpTree a) where
    show = ?

Каков наилучший способ определить этот экземпляр? Должен ли я использовать сопоставление с образцом или охранники?

Я пробовал это для leafNode, но при попытке запустить эту строку выдает ошибку: Data constructor not in scope: LeafNode :: Integer -> (): show $ LeafNode 1

instance Show a => Show (SpTree a) where
    show (a)
        |  LeafNode a = show a :: Integer

Спасибо!

1 Ответ

2 голосов
/ 12 октября 2019

Я все еще новичок в Хаскеле, но что-то подобное может сработать?

module Main where

import           Data.List

data SpTree a
    -- | Leaf node
    = LeafNode a
    -- | Series composition
    | SeriesNode a (SpTree a) (SpTree a)
    -- | Parallel composition
    | ParallelNode a (SpTree a) (SpTree a)

parens :: String -> String
parens a = "(" ++ a ++ ")"

instance Show a => Show (SpTree a) where
  show (LeafNode x) = "Leaf " ++ show x
  show (SeriesNode x y z) =
    unwords ["Ser", show x, parens $ show y, parens $ show z]
  show (ParallelNode x y z) =
    unwords ["Par", show x, parens $ show y, parens $ show z]


main = do
  putStr $ show $ LeafNode 1
...