Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override Show instance of some basic types in Haskell?

I'm writting some programs in Haskell, dealing with a lot of basic types like Word32/Word64 etc.. I use ghci to test the functions frequently, see the results in terminal.

To be convenient and fast, I always show data in hexadecimal e.g.

data Human = M Int | F Int
instance Show Human where
    show M x = printf "man, age %d" x
    show F x = printf "woman, age %d" x

but I want basic types to be showed in hexadecimal (espacially in ghci). I found instance declaration cannot be overridden. and I don't want to warp all of them up like:

newtype MyInt = MyInt Int
instance Show MyInt where
    ...

It looks a little bit stupid.

Can I modify some code in the package base for ghc? I just want everything becoming "hex". I just want ghci showing "hex". how could I achieve it?

EDIT

Since all of us agree that override Show is not proper and impractical, Any answer of "better ways to show Numeric in hexadecimal in ghci" is welcomed.

like image 678
wuxb Avatar asked Feb 15 '12 06:02

wuxb


3 Answers

No, there is no way to achieve this without newtypes; instances cannot be overriden.

If you really want this, I would suggest defining your own typeclass, ShowHex, like Show but with all the instances printing in hex. However, I would consider your Show instance incorrect; Show instances are designed for debugging and serialisation, and should output syntactically valid code.1 Yours doesn't, so I would suggest either defining your own typeclass for displaying these values, or simply using a function.

Modifying the code to base for this is impractical; not only would this change in semantics for the instances break a lot of packages, but it'd be a huge pain to get GHC to actually use your modified version.

1 Ideally, the code they produce should be semantically valid Haskell that produces a value comparing equal to show's input, but this is not strictly necessary.

like image 168
ehird Avatar answered Dec 04 '22 19:12

ehird


That would be abusing the Show instance. It's not really meant for formatting. If you want to show something in hexadecimal, just use a function to do the conversion. For example, you can use showHex from Numeric to make a small helper like this:

> import Numeric
Numeric> let hex x = showHex x ""
Numeric> hex 123456
"1e240"
like image 25
hammar Avatar answered Dec 04 '22 17:12

hammar


One extreme solution would be to use {-# LANGUAGE NoImplicitPrelude #-}, and import your own "Prelude" instead. That would probably be a lot more work than it's worth for your case, though.

like image 21
Dan Burton Avatar answered Dec 04 '22 19:12

Dan Burton