citoz
citoz

Reputation: 55

Haskell: data type for representation of binary, hexadecimal, and octal

I'm trying to define a data type to represent numbers in binary, octal and hexadecimal. The idea is to use this data type to define some functions in order to convert from octal to binary, from binary to hexadecimal and from octal to hexadecimal

This what I have until now..

data Number = Bin[Char] | Hex[Char]| Oct[Char]
                                          deriving Show

oct2Bin :: Number -> Number
bin2Hex :: Number -> Number
oct2Hex :: Number -> Number

But I'm stuck here and I don't know if I'm on the right track. I would appreciate any help I can get on this matter.

Upvotes: 0

Views: 1389

Answers (2)

Zeta
Zeta

Reputation: 105876

You should simply save the number as one of the numerical types, preferably an integral one. That way, you can easily use a function like

type Base   = Int
type Number = Integral

repr :: Integral a => Base -> a -> String

But maybe there's already a function like that? And indeed, there is (in Numeric):

showIntAtBase :: (Integral a, Show a) => 
                 a                       -- the base
              -> (Int -> Char)           -- a function to transform single digits
                                         -- (in that base)
              -> a                       -- the number
              -> ShowS                   -- ShowS = String -> String

Therefore, repr base number is simply showIntAtBase base conv number "":

repr base number = showIntAtBase base conv number ""
    where conv n  = (['0'..'9'] ++ ['a'..'z']) !! n

Although you might want to change conv to something else.

Also, Numeric already contains showHex and showOct. showBinary isn't in there, but together with repr above it's as simple as showBin = repr 2.

Upvotes: 4

osa1
osa1

Reputation: 7078

Why not use Int to represent your number and when you for some reason need a String representation, use Number -> String functions? Example:

type Number = Int

toBin :: Number -> String
toOct :: Number -> String
toHex :: Number -> String

toOct = show
... implement others as usual ...

Using a cannonical representation like this(in this case our representation is as Int) you can minimize required conversions between types. All operations on this type will work without conversions. Only conversion will happen when you need a String representation.

(There's also problems with combinatorial explosions like @Karoly mentioned in comments but as far as you guarantee that transitively all formats are reachable I think you can avoid it -- even though your implementation will probably be very inefficient)

Upvotes: 1

Related Questions