-- This Haskell program converts positive integers to the English phrase equivalent. It only deals with integers of up to 12 digits. -- The main function is cvt. Type cvt 13472 for example. -- There is also a 'display' version that prints the string to standard output rather than returning the string as result. import Char(toUpper) convert2 :: Int -> String convert2 n = combine2 (tens n) tens :: Int -> (Int,Int) tens n = (n `div` 10, n `mod` 10) unitwords, teenwords, tenwords :: [String] unitwords = ["one","two","three","four","five","six","seven","eight","nine"] teenwords = ["ten","eleven","twelve","thirteen","fourteen","fifteen", "sixteen","seventeen","eighteen","nineteen"] tenwords = ["twenty","thirty","forty","fifty","sixty","seventy", "eighty","ninety"] combine2 :: (Int,Int) -> String combine2 (0, u+1) = unitwords!!u -- remember indexing is from 0 combine2 (1, u) = teenwords!!u combine2 (t+2, 0) = tenwords!!t combine2 (t+2, u+1) = tenwords!!t ++ "-" ++ unitwords!!u convert3 :: Int -> String convert3 n = combine3 (hundreds n) hundreds :: Int -> (Int,Int) hundreds n = (n `div` 100, n `mod` 100) combine3 :: (Int,Int) -> String combine3 (0, u) = convert2 u combine3 (h+1, 0) = unitwords!!h ++ " hundred" combine3 (h+1, u) = unitwords!!h ++ " hundred and " ++ convert2 u convert6 :: Int -> String convert6 n = combine6 (thousands n) thousands :: Int -> (Int,Int) thousands n = ( n `div` 1000, n `mod` 1000) combine6 :: (Int,Int) -> String combine6 (0, u) = convert3 u combine6 (th, 0) = convert3 th ++ " thousand" combine6 (th, u) = convert3 th ++ " thousand" ++ link u ++ convert3 u link h | h < 100 = " and " | otherwise = " " -- alternatively ", " -- Extension to billions. (i.e. up to 12 digits.) convert12 :: Int -> String convert12 n = combine12 (millions n) millions :: Int -> (Int,Int) millions n = (n `div` 1000000, n `mod` 1000000) combine12 :: (Int,Int) -> String combine12 (0, u) = convert6 u combine12 (m, 0) = convert6 m ++ " million" combine12 (m, u) = convert6 m ++ " million" ++ link u ++ convert6 u -- Extension to full stop and capitalise first word. cvt :: Int -> String cvt 0 = "Zero." cvt n = (toUpper ch):chs where (ch:chs) = convert12 n ++ "." -- Print the converted result to standard output. wordify :: Int -> IO() wordify n = putStr (cvt n)