Como uma substituição é exibida para um novo tipo?

Quero substituir os construtores inteiros padrão em Haskell para que eles produzam strings (principalmente por curiosidade, mas temporariamente para fazer uma boa alternativa de entrada para a inconveniência do \ frac {} {} do LaTeX).

Eu queria poder usar o próprio idioma, em vez de um analisador especial, mas acho que isso provavelmente não vai dar certo ...

module Main where

import Prelude hiding ((+))

newtype A = A Int deriving (Eq, Show, Num)
default (A)

(+) :: A -> (A -> String)
(A a) + (A b) = (show a) ++ " + " ++ (show b)

main2 = 3+4

main :: IO ()
main = putStrLn main2

O problema com o exposto acima é que a função + funciona apenas para (A, A) em vez de (A, String), etc. Se alguém simplesmente deixar de lado a correspondência de padrão "(A a)" e escrever "a", então a função show () precede "A" para que "3" se torne "A 3" em vez de apenas "3".

Quero substituir o Show por A, mas parece ser uma dor de cabeça ...

questionAnswers(3)

yourAnswerToTheQuestion