Reputation: 512
This is a quite simple piece of code. It takes an integer and decomposes its decimal digits using quotient and remainder. On each call, it prints a line with r characters 'I', where r is the last digit, then calls itself with the quotient as its new argument.
decToUnary 0 = return ()
decToUnary n = let (q, r) = quotRem n 10 in
do
putStrLn (take r "IIIIIIIIII")
decToUnary q
It works correctly for numbers with less than 10 digits, but for 10 or more digits it scrambles the output. What am I doing wrong, and why does it work this way? Here are some examples of output, the first is correct, the second is wrong:
*Main> decToUnary 5432
II
III
IIII
IIIII
*Main> decToUnary 5432101234
IIIIIIII
III
IIIIIIIII
III
III
I
IIIIIII
III
I
I
Upvotes: 1
Views: 281
Reputation: 47062
This is an integer overflow question. maxBound :: Int
is 2147483647 (on 32-bit machines), so values greater than that overflow.
Use Integer
instead of Int
: Integer
is not a fixed length integer so it won't overflow.
Edit: As applicative notes, you will then need to replace the take r "IIIIIIIIII"
with take (fromIntegral r) "IIIIIIIIII"
or genericTake r "IIIIIIIIII"
; I'd prefer genericReplicate r 'I'
.
genericTake
and genericReplicate
are both in Data.List.
Upvotes: 13