Reputation: 39
I am attempting to write a code to take in an integer and output that integer in words. Ex: if the input is 4321 the output is four thousand three hundred twenty one. For this, I would first like to break the input into it's individual digits. ex input 4321 would become an array of [4,3,2,1].
My current code
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)
At the moment, I think i'm getting a type error. Please note that this needs to be able to hand both positive and negative numbers. Also, if you can think of an efficient way to do the conversion i'm looking for, it would be much appreciated.
Upvotes: 2
Views: 134
Reputation: 2703
Names of types cannot begin with a lowercase letter. Change wordInt
to WordInt
here:
newtype wordInt = WI Int
The method show
of the Show
class must return a String
and your helper
has the type Int -> [Int]
(when applied to an Int
). You need to somehow convert the list into a String
, for instance by calling show
on the list:
instance Show WordInt where
show (WI x) | x >= 0 = show $ helper x
| x < 0 = show $ helper (-x)
Finally, notice that I put -x
in parentheses. This is needed for unary minus because otherwise the compiler will think you are trying to subtract x
from helper
(which is a function and not an Int
).
However, your implementation of helper
is wrong because it returns the list of digits in reverse. To fix this, you can write a helper function to split the digits and then reverse the list:
helper :: Int -> [Int]
helper = reverse . go
where go 0 = [0]
go x = x `mod` 10 : go (x `div` 10)
However, this will pad the number with a leading zero:
λ. helper 4321
[0,4,3,2,1]
This doesn't change the meaning, of course, but if it is a problem, write a wrapper function to deal with this case:
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)
It then works in both cases:
λ. helper 0
[0]
λ. helper 4321
[4,3,2,1]
Upvotes: 2