Num2Str

Overview

Num2Str is a Haskell library to provide the ability to convert from integers to string representations.

Code

--Convert from number such as 2042 to string like "two thousand and forty-two.
--There are some basic rules implemented which are hopefully clear.
--Number list taken from http://www.jimloy.com/math/billion.htm
 
data Number = Unit Integer String
            | Add Integer String
            | Mult Integer String
    deriving (Show)
 
--Utility routine to calculate powers of ten
 
toThe :: Int -> Integer
toThe n = product $ replicate n 10
 
value :: Number -> Integer
value (Unit n _) = n
value (Add n _) = n
value (Mult n _) = n
 
--Given an integer and a framework to work with, return the Numbers which
 
process :: [Number] -> Integer -> [(Integer, Number)]
process _ 0 = []
process (n:ns) num = filter ( (>0).fst ) $ (count, n) : process ns (num-count * vNum)
   where count = num `div` vNum
         vNum = value n
 
stringify :: [(Integer, Number)] -> String
stringify ((count,base):ns) =
   case base of
        (Unit n s) -> if count /= 1
                         then error "Non-unit count for Unit"
                         else s
        (Add n s) -> if count /= 1
                        then error "Non-unit count for Add"
                        else if areMore
                                then s ++ "-" ++ stringify ns
                                else s
        (Mult n s) -> num2str count ++ " " ++ s ++
                          if areMore
                             then if nextIsMult
                                     then " " ++  stringify ns
                                     else " and " ++ stringify ns
                             else ""
    where areMore = not $ null ns
          nextIsMult = areMore && case (snd $ head ns) of
                                       (Unit _ _) -> False
                                       (Add _ _) -> False
                                       (Mult _ _) -> True
 
num2str :: Integer -> String
num2str n = stringify $ process m n
    where m = reverse [
              (Unit  0            "zero"),
              (Unit  1            "one"),
              (Unit  2            "two"),
              (Unit  3            "three"),
              (Unit  4            "four"),
              (Unit  5            "five"),
              (Unit  6            "six"),
              (Unit  7            "seven"),
              (Unit  8            "eight"),
              (Unit  9            "nine"),
              (Add  10            "ten"),
              (Add  11            "eleven"),
              (Add  12            "twelve"),
              (Add  13            "thirteen"),
              (Add  14            "fourteen"),
              (Add  15            "fifteen"),
              (Add  16            "sixteen"),
              (Add  17            "seventeen"),
              (Add  18            "eighteen"),
              (Add  19            "nineteen"),
              (Add  20            "twenty"),
              (Add  30            "thirty"),
              (Add  40            "forty"),
              (Add  50            "fifty"),
              (Add  60            "sixty"),
              (Add  70            "seventy"),
              (Add  80            "eighty"),
              (Add  90            "ninety"),
              (Mult 100           "hundred"),
              (Mult 1000          "thousand"),
              (Mult (toThe 6)     "million"),
              (Mult (toThe 9)     "billion"),
              (Mult (toThe 12)    "trillion"),
              (Mult (toThe 15)    "quadrillion"),
              (Mult (toThe 18)    "quintillion"),
              (Mult (toThe 21)    "quintillion"),
              (Mult (toThe 24)    "septillion"),
              (Mult (toThe 27)    "octillion"),
              (Mult (toThe 30)    "nonillion"),
              (Mult (toThe 33)    "decillion"),
              (Mult (toThe 36)    "undecillion"),
              (Mult (toThe 39)    "undecillion"),
              (Mult (toThe 42)    "tredecillion"),
              (Mult (toThe 45)    "quattuordecillion"),
              (Mult (toThe 48)    "quindecillion"),
              (Mult (toThe 51)    "sexdecillion"),
              (Mult (toThe 54)    "septendecillion"),
              (Mult (toThe 57)    "octodecillion"),
              (Mult (toThe 60)    "novemdecillion"),
              (Mult (toThe 63)    "vigintillion"),
              (Mult (toThe 100)   "googol"),
              (Mult (toThe 303)   "centillion")
              ]

Leave a Comment