Take a number and return English language representation
At first glance, you're trying to be a bit cute here and it's making your code more complex than necessary.  For example, why not handle 11 and 12 as part of the teens and why not just type out the teen and decade names in full rather than having extra logic to append a not-quite common suffix ("teen" and "ty")?

For n &lt; 1000 you have the following rules (let &lt;n&gt; mean "n in words", % mean modulo, and // mean integer division):

if 100 &lt;= n then &lt;n // 100&gt; " hundred" ++ 
                 (if n % 100 == 0 then "" else " and " ++ &lt;n % 100&gt;)
if 20 &lt;= n then  {"", "twenty", ..., "ninety"}[n // 10] ++ 
                 (if n % 10 == 0 then "" else " " ++ &lt;n % 10&gt;)
otherwise        {"zero", "one", "two", ..., "ten", "eleven", ..., "nineteen"}[n]


Now you only need to deal with the orders of magnitude ("thousand", "million", etc.).