<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<link rel="self" href="/Atom/" />
	<id>http://billmill.org/</id>
	<title>My Name Rhymes</title>
	<subtitle>Bill Mill blogs irregularly</subtitle>
	<updated>2008-01-12T17:52:00Z</updated>
	<author>
		<name>Bill Mill</name>
		<email>bill.mill@gmail.com</email>
		<uri>http://billmill.org/</uri>
	</author>
	<link href="http://billmill.org/" />
	<entry>
		<title>Functional Roman Numerals in Python</title>
		<link href="http://billmill.org/python_roman.html" />	
		<id>http://billmill.org/python_roman.html</id>
		<updated>2008-01-12T17:52:00Z</updated>
		<summary type="html">Just as a quck note, I thought I'd post the cleanest python I could come up 
with to solve the &lt;a href="http://billmill.org/roman.html"&gt;roman numerals&lt;/a&gt; 
problem I discussed earlier. It tries to use a functional style while actually 
avoiding recursion. To do so, I wrote an iterative python unfold:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    res &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []                       
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;:
        &lt;span style="font-weight: bold"&gt;try&lt;/span&gt;:
            w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
            res&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(w)
        &lt;span style="font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;TypeError&lt;/span&gt;:
            &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; res
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then the answer becomes:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
    (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
    (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
    (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;] &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x: &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (n[&lt;span style="color: #009999"&gt;0&lt;/span&gt;], x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;])

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(unfold(next, n))
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compare to the haskell I posted before:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
    &lt;span style="font-weight: bold"&gt;where&lt;/span&gt; next &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
          next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
          numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The "where" idiom allows you to group helper functions and constants 
underneath the main function, and the unimportance of function order means you 
can highlight the high-level logic. The haskell code is much shorter and 
tighter than the python.
&lt;p&gt;Having powerful iterative functions like unfoldr in the standard library is 
another clear win for Haskell; it took me more lines to define unfold than it 
did to define both next() and romanize(). (By the by, some googling failed to 
turn up a previous python implementation of unfold(); I think this code gets a 
lot uglier without it. I also don't see any obvious way to do it with 
itertools.)
&lt;p&gt;On the other hand, I find the simplicity of the python next() appealing, 
with its constructive instead of declarative approach. It's a less generic 
solution that's intuitively simpler (for me, still an imperative thinker).  
&lt;p&gt;You could match the haskell more exactly:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #555555"&gt;itertools&lt;/span&gt; &lt;span style="font-weight: bold"&gt;import&lt;/span&gt; ifilter

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;second&lt;/span&gt;(f, (a, b)): &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (a, f(b))

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a, ifilter(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next()
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;but the result is pretty ugly. The inability to compose functions compactly
results in a lot of boilerplate, and in having to pick a lot of meaningless 
variable names that obscure what's going on. We could move the lambdas out of
the call and give them names:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    subx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a
    ltx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x

    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(subx, ifilter(ltx, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next())
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And it's a little better, but I think we're now pretty far from idiomatic 
python.
&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The python translation of the haskell isn't bad, but I do think it loses
something. The unfold() trick works really well, and translates easily into
an imperative, pythonic implementation; I'll look for ways to use it in the 
future. And, finally, I'm pretty jealous of Haskell's function combination
abilities.
&lt;p&gt;&lt;h2&gt;Updates&lt;/h2&gt;
&lt;p&gt;In the &lt;a href="http://programming.reddit.com/info/65bpf/comments/"&gt;comments&lt;/a&gt;
at reddit, nostrademons posts a nicer unfold function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #999999"&gt;True&lt;/span&gt;:
        w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
        &lt;span style="font-weight: bold"&gt;yield&lt;/span&gt; w
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And Kay Schluehr prefers the iterative solution:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; ((&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
(&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;), 
(&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;))

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    roman &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; ltr, num &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        (k,n) &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #999999"&gt;divmod&lt;/span&gt;(n, num)
        roman&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(ltr&lt;span style="font-weight: bold"&gt;*&lt;/span&gt;k)
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(roman)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;David Pollak contributes a Scala unfold and romanize &lt;a
href="http://scala-blogs.org/2008/01/roman-numerals-in-scala.html"&gt;at
his blog&lt;/a&gt;.
</summary>
		<content type="html">Just as a quck note, I thought I'd post the cleanest python I could come up 
with to solve the &lt;a href="http://billmill.org/roman.html"&gt;roman numerals&lt;/a&gt; 
problem I discussed earlier. It tries to use a functional style while actually 
avoiding recursion. To do so, I wrote an iterative python unfold:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    res &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []                       
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #009999"&gt;1&lt;/span&gt;:
        &lt;span style="font-weight: bold"&gt;try&lt;/span&gt;:
            w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
            res&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(w)
        &lt;span style="font-weight: bold"&gt;except&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;TypeError&lt;/span&gt;:
            &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; res
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then the answer becomes:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
    (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
    (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
    (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; n &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;] &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x: &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (n[&lt;span style="color: #009999"&gt;0&lt;/span&gt;], x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;n[&lt;span style="color: #009999"&gt;1&lt;/span&gt;])

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(unfold(next, n))
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compare to the haskell I posted before:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
    &lt;span style="font-weight: bold"&gt;where&lt;/span&gt; next &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
          next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
          numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The "where" idiom allows you to group helper functions and constants 
underneath the main function, and the unimportance of function order means you 
can highlight the high-level logic. The haskell code is much shorter and 
tighter than the python.
&lt;p&gt;Having powerful iterative functions like unfoldr in the standard library is 
another clear win for Haskell; it took me more lines to define unfold than it 
did to define both next() and romanize(). (By the by, some googling failed to 
turn up a previous python implementation of unfold(); I think this code gets a 
lot uglier without it. I also don't see any obvious way to do it with 
itertools.)
&lt;p&gt;On the other hand, I find the simplicity of the python next() appealing, 
with its constructive instead of declarative approach. It's a less generic 
solution that's intuitively simpler (for me, still an imperative thinker).  
&lt;p&gt;You could match the haskell more exactly:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;from&lt;/span&gt; &lt;span style="color: #555555"&gt;itertools&lt;/span&gt; &lt;span style="font-weight: bold"&gt;import&lt;/span&gt; ifilter

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;second&lt;/span&gt;(f, (a, b)): &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; (a, f(b))

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a, ifilter(&lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next()
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;but the result is pretty ugly. The inability to compose functions compactly
results in a lot of boilerplate, and in having to pick a lot of meaningless 
variable names that obscure what's going on. We could move the lambdas out of
the call and give them names:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt;(x):
    subx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; a: x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;a
    ltx &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;lambda&lt;/span&gt; (y, z): z &lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt; x

    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; second(subx, ifilter(ltx, numerals)&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;next())
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And it's a little better, but I think we're now pretty far from idiomatic 
python.
&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The python translation of the haskell isn't bad, but I do think it loses
something. The unfold() trick works really well, and translates easily into
an imperative, pythonic implementation; I'll look for ways to use it in the 
future. And, finally, I'm pretty jealous of Haskell's function combination
abilities.
&lt;p&gt;&lt;h2&gt;Updates&lt;/h2&gt;
&lt;p&gt;In the &lt;a href="http://programming.reddit.com/info/65bpf/comments/"&gt;comments&lt;/a&gt;
at reddit, nostrademons posts a nicer unfold function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;unfold&lt;/span&gt;(f, x):
    &lt;span style="font-weight: bold"&gt;while&lt;/span&gt; &lt;span style="color: #999999"&gt;True&lt;/span&gt;:
        w, x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; f(x)
        &lt;span style="font-weight: bold"&gt;yield&lt;/span&gt; w
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And Kay Schluehr prefers the iterative solution:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; ((&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
(&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;), 
(&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;))

&lt;span style="font-weight: bold"&gt;def&lt;/span&gt; &lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt;(n):
    roman &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; []
    &lt;span style="font-weight: bold"&gt;for&lt;/span&gt; ltr, num &lt;span style="font-weight: bold"&gt;in&lt;/span&gt; numerals:
        (k,n) &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #999999"&gt;divmod&lt;/span&gt;(n, num)
        roman&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;append(ltr&lt;span style="font-weight: bold"&gt;*&lt;/span&gt;k)
    &lt;span style="font-weight: bold"&gt;return&lt;/span&gt; &lt;span style="color: #bb8844"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;join(roman)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;David Pollak contributes a Scala unfold and romanize &lt;a
href="http://scala-blogs.org/2008/01/roman-numerals-in-scala.html"&gt;at
his blog&lt;/a&gt;.
</content>
	</entry>
	<entry>
		<title>Beautiful Code</title>
		<link href="http://billmill.org/roman.html" />	
		<id>http://billmill.org/roman.html</id>
		<updated>2008-01-12T03:32:00Z</updated>
		<summary type="html">This bit of code for converting numbers into their Roman numeral equivalents 
was posted by &lt;a 
href="http://programming.reddit.com/info/658ys/comments/c02vm1j"&gt;geezusfreeek&lt;/a&gt; 
on reddit, and I found it so alarmingly pretty that I'm going to spend some 
time to break it down.  This exercise is largely for my own edification, but 
perhaps somebody else will learn a bit along the way. Here's the code:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;List&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;Control.Arrow&lt;/span&gt;

&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
    &lt;span style="font-weight: bold"&gt;where&lt;/span&gt; next &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
          next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
          numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Starting from the inside out is usually the easiest method of understanding 
blocks like this, so we'll look first at the "numerals" list. It is, simply, a 
list of tuples matching Roman numerals to their value. Importantly, it's 
ordered from largest to smallest; we'll see why shortly.&lt;/p&gt;
&lt;p&gt;The meat of this snippet comes in the "next" function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This function is going to return either Nothing (in the base case) or Just a 
tuple of type (String, Integer), where the string is the largest roman numeral 
that's smaller than x and the int is the difference between x and the value of 
that roman numeral.
&lt;p&gt;The first thing we do is filter out the numerals larger than x; we can run 
some quick tests at the interactive console to see how this works:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
[(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We use head to grab the largest numeral we can squeeze into the current 
value:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals 
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then we subtract the value of the roman numeral from the current value of x, 
in order to return the remainder to be operated on next:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;900&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;0&lt;/span&gt;)
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And, finally, we wrap it up in a Maybe monad, so that the main function can 
handle the base case transparently:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;)  &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; 
    filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt;  snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And now we're getting pretty close! What we have is a function that returns 
either Nothing or a tuple containing a letter to add to our roman numeral and 
the next value to operate on. All we have left is the code to drive the 
operation:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The use of unfoldr helps explain why we've wrapped next up in Maybe; here's 
its type:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;t unfoldr
&lt;span style="color: #990000; font-weight: bold"&gt;unfoldr&lt;/span&gt; &lt;span style="font-weight: bold"&gt;::&lt;/span&gt; (b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Maybe&lt;/span&gt; (a, b)) &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; [a]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So we'll take a function from b -&gt; Maybe (a, b), a value of type b, and 
return a list of [a]. In our case, a = String and b = Integer.
&lt;p&gt;All unfoldr does is call the function it's given as a first argument, which 
returns a tuple or Nothing. If it's a tuple, it appends its first element to a 
list and calls the same function with the second element. If it's Nothing, it 
returns the list it's built up to this point.
&lt;p&gt;As we can see, that matches up perfectly with the "next" function we've 
already defined, and the unfoldr will build up a list of roman numeral strings:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;), 
(&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; x&lt;span style="font-weight: bold"&gt;==&lt;/span&gt;&lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;then&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;               
    &lt;span style="font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;9&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;8&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(We had to mangle the definition of next a bit to fit into the interactive 
interpreter, but we haven't changed anything fundamental about it.)
&lt;p&gt;Finally, all we have to do is concatenate the strings into our final result:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; (concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next) &lt;span style="color: #009999"&gt;8&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;&amp;quot;VIII&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Phew - that's an awful lot of information stuffed into a few pretty lines! I 
still have a hell of a time geting the types to match up so that I can write 
stuff like this, but that doesn't mean that I can't appreciate the beauty of 
how it all fits together. The original function presented here is tight in the 
very best sense of the word.
</summary>
		<content type="html">This bit of code for converting numbers into their Roman numeral equivalents 
was posted by &lt;a 
href="http://programming.reddit.com/info/658ys/comments/c02vm1j"&gt;geezusfreeek&lt;/a&gt; 
on reddit, and I found it so alarmingly pretty that I'm going to spend some 
time to break it down.  This exercise is largely for my own edification, but 
perhaps somebody else will learn a bit along the way. Here's the code:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;List&lt;/span&gt;
&lt;span style="font-weight: bold"&gt;import&lt;/span&gt; &lt;span style="color: #555555"&gt;Control.Arrow&lt;/span&gt;

&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
    &lt;span style="font-weight: bold"&gt;where&lt;/span&gt; next &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
          next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
          numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CD&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;400&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;100&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XC&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;90&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;50&lt;/span&gt;),  (&lt;span style="color: #bb8844"&gt;&amp;quot;XL&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;40&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;),   (&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;),
                      (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Starting from the inside out is usually the easiest method of understanding 
blocks like this, so we'll look first at the "numerals" list. It is, simply, a 
list of tuples matching Roman numerals to their value. Importantly, it's 
ordered from largest to smallest; we'll see why shortly.&lt;/p&gt;
&lt;p&gt;The meat of this snippet comes in the "next" function:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; &lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;
&lt;span style="color: #990000; font-weight: bold"&gt;next&lt;/span&gt; x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This function is going to return either Nothing (in the base case) or Just a 
tuple of type (String, Integer), where the string is the largest roman numeral 
that's smaller than x and the int is the difference between x and the value of 
that roman numeral.
&lt;p&gt;The first thing we do is filter out the numerals larger than x; we can run 
some quick tests at the interactive console to see how this works:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;M&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1000&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;900&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
[(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;),(&lt;span style="color: #bb8844"&gt;&amp;quot;D&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;500&lt;/span&gt;)]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We use head to grab the largest numeral we can squeeze into the current 
value:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals 
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;900&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then we subtract the value of the roman numeral from the current value of x, 
in order to return the remainder to be operated on next:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;900&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;900&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;0&lt;/span&gt;)
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
(&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And, finally, we wrap it up in a Maybe monad, so that the main function can 
handle the base case transparently:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (&lt;span style="color: #009999"&gt;915&lt;/span&gt;&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;)  &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; 
    filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;&lt;span style="color: #009999"&gt;915&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt;  snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; (&lt;span style="color: #bb8844"&gt;&amp;quot;CM&amp;quot;&lt;/span&gt;,&lt;span style="color: #009999"&gt;15&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And now we're getting pretty close! What we have is a function that returns 
either Nothing or a tuple containing a letter to add to our roman numeral and 
the next value to operate on. All we have left is the code to drive the 
operation:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #990000; font-weight: bold"&gt;romanize&lt;/span&gt; &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The use of unfoldr helps explain why we've wrapped next up in Maybe; here's 
its type:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;t unfoldr
&lt;span style="color: #990000; font-weight: bold"&gt;unfoldr&lt;/span&gt; &lt;span style="font-weight: bold"&gt;::&lt;/span&gt; (b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Maybe&lt;/span&gt; (a, b)) &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; b &lt;span style="font-weight: bold"&gt;-&amp;gt;&lt;/span&gt; [a]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So we'll take a function from b -&gt; Maybe (a, b), a value of type b, and 
return a list of [a]. In our case, a = String and b = Integer.
&lt;p&gt;All unfoldr does is call the function it's given as a first argument, which 
returns a tuple or Nothing. If it's a tuple, it appends its first element to a 
list and calls the same function with the second element. If it's Nothing, it 
returns the list it's built up to this point.
&lt;p&gt;As we can see, that matches up perfectly with the "next" function we've 
already defined, and the unfoldr will build up a list of roman numeral strings:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;:&lt;/span&gt;m &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; numerals &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; [(&lt;span style="color: #bb8844"&gt;&amp;quot;X&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;10&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;9&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;5&lt;/span&gt;), 
(&lt;span style="color: #bb8844"&gt;&amp;quot;IV&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;4&lt;/span&gt;), (&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;, &lt;span style="color: #009999"&gt;1&lt;/span&gt;)]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold"&gt;let&lt;/span&gt; next x &lt;span style="font-weight: bold"&gt;=&lt;/span&gt; &lt;span style="font-weight: bold"&gt;if&lt;/span&gt; x&lt;span style="font-weight: bold"&gt;==&lt;/span&gt;&lt;span style="color: #009999"&gt;0&lt;/span&gt; &lt;span style="font-weight: bold"&gt;then&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Nothing&lt;/span&gt;               
    &lt;span style="font-weight: bold"&gt;else&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Just&lt;/span&gt; &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; second (x&lt;span style="font-weight: bold"&gt;-&lt;/span&gt;) &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; head &lt;span style="font-weight: bold"&gt;$&lt;/span&gt; filter ((&lt;span style="font-weight: bold"&gt;&amp;lt;=&lt;/span&gt;x) &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; snd) numerals
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;9&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;IX&amp;quot;&lt;/span&gt;]
&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; unfoldr next &lt;span style="color: #009999"&gt;8&lt;/span&gt;
[&lt;span style="color: #bb8844"&gt;&amp;quot;V&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;,&lt;span style="color: #bb8844"&gt;&amp;quot;I&amp;quot;&lt;/span&gt;]
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(We had to mangle the definition of next a bit to fit into the interactive 
interpreter, but we haven't changed anything fundamental about it.)
&lt;p&gt;Finally, all we have to do is concatenate the strings into our final result:
&lt;p&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Prelude&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;Control&lt;/span&gt;&lt;span style="font-weight: bold"&gt;.&lt;/span&gt;&lt;span style="color: #445588; font-weight: bold"&gt;Arrow&lt;/span&gt; &lt;span style="color: #445588; font-weight: bold"&gt;List&lt;/span&gt;&lt;span style="font-weight: bold"&gt;&amp;gt;&lt;/span&gt; (concat &lt;span style="font-weight: bold"&gt;.&lt;/span&gt; unfoldr next) &lt;span style="color: #009999"&gt;8&lt;/span&gt;
&lt;span style="color: #bb8844"&gt;&amp;quot;VIII&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Phew - that's an awful lot of information stuffed into a few pretty lines! I 
still have a hell of a time geting the types to match up so that I can write 
stuff like this, but that doesn't mean that I can't appreciate the beauty of 
how it all fits together. The original function presented here is tight in the 
very best sense of the word.
</content>
	</entry>
</feed>
