How does one override show for a newtype?

gatoatigrado picture gatoatigrado · Apr 18, 2010 · Viewed 9.7k times · Source

I want to override the default integer constructors in Haskell so they produce strings (mostly for curiosity, but temporarily to make a nice input alternative for LaTeX's \frac{}{} inconvenience).

I wanted to be able to use the language itself, instead of a special parser, but I guess that's probably not going to work out...

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

The problem with the above is that the + function only works for (A, A) instead of (A, String), etc. If one simply leaves out the pattern match "(A a)" and writes "a" instead, then the show() function prepends "A " so "3" becomes "A 3" instead of just "3".

I want to override Show for A, but it seems to be quite a headache...

Answer

MtnViewMark picture MtnViewMark · Apr 18, 2010

If you want your own Show instance for A, then just don't derive it and make your own instance:

newtype A = A Int deriving (Eq, Num)

instance Show A where
  show (A a) = show a

Then you can write something like:

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

Of course, if you are defining your own + operator like that, then I don't think your problem requires the newtype A declaration:

module Main where

import Prelude hiding ((+))

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

aSum = 3 + 4

main :: IO ()
main = putStrLn aSum