```
module Wordify (wordifyWords, wordify) where
digiteenNames :: [String]
digiteenNames = ["", "one", "two", "three", "four", "five"
,"six", "seven", "eight", "nine", "ten"
,"eleven", "twelve", "thirteen", "fourteen"
,"fifteen","sixteen", "seventeen"
,"eighteen", "nineteen"
]
-- Returns the string form of a particular digit.
digiteen :: Integer -> String
digiteen n = digiteenNames !! fromIntegral n
tenNames :: [String]
tenNames = ["","","twenty", "thirty", "forty", "fifty"
,"sixty", "seventy", "eighty", "ninety"
]
-- Returns the string form for a particular multiple of ten.
tenName :: Integer -> String
tenName n = tenNames !! fromIntegral n
-- Converts a two digit number to its string form.
twodigit :: Integer -> String
twodigit n | n < 20 = digiteen n
| units == 0 = tenName tens
| otherwise = tenName tens ++ "-" ++ digiteen units
where (tens, units) = divMod n 10
-- Converts a three digit number to an array of words. For example:
--
-- threedigit 54 = ["fifty-four"]
-- threedigit 923 = ["nine", "hundred", "twenty-three"]
-- threedigit 400 = ["four", "hundred"]
threedigit :: Integer -> [String]
threedigit n
| hundi == 0 = [twodigit n]
| twodi == 0 = [digiteen hundi, "hundred"]
| otherwise = [digiteen hundi, "hundred", twodigit twodi]
where (hundi, twodi) = divMod n 100
-- periodNames = [[], ["thousand"], ["million"], ...
--
-- This list uses fake names after decillion.
periodNames :: [[String]]
periodNames = [] : map (:[]) ps
where ps = ["thousand", "million", "billion", "trillion"
,"quadrillion", "quintillion", "sextillion"
,"octillion", "septillion", "novemtillion"
,"decillion"] ++ fakes 11
fakes n = (wordify n ++ "-tillion") : fakes (n + 1)
-- Converts a large (or small) positive number to a list of words.
manydigit :: Integer -> [String]
manydigit m = aux periodNames m []
where aux _ 0 tail = tail
aux (p:ps) n tail
= let (n', front) = divMod n 1000
in aux ps n' (case front of
0 -> tail
_ -> threedigit front ++ p ++ tail)
-- Converts any integer to word form, making a list of words.
wordifyWords :: Integer -> [String]
wordifyWords n
| n < 0 = "negative" : manydigit (negate n)
| n == 0 = ["zero"] -- a special case!
| otherwise = manydigit n
-- Converts an integer to string form. For example,
-- wordify 123456000999 = "one hundred twenty-three billion \
-- \four hundred fifty-six million \
-- \nine hundred ninety-nine"
wordify :: Integer -> String
wordify = unwords . wordifyWords
```

**Are you able to help answer this sponsored question?**

Questions asked by members who have earned a lot of community kudos are featured in order to give back and encourage quality replies.

Recommended Topics