Я бы просто реализовал show
соответственно (вместо того, чтобы выводить из него), что можно сделать довольно легко, по крайней мере, если вы не возражаете против включения ненужных скобок:
instance (show a) => show (Expr a) where
show (Number x) = show x
-- ...
show (Prod x y) = "("++show x++")*("++show y++")"
-- ...
Это можно сделать лучше и эффективнее, но, возможно, этого решения вам достаточно.
В комментариях выше было сказано, что show
должен быть легковесным средством сериализации и, в частности, должен удовлетворять (read . show) x = x
. Я согласен, и это означает, что вы не должны, например, делать какие-либо реальные вещи с надписью prettyprint (например, вывод в LaTeX, что, безусловно, будет хорошим способом вывода таких данных). IMO означает, что не означает, что show
всегда должен вести себя как производный экземпляр, не если этот вывод ненадежно менее читабелен, длиннее и / или менее четок, если просматривается без кода haskell в качестве контекста.
Еще один пункт Хаммара, сделанный в комментариях выше: вывод show
должен быть действительным кодом haskell. Чтобы мое решение соответствовало этому, вам нужно сделать Expr
экземпляром Num
и Fractional
или Integral
.