这是一段相当简单的代码。它需要一个整数并使用商和余数分解其十进制数字。在每次调用时,它会打印一行包含r个字符' I',其中r是最后一个数字,然后使用商作为新参数调用自身。
decToUnary 0 = return ()
decToUnary n = let (q, r) = quotRem n 10 in
do
putStrLn (take r "IIIIIIIIII")
decToUnary q
它适用于少于10位的数字,但对于10位或更多位数字,它会对输出进行加扰。我做错了什么,为什么这样做? 以下是一些输出示例,第一个是正确的,第二个是错误的:
*Main> decToUnary 5432
II
III
IIII
IIIII
*Main> decToUnary 5432101234
IIIIIIII
III
IIIIIIIII
III
III
I
IIIIIII
III
I
I
答案 0 :(得分:13)
这是一个整数溢出问题。 maxBound :: Int
是2147483647(在32位计算机上),因此值大于溢出值。
使用Integer
代替Int
:Integer
不是固定长度的整数,因此不会溢出。
修改:作为应用说明,您需要将take r "IIIIIIIIII"
替换为take (fromIntegral r) "IIIIIIIIII"
或genericTake r "IIIIIIIIII"
;我更喜欢genericReplicate r 'I'
。
genericTake
和genericReplicate
都在Data.List。