Sarah Xoxo
Sarah Xoxo

Reputation: 115

haskell convert Integer to String without show

Is there a way to convert an Integer to String in Haskell without using show?

The problem is that in my code I have already declared a show instance.

instance Show ZZ where
    show zz = toHexa (zzToInt zz)

So that the program throws the following error when I try to use show at another position

Ambiguous variable occurrence "show"

The way I try to use the "normal" show is the following:

toBin :: Int -> String
toBin 0 = "0"
toBin 1 = "1"
toBin n
 | n `mod` 2 == 0 = show (toBin (n `div` 2)) ++ "0"
 | otherwise = show (toBin (n `div` 2)) ++ "1"

So I need another possibility for show

Upvotes: 2

Views: 2342

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476503

Your toBin does not need a call to show here. Indeed toBin has signature Int -> String, so that means that toBin (n `div` 2) will return a String. By calling show on that value, you will add double quotes around it (making it look like a string literal).

You thus can implement the toBin as:

import Data.Char(intToDigit)

toBin :: Int -> String
toBin 0 = "0"
toBin 1 = "1"
toBin n
  | mod n 2 == 0 = rest ++ "0"
  | otherwise = rest ++ "1"
  where rest = toBin (div n 2)

or more efficient:

import Data.Char(intToDigit)

toBin :: Int -> String
toBin = reverse . go
    where go 0 = "0"
          go 1 = "1"
          go n = intToDigit (mod n 2) : go (div n 2)

For example:

Prelude Data.Char> toBin 1425
"10110010001"

Defining an extra instance for Show is not a problem. In fact the base package of Haskell has several dozens of Show instances.

There are two reasons why the call might be ambiguous:

  1. it is not clear to the compiler what the type is you call show on. You can sometimes add a type clause to give the compiler a hint, like show (a :: Int);
  2. you defined another show function outside the instance Show … where … scope, and thus defined another function.

Upvotes: 2

Related Questions