2

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.

3
  • Your helper function is fine (up to using ' instead of ` on div), but only goes halfway to your goal; i.e. it breaks the input into its individual digits but does not translate them into words. That is why the compiler is complaining. Commented Oct 15, 2016 at 18:28
  • that was a typo when i added it to stack. my actual code has div not 'div'. Commented Oct 15, 2016 at 18:31
  • And don't forget that -minInt == minInt. Commented Oct 15, 2016 at 21:54

1 Answer 1

2

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]
Sign up to request clarification or add additional context in comments.

6 Comments

I just noticed that your helper implementation is wrong too (in the sense of giving wrong answers). I'll update my answer shortly.
wouldn't it be better to have the list in reverse? Thinking ahead, would it not be easier to convert to text by processing the ones digit before the tens digit?
What do you mean by "to have the list in reverse"? If you mean to construct it reversed in the first place, this is possible (by using (++) to append) but inefficient if processing the number from the smaller to the larger end (right-to-left). Regarding your second question, you're already processing the ones digits before the tens digit. Did you mean to say process the number left-to-right?
just as you said, my version of the helper function returns the list of digits in reverse.
now, i'm not sure how i can take this list of digits and change it to words. But this makes sense as the first step. I was thinking that my version of the helper function would make the next step easier than yours because it would allow me to process the number right to left. or no?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.