Я бы просто объявил ваш тип данных экземпляром класса type Show:
data Exp a = Const a | Eq (Exp a) (Exp a)
instance (Show a) => Show (Exp a) where
show (Const a) = show a
show (Eq x y ) = "[ " ++ show x ++ " , " ++ show y ++ " ]"
Посмотрите, что происходит, когда вы загружаете это в ghci и делаете:
*Main> let x = Eq (Const 1) (Eq (Const 2) (Const 3))
*Main> x
[1 , [2 , 3] ]
Ответ на комментарий:
Вы можете легко иметь дело с различными типами. Предположим, вы хотите разобрать математические выражения. Вы можете иметь следующую структуру, например:
data Expr = Var String | Sum (Expr) (Expr) | Number Int | Prod (Expr) (Expr)
Этого достаточно, чтобы представить любое выражение, состоящее из сумм и произведений чисел и именованных переменных. Например:
x = Sum (Var "x") (Prod (Number 5) (Var "y"))
обозначает: x + 5y
Чтобы напечатать это красиво, я бы сделал:
instance Show Expr where
show (Var s) = show s
show (Sum x y) = (show x) ++ " + " (show y)
show (Prod x y) = (Show x) ++ (show y)
show (Number x) = show x
Это бы сработало. Вы также можете использовать ГАДЦ:
data Expr where
Var :: String -> Expr
Sum :: Expr -> Expr -> Expr
и т.д ..., а затем создать экземпляр как Show.