我正在尝试编写一个代码来接受一个整数并输出整数字。例如:如果输入是4321,则输出是四千三百二十一。 为此,我首先想要将输入分解为它的个别数字。 ex输入4321将成为[4,3,2,1]的数组。
我当前的代码
newtype wordInt = WI Int
instance Show WordInt where
show (WI x) | x>= 0 = helper x
| x < 0 = helper -x
helper 0 = [0]
helper x = x `mod` 10 : helper (x `div` 10)
目前,我认为我遇到了类型错误。 请注意,这需要能够传递正数和负数。此外,如果您能想到一种有效的方式来进行我正在寻找的转换,我们将非常感激。
答案 0 :(得分:2)
类型名称不能以小写字母开头。在此处将wordInt
更改为WordInt
:
newtype wordInt = WI Int
show
类的方法Show
必须返回String
,而您的helper
类型为Int -> [Int]
(当应用于Int
时})。您需要以某种方式将列表转换为String
,例如通过调用列表中的show
:
instance Show WordInt where
show (WI x) | x >= 0 = show $ helper x
| x < 0 = show $ helper (-x)
最后,请注意我将-x
放在括号中。这对于一元减号是必需的,否则编译器会认为您试图从x
(这是一个函数而不是helper
)中减去Int
。
但是,helper
的实现是错误的,因为它会反向返回数字列表。要解决此问题,您可以编写辅助函数来拆分数字,然后反转列表:
helper :: Int -> [Int]
helper = reverse . go
where go 0 = [0]
go x = x `mod` 10 : go (x `div` 10)
但是,这将填充前导零的数字:
λ. helper 4321
[0,4,3,2,1]
当然,这并没有改变含义,但如果是一个问题,请编写一个包装函数来处理这种情况:
helper :: Int -> [Int]
helper x =
case splitIntoDigits x of
[] -> [0]
xs -> reverse xs
splitIntoDigits :: Int -> [Int]
splitIntoDigits 0 = []
splitIntoDigits x = x `mod` 10 : splitIntoDigits (x `div` 10)
然后它适用于两种情况:
λ. helper 0
[0]
λ. helper 4321
[4,3,2,1]