<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress.com" -->
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	>

<channel>
	<title>haskell &amp;laquo; WordPress.com Tag Feed</title>
	<link>http://en.wordpress.com/tag/haskell/</link>
	<description>Feed of posts on WordPress.com tagged "haskell"</description>
	<pubDate>Sat, 28 Nov 2009 00:35:51 +0000</pubDate>

	<generator>http://en.wordpress.com/tags/</generator>
	<language>en</language>

<item>
<title><![CDATA[Programming Praxis - $7.11]]></title>
<link>http://bonsaicode.wordpress.com/2009/11/27/programming-praxis-7-11/</link>
<pubDate>Fri, 27 Nov 2009 12:32:48 +0000</pubDate>
<dc:creator>Remco Niemeijer</dc:creator>
<guid>http://bonsaicode.wordpress.com/2009/11/27/programming-praxis-7-11/</guid>
<description><![CDATA[Today&#8217;s Programming Praxis problem is an easy one.  We&#8217;re supposed to give the prices of]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://programmingpraxis.com/2009/11/27/7-11/" target="_blank">Today&#8217;s</a> Programming Praxis problem is an easy one.  We&#8217;re supposed to give the prices of four items, that both sum up and multiply to $7.11. Let&#8217;s get started.</p>
<p>While we could just do a brute force test on all possible combinations, this would take rather long. So in order to speed things up we only check numbers that are a proper divisor of $7.11.</p>
<pre style="color:#000000;background-color:#ffffff;font-size:9pt;font-family:'Courier New';">divs <span style="color:#ff0000;">:: [</span><span style="color:#0000ff;">Int</span><span style="color:#ff0000;">]</span>
divs <span style="color:#ff0000;">= [</span>x <span style="color:#ff0000;">&#124;</span> x <span style="color:#ff0000;">&#60;- [</span><span style="color:#a900a9;">1</span><span style="color:#ff0000;">.</span><span style="color:#a900a9;">.711</span><span style="color:#ff0000;">],</span> <span style="color:#ec7f15;">mod</span> <span style="color:#ff0000;">(</span><span style="color:#a900a9;">711</span> <span style="color:#ff0000;">*</span> <span style="color:#a900a9;">10</span>^<span style="color:#a900a9;">6</span><span style="color:#ff0000;">)</span> x <span style="color:#ff0000;">==</span> <span style="color:#a900a9;">0</span><span style="color:#ff0000;">]</span>
</pre>
<p>Once we have the divisors, solving the problem becomes a fairly trivial list comprehension (the &#60;= bits are another optimization to eliminate some identical combinations).</p>
<pre style="color:#000000;background-color:#ffffff;font-size:9pt;font-family:'Courier New';">main <span style="color:#ff0000;">::</span> <span style="color:#0000ff;">IO</span> <span style="color:#ff0000;">()</span>
main <span style="color:#ff0000;">=</span> <span style="color:#ec7f15;">print</span> <span style="color:#ff0000;">[(</span>a<span style="color:#ff0000;">,</span>b<span style="color:#ff0000;">,</span>c<span style="color:#ff0000;">,</span>d<span style="color:#ff0000;">) &#124;</span> a <span style="color:#ff0000;">&#60;-</span> divs<span style="color:#ff0000;">,</span>         b <span style="color:#ff0000;">&#60;-</span> divs<span style="color:#ff0000;">,</span> b <span style="color:#ff0000;">&#60;=</span> a<span style="color:#ff0000;">,</span>
                          c <span style="color:#ff0000;">&#60;-</span> divs<span style="color:#ff0000;">,</span> c <span style="color:#ff0000;">&#60;=</span> b<span style="color:#ff0000;">,</span> d <span style="color:#ff0000;">&#60;-</span> divs<span style="color:#ff0000;">,</span> d <span style="color:#ff0000;">&#60;=</span> c<span style="color:#ff0000;">,</span>
                          a <span style="color:#ff0000;">+</span> b <span style="color:#ff0000;">+</span> c <span style="color:#ff0000;">+</span> d <span style="color:#ff0000;">==</span> <span style="color:#a900a9;">711</span><span style="color:#ff0000;">,</span>
                          a <span style="color:#ff0000;">*</span> b <span style="color:#ff0000;">*</span> c <span style="color:#ff0000;">*</span> d <span style="color:#ff0000;">==</span> <span style="color:#a900a9;">711</span> <span style="color:#ff0000;">*</span> <span style="color:#a900a9;">10</span>^<span style="color:#a900a9;">6</span><span style="color:#ff0000;">]</span></pre>
<p>If we run this, we find there is only one combination that satisfies both requirements.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Released package-vt-0.1.3.3]]></title>
<link>http://mostlycode.wordpress.com/2009/11/27/released-package-vt-0-1-3-3/</link>
<pubDate>Fri, 27 Nov 2009 02:48:10 +0000</pubDate>
<dc:creator>Tener</dc:creator>
<guid>http://mostlycode.wordpress.com/2009/11/27/released-package-vt-0-1-3-3/</guid>
<description><![CDATA[Just a quick update now. I&#8217;ve just released a brand new tool called package-vt. It should be u]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Just a quick update now. I&#8217;ve just released a brand new tool called package-vt. It should be used for detecting changes in packages that should cause a version bump. </p>
<p>You can read more on <a href="http://www.haskell.org/pipermail/haskell-cafe/2009-November/069692.html">Haskell Cafe</a>.<br />
Page on <a href="http://hackage.haskell.org/package/package-vt">Hackage</a>.<br />
Git <a href="http://github.com/Tener/haskell-package-vt">repo</a>.</p>
<p>Stay tuned for more info!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Dlaczego Haskell 20 powodów]]></title>
<link>http://gracjanpolak.wordpress.com/2009/11/26/dlaczego-haskell-20-powodow/</link>
<pubDate>Thu, 26 Nov 2009 17:02:08 +0000</pubDate>
<dc:creator>gracjanpolak</dc:creator>
<guid>http://gracjanpolak.wordpress.com/2009/11/26/dlaczego-haskell-20-powodow/</guid>
<description><![CDATA[Sprawdzony Haskell narodził się w 1987 roku, ponad 20 lat na rynku. Popularny Język Haskell wypada d]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><a href="http://gracjanpolak.wordpress.com/files/2009/10/haskell-princess.png"><img src="http://gracjanpolak.wordpress.com/files/2009/10/haskell-princess.png?w=300" alt="haskell-princess" title="haskell-princess" width="300" height="300" class="alignright size-medium wp-image-192" /></a></p>
<ol>
<li><strong>Sprawdzony</strong><br />
Haskell narodził się w 1987 roku, ponad 20 lat na rynku.</li>
<li><strong>Popularny</strong><br />
Język Haskell wypada dzisiaj znać. Wszyscy dzisiaj o nim mówią i piszą.</li>
<li><strong>Dziecinnie łatwy w instalacji</strong><br />
dzięki Haskell Platform. Zobacz chociażby niedawny wpis.</li>
<li><strong>Tysiące bibliotek</strong><br />
Właściwie jeden tysiąc (na razie), ale za to jak łatwo dostępne! Wszystko jest na Hackage, dziecinnie proste w instalacji przy użyciu Cabal. </li>
<li><strong>Platformy</strong><br />
systemy Windows, Unix, MacOSX, Linux. Architektury PowerPC, x86, ARM. Wersje 32 i 64bit.</li>
<li><strong>Otwarty</strong><br />
źródła praktycznie każdego narzędzia dostępne na otwartych licencjach, wszystko oparte o publiczne specyfikacje. Gratis!</li>
<li><strong>Skrzynka z narzędziami</strong><br />
zawiera wszystko, co potrzebne do wygodnej i wydajnej pracy, takich jako kompilatory, profilery, debuggery, dokumentacja, testy. W skrzynce jest też kilka nowiutkich zabawek!</li>
<li><strong>Równoległy i współbieżny</strong><br />
programowanie równoległe i współbieżne jeszcze nigdy nie dawało takich wyników.</li>
<li><strong>Dostajesz co zamówiłeś</strong><br />
Statyczne typowanie zapewnia bezpieczeństwo podczas używania zmiennych. Z żadnego kontenera nie wyciągniesz już królika!</li>
<li><strong>Oszczędź sobie niespodzianek</strong><br />
dzięki algebraicznym typom danych oraz dopasowywaniu wzorca nie zapomnisz już o żadnym szczególnym przypadku.</li>
<li><strong>Typ z klasą</strong><br />
klasy typów to zestawy metod (interfejsy). Haskell jest elastyczny i pozwala implementować interfejsy od definiowanych obiektów.</li>
<li><strong>Szablony wykonane prawidłowo</strong><br />
Funkcje oraz typy mogą zostać zdefiniowane dla danych uogólnionych dzięki polimorfizmowi parametrycznemu.</li>
<li><strong>Nie daj się zaskoczyć</strong><br />
Czyste funkcje dotrzymują słowa: żadnych efektów ubocznych!</li>
<li><strong>Programowalny średnik</strong><br />
Monady potrafią więcej, niż możesz sobie wyobrazić.</li>
<li><strong>Lenistwo</strong><br />
a właściwie leniwość. Operuj na nieskończonych strukturach danych istniejących potencjalnie tylko w Twojej wyobraźni!</li>
<li><strong>Inteligentny kompilator</strong><br />
nie Ty informujesz kompilator o typie danych, o typie danych kompilator informuje Ciebie.</li>
<li><strong>Funkcje wyższego rzędu</strong><br />
korzystaj z narzędzi z najwyższej półki dostępnych w każdej chwili.</li>
<li><strong>Żadnych wskaźników</strong><br />
oraz oczywiście automatyczne zarządzanie pamięcią. Haskell dba o Twoje zdrowie psychiczne.</li>
<li><strong>Towarzyski</strong><br />
Haskell tworzy zdrowy ekosystem z kodem napisanym w C, Objective C, COM, SOAP, AppleAcript, Lua, i innymi.</li>
<li><strong>Nie jesteś sam</strong><br />
społeczność wokół języka Haskell jest ogromna i ciągle rośnie! Jest planet, jest #haskell, ze dwie listy mailingowe haskell-cafe i haskell-beginners. </li>
<li><strong>Zwięzły i elegancki</strong><br />
Haskell po prostu da się kochać.</li>
</ol>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[NoSlow: Microbenchmarks for Haskell array libraries]]></title>
<link>http://unlines.wordpress.com/2009/11/27/noslow/</link>
<pubDate>Thu, 26 Nov 2009 15:15:20 +0000</pubDate>
<dc:creator>Roman Leshchinskiy</dc:creator>
<guid>http://unlines.wordpress.com/2009/11/27/noslow/</guid>
<description><![CDATA[Over the last couple of days, I have implemented a small benchmark suite which tries to measure the ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Over the last couple of days, I have implemented a small benchmark suite which tries to measure the performance of various Haskell array libraries, with particular emphasis on finding out how well they are able to fuse things. It is now on <a href="http://hackage.haskell.org/package/NoSlow">Hackage</a> under the very creative and imaginative name <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> (Haskell seems to have gained a tradition of naming benchmark suites no<em>something</em>). What it does is compile and run a set of micro-benchmarks using these libraries:</p>
<ul>
<li>standard lists</li>
<li>primitive arrays from the <a href="http://www.haskell.org/haskellwiki/GHC/Data_Parallel_Haskell">DPH project</a> (package <tt>dph-prim-seq</tt>)</li>
<li><a href="http://hackage.haskell.org/package/uvector">uvector</a> (a fork of the above)</li>
<li><a href="http://hackage.haskell.org/package/vector">vector</a> (primitive, storable and boxed arrays)</li>
<li><a href="http://hackage.haskell.org/package/storablevector">storablevector</a></li>
</ul>
<p>The actual benchmarking is done by Brian O&#8217;Sullivan&#8217;s wonderful <a href="http://hackage.haskell.org/package/criterion">criterion</a>.</p>
<p><a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> is a very young project so the output isn&#8217;t particularly pretty but it does the job. It is also not very thoroughly tested and only includes a very restricted set of benchmarks so saying &#8220;library <em>x</em> is better than library <em>y</em> because it produces better numbers in <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a>&#8221; would be completely and utterly wrong. However, it is quite useful for identifying cases where taking a closer look at the code generated for a particular loop might be a good idea. It already helped me spot one <a href="http://www.haskell.org/pipermail/cvs-libraries/2009-November/011522.html">tricky performance regression</a> in the standard list library.</p>
<p>Here is an example of the data it produces.</p>
<table border="1" style='font-size:80%;white-space:nowrap;'>
<caption>NoSlow results for GHC 6.13.20091124 (only loops specialised for Double)</caption>
<tr>
<th></th>
<th colspan="1">dph-prim</th>
<th colspan="1">list</th>
<th colspan="1">storablevector</th>
<th colspan="1">uvector</th>
<th colspan="3">vector</th>
</tr>
<tr>
<th></th>
<th colspan="1">seq</th>
<th colspan="1"></th>
<th colspan="1"></th>
<th colspan="1"></th>
<th colspan="1">Primitive</th>
<th colspan="1">Storable</th>
<th colspan="1">boxed</th>
</tr>
<tr>
<th>$a+1</th>
<td>58.38504 us</td>
<td>192.9597 us</td>
<td>58.25747 us</td>
<td>58.47876 us</td>
<td>58.52366 us</td>
<td>58.77233 us</td>
<td>405.5711 us</td>
</tr>
<tr>
<th>$a+^1</th>
<td>59.03597 us</td>
<td>356.6624 us</td>
<td>210.4899 us</td>
<td>80.25804 us</td>
<td>58.53107 us</td>
<td>59.19546 us</td>
<td>417.2587 us</td>
</tr>
<tr>
<th>$a+x</th>
<td>55.62417 us</td>
<td>236.2620 us</td>
<td>55.63200 us</td>
<td>55.62767 us</td>
<td>55.33446 us</td>
<td>55.96459 us</td>
<td>477.2455 us</td>
</tr>
<tr>
<th>$a+^x</th>
<td>56.91372 us</td>
<td>445.1638 us</td>
<td>237.9741 us</td>
<td>75.81757 us</td>
<td>55.79731 us</td>
<td>56.45521 us</td>
<td>491.3216 us</td>
</tr>
<tr>
<th>$a+x+x+x+x</th>
<td>96.75086 us</td>
<td>280.3636 us</td>
<td>236.0562 us</td>
<td>96.76510 us</td>
<td>95.07297 us</td>
<td>97.15892 us</td>
<td>519.6680 us</td>
</tr>
<tr>
<th>$a+$b</th>
<td>64.82325 us</td>
<td>255.3842 us</td>
<td>91.09551 us</td>
<td>64.82592 us</td>
<td>65.21805 us</td>
<td>65.10213 us</td>
<td>500.7479 us</td>
</tr>
<tr>
<th>$a+$b(zip)</th>
<td>64.48503 us</td>
<td>347.4379 us</td>
<td></td>
<td>64.49701 us</td>
<td></td>
<td></td>
<td>499.5277 us</td>
</tr>
<tr>
<th>x*$a+$b</th>
<td>75.63250 us</td>
<td>452.0626 us</td>
<td>154.3398 us</td>
<td>75.68617 us</td>
<td>110.5486 us</td>
<td>155.2830 us</td>
<td>649.9281 us</td>
</tr>
<tr>
<th>($a+$b)*($c+$d)</th>
<td>125.0923 us</td>
<td>1.080122 ms</td>
<td>288.3781 us</td>
<td>125.0150 us</td>
<td>919.2376 us</td>
<td>1.132326 ms</td>
<td>2.967417 ms</td>
</tr>
<tr>
<th>($a+$b)*($c+$d)(zip)</th>
<td>155.3547 us</td>
<td>742.2439 us</td>
<td></td>
<td>155.3554 us</td>
<td></td>
<td></td>
<td>2.509351 ms</td>
</tr>
<tr>
<th>(x+$a)*(y+$b)</th>
<td>104.0011 us</td>
<td>678.5383 us</td>
<td>203.9229 us</td>
<td>103.9131 us</td>
<td>89.32382 us</td>
<td>89.98352 us</td>
<td>401.6301 us</td>
</tr>
<tr>
<th>(^x+$a)*(^y+$b)</th>
<td>118.5413 us</td>
<td>1.061493 ms</td>
<td>534.0542 us</td>
<td>150.2891 us</td>
<td>822.7933 us</td>
<td>930.1098 us</td>
<td>2.650773 ms</td>
</tr>
<tr>
<th>filter(neq0)(map0)</th>
<td>61.45542 us</td>
<td>78.80583 us</td>
<td>104.6501 us</td>
<td>61.35867 us</td>
<td>68.04449 us</td>
<td>61.67384 us</td>
<td>124.5576 us</td>
</tr>
<tr>
<th>filter(neq0)(^0)</th>
<td>17.42000 us</td>
<td>23.41616 us</td>
<td>173.0071 us</td>
<td>17.91704 us</td>
<td>23.33224 us</td>
<td>24.97328 us</td>
<td>59.48926 us</td>
</tr>
<tr>
<th>filter(eq0)(map0)</th>
<td>69.61809 us</td>
<td>174.2209 us</td>
<td>242.6149 us</td>
<td>69.63563 us</td>
<td>69.34671 us</td>
<td>69.89652 us</td>
<td>331.1557 us</td>
</tr>
<tr>
<th>filter(eq0)(^0)</th>
<td>45.96399 us</td>
<td>94.22360 us</td>
<td>308.5451 us</td>
<td>45.75672 us</td>
<td>52.15233 us</td>
<td>45.52413 us</td>
<td>201.7559 us</td>
</tr>
<tr>
<th>zip_filter</th>
<td>76.31172 us</td>
<td>466.6432 us</td>
<td>334.0208 us</td>
<td>76.24536 us</td>
<td>99.80086 us</td>
<td>100.4251 us</td>
<td>341.6012 us</td>
</tr>
<tr>
<th>filter_zip</th>
<td>81.01137 us</td>
<td>468.8768 us</td>
<td>239.6135 us</td>
<td>79.83034 us</td>
<td>80.92583 us</td>
<td>87.66268 us</td>
<td>255.4129 us</td>
</tr>
<tr>
<th>filter_evens</th>
<td>59.13895 us</td>
<td>182.2491 us</td>
<td></td>
<td>58.59793 us</td>
<td></td>
<td></td>
<td>337.2523 us</td>
</tr>
<tr>
<th>sum($a*$b)</th>
<td>115.0304 us</td>
<td>1.130831 ms</td>
<td>145.4783 us</td>
<td>115.0499 us</td>
<td>73.86368 us</td>
<td>74.39775 us</td>
<td>99.39568 us</td>
</tr>
<tr>
<th>sum($a*$b)(zip)</th>
<td>114.9057 us</td>
<td>1.420020 ms</td>
<td></td>
<td>114.8766 us</td>
<td></td>
<td></td>
<td>99.43429 us</td>
</tr>
<tr>
<th>sum[m..n]</th>
<td>53.50359 us</td>
<td>646.0969 us</td>
<td>235.4800 us</td>
<td>53.76784 us</td>
<td>129.2202 us</td>
<td>133.0979 us</td>
<td>134.6730 us</td>
</tr>
<tr>
<th>sumsq(map)</th>
<td>67.20919 us</td>
<td>653.9266 us</td>
<td>292.8844 us</td>
<td>67.21005 us</td>
<td>143.1072 us</td>
<td>142.2476 us</td>
<td>143.5639 us</td>
</tr>
<tr>
<th>sumsq(zip)</th>
<td>67.24133 us</td>
<td>1.928390 ms</td>
<td>311.0818 us</td>
<td>160.3321 us</td>
<td>369.7680 us</td>
<td>380.4847 us</td>
<td>914.5373 us</td>
</tr>
<tr>
<th>sum_evens</th>
<td>120.4421 us</td>
<td>401.7939 us</td>
<td></td>
<td>120.4255 us</td>
<td></td>
<td></td>
<td>150.9723 us</td>
</tr>
</table>
<p><h1>Benchmarks</h1>
</p>
<p>At the moment, <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> only benchmarks a bunch of very small and fairly random loop kernels as I was more concerned with getting the infrastructure in place. Here is an example  (called <i>$a+$b</i> in the table):</p>
<pre>dotp as bs = sum (zipWith (*) as bs)
</pre>
<p>When it is built, <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> compiles several different versions of this loop. For instance, for the <a href="http://hackage.haskell.org/package/storablevector">storablevector</a> backend it will generate these two functions:</p>
<pre>
dotp :: (Storable a, Num a) =&#62; StorableVector a -&#62; StorableVector a -&#62; a
dotp :: StorableVector Double -&#62; StorableVector Double -&#62; Double
</pre>
<p>The first one is overloaded on the element type whereas the second one is specialised to <tt>Double</tt>. <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> does this for all its backends and then runs all generated versions of the benchmark with the same test data. With more testing and more benchmarks, this will give us a rough estimate of the relative performance of the different array libraries. It also shows how much faster specialised loops are compared to their polymorphic versions</p>
<p>Here is the output of a full run. <i>*Double</i> and <i>Double</i> are overloaded and specialised loops, respectively. At the moment, <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> only does Double benchmarks but adding more types is easy.</p>
<table border="1" style='font-size:80%;white-space:nowrap;'>
<caption>NoSlow results for GHC 6.13.20091124</caption>
<tr>
<th></th>
<th colspan="2">dph-prim</th>
<th colspan="2">list</th>
<th colspan="2">storablevector</th>
<th colspan="2">uvector</th>
<th colspan="6">vector</th>
</tr>
<tr>
<th></th>
<th colspan="2">seq</th>
<th colspan="2"></th>
<th colspan="2"></th>
<th colspan="2"></th>
<th colspan="2">Primitive</th>
<th colspan="2">Storable</th>
<th colspan="2">boxed</th>
</tr>
<tr>
<th></th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
</tr>
<tr>
<th>$a+1</th>
<td>388.9189 us</td>
<td>58.38504 us</td>
<td>334.0156 us</td>
<td>192.9597 us</td>
<td>310.7921 us</td>
<td>58.25747 us</td>
<td>410.9401 us</td>
<td>58.47876 us</td>
<td>831.8845 us</td>
<td>58.52366 us</td>
<td>467.6662 us</td>
<td>58.77233 us</td>
<td>563.7031 us</td>
<td>405.5711 us</td>
</tr>
<tr>
<th>$a+^1</th>
<td>412.6220 us</td>
<td>59.03597 us</td>
<td>361.8679 us</td>
<td>356.6624 us</td>
<td>808.4398 us</td>
<td>210.4899 us</td>
<td>554.7731 us</td>
<td>80.25804 us</td>
<td>842.5514 us</td>
<td>58.53107 us</td>
<td>469.5773 us</td>
<td>59.19546 us</td>
<td>570.0256 us</td>
<td>417.2587 us</td>
</tr>
<tr>
<th>$a+x</th>
<td>398.3495 us</td>
<td>55.62417 us</td>
<td>266.9966 us</td>
<td>236.2620 us</td>
<td>317.0817 us</td>
<td>55.63200 us</td>
<td>416.8037 us</td>
<td>55.62767 us</td>
<td>848.4946 us</td>
<td>55.33446 us</td>
<td>479.7607 us</td>
<td>55.96459 us</td>
<td>576.0136 us</td>
<td>477.2455 us</td>
</tr>
<tr>
<th>$a+^x</th>
<td>401.3565 us</td>
<td>56.91372 us</td>
<td>376.1232 us</td>
<td>445.1638 us</td>
<td>821.9274 us</td>
<td>237.9741 us</td>
<td>560.3928 us</td>
<td>75.81757 us</td>
<td>854.3754 us</td>
<td>55.79731 us</td>
<td>483.5405 us</td>
<td>56.45521 us</td>
<td>579.5658 us</td>
<td>491.3216 us</td>
</tr>
<tr>
<th>$a+x+x+x+x</th>
<td>1.099485 ms</td>
<td>96.75086 us</td>
<td>989.8561 us</td>
<td>280.3636 us</td>
<td>1.367973 ms</td>
<td>236.0562 us</td>
<td>1.108161 ms</td>
<td>96.76510 us</td>
<td>1.732897 ms</td>
<td>95.07297 us</td>
<td>1.402448 ms</td>
<td>97.15892 us</td>
<td>1.918533 ms</td>
<td>519.6680 us</td>
</tr>
<tr>
<th>$a+$b</th>
<td>675.8037 us</td>
<td>64.82325 us</td>
<td>266.1987 us</td>
<td>255.3842 us</td>
<td>695.4756 us</td>
<td>91.09551 us</td>
<td>721.3087 us</td>
<td>64.82592 us</td>
<td>1.238228 ms</td>
<td>65.21805 us</td>
<td>758.5373 us</td>
<td>65.10213 us</td>
<td>579.0221 us</td>
<td>500.7479 us</td>
</tr>
<tr>
<th>$a+$b(zip)</th>
<td>674.6217 us</td>
<td>64.48503 us</td>
<td>486.2640 us</td>
<td>347.4379 us</td>
<td></td>
<td></td>
<td>718.1258 us</td>
<td>64.49701 us</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>579.6009 us</td>
<td>499.5277 us</td>
</tr>
<tr>
<th>x*$a+$b</th>
<td>843.1906 us</td>
<td>75.63250 us</td>
<td>576.2166 us</td>
<td>452.0626 us</td>
<td>1.086456 ms</td>
<td>154.3398 us</td>
<td>889.1795 us</td>
<td>75.68617 us</td>
<td>1.494543 ms</td>
<td>110.5486 us</td>
<td>877.4670 us</td>
<td>155.2830 us</td>
<td>1.226473 ms</td>
<td>649.9281 us</td>
</tr>
<tr>
<th>($a+$b)*($c+$d)</th>
<td>1.510817 ms</td>
<td>125.0923 us</td>
<td>1.003353 ms</td>
<td>1.080122 ms</td>
<td>1.958700 ms</td>
<td>288.3781 us</td>
<td>1.582407 ms</td>
<td>125.0150 us</td>
<td>3.109755 ms</td>
<td>919.2376 us</td>
<td>1.915603 ms</td>
<td>1.132326 ms</td>
<td>3.199406 ms</td>
<td>2.967417 ms</td>
</tr>
<tr>
<th>($a+$b)*($c+$d)(zip)</th>
<td>1.585162 ms</td>
<td>155.3547 us</td>
<td>1.345901 ms</td>
<td>742.2439 us</td>
<td></td>
<td></td>
<td>1.845875 ms</td>
<td>155.3554 us</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>2.749534 ms</td>
<td>2.509351 ms</td>
</tr>
<tr>
<th>(x+$a)*(y+$b)</th>
<td>1.139386 ms</td>
<td>104.0011 us</td>
<td>969.7649 us</td>
<td>678.5383 us</td>
<td>1.451681 ms</td>
<td>203.9229 us</td>
<td>1.174562 ms</td>
<td>103.9131 us</td>
<td>1.950864 ms</td>
<td>89.32382 us</td>
<td>1.404879 ms</td>
<td>89.98352 us</td>
<td>2.030718 ms</td>
<td>401.6301 us</td>
</tr>
<tr>
<th>(^x+$a)*(^y+$b)</th>
<td>1.095473 ms</td>
<td>118.5413 us</td>
<td>1.154678 ms</td>
<td>1.061493 ms</td>
<td>2.512015 ms</td>
<td>534.0542 us</td>
<td>1.530284 ms</td>
<td>150.2891 us</td>
<td>2.452523 ms</td>
<td>822.7933 us</td>
<td>1.825248 ms</td>
<td>930.1098 us</td>
<td>3.399711 ms</td>
<td>2.650773 ms</td>
</tr>
<tr>
<th>filter(neq0)(map0)</th>
<td>357.0597 us</td>
<td>61.45542 us</td>
<td>320.2454 us</td>
<td>78.80583 us</td>
<td>581.4489 us</td>
<td>104.6501 us</td>
<td>364.2109 us</td>
<td>61.35867 us</td>
<td>609.2637 us</td>
<td>68.04449 us</td>
<td>531.9321 us</td>
<td>61.67384 us</td>
<td>370.0963 us</td>
<td>124.5576 us</td>
</tr>
<tr>
<th>filter(neq0)(^0)</th>
<td>19.80998 us</td>
<td>17.42000 us</td>
<td>6.715188 us</td>
<td>23.41616 us</td>
<td>404.8197 us</td>
<td>173.0071 us</td>
<td>20.19333 us</td>
<td>17.91704 us</td>
<td>24.38774 us</td>
<td>23.33224 us</td>
<td>24.77845 us</td>
<td>24.97328 us</td>
<td>59.51524 us</td>
<td>59.48926 us</td>
</tr>
<tr>
<th>filter(eq0)(map0)</th>
<td>527.7883 us</td>
<td>69.61809 us</td>
<td>499.8775 us</td>
<td>174.2209 us</td>
<td>839.2031 us</td>
<td>242.6149 us</td>
<td>542.4786 us</td>
<td>69.63563 us</td>
<td>1.015737 ms</td>
<td>69.34671 us</td>
<td>622.5425 us</td>
<td>69.89652 us</td>
<td>619.5380 us</td>
<td>331.1557 us</td>
</tr>
<tr>
<th>filter(eq0)(^0)</th>
<td>153.7917 us</td>
<td>45.96399 us</td>
<td>87.08318 us</td>
<td>94.22360 us</td>
<td>648.8350 us</td>
<td>308.5451 us</td>
<td>162.6549 us</td>
<td>45.75672 us</td>
<td>417.1879 us</td>
<td>52.15233 us</td>
<td>126.1947 us</td>
<td>45.52413 us</td>
<td>214.1162 us</td>
<td>201.7559 us</td>
</tr>
<tr>
<th>zip_filter</th>
<td>696.4477 us</td>
<td>76.31172 us</td>
<td>631.0826 us</td>
<td>466.6432 us</td>
<td>1.158844 ms</td>
<td>334.0208 us</td>
<td>735.2156 us</td>
<td>76.24536 us</td>
<td>1.042058 ms</td>
<td>99.80086 us</td>
<td>635.7235 us</td>
<td>100.4251 us</td>
<td>588.1413 us</td>
<td>341.6012 us</td>
</tr>
<tr>
<th>filter_zip</th>
<td>741.1476 us</td>
<td>81.01137 us</td>
<td>467.9363 us</td>
<td>468.8768 us</td>
<td>1.073220 ms</td>
<td>239.6135 us</td>
<td>789.2609 us</td>
<td>79.83034 us</td>
<td>1.249209 ms</td>
<td>80.92583 us</td>
<td>835.3062 us</td>
<td>87.66268 us</td>
<td>507.6646 us</td>
<td>255.4129 us</td>
</tr>
<tr>
<th>filter_evens</th>
<td>315.2792 us</td>
<td>59.13895 us</td>
<td>185.6894 us</td>
<td>182.2491 us</td>
<td></td>
<td></td>
<td>342.7927 us</td>
<td>58.59793 us</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>321.4253 us</td>
<td>337.2523 us</td>
</tr>
<tr>
<th>sum($a*$b)</th>
<td>889.3029 us</td>
<td>115.0304 us</td>
<td>1.113731 ms</td>
<td>1.130831 ms</td>
<td>837.7596 us</td>
<td>145.4783 us</td>
<td>630.7635 us</td>
<td>115.0499 us</td>
<td>1.046405 ms</td>
<td>73.86368 us</td>
<td>956.1445 us</td>
<td>74.39775 us</td>
<td>310.2107 us</td>
<td>99.39568 us</td>
</tr>
<tr>
<th>sum($a*$b)(zip)</th>
<td>893.2471 us</td>
<td>114.9057 us</td>
<td>1.890718 ms</td>
<td>1.420020 ms</td>
<td></td>
<td></td>
<td>624.3066 us</td>
<td>114.8766 us</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>371.0969 us</td>
<td>99.43429 us</td>
</tr>
<tr>
<th>sum[m..n]</th>
<td>480.6165 us</td>
<td>53.50359 us</td>
<td>1.006370 ms</td>
<td>646.0969 us</td>
<td>599.5453 us</td>
<td>235.4800 us</td>
<td>257.9740 us</td>
<td>53.76784 us</td>
<td>520.8189 us</td>
<td>129.2202 us</td>
<td>455.0702 us</td>
<td>133.0979 us</td>
<td>450.9119 us</td>
<td>134.6730 us</td>
</tr>
<tr>
<th>sumsq(map)</th>
<td>601.0236 us</td>
<td>67.20919 us</td>
<td>1.389623 ms</td>
<td>653.9266 us</td>
<td>916.6944 us</td>
<td>292.8844 us</td>
<td>361.3013 us</td>
<td>67.21005 us</td>
<td>633.0462 us</td>
<td>143.1072 us</td>
<td>632.7607 us</td>
<td>142.2476 us</td>
<td>626.6808 us</td>
<td>143.5639 us</td>
</tr>
<tr>
<th>sumsq(zip)</th>
<td>581.3862 us</td>
<td>67.24133 us</td>
<td>2.487876 ms</td>
<td>1.928390 ms</td>
<td>1.391611 ms</td>
<td>311.0818 us</td>
<td>931.6956 us</td>
<td>160.3321 us</td>
<td>2.725828 ms</td>
<td>369.7680 us</td>
<td>1.892799 ms</td>
<td>380.4847 us</td>
<td>1.770848 ms</td>
<td>914.5373 us</td>
</tr>
<tr>
<th>sum_evens</th>
<td>522.6244 us</td>
<td>120.4421 us</td>
<td>377.5469 us</td>
<td>401.7939 us</td>
<td></td>
<td></td>
<td>283.7662 us</td>
<td>120.4255 us</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>293.9641 us</td>
<td>150.9723 us</td>
</tr>
</table>
<p>
<a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> can also be used to see how well different GHC versions optimise array loops. Here is a comparison of the current HEAD to GHC 6.10.4 (2 means 6.13 is 2x slower, 0.5 means it is 2x faster).</p>
<table border="1" style='font-size:80%;white-space:nowrap;'>
<caption>NoSlow results for GHC 6.13.20091124 vs GHC 6.10.4</caption>
<tr>
<th></th>
<th colspan="2">dph-prim</th>
<th colspan="2">list</th>
<th colspan="2">storablevector</th>
<th colspan="2">uvector</th>
<th colspan="6">vector</th>
</tr>
<tr>
<th></th>
<th colspan="2">seq</th>
<th colspan="2"></th>
<th colspan="2"></th>
<th colspan="2"></th>
<th colspan="2">Primitive</th>
<th colspan="2">Storable</th>
<th colspan="2">boxed</th>
</tr>
<tr>
<th></th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
<th>*Double</th>
<th>Double</th>
</tr>
<tr>
<th>$a+1</th>
<td>0.169</td>
<td>0.998</td>
<td>1.821</td>
<td>1.023</td>
<td>0.879</td>
<td>1.000</td>
<td>0.183</td>
<td>1.000</td>
<td>0.109</td>
<td>0.019</td>
<td>0.069</td>
<td>1.000</td>
<td>0.994</td>
<td>0.985</td>
</tr>
<tr>
<th>$a+^1</th>
<td>0.178</td>
<td>1.001</td>
<td>1.027</td>
<td>1.029</td>
<td>0.068</td>
<td>0.114</td>
<td>0.130</td>
<td>1.001</td>
<td>0.058</td>
<td>0.014</td>
<td>0.031</td>
<td>0.999</td>
<td>1.011</td>
<td>1.004</td>
</tr>
<tr>
<th>$a+x</th>
<td>0.172</td>
<td>1.004</td>
<td>1.138</td>
<td>0.989</td>
<td>0.970</td>
<td>1.006</td>
<td>0.185</td>
<td>1.005</td>
<td>0.121</td>
<td>0.018</td>
<td>0.072</td>
<td>1.002</td>
<td>1.024</td>
<td>0.965</td>
</tr>
<tr>
<th>$a+^x</th>
<td>0.173</td>
<td>0.982</td>
<td>1.034</td>
<td>1.023</td>
<td>0.068</td>
<td>0.127</td>
<td>0.132</td>
<td>0.992</td>
<td>0.060</td>
<td>0.013</td>
<td>0.032</td>
<td>1.007</td>
<td>1.012</td>
<td>0.979</td>
</tr>
<tr>
<th>$a+x+x+x+x</th>
<td>0.400</td>
<td>1.019</td>
<td>1.082</td>
<td>1.007</td>
<td>1.033</td>
<td>0.274</td>
<td>0.386</td>
<td>1.019</td>
<td>0.059</td>
<td>0.008</td>
<td>0.049</td>
<td>0.089</td>
<td>1.034</td>
<td>0.981</td>
</tr>
<tr>
<th>$a+$b</th>
<td>0.214</td>
<td>0.966</td>
<td>1.014</td>
<td>1.010</td>
<td>0.067</td>
<td>1.226</td>
<td>0.223</td>
<td>0.966</td>
<td>0.121</td>
<td>0.014</td>
<td>0.072</td>
<td>1.000</td>
<td>0.974</td>
<td>0.984</td>
</tr>
<tr>
<th>$a+$b(zip)</th>
<td>0.213</td>
<td>0.965</td>
<td>1.740</td>
<td>1.358</td>
<td></td>
<td></td>
<td>0.223</td>
<td>0.963</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>0.984</td>
<td>1.002</td>
</tr>
<tr>
<th>x*$a+$b</th>
<td>0.251</td>
<td>0.997</td>
<td>1.000</td>
<td>0.982</td>
<td>0.101</td>
<td>1.065</td>
<td>0.263</td>
<td>0.997</td>
<td>0.085</td>
<td>0.020</td>
<td>0.051</td>
<td>1.292</td>
<td>1.007</td>
<td>1.034</td>
</tr>
<tr>
<th>($a+$b)*($c+$d)</th>
<td>0.287</td>
<td>0.199</td>
<td>1.168</td>
<td>1.483</td>
<td>0.064</td>
<td>0.271</td>
<td>0.293</td>
<td>0.199</td>
<td>0.101</td>
<td>0.061</td>
<td>0.060</td>
<td>1.058</td>
<td>0.992</td>
<td>1.299</td>
</tr>
<tr>
<th>($a+$b)*($c+$d)(zip)</th>
<td>0.302</td>
<td>1.262</td>
<td>1.301</td>
<td>0.906</td>
<td></td>
<td></td>
<td>0.350</td>
<td>1.257</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>0.949</td>
<td>1.249</td>
</tr>
<tr>
<th>(x+$a)*(y+$b)</th>
<td>0.298</td>
<td>1.119</td>
<td>1.019</td>
<td>0.929</td>
<td>0.138</td>
<td>0.372</td>
<td>0.270</td>
<td>1.119</td>
<td>0.080</td>
<td>0.008</td>
<td>0.059</td>
<td>0.136</td>
<td>0.991</td>
<td>1.001</td>
</tr>
<tr>
<th>(^x+$a)*(^y+$b)</th>
<td>0.323</td>
<td>0.166</td>
<td>0.911</td>
<td>1.057</td>
<td>0.074</td>
<td>0.114</td>
<td>0.207</td>
<td>0.199</td>
<td>0.061</td>
<td>0.039</td>
<td>0.043</td>
<td>0.799</td>
<td>1.123</td>
<td>1.200</td>
</tr>
<tr>
<th>filter(neq0)(map0)</th>
<td>0.374</td>
<td>0.999</td>
<td>1.275</td>
<td>0.990</td>
<td>0.828</td>
<td>0.519</td>
<td>0.364</td>
<td>1.000</td>
<td>0.067</td>
<td>0.047</td>
<td>0.064</td>
<td>0.999</td>
<td>0.986</td>
<td>0.982</td>
</tr>
<tr>
<th>filter(neq0)(^0)</th>
<td>0.191</td>
<td>0.949</td>
<td>0.062</td>
<td>1.000</td>
<td>0.189</td>
<td>0.090</td>
<td>0.180</td>
<td>1.016</td>
<td>0.004</td>
<td>0.036</td>
<td>0.004</td>
<td>1.014</td>
<td>0.423</td>
<td>1.029</td>
</tr>
<tr>
<th>filter(eq0)(map0)</th>
<td>0.220</td>
<td>1.000</td>
<td>1.163</td>
<td>1.049</td>
<td>0.334</td>
<td>0.805</td>
<td>0.231</td>
<td>1.005</td>
<td>0.090</td>
<td>0.019</td>
<td>0.057</td>
<td>1.003</td>
<td>0.981</td>
<td>1.014</td>
</tr>
<tr>
<th>filter(eq0)(^0)</th>
<td>0.131</td>
<td>1.010</td>
<td>0.435</td>
<td>1.177</td>
<td>0.164</td>
<td>0.154</td>
<td>0.137</td>
<td>1.008</td>
<td>0.050</td>
<td>0.019</td>
<td>0.014</td>
<td>1.003</td>
<td>0.738</td>
<td>1.060</td>
</tr>
<tr>
<th>zip_filter</th>
<td>0.327</td>
<td>0.991</td>
<td>1.476</td>
<td>0.997</td>
<td>0.093</td>
<td>0.447</td>
<td>0.339</td>
<td>0.995</td>
<td>0.068</td>
<td>0.014</td>
<td>0.041</td>
<td>0.201</td>
<td>1.277</td>
<td>0.815</td>
</tr>
<tr>
<th>filter_zip</th>
<td>0.283</td>
<td>0.990</td>
<td>1.024</td>
<td>1.475</td>
<td>0.077</td>
<td>0.785</td>
<td>0.297</td>
<td>0.982</td>
<td>0.083</td>
<td>0.019</td>
<td>0.054</td>
<td>1.000</td>
<td>1.071</td>
<td>0.987</td>
</tr>
<tr>
<th>filter_evens</th>
<td>0.180</td>
<td>0.984</td>
<td>0.985</td>
<td>0.998</td>
<td></td>
<td></td>
<td>0.186</td>
<td>0.548</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>0.109</td>
<td>0.115</td>
</tr>
<tr>
<th>sum($a*$b)</th>
<td>0.167</td>
<td>1.475</td>
<td>0.982</td>
<td>0.978</td>
<td>0.074</td>
<td>1.115</td>
<td>0.141</td>
<td>1.476</td>
<td>0.090</td>
<td>0.941</td>
<td>0.079</td>
<td>0.955</td>
<td>0.120</td>
<td>0.642</td>
</tr>
<tr>
<th>sum($a*$b)(zip)</th>
<td>0.167</td>
<td>1.475</td>
<td>1.430</td>
<td>1.344</td>
<td></td>
<td></td>
<td>0.139</td>
<td>1.474</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>0.143</td>
<td>0.998</td>
</tr>
<tr>
<th>sum[m..n]</th>
<td>0.137</td>
<td>0.516</td>
<td>1.042</td>
<td>0.994</td>
<td>0.273</td>
<td>1.014</td>
<td>0.104</td>
<td>0.371</td>
<td>0.063</td>
<td>0.043</td>
<td>0.062</td>
<td>0.065</td>
<td>0.090</td>
<td>0.048</td>
</tr>
<tr>
<th>sumsq(map)</th>
<td>0.167</td>
<td>0.566</td>
<td>1.012</td>
<td>0.985</td>
<td>0.364</td>
<td>1.012</td>
<td>0.140</td>
<td>0.404</td>
<td>0.079</td>
<td>0.047</td>
<td>0.082</td>
<td>0.069</td>
<td>0.120</td>
<td>0.051</td>
</tr>
<tr>
<th>sumsq(zip)</th>
<td>0.088</td>
<td>0.557</td>
<td>1.009</td>
<td>0.968</td>
<td>0.115</td>
<td>1.002</td>
<td>0.165</td>
<td>1.017</td>
<td>0.153</td>
<td>0.061</td>
<td>0.107</td>
<td>0.180</td>
<td>0.272</td>
<td>0.309</td>
</tr>
<tr>
<th>sum_evens</th>
<td>0.190</td>
<td>2.114</td>
<td>0.938</td>
<td>1.041</td>
<td></td>
<td></td>
<td>0.115</td>
<td>1.379</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td>0.078</td>
<td>0.053</td>
</tr>
</table>
<p><h1>Usage</h1>
</p>
<p>The current interface is rather minimalistic. After building <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a>, you get two binaries: <tt>noslow</tt> and <tt>noslow-table</tt>. The first one runs the actual benchmarks and produces a log file:</p>
<pre>
noslow -u log
</pre>
<p> The log can then be fed to <tt>noslow-table</tt> to generate HTML tables:</p>
<pre>
noslow-table log &#62; table.html
</pre>
<p>We can also restrict the output to a particular data type:</p>
<pre>
noslow-table log --type=Double &#62; table.html
</pre>
<p>or compare two logs:</p>
<pre>
noslow-table --diff log1 log2 &#62; table.html
</pre>
<p>In this case, the table will contain ratios of corresponding values from the two logs, just like in the table above.</p>
<h1>Compiling</h1>
<p><a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> should work out of the box with GHC 6.10. I haven&#8217;t tried it with 6.12 because I didn&#8217;t have time to install the release candidate and the required packages. Getting it to build with the HEAD (which is what I&#8217;m interested in) is a rather annoying process, though, because <a href="http://hackage.haskell.org/package/uvector">uvector</a> is missing a DPH patch which would make it work with the new IO system. Fortunately, I could simply transplant some code from the DPH library (the module is <tt>dph-base/Data/Array/Parallel/Data/Array/Parallel/Arr/BUArr.hs</tt>) and everything worked.</p>
<p>Also, <a href="http://hackage.haskell.org/package/storablevector">storablevector</a> depends on QuickCheck 1 which doesn&#8217;t seem to compile with the HEAD. I just removed all references to QuickCheck from the code but it might be easier to simply not build the <a href="http://hackage.haskell.org/package/storablevector">storablevector</a> backend (there is a flag for that).</p>
<h1>How it works</h1>
<p>Benchmarking itself is rather straighforward &#8211; all the exciting bits are in <a href="http://hackage.haskell.org/package/criterion">criterion</a>. The heart of <a href="http://hackage.haskell.org/package/NoSlow">NoSlow</a> is the specialiser &#8211; a <a href="http://www.haskell.org/haskellwiki/Template_Haskell">Template Haskell</a> function that takes a bunch of abstract loop kernels and specialises them for a particular backend and data type. Here is how it works. The kernels themselves are implemented in a TH quote:</p>
<pre>
kernels = [d&#124; ...
    dotp :: (Num a, I.Vector v a) =&#62; Ty (v a) -&#62; v a -&#62; v a -&#62; a
    dotp _ as bs = named "sum($a*$b)" $ I.sum (I.zipWith (*) as bs)
    ... &#124;]
</pre>
<p>They refer to functions from module <tt>I</tt> (short for <tt>NoName.Backend.Interface</tt>) which are just stubs and do not provide any real functionality. The specialiser traverses the ASTs of the kernels (which it has access to since they are quoted) and replaces references to those stubs with calls to functions from the backend that it is specialising for. For instance, it replaces <tt>I.sum</tt> by <tt>NoSlow.Backend.List.sum</tt> (which is just a reexport of the Prelude function) when specialising for lists.  It also adjusts signatures and looks for tags like <tt>named</tt> in the example above which defines the kernel&#8217;s name in the HTML output.</p>
<p>This scheme has one big advantage: it allows backends to mark some kernels as unsupported. An example is <a href="http://hackage.haskell.org/package/storablevector">storablevector</a> which does not support arrays of pairs. The corresponding backend defines <tt>zip</tt> like this:</p>
<pre>
zip :: Undefined
zip = Undefined
</pre>
<p>When replacing <tt>I.zip</tt> with <tt>NoSlow.Backend.StorableVector.zip</tt>, the specialiser reifies the latter, notices that its type is <tt>Unsupported</tt> and omits the kernel that contains the call to <tt>zip</tt> altogether.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[If wishes were tests, code would be perfect]]></title>
<link>http://ivanmiljenovic.wordpress.com/2009/11/26/if-wishes-were-tests-code-would-be-perfect/</link>
<pubDate>Thu, 26 Nov 2009 04:19:29 +0000</pubDate>
<dc:creator>Ivan Miljenovic</dc:creator>
<guid>http://ivanmiljenovic.wordpress.com/2009/11/26/if-wishes-were-tests-code-would-be-perfect/</guid>
<description><![CDATA[(With apologies to wherever the original came from.) As I&#8217;ve mentioned previously, I&#8217;m c]]></description>
<content:encoded><![CDATA[(With apologies to wherever the original came from.) As I&#8217;ve mentioned previously, I&#8217;m c]]></content:encoded>
</item>
<item>
<title><![CDATA[Będziesz gorszym programistą przez Haskella lub Pythona]]></title>
<link>http://gracjanpolak.wordpress.com/2009/11/23/bedziesz-gorszym-programista-przez-haskella-lub-pythona/</link>
<pubDate>Mon, 23 Nov 2009 18:10:42 +0000</pubDate>
<dc:creator>gracjanpolak</dc:creator>
<guid>http://gracjanpolak.wordpress.com/2009/11/23/bedziesz-gorszym-programista-przez-haskella-lub-pythona/</guid>
<description><![CDATA[Wpis jest tłumaczeniem Why learning Haskell/Python makes you a worse programmer by Luke Palmer z 200]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Wpis jest tłumaczeniem<a href="http://lukeplant.me.uk/blog/posts/why-learning-haskell-python-makes-you-a-worse-programmer/"> Why learning Haskell/Python makes you a worse programmer by Luke Palmer</a> z 2006 roku. Czy dziś sytuacja wygląda tak samo? Oceńcie sami:</p>
<p>Stwierdziłem, że w przeciwieństwie do tego co można czasem przeczytać tu i ówdzie, nauczenie się Pythona lub Haskella nie podniosło jakości mojego kodu w innych językach. W szczególności Haskell, tak inny od języków imperatywnych, podobno miał wznieść moje programowanie na wyższe poziomy świadomości, nawet jeśli nie będę używał innych narzędzi. Moje aktualne doświadczenia nie popierają tej tezy. Oto dlaczego:</p>
<ol>
<li>Obniżenie motywacji.
<p>Zacząłem myśleć w Pythonie, a nawet w Haskellu, w którym programowałem bardzo mało. Cały czas mam ochotę używać idiomów z tych języków, bez przerwy zauważam, ile mniej kodu byłoby potrzebne. Oba, wprawdzie różne, jednak są znacznie potężniejsze niż język C# używany przeze mnie obecnie w pracy. Zauważam bardzo często, że pewnego fragmentu kodu mogłyby być 2 lub 3 (a wcale nie tak rzadko 10 czy 20) razy krótsze.</p>
<p>Dalej, przez moje doświadczenia z Haskellem teraz w kodzie imperatywnym wszędzie widzę potencjalne błędy. Wcześniej byłem w pełni świadomy problemów, które niesie za sobą programowanie stanowe i zagrożeń związanych z efektami ubocznymi. Spędziłem niezliczone godziny rozwiązując tabuny błędów tego typu. Ale ponieważ wtedy nie znałem żadnej alternatywy, więc po prostu z tym żyłem. Od kiedy znam inny sposób zapobiegania tego typu zagrożeniom, ciężko jest mi być zadowolonym z mojego kodu. Cały czas mam świadomość, że zastawiam imperatywne pułapki, w które najprawdopodobniej kiedyś wpadną niewinni ludzie.</p>
<p>Także kod w C# wydaje mi się być wyjątkowo brzydki w porównaniu z Pythonem czy Haskellem. Wizualne używanie takiej ilości obowiązkowych nawiasów klamrowych wszędzie (OK, nie obowiązkowych, ale zwykle wymaganych standardami kodowania) powoduje, że kod zawiera wiele niepotrzebnego szumu i pustego miejsca. W połączeniu z ogólną wylewnością bibliotek oraz deklaracji typów często zdarza się, że cała strona kodu C# nie robi praktycznie nic. Mam w tej chwili na myśli też piękno w matematycznym tego słowa znaczeniu. C# to gliniana chatka stojąca w cieniu przepięknej wieży Haskella. </p>
<p>Efektem moich przemyśleń jest poczucie zdołowania i demoralizacji. Czuję się jak ludzki kompilator, tłumaczący Haskella czy Pythona w mojej głowie na język położony cały poziom niżej.</p>
<li>Używanie funkcyjnego stylu programowania zaciemnia kod w innych językach.
<p>C# od pewnego czasu nabiera własności pomocnych w programowaniu funkcyjnym. Któregoś dnia spróbowałem użyć ich do funkcyjnego rozwiązania prostego problemu. Mam listę obiektów typu Foo, każdy ma metodę Description() zwracającą napis. Zadanie polega na  połączeniu wszystkich niepustych opisów wstawiając pomiędzy nie znaki końca linii.</p>
<p>Chciałem napisać odpowiednik Pythonowego kodu:</p>
<pre>
"\n".join(foo.description() for foo in mylist
                         if foo.description() != "")
</pre>
<p>Albo takiego w Haskellu:</p>
<pre>
concat $ List.intersperse "\n" $ filter (/= "") $ map description mylist
</pre>
<p>Używając generyków z C# 2.0 najlepsze do czego doszedłem to:</p>
<pre>
string.Join("\n", mylist.ConvertAll&#60;string&#62;(
            delegate(Foo foo)
            {
                    return foo.Description();
            }).FindAll(
            delegate(string x)
            {
                    return x != "";
            }).ToArray());
</pre>
<p>Strach pomyśleć co by było, gdybym wyszedł od innej struktury danych: wersja C# byłaby pewnie jeszcze gorsza. A C# posiada przecież setki różnych klas kontenerów z niekompatybilnymi interfejsami. Trzeba też zauważyć, że jeśli piszę jakąś metodę, która przyjmuje &#8216;delegatów&#8217; (najbliższy odpowiednik pełnoprawnych funkcji) musisz dla nich napisać nagłówek typu osobno jeśli takowy jeszcze nie istnieje (lub nie wiesz gdzie go znaleźć), co dodatkowo powoduje rozrost kodu pisanego w stylu funkcyjnym.</p>
<p>Wersja C# ma kilka poważnych wad. Wcale nie jest krótsza od kodu imperatywnego. Porównajmy ze zwykłą pętlą:</p>
<pre>
string retval = "";
foreach (Foo foo in mylist)
{
    string desc = foo.description();
    if (desc != "")
    {
            if (retval != "")
               retval += "\n";
            retval += desc;
    }
}
</pre>
<p>Nie ma tutaj niespodzianek.</p>
<p>Po drugie, wersję funkcyjną pisałem dłużej. Musiałem trochę po eksperymentować ile potrzeba dodatkowej informacji o typach do zadowolenia kompilatora. Okazało się, że bezpośrednie kastowanie dla delegata nie było potrzebne, ale za to trzeba było napisać <code>ConvertAll&#60;string&#62;</code> zamiast <code>ConvertAl</code>l.</p>
<p>W końcu, ten kod spowoduje, że mam przechlapane u kolegów. Dlaczegóż piszę tak skomplikowany kod – z takimi zaawansowanymi cudactwami jak anonimowi delegaci – skoro zwykła pętla wystarczy? Zostawiłem wersję funkcyjną, ale poczułem się tak nieswojo, że dodałem notkę wyjaśniającą powyższy fragment.</p>
<p>Prawdą jest, że idiomy funkcyjne źle działają w językach, które nie mają dla nich wsparcia składniowego. Java, z tego co wiem, byłaby jeszcze gorsza niż C#, który na szczęście od niedawnej wersji 2.0 posiada coraz więcej cech pozwalających na przyjemniejsze programowanie funkcyjne. Jednak ogromne części bibliotek .NET się nie zmieniły i nie korzystają z udogodnień, a nasz własny kod na pewno też nie jest lepszy.</p>
<p>Można się uprzeć i dalej używać zasad programowania funkcyjnego (żadnych efektów ubocznych, funkcje zależą tylko od swoich argumentów, itp.) i czerpać z tego korzyści, nawet nie używając idiomów. W rzeczywistości jednak biblioteki i frameworki zaprojektowane dla języków imperatywnych nie działają w ten sposób. ASP.NET jest szczególnie fatalnym przykładem. Tworzę kontrolki dziedzicząc po klasie Control i nadpisuję poszczególne metody. Większość z nich nie ma argumentów i nie zwraca żadnych wartości, za to działa tylko i wyłącznie przez zmianę wewnętrznego stanu obiektów. Są wywoływane przez framework w prawdziwie delikatnym i skomplikowanym porządku (tak, koszmar do debugowania).</p>
<p>W rzeczywistości stosowanie się do zasad programowania funkcyjnego prowadziłby mnie do używania wyłącznie metod statycznych (nigdy metod instancji obiektu), omijanie szerokim łukiem wszystkiego co zmienia stan (lub niesie możliwość zmiany stanu). Używałbym wszędzie kilku prostych typów danych i pilnował oddzielenia ich od algorytmów. To przeczy naukom i praktyce głównego dzisiaj nurtu programistycznego czyli programowania obiektowego. Nie mogę używać według mnie dobrych zasad pisania kodu bez odrzucenia głównego paradygmatu języka i bibliotek w jakich się poruszam. Jest to droga donikąd.
</ol>
<p>Python i Haskell zdemoralizowały mnie i zachęciły do pisania kodu, który jest dziwny, trudny do zrozumienia, a w kontekście bazy obiektowego zorientowanego kodu nie daje żadnych profitów ponad programowanie imperatywne. Nie wątpię, że ogólnie stałem się lepszym programistą dzięki tym językom, ale w obecnej sytuacji nie jestem lepszym deweloperem – moja produktywność w rzeczywistości poleciała w dół na łeb na szyję. Jak czuję się sfrustrowany napisanym przez siebie kodem w C#, piszę go po raz wtóry w Pythonie czy Haskellu, żeby udowodnić sam sobie jak dużo lepsze są te języki, co jest bezsensowne samo w sobie i demotywuje mnie jeszcze bardziej.</p>
<p>Morał opowieści: nie próbuj rozwijać się, jeśli nie masz wolności rozwinąć również swojego środowiska. Wiem, to raczej depresyjny wniosek. Niech mnie ktoś przytuli&#8230;</p>
<p><i>Uaktualnienie: możliwe, że powinienem bardziej otwarcie przyznać, że tytuł postu nie jest absolutnie poważny i miał na celu przykuć uwagę.<br />
</i></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Haskell]]></title>
<link>http://avaldi.wordpress.com/2009/11/23/haskell/</link>
<pubDate>Mon, 23 Nov 2009 10:09:30 +0000</pubDate>
<dc:creator>Andrea Valdi</dc:creator>
<guid>http://avaldi.wordpress.com/2009/11/23/haskell/</guid>
<description><![CDATA[Per il corso di logica informatica qui a Granada devo sviluppare alcuni piccoli progetti pratici in ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Per il corso di logica informatica qui a Granada devo sviluppare alcuni piccoli progetti pratici in <a href="http://www.haskell.org/" target="_blank">Haskell</a>.</p>
<p>Ne sto letteralmente uscendo matto.</p>
<p>Ho trovato questo free book (c&#8217;è la versione online o pdf) che sembra essere interessante, lo segnalo nel caso potesse servire a qualcuno: <a href="http://en.wikibooks.org/wiki/Haskell" target="_blank">Wikibooks &#8211; Haskell</a></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[England 6 New Zealand 19]]></title>
<link>http://joshblack2.wordpress.com/2009/11/22/england-6-new-zealand-19/</link>
<pubDate>Sun, 22 Nov 2009 10:56:47 +0000</pubDate>
<dc:creator>joshblack2</dc:creator>
<guid>http://joshblack2.wordpress.com/2009/11/22/england-6-new-zealand-19/</guid>
<description><![CDATA[The All Blacks were supposed to be England’s toughest Test. After each game in this series, it was; ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The All Blacks were supposed to be England’s toughest Test. After each game in this series, it was; ‘We’ll get massacred by New Zealand if we play like that.” As it happens, being the underdogs gave England an opportunity to have a go at the underperforming, but still fearsome Kiwis (though not to the same degree as plucky Scotland, who won a deserved victory over Australia).</p>
<p>The early sparring saw England twice go ahead, 3-0, then 6-3, before Dan Carter levelled each time.  Ugo Monye nearly did the team an even bigger favour, just failing to intercept the ball when he had come off his wing and the All Blacks had decided to run from their 22.  In all, however, it was quite a dull first half, with England holding on and Carter missing the kicks that would have allowed New Zealand the comfort to play their own game.</p>
<p>It was in the second half that England began to exert some pressure of their own, but the game was determined in a ten-minute period starting fifteen minutes into the second half.  First, Wilkinson’s chip into the 22 saw a whole pack of England players bearing down on New Zealand.  The All Blacks, however, were quite content to use the space run it out of their 22.  Nonu’s inside pass releasing Zac Guildford, and Wilkinson had to backtrack thirty metres to dislodge the ball from the winger.</p>
<p>Not long afterwards New Zealand took clean ball from a lineout and as the forwards drove into the England 22, created space on the blindside.  Although Sivivatu was marked by Banahan, he jinked and held the defender in place as Richie McCaw and Jimmy Cowan came round the scrum.  Sivivatu slipped the ball inside, for McCaw to play in Cowan.  It was a devastating display of passing, allowing New Zealand to turn a non-advantage into a decisive overlap.</p>
<p>England found themselves in the All Black’s half several times with options, but frequently took the wrong ones.  Wilkinson’s first option when given the ball on the 22 was to take a drop, highlighting the paucity of England’s ambition.  In response, Mils Muliaina sliced through England’s defence before feeding Conrad Smith, who was forced into touch just yards from the line.</p>
<p>Haskell made a few half-breaks, but it was Tom Croft (on for the injured Joe Worsely after two minutes) who ripped the ball from a New Zealand maul after Wilkinson’s teasing kick, and seemed almost certain to cross but for determined defence.  Duncan Bell picked up and dived for the blindside, but was held up short, and the forwards could not clear the ball.  The resulting scrum proved disastrous, and the put-in was reversed.</p>
<p>Late on, Geraghty’s chip could have found Monye but bounced short and a last minute encampment on the New Zealand line turned to farce.  As has become common, England’s attack had wanted composure and received only individualism.</p>
<p>It is getting easy to forget what England are good at, but the scrum and particularly the lineout were solid.  Wilkinson, Borthwick and Moody typified an almost complete defensive performance, but it is possession that seems to worry England most.  In Haskell, Croft and Hartley, they have plenty of quick forwards who love to run, but no stand-out ball carriers who will break the gain line when defences have re-grouped.  For that, they probably missed Worsley and later, Shaw, but the distribution was also inadequate.  Hodgson seems to get drawn into rucks too easily, and Wilkinson plays too deep to encourage players to run good lines.  England miss Flutey desperately.  Unfortunately, Wilkinson’s defence is just too invaluable, so the first-receiver problem is key.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Waddaya know, testing WORKS!]]></title>
<link>http://ivanmiljenovic.wordpress.com/2009/11/17/waddaya-know-testing-works/</link>
<pubDate>Tue, 17 Nov 2009 01:36:09 +0000</pubDate>
<dc:creator>Ivan Miljenovic</dc:creator>
<guid>http://ivanmiljenovic.wordpress.com/2009/11/17/waddaya-know-testing-works/</guid>
<description><![CDATA[In my previous post (what? I&#8217;m doing another post just three days after my previous one? ), I ]]></description>
<content:encoded><![CDATA[In my previous post (what? I&#8217;m doing another post just three days after my previous one? ), I ]]></content:encoded>
</item>
<item>
<title><![CDATA[Sorting Type-Heterogeneous Values with Type Families]]></title>
<link>http://greayer.wordpress.com/2009/11/15/sorting-type-heterogeneous-values-with-type-families/</link>
<pubDate>Mon, 16 Nov 2009 01:55:22 +0000</pubDate>
<dc:creator>robgreayer</dc:creator>
<guid>http://greayer.wordpress.com/2009/11/15/sorting-type-heterogeneous-values-with-type-families/</guid>
<description><![CDATA[In an ongoing project, I&#8217;ve needed to do a bit of Haskell type-hackery with type functions imp]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>In an ongoing project, I&#8217;ve needed to do a bit of Haskell type-hackery with <a href="http://haskell.org/haskellwiki/Simonpj/Talk:FunWithTypeFuns">type functions</a> implemented with <a href="http://www.cse.unsw.edu.au/~chak/papers/SPCS08.html">type families</a>. One thing I&#8217;ve needed is a type-heterogeneous sort &#8212; more than a type level sort, but a function that takes a value of one product type, and produces a value of a different, sorted product type. In doing so it needs to both sort the parameter type into a (potentially) different result type, as well as sort the parameter value into a result value (which of course needs to be of the result type). This works out to be a bit more complex than a pure type level sort (such as the quicksort implemented <a href="http://www.haskell.org/haskellwiki/Type_arithmetic#An_Advanced_Example_:_Type-Level_Quicksort">here</a>, using funcitonal dependencies, or the merge sort implmenented <a href="http://snipplr.com/view/18891/merge-sort/">here</a>, again using functional dependencies), as Haskell type classes have to be used to select the right value-level functions to use for each step of the sort process. It was an interesting puzzle to solve &#8212; at least for me, as type level programming isn&#8217;t my strong point! (To make the problem a bit easier, I implemented a simpler, if less efficient, sorting algorithm, but quick sort or merge sort should also work at the type/value level).</p>
<p>Given a type for tagged values, e.g.</p>
<pre><code>    <span style="color:green;">-- n is a phantom, type-level natural</span>
    <span style="color:blue;font-weight:bold;">newtype</span> <span>Tagged</span> <span>n</span> <span>t</span> <span style="color:red;">=</span> <span>Tagged</span> <span>t</span></code></pre>
<p>And a product type, e.g.</p>
<pre><code>    <span style="color:blue;font-weight:bold;">data</span> <span>a</span> <span>:*</span> <span>b</span> <span style="color:red;">=</span> <span>a</span> <span>:*</span> <span>b</span>
    <span style="color:blue;font-weight:bold;">infixr</span> <span class="hs-num">6</span> <span>:*</span></code></pre>
<p>I want to define tagged values such as:</p>
<pre><code>    <span>tv0</span> <span style="color:red;">::</span> <span>Tagged</span> <span>N0</span> <span>String</span>
    <span>tv0</span> <span style="color:red;">=</span> <span>Tagged</span> <span style="color:teal;">"hello"</span>
    <span>tv1</span> <span style="color:red;">::</span> <span>Tagged</span> <span>N1</span> <span>Int</span>
    <span>tv1</span> <span style="color:red;">=</span> <span>Tagged</span> <span class="hs-num">2</span>
    <span>tv2</span> <span style="color:red;">::</span> <span>Tagged</span> <span>N2</span> <span>Bool</span>
    <span>tv2</span> <span style="color:red;">=</span> <span>Tagged</span> <span>False</span>
    <span style="color:green;">-- etc.</span></code></pre>
<p>I want to be able to apply a function <code>sort</code> to an arbitrary product of these types:</p>
<pre><code>    <span>x</span> <span style="color:red;">=</span> <span>sort</span> <span style="color:red;">(</span> <span>tv2</span> <span>:*</span> <span>tv0</span> <span>:*</span> <span>tv1</span> <span style="color:red;">)</span>
    <span>y</span> <span style="color:red;">=</span> <span>sort</span> <span style="color:red;">(</span> <span>tv1</span> <span>:*</span> <span>tv2</span> <span>:*</span> <span>tv0</span> <span style="color:red;">)</span></code></pre>
<p>And the result should be the sorted product, i.e. <code>x == y &#38;&#38; x == Tagged &#34;hello&#34; :* Tagged 2 :* Tagged False</code>. Note that in the first application of sort, sort needs a type like:</p>
<pre><code>    <span>sort</span> <span style="color:red;">::</span> <span style="color:red;">(</span><span>Tagged</span> <span>N2</span> <span>Bool</span> <span>:*</span> <span>Tagged</span> <span>N0</span> <span>String</span> <span>:*</span> <span>Tagged</span> <span>N1</span> <span>Int</span><span style="color:red;">)</span> <span style="color:red;">-&#62;</span>
        <span style="color:red;">(</span><span>Tagged</span> <span>N0</span> <span>String</span> <span>:*</span> <span>Tagged</span> <span>N1</span> <span>Int</span> <span>:*</span> <span>Tagged</span> <span>N2</span> <span>Bool</span><span style="color:red;">)</span></code></pre>
<p>and in the second, it needs:</p>
<pre><code>    <span>sort</span> <span style="color:red;">::</span> <span style="color:red;">(</span><span>Tagged</span> <span>N1</span> <span>Int</span> <span>:*</span> <span>Tagged</span> <span>N2</span> <span>Bool</span> <span>:*</span> <span>Tagged</span> <span>N0</span> <span>String</span><span style="color:red;">)</span> <span style="color:red;">-&#62;</span>
        <span style="color:red;">(</span><span>Tagged</span> <span>N0</span> <span>String</span> <span>:*</span> <span>Tagged</span> <span>N1</span> <span>Int</span> <span>:*</span> <span>Tagged</span> <span>N2</span> <span>Bool</span><span style="color:red;">)</span></code></pre>
<p>It needs to work for arbitrarily long products of any Tagged type (with the constraint that the index <code>n</code> must be a type-level natural). My solution to the problem follows.</p>
<pre><code><span>&#62;</span> <span style="color:green;">{-# LANGUAGE EmptyDataDecls, TypeFamilies, UndecidableInstances,
&#62;              ScopedTypeVariables, OverlappingInstances, TypeOperators,
&#62;              FlexibleInstances, NoMonomorphismRestriction #-}</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">module</span> <span>TSort</span> <span style="color:blue;font-weight:bold;">where</span>
</code></pre>
<p>I started with the usual definition for type level naturals (with some convenient aliases for a few of them):</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>Zero</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>Succ</span> <span>n</span>
</code></pre>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N0</span> <span style="color:red;">=</span> <span>Zero</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N1</span> <span style="color:red;">=</span> <span>Succ</span> <span>Zero</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N2</span> <span style="color:red;">=</span> <span>Succ</span> <span>N1</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N3</span> <span style="color:red;">=</span> <span>Succ</span> <span>N2</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N4</span> <span style="color:red;">=</span> <span>Succ</span> <span>N3</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N5</span> <span style="color:red;">=</span> <span>Succ</span> <span>N4</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N6</span> <span style="color:red;">=</span> <span>Succ</span> <span>N5</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N7</span> <span style="color:red;">=</span> <span>Succ</span> <span>N6</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N8</span> <span style="color:red;">=</span> <span>Succ</span> <span>N7</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N9</span> <span style="color:red;">=</span> <span>Succ</span> <span>N8</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>N10</span> <span style="color:red;">=</span> <span>Succ</span> <span>N9</span>
</code></pre>
<p>I also use type level booleans:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>TRUE</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>FALSE</span>
</code></pre>
<p>I need one inequality operator on naturals:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>family</span> <span>LessThan</span> <span>m</span> <span>n</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span style="color:blue;font-weight:bold;">instance</span> <span>LessThan</span> <span>Zero</span> <span>Zero</span> <span style="color:red;">=</span> <span>FALSE</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span style="color:blue;font-weight:bold;">instance</span> <span>LessThan</span> <span style="color:red;">(</span><span>Succ</span> <span>n</span><span style="color:red;">)</span> <span>Zero</span> <span style="color:red;">=</span> <span>FALSE</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span style="color:blue;font-weight:bold;">instance</span> <span>LessThan</span> <span>Zero</span> <span style="color:red;">(</span><span>Succ</span> <span>n</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>TRUE</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span style="color:blue;font-weight:bold;">instance</span> <span>LessThan</span> <span style="color:red;">(</span><span>Succ</span> <span>m</span><span style="color:red;">)</span> <span style="color:red;">(</span><span>Succ</span> <span>n</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>LessThan</span> <span>m</span> <span>n</span>
</code></pre>
<p>I need a type level if statement:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span>family</span> <span>Cond</span> <span>c</span> <span>t</span> <span>f</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Cond</span> <span>TRUE</span> <span>t</span> <span>f</span> <span style="color:red;">=</span> <span>t</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">type</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Cond</span> <span>FALSE</span> <span>t</span> <span>f</span> <span style="color:red;">=</span> <span>f</span>
</code></pre>
<p>I need my tagged and product types:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">newtype</span> <span>Tagged</span> <span>n</span> <span>a</span> <span style="color:red;">=</span> <span>Tagged</span> <span>a</span> <span style="color:blue;font-weight:bold;">deriving</span> <span style="color:red;">(</span><span>Show</span><span style="color:red;">,</span><span>Eq</span><span style="color:red;">)</span>
</code></pre>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>a</span> <span>:*</span> <span>b</span> <span style="color:red;">=</span> <span>a</span> <span>:*</span> <span>b</span> <span style="color:blue;font-weight:bold;">deriving</span> <span style="color:red;">(</span><span>Show</span><span style="color:red;">,</span><span>Eq</span><span style="color:red;">)</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">infixr</span> <span class="hs-num">6</span> <span>:*</span>
</code></pre>
<p>The general type of my sort is going to be something like (but not exactly):</p>
<pre><code>    <span>sort</span> <span style="color:red;">::</span> <span style="color:red;">(</span><span>Sortable</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">=&#62;</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>Sorted</span> <span>a</span></code></pre>
<p>where <code>Sortable</code> is a type class and <code>Sorted</code> is a associated type of that type class. It didn&#8217;t work out to be quite that simple, but this is how I started thinking about the problem.</p>
<p>I envisioned the <code>Sortable</code> class as:</p>
<pre><code>    <span style="color:blue;font-weight:bold;">class</span> <span>Sortable</span> <span>a</span> <span style="color:blue;font-weight:bold;">where</span>
        <span style="color:blue;font-weight:bold;">type</span> <span>Sorted</span> <span>a</span>
        <span>sort</span> <span style="color:red;">::</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>Sorted</span> <span>a</span></code></pre>
<p>Trying to create a simple instance of this type, for a pair of tagged values got me a bit bogged down:</p>
<pre><code>    <span style="color:blue;font-weight:bold;">instance</span> <span>Sortable</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
        <span style="color:blue;font-weight:bold;">type</span> <span>Sorted</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>???</span>
        <span>sort</span> <span style="color:red;">=</span> <span>???</span></code></pre>
<p>The type of <code>Sorted</code> for this pair is conditional based on the value of the indices <code>m</code> and <code>n</code>, so I can write the type function like this:</p>
<pre><code>    <span style="color:blue;font-weight:bold;">type</span> <span>Sorted</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:red;">=</span>
        <span>Cond</span> <span style="color:red;">(</span><span>LessThan</span> <span>n</span> <span>m</span><span style="color:red;">)</span> <span style="color:green;">-- if n &#60; m</span>
            <span style="color:red;">(</span><span>Tagged</span> <span>n</span> <span>b</span> <span>:*</span> <span>Tagged</span> <span>m</span> <span>a</span><span style="color:red;">)</span> <span style="color:green;">-- then swap</span>
            <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:green;">-- else don't</span></code></pre>
<p>but how to write the <code>sort</code> function? It can&#8217;t test the type and decide whether to swap the values. The key insight for solving this problem was that I needed some additional types to represent the operations I needed. For this simple reordering of a pair, I need two operations &#8211; <em>Swap</em>, to swap the elements of the pair if they are out of order, and <em>Id</em> (identity), to leave them alone if they are already in order:</p>
<pre><code>    <span style="color:blue;font-weight:bold;">data</span> <span>Swap</span> <span>x</span> <span>y</span> <span style="color:red;">=</span> <span>Swap</span> <span>x</span> <span>y</span>
    <span style="color:blue;font-weight:bold;">data</span> <span>Id</span> <span>a</span> <span style="color:red;">=</span> <span>Id</span> <span>a</span></code></pre>
<p>Each of these can be seen as implementing a single step in a sorting algorithm). Each will be an instance of a <code>Sorter</code> class:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">class</span> <span>Sorter</span> <span>a</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Sorted</span> <span>a</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Unsorted</span> <span>a</span>
</code></pre>
<p><code>mkSort</code> &#8216;makes&#8217; a sort function from (Unsorted a -&#62; Sorted a) based on the type of its first argument, which is a proxy argument (its value is never examined).</p>
<pre><code><span>&#62;</span>     <span>mkSort</span> <span style="color:red;">::</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>Unsorted</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>Sorted</span> <span>a</span>
</code></pre>
<p>The <code>Swap</code> instance of <code>Sorter</code> just swaps the values in a pair:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Sorter</span> <span style="color:red;">(</span><span>Swap</span> <span>x</span> <span>y</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Sorted</span> <span style="color:red;">(</span><span>Swap</span> <span>x</span> <span>y</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>y</span> <span>:*</span> <span>x</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Unsorted</span> <span style="color:red;">(</span><span>Swap</span> <span>x</span> <span>y</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>x</span> <span>:*</span> <span>y</span>
<span>&#62;</span>     <span>mkSort</span> <span style="color:blue;font-weight:bold;">_</span> <span style="color:red;">(</span><span>x</span> <span>:*</span> <span>y</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>y</span> <span>:*</span> <span>x</span>
</code></pre>
<p>The <code>Id</code> instance of <code>Sorter</code> leaves its value alone:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Sorter</span> <span style="color:red;">(</span><span>Id</span> <span>a</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Sorted</span> <span style="color:red;">(</span><span>Id</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>a</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Unsorted</span> <span style="color:red;">(</span><span>Id</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>a</span>
<span>&#62;</span>     <span>mkSort</span> <span style="color:blue;font-weight:bold;">_</span> <span>v</span> <span style="color:red;">=</span> <span>v</span>
</code></pre>
<p>Now my <code>Sortable</code> class, instead of having a <code>sort</code> function, needs instead a function to produce a sorter value:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">class</span> <span>Sortable</span> <span>a</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>SorterType</span> <span>a</span>
<span>&#62;</span>     <span>sorter</span> <span style="color:red;">::</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>SorterType</span> <span>a</span>
</code></pre>
<p>And the sort can be written in terms of functions from the two classes:</p>
<pre><code><span>&#62;</span> <span>sort</span> <span>v</span> <span style="color:red;">=</span> <span>mkSort</span> <span style="color:red;">(</span><span>sorter</span> <span>v</span><span style="color:red;">)</span> <span>v</span>
</code></pre>
<p>But still, how to implement the <code>sorter</code> function for my pair of tagged elements?</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Sortable</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
</code></pre>
<p>The type function for the <code>SorterType</code> is now:</p>
<pre><code><span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>SorterType</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:red;">=</span>
<span>&#62;</span>         <span>Cond</span> <span style="color:red;">(</span><span>LessThan</span> <span>n</span> <span>m</span><span style="color:red;">)</span>
<span>&#62;</span>             <span style="color:red;">(</span><span>Swap</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">(</span><span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>             <span style="color:red;">(</span><span>Id</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>     <span>sorter</span> <span style="color:red;">=</span> <span>undefined</span> <span style="color:green;">-- ???</span>
</code></pre>
<p>As it turns out, the above implementation is sufficient. Since the <code>mkSort</code> function doesn&#8217;t examine its first argument &#8212; it&#8217;s merely a proxy &#8212; the sorter function doesn&#8217;t need to produce a value. So <code>sorter</code> can be left undefined &#8212; all its &#8216;work&#8217; is done at compile time, in producing the right type such that the instance of &#8216;mkSort&#8217; can be inferred (I have to admit, I discovered this accidentally while writing the sorting function. I left <code>sorter</code> undefined because I couldn&#8217;t think of how to define it, then wrote <code>sort</code> in terms of it, and accidentally ran it. It worked, my mind boggled, and then I figured out what what going on). Because no concrete <em>value</em> of either the <code>Id</code> or <code>Swap</code> types are ever needed, the actual definitions for these can be:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>Id</span> <span>a</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>Swap</span> <span>a</span> <span>b</span>
</code></pre>
<p>To sort something more than a pair, I need to be able to do more than just swap two types and values. A simple algorithm for sorting the product is to sort the &#8216;tail&#8217; of the product, then insert the head of the product into the sorted tail (this is insertion sort &#8212; not the most efficient, but simpler than merge sort or quick sort). For this I need two more operations, a <em>sort-then-insert</em> operation, and an <em>insert</em> operation (the sort-then-insert operation sorts its &#8216;tail&#8217; and then (if necessary) uses the insert operation to insert its head into the sorted tail). I need these operation types:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>SortInsert</span> <span>h</span> <span>t</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>Insert</span> <span>x</span> <span>y</span>
</code></pre>
<p>I need a new class similar to <code>Sortable</code>, which has a <code>InserterType</code> and a function to produce a <code>InserterType</code> from the instance type:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">class</span> <span>Insertable</span> <span>a</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>InserterType</span> <span>a</span>
<span>&#62;</span>     <span>inserter</span> <span style="color:red;">::</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>InserterType</span> <span>a</span>
</code></pre>
<p>A insertable assumes that its tail is sorted. For a product of tagged values (more than a pair), the <code>Insertable</code> instance looks like this:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Insertable</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
</code></pre>
<p>The <code>InserterType</code> depends on whether the head element is less than the first element of the sorted tail. If it is, then the <code>InserterType</code> is the identity, otherwise it is an <code>Insert x y</code>:</p>
<pre><code><span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>InserterType</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span> <span style="color:red;">=</span>
<span>&#62;</span>              <span>Cond</span> <span style="color:red;">(</span><span>LessThan</span> <span>n</span> <span>m</span><span style="color:red;">)</span>
<span>&#62;</span>                  <span style="color:red;">(</span><span>Insert</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">(</span><span>Tagged</span> <span>n</span> <span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>                  <span style="color:red;">(</span><span>Id</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span>
</code></pre>
<p>As in the <code>sorter</code> function of a <code>Sortable</code>, we don&#8217;t need the <code>inserter</code> to do anything more than create a proxy argument:</p>
<pre><code><span>&#62;</span>     <span>inserter</span> <span style="color:red;">=</span> <span>undefined</span>
</code></pre>
<p>Inserting two elements is the same as sorting them:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Insertable</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>InserterType</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span> <span style="color:red;">=</span>
<span>&#62;</span>         <span>Cond</span> <span style="color:red;">(</span><span>LessThan</span> <span>n</span> <span>m</span><span style="color:red;">)</span> <span style="color:red;">(</span><span>Swap</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">(</span><span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>             <span style="color:red;">(</span><span>Id</span> <span style="color:red;">(</span><span>Tagged</span> <span>m</span> <span>a</span> <span>:*</span> <span>Tagged</span> <span>n</span> <span>b</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>     <span>inserter</span> <span style="color:red;">=</span> <span>undefined</span>
</code></pre>
<p>A <code>Inserter</code> is similar to a sorter: it takes an value of an <code>Uninserted</code> type and produces a value of an <code>Inserted</code> type:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">class</span> <span>Inserter</span> <span>a</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Inserted</span> <span>a</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Uninserted</span> <span>a</span>
</code></pre>
<p><code>mkInsert</code> &#8216;makes&#8217; a function <code>(Uninserted a -&#62; Inserted a)</code> from the instance type. The first argument again is just a proxy, it&#8217;s value never inspected:</p>
<pre><code><span>&#62;</span>     <span>mkInsert</span> <span style="color:red;">::</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>Uninserted</span> <span>a</span> <span style="color:red;">-&#62;</span> <span>Inserted</span> <span>a</span>
</code></pre>
<p>The identity instance is straightforward:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Inserter</span> <span style="color:red;">(</span><span>Id</span> <span>a</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Inserted</span> <span style="color:red;">(</span><span>Id</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>a</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Uninserted</span> <span style="color:red;">(</span><span>Id</span> <span>a</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>a</span>
<span>&#62;</span>     <span>mkInsert</span> <span style="color:blue;font-weight:bold;">_</span> <span>v</span> <span style="color:red;">=</span> <span>v</span>
</code></pre>
<p>The <code>Swap</code> instance of <code>Inserter</code> is essentially the same as the <code>Swap</code> instance of <code>Sorter</code>:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span>Inserter</span> <span style="color:red;">(</span><span>Swap</span> <span>a</span> <span>b</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>    <span style="color:blue;font-weight:bold;">type</span> <span>Inserted</span> <span style="color:red;">(</span><span>Swap</span> <span>a</span> <span>b</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>b</span> <span>:*</span> <span>a</span>
<span>&#62;</span>    <span style="color:blue;font-weight:bold;">type</span> <span>Uninserted</span> <span style="color:red;">(</span><span>Swap</span> <span>a</span> <span>b</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>a</span> <span>:*</span> <span>b</span>
<span>&#62;</span>    <span>mkInsert</span> <span style="color:blue;font-weight:bold;">_</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>b</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>b</span> <span>:*</span> <span>a</span>
</code></pre>
<p>The <code>Insert</code> instance for a longer product has a rather convoluted context:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span style="color:red;">(</span><span>Insertable</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>c</span><span style="color:red;">)</span>
<span>&#62;</span>          <span style="color:red;">,</span> <span>Inserter</span> <span style="color:red;">(</span><span>InserterType</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>          <span style="color:red;">,</span><span style="color:red;">(</span><span>a</span> <span>:*</span> <span>c</span><span style="color:red;">)</span> <span style="color:red;">~</span> <span>Uninserted</span> <span style="color:red;">(</span><span>InserterType</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>          <span style="color:red;">)</span> <span style="color:red;">=&#62;</span> <span>Inserter</span> <span style="color:red;">(</span><span>Insert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
</code></pre>
<p>The <code>Inserted</code> type is the first element of the tail followed by a inserted into the tail (via sort):</p>
<pre><code><span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Inserted</span> <span style="color:red;">(</span><span>Insert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>b</span> <span>:*</span> <span>Inserted</span> <span style="color:red;">(</span><span>InserterType</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span>
</code></pre>
<p>The uninserted type is simply the original (uninserted) product:</p>
<pre><code><span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Uninserted</span> <span style="color:red;">(</span><span>Insert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>a</span> <span>:*</span> <span>b</span> <span>:*</span> <span>c</span>
</code></pre>
<p>And the insert function effectively swaps the first two elements of the product and inserts the (new) tail:</p>
<pre><code><span>&#62;</span>     <span>mkInsert</span> <span style="color:blue;font-weight:bold;">_</span> <span style="color:red;">(</span><span>x</span> <span>:*</span> <span>y</span> <span>:*</span> <span>z</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>y</span> <span>:*</span> <span>mkInsert</span> <span style="color:red;">(</span><span>inserter</span> <span>$</span> <span>x</span> <span>:*</span> <span>z</span><span style="color:red;">)</span> <span style="color:red;">(</span><span>x</span> <span>:*</span> <span>z</span><span style="color:red;">)</span>
</code></pre>
<p>The <code>Sorter</code> instance for a <code>SortInsert</code> that we need again has a convoluted context:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span style="color:red;">(</span><span>Sortable</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span>
<span>&#62;</span>           <span style="color:red;">,</span><span>Unsorted</span> <span style="color:red;">(</span><span>SorterType</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:red;">~</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span>
<span>&#62;</span>           <span style="color:red;">,</span><span>Uninserted</span> <span style="color:red;">(</span><span>InserterType</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>Sorted</span> <span style="color:red;">(</span><span>SorterType</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:red;">~</span>
<span>&#62;</span>                <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>Sorted</span> <span style="color:red;">(</span><span>SorterType</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>           <span style="color:red;">,</span><span>Sorter</span> <span style="color:red;">(</span><span>SorterType</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>           <span style="color:red;">,</span><span>Insertable</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>Sorted</span> <span style="color:red;">(</span><span>SorterType</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>           <span style="color:red;">,</span><span>Inserter</span> <span style="color:red;">(</span><span>InserterType</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>Sorted</span> <span style="color:red;">(</span><span>SorterType</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span>           <span style="color:red;">)</span> <span style="color:red;">=&#62;</span>
<span>&#62;</span>         <span>Sorter</span> <span style="color:red;">(</span><span>SortInsert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
</code></pre>
<p>The type of the output of the sort is the type of the output of the head of the product inserted with the sorted tail:</p>
<pre><code><span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Sorted</span> <span style="color:red;">(</span><span>SortInsert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:red;">=</span>
<span>&#62;</span>         <span>Inserted</span> <span style="color:red;">(</span><span>InserterType</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span style="color:red;">(</span><span>Sorted</span> <span style="color:red;">(</span><span>SorterType</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span>
</code></pre>
<p>The type of the input of the sort is the original (unsorted, uninserted) product:</p>
<pre><code><span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>Unsorted</span> <span style="color:red;">(</span><span>SortInsert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>a</span> <span>:*</span> <span>b</span> <span>:*</span> <span>c</span>
</code></pre>
<p>And the sort function is just the insert of the head into the tail after the tail is sorted:</p>
<pre><code><span>&#62;</span>     <span>mkSort</span> <span style="color:blue;font-weight:bold;">_</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>mkInsert</span> <span style="color:red;">(</span><span>inserter</span> <span>preinsert</span><span style="color:red;">)</span> <span>preinsert</span>
<span>&#62;</span>         <span style="color:blue;font-weight:bold;">where</span> <span>preinsert</span> <span style="color:red;">=</span> <span>a</span> <span>:*</span> <span>sort</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span>
</code></pre>
<p>Finally, the <code>Sortable</code> instance for an arbitrary product is:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">instance</span> <span style="color:red;">(</span><span>Sortable</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">,</span> <span>Sorter</span> <span style="color:red;">(</span><span>SortInsert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span><span style="color:red;">)</span><span style="color:red;">)</span> <span style="color:red;">=&#62;</span>
<span>&#62;</span>     <span>Sortable</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">type</span> <span>SorterType</span> <span style="color:red;">(</span><span>a</span> <span>:*</span> <span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>SortInsert</span> <span>a</span> <span style="color:red;">(</span><span>b</span> <span>:*</span> <span>c</span><span style="color:red;">)</span>
<span>&#62;</span>     <span>sorter</span> <span style="color:red;">=</span> <span>undefined</span>
</code></pre>
<p>Given some tagged values, I can try out the sort function:</p>
<pre><code><span>&#62;</span> <span>t0</span> <span style="color:red;">::</span> <span>Tagged</span> <span>N0</span> <span>String</span>
<span>&#62;</span> <span>t0</span> <span style="color:red;">=</span> <span>Tagged</span> <span style="color:teal;">"hello"</span>
<span>&#62;</span> <span>t1</span> <span style="color:red;">::</span> <span>Tagged</span> <span>N1</span> <span>Bool</span>
<span>&#62;</span> <span>t1</span> <span style="color:red;">=</span> <span>Tagged</span> <span>True</span>
<span>&#62;</span> <span>t2</span> <span style="color:red;">::</span> <span>Tagged</span> <span>N2</span> <span>Int</span>
<span>&#62;</span> <span>t2</span> <span style="color:red;">=</span> <span>Tagged</span> <span class="hs-num">5</span>
<span>&#62;</span> <span>t3</span> <span style="color:red;">::</span> <span>Tagged</span> <span>N3</span> <span>String</span>
<span>&#62;</span> <span>t3</span> <span style="color:red;">=</span> <span>Tagged</span> <span style="color:teal;">"goodbye"</span>
</code></pre>
<pre><code>   *TSort1&#62; sort (t2 :* t0 :* t1 :* t3)
   Tagged "hello" :* (Tagged True :* (Tagged 5 :* Tagged "goodbye"))
   *TSort1&#62; sort (t3 :* t2 :* t1 :* t0)
   Tagged "hello" :* (Tagged True :* (Tagged 5 :* Tagged "goodbye"))
   *TSort1&#62;</code></pre>
<p>Beyond being an interesting puzzle to solve, there&#8217;s at least some use for such a function. For example, in a DSL that has operations that support named parameter association:</p>
<pre><code><span>&#62;</span> <span>rawConnect</span> <span style="color:red;">::</span> <span style="color:red;">(</span><span>Tagged</span> <span>N0</span> <span>String</span> <span>:*</span> <span>Tagged</span> <span>N1</span> <span>Int</span> <span>:*</span> <span>Tagged</span> <span>N2</span> <span>String</span> <span>:*</span>
<span>&#62;</span>      <span>Tagged</span> <span>N3</span> <span>String</span><span style="color:red;">)</span> <span style="color:red;">-&#62;</span> <span>IO</span> <span>()</span>
<span>&#62;</span> <span>rawConnect</span> <span style="color:red;">(</span><span>Tagged</span> <span>host</span> <span>:*</span> <span>Tagged</span> <span>port</span> <span>:*</span> <span>Tagged</span> <span>user</span> <span>:*</span> <span>Tagged</span> <span>pass</span><span style="color:red;">)</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span>putStrLn</span> <span>$</span> <span style="color:teal;">"connecting to "</span> <span>++</span> <span>host</span> <span>++</span> <span style="color:teal;">" on port "</span> <span>++</span> <span>show</span> <span>port</span> <span>++</span>
<span>&#62;</span>        <span style="color:teal;">" with username "</span> <span>++</span> <span>user</span> <span>++</span> <span style="color:teal;">" and password "</span> <span>++</span> <span>pass</span>
<span>&#62;</span>
<span>&#62;</span> <span>connect</span> <span style="color:red;">=</span> <span>rawConnect</span> <span>.</span> <span>sort</span>
<span>&#62;</span>
<span>&#62;</span> <span style="color:red;">(</span><span>=:</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span style="color:red;">(</span><span>$</span><span style="color:red;">)</span>
<span>&#62;</span> <span>host</span> <span style="color:red;">::</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>Tagged</span> <span>N0</span> <span>String</span>
<span>&#62;</span> <span>host</span> <span style="color:red;">=</span> <span>Tagged</span>
<span>&#62;</span> <span>port</span> <span style="color:red;">::</span> <span>Int</span> <span style="color:red;">-&#62;</span> <span>Tagged</span> <span>N1</span> <span>Int</span>
<span>&#62;</span> <span>port</span> <span style="color:red;">=</span> <span>Tagged</span>
<span>&#62;</span> <span>user</span> <span style="color:red;">::</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>Tagged</span> <span>N2</span> <span>String</span>
<span>&#62;</span> <span>user</span> <span style="color:red;">=</span> <span>Tagged</span>
<span>&#62;</span> <span>password</span> <span style="color:red;">::</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>Tagged</span> <span>N3</span> <span>String</span>
<span>&#62;</span> <span>password</span> <span style="color:red;">=</span> <span>Tagged</span>
</code></pre>
<p>Now you can invoke the &#8216;connect&#8217; operation with parameters in no particular order:</p>
<pre><code><span>&#62;</span> <span>doit</span> <span style="color:red;">=</span> <span style="color:blue;font-weight:bold;">do</span>
<span>&#62;</span>    <span>putStrLn</span> <span style="color:teal;">"trying to connect!"</span>
<span>&#62;</span>    <span>connect</span> <span style="color:red;">(</span> <span>user</span> <span>=:</span> <span style="color:teal;">"admin"</span> <span>:*</span>
<span>&#62;</span>              <span>password</span> <span>=:</span> <span style="color:teal;">"pa55w0rd"</span> <span>:*</span>
<span>&#62;</span>              <span>port</span> <span>=:</span> <span class="hs-num">22</span> <span>:*</span>
<span>&#62;</span>              <span>host</span> <span>=:</span> <span style="color:teal;">"example.com"</span> <span style="color:red;">)</span>
<span>&#62;</span>    <span>putStrLn</span> <span style="color:teal;">"connected!"</span>
</code></pre>
<p>&#8230; which is at least mildly cool, for certain definitions of cool.</p>
<p><em>Brought to you by <a href="http://hackage.haskell.org/package/BlogLiterately">BlogLiterately</a> with generous support from <a href="http://http://johnmacfarlane.net/pandoc/">pandoc</a>, <a href="http://www.cs.york.ac.uk/fp/darcs/hscolour/">hscolour</a> and viewers like you.</em></p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[My Intro to Functional Programming]]></title>
<link>http://silentzephyr.wordpress.com/2009/11/14/my-intro-to-functional-programming/</link>
<pubDate>Sat, 14 Nov 2009 23:49:31 +0000</pubDate>
<dc:creator>silentzephyr</dc:creator>
<guid>http://silentzephyr.wordpress.com/2009/11/14/my-intro-to-functional-programming/</guid>
<description><![CDATA[Wrote some &#8220;functions&#8221; in Function Programming (FP) the other day. Interesting, to say t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Wrote some &#8220;functions&#8221; in Function Programming (FP) the other day. Interesting, to say the least. It was for a class but it was really my first hands on experience with a functional language.</p>
<p>Although there is an interpreter for this language, it isn&#8217;t as developed as it could be and it definitely needs a debugger. Anyway, interesting first experience.</p>
<p>Now onto Haskell. Oh fun. At least there&#8217;s a huge amount of documentation and books on how to program in Haskell =) It&#8217;s always good to have resources. Will write more about it when I know what I&#8217;m doing!</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[テキスト読み込みとコマンド実行]]></title>
<link>http://tsurushuu.wordpress.com/2009/11/14/%e3%83%86%e3%82%ad%e3%82%b9%e3%83%88%e8%aa%ad%e3%81%bf%e8%be%bc%e3%81%bf%e3%81%a8%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e5%ae%9f%e8%a1%8c/</link>
<pubDate>Fri, 13 Nov 2009 15:05:53 +0000</pubDate>
<dc:creator>tsurushuu</dc:creator>
<guid>http://tsurushuu.wordpress.com/2009/11/14/%e3%83%86%e3%82%ad%e3%82%b9%e3%83%88%e8%aa%ad%e3%81%bf%e8%be%bc%e3%81%bf%e3%81%a8%e3%82%b3%e3%83%9e%e3%83%b3%e3%83%89%e5%ae%9f%e8%a1%8c/</guid>
<description><![CDATA[Haskellは、ファイルの入出力が簡単。 ですが、モナドを使いこなさなくてはならないので、適当に書いていると、しょっちゅうエラーが出てくる。 入力はreadFile、出力はwriteFile。do記]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>Haskellは、ファイルの入出力が簡単。<br />
ですが、モナドを使いこなさなくてはならないので、適当に書いていると、しょっちゅうエラーが出てくる。</p>
<p>入力はreadFile、出力はwriteFile。do記法を使う。IOの結果を、　&#60;-　で取り出してしまえば後は簡単。</p>
<pre class="brush: python;">
main = do
  contents &#60;- readFile &#34;test.txt&#34;
  writeFile &#34;output0.txt&#34; $ contents                                      -- そのまま出力
  writeFile &#34;output1.txt&#34; $ unlines $ map (&#34;#&#34; ++) $ lines contents       -- 各行の先頭に # をつける
  writeFile &#34;output2.txt&#34; $ unlines $ map (reverse) $ lines contents      -- 各行を反転させる
</pre>
<ul>
<li>readFile :: FilePath -&#62; IO String　　ファイルを読み込み、Stringにして返す</li>
<li>writeFile :: FilePath -&#62; String -&#62; IO ()　　ファイルに出力</li>
</ul>
<p>つぎは、ファイルから入力した内容によってなんらかの作業を行う。</p>
<pre class="brush: python;">
import System.Cmd(system)
import System.Posix

main = do
  contents &#60;- readFile &#34;test.txt&#34;
  mapM_ system $ lines contents                                                -- 読み込んだ内容の各行をコマンドとして実行
  (sequence_ $ take 10 $ cycle [testSleep, print ”aaa”])               -- スリーブとprintを交互に実行

testSleep = do
  sleep 1
  return ()
</pre>
<ul>
<li>system　　コマンドの実行</li>
<li>sequence_　　リストの中身を順に実行。結果を無視する。</li>
<li>mapM_　　sequence_ . map と同等</li>
</ul>
<p>コマンドの実行は、systemでいいのですが、ここで、mapを使って、要素に対してsystemを使いたいとする。しかし、<br />
map system xs<br />
とするだけでは、IOのリストになってしまい、なにも実行されない。（というより、mainのdo記法の中に直接書くとコンパイル出来ない。）sequence_ で、「順に実行する」という関数にしておくことで、doの中に書けるようになる。</p>
<pre class="brush: plain;">

Prelude System.Cmd&#62; :t map system [&#34;ls&#34;, &#34;pwd&#34;]
map system [&#34;ls&#34;, &#34;pwd&#34;] :: [IO GHC.IOBase.ExitCode]

Prelude System.Cmd&#62; :t sequence_ $ map system [&#34;ls&#34;, &#34;pwd&#34;]
sequence_ $ map system [&#34;ls&#34;, &#34;pwd&#34;] :: IO ()
</pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[I'm not dead]]></title>
<link>http://mostlycode.wordpress.com/2009/11/10/im-not-dead/</link>
<pubDate>Wed, 11 Nov 2009 01:51:14 +0000</pubDate>
<dc:creator>Tener</dc:creator>
<guid>http://mostlycode.wordpress.com/2009/11/10/im-not-dead/</guid>
<description><![CDATA[&#8230; yet. It&#8217;s actually quite the opposite: I&#8217;m alive but quite busy. It&#8217;s hard]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>&#8230; yet. It&#8217;s actually quite the opposite: I&#8217;m alive but quite busy. It&#8217;s hard for me to find any time to write anything for the blog. I&#8217;ve been writing quite a lot recently, most of which you can read in <a href="http://informatyka.wroc.pl/node/283">this article</a>.</p>
<p>To be more specific: I wrote an introductory article about basics of Haskell for a polish computer science portal. I put quite some effort in it (~25h), but I hope there are people that will benefit from it greatly.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Thinking Like a Programmer]]></title>
<link>http://kittenthebad.wordpress.com/2009/11/11/thinking-like-a-programmer/</link>
<pubDate>Wed, 11 Nov 2009 00:36:15 +0000</pubDate>
<dc:creator>Cate</dc:creator>
<guid>http://kittenthebad.wordpress.com/2009/11/11/thinking-like-a-programmer/</guid>
<description><![CDATA[CA assignment 3 is now out, and in class today we were looking at the stuff we needed for question 2]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>CA assignment 3 is now out, and in class today we were looking at the stuff we needed for question 2 (which is <a href="http://books.google.com/books?id=-Lz3BlxzsLoC&#38;lpg=PP1&#38;ots=urfi6HX6nL&#38;dq=combinatorial%20algorithms%20kreher&#38;pg=PA275#v=onepage&#38;q=&#38;f=false">ex. 7.1 in the textbook</a>). It&#8217;s to manually solve the isomorphism for the two graphs below:</p>
<div id="attachment_698" class="wp-caption aligncenter" style="width: 479px"><img class="size-full wp-image-698" title="Petersen Graph" src="http://kittenthebad.wordpress.com/files/2009/11/screen-shot-2009-11-10-at-7-19-24-pm.png" alt="Petersen Graph" width="469" height="192" /><p class="wp-caption-text">Petersen Graph</p></div>
<p>So I start sketching this out, and then it occurs to me that &#8211; ooh, I could easily write some code to validate it for me after I&#8217;ve worked it out.</p>
<p>And then it occurs to me that all I&#8217;m doing is trying permutations of &#8220;abcdefghij&#8221; (where the position in the string is the number they&#8217;re trying to replace). And if I used Haskell and the handy &#8220;permutations&#8221; method I could just code it in a brute force manner, and it would solve it for me.</p>
<p>So of course that&#8217;s what I did. This is a programmer thing, I think. We work out how to automate things and then we automate them. Yes, it probably took me longer to write the code than it would have to solve the thing manually. I was quite shocked that it ended up being over 60 lines (including white-space, but still&#8230; this is Haskell) although I did include my data (the edges) and methods to validate them. I think it could be done with less code, my Haskell is a little rusty.</p>
<p>I find programming much more satisfying than drawing the graph countless times until you get the right answer. Also, my code is purring away now generating all the valid permutations.</p>
<p>In case you&#8217;re interested&#8230; here are the first 20:</p>
<blockquote><p>(&#8216;c&#8217;,0),(&#8216;d&#8217;,1),(&#8216;e&#8217;,2),(&#8216;f&#8217;,3),(&#8216;g&#8217;,4),(&#8216;b&#8217;,5),(&#8216;i&#8217;,6),(&#8216;h&#8217;,7),(&#8216;a&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;e&#8217;,0),(&#8216;d&#8217;,1),(&#8216;c&#8217;,2),(&#8216;b&#8217;,3),(&#8216;h&#8217;,4),(&#8216;f&#8217;,5),(&#8216;i&#8217;,6),(&#8216;g&#8217;,7),(&#8216;a&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;d&#8217;,0),(&#8216;e&#8217;,1),(&#8216;f&#8217;,2),(&#8216;a&#8217;,3),(&#8216;i&#8217;,4),(&#8216;c&#8217;,5),(&#8216;h&#8217;,6),(&#8216;g&#8217;,7),(&#8216;b&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;f&#8217;,0),(&#8216;e&#8217;,1),(&#8216;d&#8217;,2),(&#8216;c&#8217;,3),(&#8216;g&#8217;,4),(&#8216;a&#8217;,5),(&#8216;h&#8217;,6),(&#8216;i&#8217;,7),(&#8216;b&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;a&#8217;,0),(&#8216;f&#8217;,1),(&#8216;e&#8217;,2),(&#8216;d&#8217;,3),(&#8216;i&#8217;,4),(&#8216;b&#8217;,5),(&#8216;g&#8217;,6),(&#8216;h&#8217;,7),(&#8216;c&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;e&#8217;,0),(&#8216;f&#8217;,1),(&#8216;a&#8217;,2),(&#8216;b&#8217;,3),(&#8216;h&#8217;,4),(&#8216;d&#8217;,5),(&#8216;g&#8217;,6),(&#8216;i&#8217;,7),(&#8216;c&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;b&#8217;,0),(&#8216;c&#8217;,1),(&#8216;d&#8217;,2),(&#8216;e&#8217;,3),(&#8216;h&#8217;,4),(&#8216;a&#8217;,5),(&#8216;g&#8217;,6),(&#8216;i&#8217;,7),(&#8216;f&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;d&#8217;,0),(&#8216;c&#8217;,1),(&#8216;b&#8217;,2),(&#8216;a&#8217;,3),(&#8216;i&#8217;,4),(&#8216;e&#8217;,5),(&#8216;g&#8217;,6),(&#8216;h&#8217;,7),(&#8216;f&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;f&#8217;,0),(&#8216;a&#8217;,1),(&#8216;b&#8217;,2),(&#8216;c&#8217;,3),(&#8216;g&#8217;,4),(&#8216;e&#8217;,5),(&#8216;i&#8217;,6),(&#8216;h&#8217;,7),(&#8216;d&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;b&#8217;,0),(&#8216;a&#8217;,1),(&#8216;f&#8217;,2),(&#8216;e&#8217;,3),(&#8216;h&#8217;,4),(&#8216;c&#8217;,5),(&#8216;i&#8217;,6),(&#8216;g&#8217;,7),(&#8216;d&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;c&#8217;,0),(&#8216;b&#8217;,1),(&#8216;a&#8217;,2),(&#8216;f&#8217;,3),(&#8216;g&#8217;,4),(&#8216;d&#8217;,5),(&#8216;h&#8217;,6),(&#8216;i&#8217;,7),(&#8216;e&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;a&#8217;,0),(&#8216;b&#8217;,1),(&#8216;c&#8217;,2),(&#8216;d&#8217;,3),(&#8216;i&#8217;,4),(&#8216;f&#8217;,5),(&#8216;h&#8217;,6),(&#8216;g&#8217;,7),(&#8216;e&#8217;,8),(&#8216;j&#8217;,9)</p>
<p>(&#8216;e&#8217;,0),(&#8216;d&#8217;,1),(&#8216;c&#8217;,2),(&#8216;g&#8217;,3),(&#8216;f&#8217;,4),(&#8216;h&#8217;,5),(&#8216;i&#8217;,6),(&#8216;b&#8217;,7),(&#8216;j&#8217;,8),(&#8216;a&#8217;,9)</p>
<p>(&#8216;e&#8217;,0),(&#8216;h&#8217;,1),(&#8216;j&#8217;,2),(&#8216;g&#8217;,3),(&#8216;f&#8217;,4),(&#8216;d&#8217;,5),(&#8216;b&#8217;,6),(&#8216;i&#8217;,7),(&#8216;c&#8217;,8),(&#8216;a&#8217;,9)</p>
<p>(&#8216;j&#8217;,0),(&#8216;h&#8217;,1),(&#8216;e&#8217;,2),(&#8216;d&#8217;,3),(&#8216;i&#8217;,4),(&#8216;g&#8217;,5),(&#8216;b&#8217;,6),(&#8216;f&#8217;,7),(&#8216;c&#8217;,8),(&#8216;a&#8217;,9)</p>
<p>(&#8216;g&#8217;,0),(&#8216;c&#8217;,1),(&#8216;d&#8217;,2),(&#8216;e&#8217;,3),(&#8216;f&#8217;,4),(&#8216;j&#8217;,5),(&#8216;b&#8217;,6),(&#8216;i&#8217;,7),(&#8216;h&#8217;,8),(&#8216;a&#8217;,9)</p>
<p>(&#8216;d&#8217;,0),(&#8216;c&#8217;,1),(&#8216;g&#8217;,2),(&#8216;j&#8217;,3),(&#8216;i&#8217;,4),(&#8216;e&#8217;,5),(&#8216;b&#8217;,6),(&#8216;f&#8217;,7),(&#8216;h&#8217;,8),(&#8216;a&#8217;,9)</p>
<p>(&#8216;h&#8217;,0),(&#8216;j&#8217;,1),(&#8216;g&#8217;,2),(&#8216;c&#8217;,3),(&#8216;b&#8217;,4),(&#8216;e&#8217;,5),(&#8216;i&#8217;,6),(&#8216;f&#8217;,7),(&#8216;d&#8217;,8),(&#8216;a&#8217;,9)</p>
<p>(&#8216;g&#8217;,0),(&#8216;j&#8217;,1),(&#8216;h&#8217;,2),(&#8216;e&#8217;,3),(&#8216;f&#8217;,4),(&#8216;c&#8217;,5),(&#8216;i&#8217;,6),(&#8216;b&#8217;,7),(&#8216;d&#8217;,8),(&#8216;a&#8217;,9)</p>
<p>(&#8216;d&#8217;,0),(&#8216;e&#8217;,1),(&#8216;h&#8217;,2),(&#8216;j&#8217;,3),(&#8216;i&#8217;,4),(&#8216;c&#8217;,5),(&#8216;f&#8217;,6),(&#8216;b&#8217;,7),(&#8216;g&#8217;,8),(&#8216;a&#8217;,9)</p></blockquote>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Great Debate for 2009 Horse of the Year]]></title>
<link>http://theaspiringhorseplayer.com/2009/11/09/the-great-debate-for-2009-horse-of-the-year/</link>
<pubDate>Mon, 09 Nov 2009 15:39:03 +0000</pubDate>
<dc:creator>Kevin Stafford</dc:creator>
<guid>http://theaspiringhorseplayer.com/2009/11/09/the-great-debate-for-2009-horse-of-the-year/</guid>
<description><![CDATA[No sooner had the synthetic dust settled in the wake of Zenyatta&#8217;s dominating performance in t]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>No sooner had the synthetic dust settled in the wake of <a href="http://theaspiringhorseplayer.com/2009/11/09/the-year-of-the-filly-or-a-year-for-all-time/"><span style="color:#0000ff;">Zenyatta&#8217;s dominating performance in the 2009 Breeders&#8217; Cup Classic</span></a> at Santa Anita then the flame igniting the &#8220;Horse of the Year&#8221; debate was rekindled anew.  At question is how to properly award the top honor in U.S. racing when considering the miraculous campaigns of both Zenyatta and the 3-year-old filly sensation Rachel Alexandra. </p>
<p>At this point in time, It&#8217;s become a question I&#8217;d really rather not address at all if it were not on the lips of nearly all I&#8217;ve spoken with these past few days.  My personal feeling being that this is still Zenyatta&#8217;s moment and that at least one full week should pass before we begin doing what horseplayers do &#8211; arguing incessantly with one another over our respective levels of insanity.  One can barely get so much as a word in about the Classic right now though without the issue coming up rather directly.  Emotions seem to be running high on both sides of the isle as the immediacy of a supreme moment still actively courses through the furiously beating hearts of racing fans the world over. </p>
<p>In many ways, the pendulum seems to have swung almost completely.  Where once Rachel was considered <a href="http://theaspiringhorseplayer.com/2009/09/06/horse-of-the-year-the-case-for-rachel-alexandra/"><span style="color:#0000ff;">(including by yours truly)</span></a> a mortal lock to have already captured the honor as Horse of the Year by virtue of (most notably) her Preakness, Haskell, and Woodward victories, a new wind has begun to blow.  The much whispered &#8220;backlash&#8221; against team Rachel for having not attended the Breeders&#8217; Cup had been one element of this change.  The true spark, however, is a bit more noble in nature and seems to stem from a desire to ensure that Zenyatta is properly awarded for the undefeated career she has blessed us with. </p>
<p>As early as Saturday night, the battle lines were already being drawn.  Attending a post-Classic dinner with folks from the <a href="http://community.tvg.com/betfair/"><span style="color:#0000ff;">TVG Community</span></a><span style="color:#0000ff;"> </span>(the organizers for which I owe a great deal of thanks to for a wonderful weekend, along with those at both the <a href="http://www.ntra.com/"><span style="color:#0000ff;">NTRA</span></a> and the <a href="http://www.breederscup.com/"><span style="color:#0000ff;">Breeders&#8217; Cup</span></a>), I was asked for my opinion, and admittedly I balked a bit &#8211; attempting to play the classical Switzerland &#8220;neutrality defense.&#8221;  Like many a smaller European nation state in the opening half the 20th century, I ultimately found myself being drawn, however unwittingly, into the great conflagration.</p>
<div id="attachment_1771" class="wp-caption aligncenter" style="width: 259px"><a href="http://theaspiringhorseplayer.wordpress.com/files/2009/11/switzerland_flag_wave2.jpg"><img class="size-medium wp-image-1771" title="switzerland_flag_wave2" src="http://theaspiringhorseplayer.wordpress.com/files/2009/11/switzerland_flag_wave2.jpg?w=300" alt="switzerland_flag_wave2" width="249" height="260" /></a><p class="wp-caption-text">Not to be confused with the famous &#34;French defense&#34; in chess, the &#34;Switzerland neutrality posture&#34; in the great 2009 Horse of the Year debate is ultimately indefensible. </p></div>
<p>At the end of the day, I suppose someone does have to win the award, right?  </p>
<p>So whom do we chose?</p>
<p>As much as I&#8217;ve tried to play the Switzerland defense, it&#8217;s probably rightly noted that I&#8217;m an ever-so-slightly bigger fan of Rachel Alexandra than I am of Zenyatta.  I think that&#8217;s a fair assessment of my own emotional makeup.  That&#8217;s not to say I don&#8217;t love Zenyatta with all my heart &#8211; always have and always will &#8211; but my record of pro-Rachel Alexandra coverage is something I cannot deny being consciously aware of.  </p>
<p>That being said, I&#8217;ve loved Zenyatta since I spotted her profile prior to her maiden debut, noting <em>&#8220;hey, that&#8217;s the same connections as Giacomo &#8211; I might take a shot with this girl!&#8221;</em>  In time she became my &#8220;slow cheetah&#8221; &#8211; a name and a song that will forever have a special meaning to me.</p>
<p style="text-align:center;"><object width="425" height="254"><param name="movie" value="http://www.dailymotion.com/swf/x9xpqj"></param><param name="allowfullscreen" value="true"></param><embed src="http://www.dailymotion.com/swf/x9xpqj" type="application/x-shockwave-flash" width="425" height="334" allowfullscreen="true"></embed></object></p>
<p style="text-align:center;"> </p>
<p>I care about these two fillies so deeply that I consider it the honor of a lifetime to have been there for the finer moments of each one&#8217;s 2009 campaign;  Rachel in the Preakness and the Haskell, and Zenyatta in the Classic. </p>
<p>Much like I had been calling for a dead heat had the two ever locked horns on the track, I find myself utterly divided over who I would select as Horse of the Year.  I suppose to extract a full answer from me, one might have to subject me to brutal interrogation, straight out of the famed Russian Roulette scene in <em>The Deer Hunter.  </em>Tying me to a chair, constantly slapping my face whilst shouting <em>&#8220;Mao!&#8221;</em> and demanding that I make a selection.  I believe what follows is what my ultimate decision would be under such duress (apart from arising from said chair and declaring <em>&#8220;3 bullets!!! We play with 3 bullets!&#8221;</em> in classical De Niro fashion):</p>
<ul>
<li>Rachel Alexandra for 3-year-old filly champion</li>
<li>Zenyatta for Horse of the Year</li>
</ul>
<div id="attachment_1772" class="wp-caption aligncenter" style="width: 346px"><a href="http://theaspiringhorseplayer.wordpress.com/files/2009/11/mao.jpg"><img class="size-medium wp-image-1772" title="Mao!" src="http://theaspiringhorseplayer.wordpress.com/files/2009/11/mao.jpg?w=300" alt="Mao!" width="336" height="205" /></a><p class="wp-caption-text">Mao! Robert De Niro in the famous Russian Roulette scene from The Deer Hunter</p></div>
<p>Truth be told, I actually do believe that Rachel Alexandra had the superior overall year (with &#8220;overall&#8221; being the operative term), however Zenyatta clearly won the superior race. </p>
<p>Rachel&#8217;s year had more than one signature moment.  She was the first filly in 85 years to win the Preakness.  She was the 2nd filly in 42 years to win the Haskell.  She nearly broke the track record in the Mother Goose, coming close to the exploits of Secretariat at the same distance.  Then, of course, she became the first 3-year-old filly to defeat older males in a stakes race of more than a mile on dirt since the inception of graded stakes in the U.S.</p>
<p style="text-align:center;"><object width="425" height="254"><param name="movie" value="http://www.dailymotion.com/swf/x9x0nr"></param><param name="allowfullscreen" value="true"></param><embed src="http://www.dailymotion.com/swf/x9x0nr" type="application/x-shockwave-flash" width="425" height="334" allowfullscreen="true"></embed></object></p>
<p style="text-align:center;"> </p>
<p>Zenyatta&#8217;s overall campaign for 2009 was a bit less heralded &#8211; until her triumph in the Classic that is.  I doubt strongly that anyone will think back to her earlier races in the year and point to them as having been signature &#8211; but she did remain undefeated, even when carrying  ridiculous amounts of weight and when it seemed to all observing that her undefeated record was in it&#8217;s greatest peril at the hands of Anaaba&#8217;s Creation.  Somehow, someway, she ALWAYS found a way to win.</p>
<p>So if Rachel&#8217;s campaign is the one I believe to be more accomplished, why make Zenyatta Horse of the Year?</p>
<p>Because at some level, even if it has not historically been the case, the Breeders&#8217; Cup Classic <em>should</em> be the deciding moment.  The quintessential test of an overall champion.  Moreover, the career that Zenyatta rewarded us with is one that is deserving of top honors.  And it&#8217;s not like she didn&#8217;t race in 2009.  She just didn&#8217;t race a whole heckuva a lot of times, nor did she put herself in tremendously challenging positions where victory was assumed to be anything other than a foregone conclusion until her date with destiny in the Classic.</p>
<p>I know that technically it isn&#8217;t right to attach emotional sentiment to that which she accomplished in 2008 and then factor that into the equation, but how can one not help but do so?  In all likelihood she left us with her career defining performance on the sports biggest stage (at least the biggest stage for true fans of racing, as opposed to the Warhol-esque 2 minutes of national attention associated with the annual running of the Kentucky Derby) &#8211; a perfect story book ending to a career that will from henceforth be the measuring stick for all older fillies and mares that attempt to follow in her hoofsteps.</p>
<p>Likewise, Rachel Alexandra will go down as the new barometer by which all subsequent 3-year-old fillies will be compared.  Make no mistake about it, we&#8217;ll still invoke memories of Ruffian as well, who will continue to be the greatest of the great fillies, but my sense of things is that Rachel&#8217;s ability to both win a 3-year-old Classic (the Preakness) and then follow that up with repeat performances over 3-year-old males in the Haskell and then older males in the Woodward will cement her legacy for years (if not decades) to come.</p>
<p>The mere fact that Rachel is sometimes mentioned in the same breath as Ruffian speaks volumes for how lofty her star has risen.  Just a year ago you probably would&#8217;ve been diagnosed as certifiably mad if you dared to publicly compare any filly to Ruffian.  Now people do so without batting an eye.   I&#8217;ve refrained from making any direct comparisons myself, as I think it wise to the let the historical greats stand alone, and if nothing else become larger than the legends they were in their own time rather than replaced by newcomers and diminished in legend, but certainly folks reading this have at least heard those comparisons elsewhere and know what I&#8217;m referring to.  The point being not whether they are warranted or not, but merely an acknowledgement that such comparisons do exist.</p>
<p>For Rachel, there will be a 2010, and a chance to show she is capable of winning a Breeders&#8217; Cup Classic of her own.  For Zenyatta, the Classic was in all likelihood her swan song. </p>
<p>What better way to send off a legend than to allow their final chapter to be an ultimate achievement?  It just feels like the right thing to do.</p>
<p>As much as I love them both and am torn asunder in attempting to make a definitive statement one way or the other &#8211; I think the right thing to do is to send Zenyatta off to retirement as the 2009 Horse of the Year.  After all, she started the year as the top older female in racing, and nobody was able to defeat her.  Looking at things that way, and reducing the equation to it&#8217;s most simplistic component, it&#8217;s a bit hard to justify knocking her from her lofty perch &#8211; doubly so in the immediate aftermath of her finest hour. </p>
<p>And you know what?  At the end of the day it&#8217;s really just a silly award.  What these two ladies accomplished on the track will be remembered for years regardless of whether an additional trophy is added to their respective cases.</p>
<p>Respect for each of them has been EARNED on the track, not GIVEN at some awards ceremony.</p>
<p>That&#8217;s how I see things at least.  What say you?  Who do you think ought to receive the Eclipse Award for 2009 Horse of the Year?</p>
<a name="pd_a_2230305"></a><div class="PDS_Poll" id="PDI_container2230305" style="display:inline-block;"></div><script type="text/javascript" language="javascript" charset="utf-8" src="http://static.polldaddy.com/p/2230305.js"></script>
		<noscript>
		<a href="http://answers.polldaddy.com/poll/2230305/">View This Poll</a><br/><span style="font-size:10px;"><a href="http://www.polldaddy.com">online surveys</a></span>
		</noscript>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Solving Logic Grid Puzzles in Haskell]]></title>
<link>http://blog.willdonnelly.net/2009/11/06/solving-logic-grid-puzzles-in-haskell/</link>
<pubDate>Fri, 06 Nov 2009 19:48:05 +0000</pubDate>
<dc:creator>Will Donnelly</dc:creator>
<guid>http://blog.willdonnelly.net/2009/11/06/solving-logic-grid-puzzles-in-haskell/</guid>
<description><![CDATA[The Zebra Puzzle is a decades-old exercise in deductive logic. Unfortunately, I lack the patience to]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>The <a href="http://en.wikipedia.org/wiki/Zebra_Puzzle">Zebra Puzzle</a> is a decades-old exercise in deductive logic. Unfortunately, I lack the patience to sit down and solve this kind of puzzle. So in this post, we&#8217;re going to cheat by teaching Haskell to solve it for us.</p>
<pre style="font-size:9px;"><code>&#62; <span style="color:blue;font-weight:bold;">import</span> Data.Maybe
&#62; <span style="color:blue;font-weight:bold;">import</span> Control.Monad
</code></pre>
<p>We will take our cue from <a href="http://sandbox.rulemaker.net/ngps/119">this solution</a> written in SWI Prolog, and encode our puzzle as a set of constraints that our solving code must satisfy.</p>
<p>An &#8216;entry&#8217; is a single entity in the solution. In the Zebra puzzle, these are going to be the individual houses. For maximum generality, we&#8217;re just going to represent all the properties of the entries with strings.</p>
<p>An answer to the puzzle is a collection of several entities which together satisfy all of the rules set forth in the puzzle description.</p>
<pre style="font-size:9px;"><code>&#62; <span style="color:blue;font-weight:bold;">type</span> Entry  <span style="color:red;">=</span> <span style="color:red;">[</span>String<span style="color:red;">]</span>
&#62; <span style="color:blue;font-weight:bold;">type</span> Answer <span style="color:red;">=</span> <span style="color:red;">[</span>Entry<span style="color:red;">]</span>
</code></pre>
<p>I was going to explain the rule types at this point, but the explanation ended up being a lot harder to understand than just looking at the rules for this puzzle, so we&#8217;ll do that instead.</p>
<p>The first four rules simply teach our solver about numbers. After these rules are satisfied, the entries in the solution will be numbered one through five.</p>
<pre style="font-size:9px;"><code>&#62; rules <span style="color:red;">=</span>
&#62;   <span style="color:red;">[</span> Follows  <span style="color:red;">[</span> <span style="color:teal;">"1"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">"2"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Follows  <span style="color:red;">[</span> <span style="color:teal;">"2"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">"3"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Follows  <span style="color:red;">[</span> <span style="color:teal;">"3"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">"4"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Follows  <span style="color:red;">[</span> <span style="color:teal;">"4"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">"5"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
</code></pre>
<p>Then we specify all of the clues that make up the puzzle itself. These are given in order, so it should be easy to see the correspondence with the clues listed in the wikipedia article</p>
<pre style="font-size:9px;"><code>&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">"England"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Red"</span><span style="color:red;">,</span>    <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">"Spain"</span><span style="color:red;">,</span>   <span style="color:teal;">"Dog"</span><span style="color:red;">,</span>    <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Coffee"</span><span style="color:red;">,</span> <span style="color:teal;">"Green"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">"Ukraine"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Tea"</span><span style="color:red;">,</span>    <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Follows  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Green"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Ivory"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">"Snails"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Old Gold"</span>      <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Yellow"</span><span style="color:red;">,</span> <span style="color:teal;">"Kools"</span>         <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">"3"</span><span style="color:red;">,</span> <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Milk"</span><span style="color:red;">,</span>   <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">"1"</span><span style="color:red;">,</span> <span style="color:teal;">"Norway"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Adjacent <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Chesterfields"</span> <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">"Fox"</span><span style="color:red;">,</span>    <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Adjacent <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Kools"</span>         <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">"Horse"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Juice"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Lucky Strike"</span>  <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">"Japan"</span><span style="color:red;">,</span>   <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Parliaments"</span>   <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Adjacent <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">"Norway"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;              <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Blue"</span><span style="color:red;">,</span>   <span style="color:teal;">""</span>              <span style="color:red;">]</span>
</code></pre>
<p>Unfortunately, one drink and one animal are missing from the rules as stated, so here we just inform the solver &#8220;someone drinks water&#8221; and &#8220;someone owns a zebra&#8221;</p>
<pre style="font-size:9px;"><code>&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">"Water"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">,</span> Literal  <span style="color:red;">[</span> <span style="color:teal;">""</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>        <span style="color:teal;">"Zebra"</span><span style="color:red;">,</span>  <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span><span style="color:red;">,</span>       <span style="color:teal;">""</span>              <span style="color:red;">]</span>
&#62;   <span style="color:red;">]</span>
</code></pre>
<p>So we have three kinds of rules, for which we&#8217;ll need a data definition. By now it should be self-evident how each of these work</p>
<pre style="font-size:9px;"><code>&#62; <span style="color:blue;font-weight:bold;">data</span> Rule <span style="color:red;">=</span> Literal  Entry
&#62;           <span style="color:red;">&#124;</span> Adjacent Entry Entry
&#62;           <span style="color:red;">&#124;</span> Follows  Entry Entry
&#62;           <span style="color:blue;font-weight:bold;">deriving</span> <span style="color:red;">(</span>Show<span style="color:red;">)</span>
</code></pre>
<p>At this point, we have a nice, declarative specification of what a solution will look like, and we need to write the code to solve for it. The key to solving the puzzle efficiently is to realize that each rule is effectively describing some small portion of a possible answer, with empty strings representing unknown values. What we need next is a way to expand a rule into a list of all those answers that it represents</p>
<pre style="font-size:9px;"><code>&#62; expandRule <span style="color:red;">::</span> Int <span style="color:red;">-&#62;</span> Rule <span style="color:red;">-&#62;</span> <span style="color:red;">[</span>Answer<span style="color:red;">]</span>
&#62; expandRule n <span style="color:red;">(</span>Literal   a <span style="color:red;">)</span> <span style="color:red;">=</span> <span style="color:red;">[</span> expand n <span style="color:red;">[</span> a <span style="color:red;">]</span> x <span style="color:red;">&#124;</span> x <span style="color:red;">&#60;-</span> <span style="color:red;">[</span><span class="hs-num">0</span> <span style="color:red;">..</span> n <span style="color:green;">-</span> <span class="hs-num">1</span><span style="color:red;">]</span> <span style="color:red;">]</span>
&#62; expandRule n <span style="color:red;">(</span>Follows  a b<span style="color:red;">)</span> <span style="color:red;">=</span> <span style="color:red;">[</span> expand n <span style="color:red;">[</span>a<span style="color:red;">,</span>b<span style="color:red;">]</span> x <span style="color:red;">&#124;</span> x <span style="color:red;">&#60;-</span> <span style="color:red;">[</span><span class="hs-num">0</span> <span style="color:red;">..</span> n <span style="color:green;">-</span> <span class="hs-num">2</span><span style="color:red;">]</span> <span style="color:red;">]</span>
&#62; expandRule n <span style="color:red;">(</span>Adjacent a b<span style="color:red;">)</span> <span style="color:red;">=</span> concat <span style="color:red;">[</span>e $ Follows a b<span style="color:red;">,</span> e $ Follows b a<span style="color:red;">]</span>
&#62;   <span style="color:blue;font-weight:bold;">where</span> e <span style="color:red;">=</span> expandRule n
&#62;
&#62; expand <span style="color:red;">::</span> Int <span style="color:red;">-&#62;</span> <span style="color:red;">[</span>Entry<span style="color:red;">]</span> <span style="color:red;">-&#62;</span> Int <span style="color:red;">-&#62;</span> <span style="color:red;">[</span>Entry<span style="color:red;">]</span>
&#62; expand n rs<span style="color:red;">@</span><span style="color:red;">(</span>r:<span style="color:blue;font-weight:bold;">_</span><span style="color:red;">)</span> x <span style="color:red;">=</span> replicate x blank ++ rs ++ replicate <span style="color:red;">(</span>n <span style="color:green;">-</span> x <span style="color:green;">-</span> <span class="hs-num">1</span><span style="color:red;">)</span> blank
&#62;   <span style="color:blue;font-weight:bold;">where</span> blank <span style="color:red;">=</span> replicate <span style="color:red;">(</span>length r<span style="color:red;">)</span> <span style="color:teal;">""</span>
</code></pre>
<p>As we go about solving the puzzle, we will at all times have a collection of answers the solver currently knows to be possible, and a set of answer fragments resulting from expanding the rule we&#8217;re currently trying to satisfy. What we need is a way to test every possible combination of the old answers with the new answer fragments.</p>
<p>Our solution will make use of the nondeterminism monad, called the &#8220;list&#8221; monad by the unenlightened. As we iterate over the rules, we will expand each one in turn, test every possible combination with the old answers, and then filter out the impossible ones.</p>
<p>At first, this will cause a combinatorial explosion of possible answers, but as new rules are added, we will eventually reach a point where each additional rule manages only to decrease the number of possible solutions, until there is only one remaining.</p>
<pre style="font-size:9px;"><code>&#62; applyRules <span style="color:red;">::</span> Answer <span style="color:red;">-&#62;</span> <span style="color:red;">[</span>Rule<span style="color:red;">]</span> <span style="color:red;">-&#62;</span> <span style="color:red;">[</span>Answer<span style="color:red;">]</span>
&#62; applyRules answer rules <span style="color:red;">=</span> foldM applyRule answer rules
&#62;   <span style="color:blue;font-weight:bold;">where</span> applyRule a r <span style="color:red;">=</span> catMaybes <span style="color:red;">[</span>overlay a x <span style="color:red;">&#124;</span> x <span style="color:red;">&#60;-</span> expandRule <span style="color:red;">(</span>length a<span style="color:red;">)</span> r<span style="color:red;">]</span>
</code></pre>
<p>From the definition of <code style="font-size:9px;">applyRules</code>, it is clear that our overlay operation needs to have type <code style="font-size:9px;">Answer -&#62; Answer -&#62; Maybe Answer</code>. If any two answers are both defined and different from each other, we return <code style="font-size:9px;">Nothing</code>, and otherwise we return the most defined of the two fields.</p>
<pre style="font-size:9px;"><code>&#62; overlay <span style="color:red;">::</span> Answer <span style="color:red;">-&#62;</span> Answer <span style="color:red;">-&#62;</span> Maybe Answer
&#62; overlay old new <span style="color:red;">=</span> sequence $ zipWith overlay' old new
&#62;   <span style="color:blue;font-weight:bold;">where</span> overlay' old new <span style="color:red;">=</span> sequence $ zipWith overlay'' old new
&#62;         overlay'' <span style="color:teal;">""</span> <span style="color:teal;">""</span>  <span style="color:red;">=</span> Just <span style="color:teal;">""</span>
&#62;         overlay'' <span style="color:teal;">""</span> n   <span style="color:red;">=</span> Just n
&#62;         overlay'' o  <span style="color:teal;">""</span>  <span style="color:red;">=</span> Just o
&#62;         overlay'' o  n
&#62;           <span style="color:red;">&#124;</span> o == n       <span style="color:red;">=</span> Just o
&#62;           <span style="color:red;">&#124;</span> otherwise    <span style="color:red;">=</span> Nothing
</code></pre>
<p>Before any constraints are applied, the answer is entirely undefined, so the process of solving consists simply of applying all the rules to an initial empty answer, and seeing what results. In this case, there is only one answer, but removing one or more rules from the list can make other solutions equally valid.</p>
<pre style="font-size:9px;"><code>&#62; main <span style="color:red;">=</span> showAnswers . applyRules emptyAnswer $ rules
&#62;   <span style="color:blue;font-weight:bold;">where</span> emptyAnswer <span style="color:red;">=</span> replicate <span class="hs-num">5</span> . replicate <span class="hs-num">6</span> $ <span style="color:teal;">""</span>
&#62;         showAnswers <span style="color:red;">=</span> mapM_ $ mapM_ print
</code></pre>
<p>To see how each additional rule changes the set of possible answers, you can try something like &#8220;<code style="font-size:9px;">mapM_ print . applyRules emptyAnswer . take ## $ rules</code>&#8221; in GHCi, for all the numbers between 1 and 20.</p>
<p>(This post is Literate Haskell, meaning that it can be copied and pasted in its entirety into a <code style="font-size:9px;">*.lhs</code> file, and then run with <code style="font-size:9px;">runhaskell</code>)</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[The Effect Spectrum (I)]]></title>
<link>http://xosfaere.wordpress.com/2009/11/05/the-effect-spectrum-i/</link>
<pubDate>Thu, 05 Nov 2009 22:51:14 +0000</pubDate>
<dc:creator>xosfaere</dc:creator>
<guid>http://xosfaere.wordpress.com/2009/11/05/the-effect-spectrum-i/</guid>
<description><![CDATA[Effects of Intuition In the march of pure functional programming toward pervasive mainstream use the]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><strong>Effects of Intuition</strong></p>
<p>In the march of pure functional programming toward pervasive mainstream use the notion of effects have become an interesting topic. I&#8217;ve begun looking at what you might call &#8220;the effect spectrum&#8221; or &#8220;the effect zoo&#8221;: the different kinds of effects and what they do (to your program).</p>
<p>I shall name these functions by personal preference, these names are likely unconventional but they have &#8220;symbolic&#8221; value.The first examples will not be effects at all but I will gradually move into effects over the next few posts, well maybe just one more post. I have a few ideas queued up on time-slicing, &#8220;forced&#8221; pre-emption (OS terminology abuse alert) and exceptions.</p>
<p>The structural notation will be a &#8220;pseudo/semi-formalism&#8221;, Haskell-like.</p>
<p><strong>Exhibit 1: Non [ineffective]</strong></p>
<p>This function takes no arguments, computes nothing, does nothing and returns no result. It is the computational equivalent of brain death.</p>
<p><em>structure</em></p>
<p style="padding-left:30px;">() → ()</p>
<p><em>substance</em></p>
<p style="padding-left:30px;">public void non()<br />
{<br />
}</p>
<p><strong>Exhibit 2: Som [ineffective]</strong></p>
<p>This function takes one argument and returns that argument. The &#8220;zero&#8221; function may be seen as a special case of the &#8220;one&#8221; function, accepting only the empty tuple.</p>
<p><em><em>structure</em></em></p>
<p style="padding-left:30px;">a → a</p>
<p><em><em>substance</em></em></p>
<p style="padding-left:30px;">public void som&#60;T&#62; (T x)<br />
{<br />
&#160;&#160;return x;<br />
}</p>
<p><strong>Exhibit 3: Som-Non [ineffective]</strong></p>
<p>This function takes one argument and returns nothing as a result, never caring about what the argument actually was, you might call this a comatose function: it gets everything you say but can&#8217;t respond back with anything (the empty tuple () being the equivalent of silence).</p>
<p><em><em>structure</em></em></p>
<p style="padding-left:30px;">a → ()</p>
<p><em><em>substance</em></em></p>
<p style="padding-left:30px;">public void somnon&#60;T&#62; (T x)<br />
{<br />
}</p>
<p><strong>Exhibit 4: Non-Som [ineffective]</strong></p>
<p>This function takes nothing and returns something. It is the dual of comatose &#8211; it can only give and it always gives the same thing.</p>
<p><em>structure</em></p>
<p style="padding-left:30px;">() → a</p>
<p><em>substance</em></p>
<p style="padding-left:30px;">public T nonsom&#60;T&#62;()<br />
{<br />
&#160;&#160; return default(T);<br />
}</p>
<p><strong>Exhibit 5: Som-Time [time-"in"-effective]</strong></p>
<p>This function takes something and returns that same thing, after some time. You might say it&#8217;s the functional equivalent of bullet-time; it slows down time (if e.g. we define time as state-transitions; ticks, or whatever). This means it has an effect, meaning its &#8220;effective&#8221; but this time-effect also makes it &#8220;in-effective&#8221;.</p>
<p><em>structure</em></p>
<p style="padding-left:30px;">a → Δ a</p>
<p><em>substance</em></p>
<p style="padding-left:30px;">public T somtime&#60;T&#62;(T x)<br />
{<br />
&#160;&#160; Thread.Sleep(1000);<br />
&#160;&#160; return x;<br />
}</p>
<p>One may argue whether this function actually contains a [side-]effect (messing with time) or not. In a sense all functions mess with time, as in the real world they take time to compute. So the result is some delta into the future where the argument is some point in the past, depending on when you look at it.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Paper: Haskell Type Constraints Unleashed]]></title>
<link>http://dorchard.wordpress.com/2009/11/04/paper-haskell-type-constraints-unleashed/</link>
<pubDate>Wed, 04 Nov 2009 17:59:12 +0000</pubDate>
<dc:creator>dorchard</dc:creator>
<guid>http://dorchard.wordpress.com/2009/11/04/paper-haskell-type-constraints-unleashed/</guid>
<description><![CDATA[Tom Schrijvers and I have a new paper describing extensions to Haskell&#8217;s type-constraint term ]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><div style='font-size:1.15em;' align='justify'>
Tom Schrijvers and I have <a href='http://www.cl.cam.ac.uk/~dao29/publ/constraint-families.pdf'>a new paper</a> describing extensions to Haskell&#8217;s type-constraint term language, which considerably increases its flexibility. These extensions are particularly useful when writing polymorphic EDSLs in Haskell, thus expanding Haskell&#8217;s capacity for embedding DSLs.</p>
<p>Abstract:</p>
<blockquote><p>
The popular Glasgow Haskell Compiler extends the Haskell 98 type system with several powerful features, leading to an expressive language of type terms. In contrast, constraints over types have received much less attention, creating an imbalance in the expressivity of the type system. In this paper, we rectify the imbalance, transferring familiar type-level constructs, <i>synonyms</i> and <i>families</i>, to the language<br />
of constraints, providing a symmetrical set of features at the type-level and constraint-level. We introduce <i>constraint synonyms</i> and <i>constraint families</i>, and illustrate their increased expressivity for improving the utility of polymorphic EDSLs in Haskell, amongst other examples. We provide a discussion of the semantics of the new features relative to existing type system features and similar proposals, including details of termination.
</p></blockquote>
<p>[<a href='http://www.cl.cam.ac.uk/~dao29/publ/constraint-families.pdf'>draft pdf</a> submitted to <a href='http://http//www.kb.ecei.tohoku.ac.jp/flops2010/wiki/'>FLOPS 2010</a>]<br />
Any feedback is most welcome. Blog posts to follow if you are too lazy to read the paper.
</div>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[BlogLiterately v0.2]]></title>
<link>http://greayer.wordpress.com/2009/11/03/blogliterately-v0-2/</link>
<pubDate>Tue, 03 Nov 2009 15:04:32 +0000</pubDate>
<dc:creator>robgreayer</dc:creator>
<guid>http://greayer.wordpress.com/2009/11/03/blogliterately-v0-2/</guid>
<description><![CDATA[I&#8217;ve created a new version of BlogLiterately, now on hackage. The new version is quite similar]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>I&#8217;ve created a new version of BlogLiterately, now on <a href="http://hackage.haskell.org/package/BlogLiterately-0.2">hackage</a>. The new version is quite similar to what I blogged about <a href="http://greayer.wordpress.com/2009/10/26/blogging-literately-in-haskell/">here</a>, with some enhancements:</p>
<ul>
<li>it now supports categories.</li>
<li>it now supports highlighting-kate, if you&#8217;ve installed <a href="http://johnmacfarlane.net/pandoc/" title="Pandoc">Pandoc</a> with highlighting support.</li>
<li>you can highlight Haskell with hscolour using CSS classes or inline styles.</li>
<li>you can highlight Haskell and non-Haskell with highlighting-kate (via Pandoc). (But only via CSS classes and a separate or embedded stylesheet, not via inline styles. So it does me personally no good!).</li>
</ul>
<p>I contemplate a future upgrade will allow highlighting-kate marked up code to have the CSS class-based styling &#8216;baked&#8217; into the HTML in a way similar to how I handle hscolour.</p>
<p>Anyone who enjoys this tool, thank the authors of <a href="http://johnmacfarlane.net/pandoc/" title="Pandoc">Pandoc</a>, <a href="http://www.cs.york.ac.uk/fp/darcs/hscolour/">hscolour</a>, <a href="http://www.cs.york.ac.uk/fp/HaXml/">HaXml</a>, <a href="http://www.haskell.org/haxr/">HaXR</a> and, of course, <a href="http://www.haskell.org/ghc/">GHC</a> and the <a href="http://www.haskell.org/haskellwiki/Haskell_Platform">Haskell Platform</a>, as this program is just a bit of glue that binds these much bigger pieces together for one simple application.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ProjectEuler Problem25]]></title>
<link>http://tsurushuu.wordpress.com/2009/11/03/projecteuler-problem25/</link>
<pubDate>Mon, 02 Nov 2009 15:34:11 +0000</pubDate>
<dc:creator>tsurushuu</dc:creator>
<guid>http://tsurushuu.wordpress.com/2009/11/03/projecteuler-problem25/</guid>
<description><![CDATA[フィボナッチ。 -- | fibonacci sequence fibonacci :: (Num a) =&gt; [a] fibonacci = [1, 2] ++ zipWith (+) fib]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>フィボナッチ。</p>
<pre class="brush: python;">
-- &#124; fibonacci sequence
fibonacci :: (Num a) =&#62; [a]
fibonacci = [1, 2] ++ zipWith (+) fibonacci ( tail fibonacci )

-- problem 25
pe025 = head $ dropWhile (\ x -&#62; snd x &#60; 10^(1000-1)) $ zip [2,3..] fibonacci
</pre>
<ul>
<li>snd　　タプルの二番目を得る</li>
</ul>
<ul></ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ProjectEuler Problem24]]></title>
<link>http://tsurushuu.wordpress.com/2009/11/03/projecteuler-problem24/</link>
<pubDate>Mon, 02 Nov 2009 15:23:05 +0000</pubDate>
<dc:creator>tsurushuu</dc:creator>
<guid>http://tsurushuu.wordpress.com/2009/11/03/projecteuler-problem24/</guid>
<description><![CDATA[順列を辞書順に並べ、その10000000番目を求める。 まともに全部列挙してみる。 -- problem 24 perm [] = [] perm (x:[]) = [[x]] perm (xs) =]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>順列を辞書順に並べ、その10000000番目を求める。<br />
まともに全部列挙してみる。</p>
<pre class="brush: delphi;">
-- problem 24
perm [] = []
perm (x:[]) = [[x]]
perm (xs) = concat . zipWith (make_perms) xs . map (\ x -&#62; xs \\ [x]) $ xs
    where make_perms a xs = map (a : ) . perm $ xs

pe024 = concat $ map show $ (perm [0..9]) !! (1000000 - 1)
</pre>
<ul>
<li>\\　　リストの差。リストから要素を取り除く</li>
<li>concat　　リストを繋ぎあわせる。リストが一段階少なくなる</li>
<li>!!　　リストの要素をインデックスで指定して得る　最初の要素は０番目</li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ProjectEuler Problem20]]></title>
<link>http://tsurushuu.wordpress.com/2009/11/01/projecteuler-problem20/</link>
<pubDate>Sun, 01 Nov 2009 12:12:52 +0000</pubDate>
<dc:creator>tsurushuu</dc:creator>
<guid>http://tsurushuu.wordpress.com/2009/11/01/projecteuler-problem20/</guid>
<description><![CDATA[今回も、Integerのおかげでなんとも無い問題。 factorial = product . (enumFromTo 1) pe020 = sum $ map digitToInt $ show .]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>今回も、Integerのおかげでなんとも無い問題。</p>
<pre class="brush: delphi;">
factorial = product . (enumFromTo 1)
pe020 = sum $ map digitToInt $ show . factorial $ 100
</pre>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[ProjectEuler Problems19]]></title>
<link>http://tsurushuu.wordpress.com/2009/11/01/projecteuler-problems19/</link>
<pubDate>Sun, 01 Nov 2009 11:40:12 +0000</pubDate>
<dc:creator>tsurushuu</dc:creator>
<guid>http://tsurushuu.wordpress.com/2009/11/01/projecteuler-problems19/</guid>
<description><![CDATA[ここのブログは、ソースコードが張りつけられる訳ですが、haskellには対応してません。WordPressでHaskellを色づけする方法はあるようですが、ここは、無料WordPressサービスなので]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p>ここのブログは、ソースコードが張りつけられる訳ですが、haskellには対応してません。WordPressでHaskellを色づけする方法はあるようですが、ここは、無料WordPressサービスなので、改造出来るのか判りませんし。</p>
<p>で、無理矢理、Haskellコードを色づけ。ちょっと試した結果、python、sql、delphiくらいがよさそう。</p>
<p>で、以下はpython。</p>
<pre class="brush: python;">
numOfDay :: Int -&#62; Int -&#62; Int
numOfDay 2 year
         = if year `mod` 4 == 0 &#38;&#38; ((year `mod` 100 /= 0) &#124;&#124; (year `mod` 400 == 0) )
           then 28
           else 29
numOfDay month _
         = if month == 4 &#124;&#124; month == 6 &#124;&#124; month == 9 &#124;&#124; month == 11
           then 30
           else 31
</pre>
<p>sql。</p>
<pre class="brush: sql;">
data Date = Date {
                    day    :: Int,
                    month  :: Int,
                    year   :: Int,
                    week   :: Week
                }
                deriving Show

data Week = Mon &#124; Tue &#124; Wed &#124; Thu &#124; Fri &#124; Sut &#124; Sun deriving (Show, Eq)

weekToDigit :: Week -&#62; Int
weekToDigit Mon = 0
weekToDigit Tue = 1
weekToDigit Wed = 2
weekToDigit Thu = 3
weekToDigit Fri = 4
weekToDigit Sut = 5
weekToDigit Sun = 6

digitToWeek :: Int -&#62; Week
digitToWeek 0 = Mon
digitToWeek 1 = Tue
digitToWeek 2 = Wed
digitToWeek 3 = Thu
digitToWeek 4 = Fri
digitToWeek 5 = Sut
digitToWeek 6 = Sun
digitToWeek num = digitToWeek $ num `mod` 7

calcWeek :: Week -&#62; Int -&#62; Week
calcWeek w num = digitToWeek $ num + weekToDigit w
</pre>
<p>delphi。</p>
<pre class="brush: delphi;">
initDay = (Date 1 1 1900 Mon)

-- 指定の日付の次の月の日付が、何曜日になるか
nextMonth :: Date -&#62; Date
nextMonth (d@(Date {month = m, year = y, week = w}) )
    = d {month = m2, year = y2, week = w2}
      where
        m2 = (m `mod` 12) + 1
        y2 = if m == 12 then y+1 else y
        w2 = calcWeek w numOfDay
        numOfDay = 30

pe019 = length $ filter (== Sun) $ map week $ takeWhile (\x -&#62; year x &#60;= 2000) $ dropWhile (\x -&#62; year x &#60;= 1900) $ iterate nextMonth initDay
</pre>
<p>そういえばProjectEulerだった。<br />
今回も手こずる。</p>
<p>結局、日、月、年、曜日を格納する型を作る。で、与えられた曜日が判っていれば、そこから指定の日数だけ経った日の曜日も、mod 7 で求める事が出来る。<br />
問題は、それぞれの月が、30なのか、31なのか、28か、、、</p>
<p>&#160;</p>
<p>&#160;</p>
<ul>
<li>data　　ユーザー定義型の定義</li>
<li>deriving</li>
<li>@パターン</li>
</ul>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Literackie blogowanie w Haskellu]]></title>
<link>http://gracjanpolak.wordpress.com/2009/11/01/literackie-blogowanie-w-haskellu/</link>
<pubDate>Sun, 01 Nov 2009 10:23:50 +0000</pubDate>
<dc:creator>gracjanpolak</dc:creator>
<guid>http://gracjanpolak.wordpress.com/2009/11/01/literackie-blogowanie-w-haskellu/</guid>
<description><![CDATA[Dzisiejszy wpis jest t&#322;umaczeniem Blogging Literately in Haskell Roberta Greayera. Napisa&#322;]]></description>
<content:encoded><![CDATA[<div class='snap_preview'><p><em>Dzisiejszy wpis jest t&#322;umaczeniem</em> <a href="http://greayer.wordpress.com/2009/10/26/blogging-literately-in-haskell/"><em>Blogging Literately in Haskell</em></a> <em>Roberta Greayera.</em></p>
<p>Napisa&#322;em jeden post na blogu o Haskellu i stwierdzi&#322;em, &#380;e jest to zdecydowanie zbyt uci&#261;&#380;liwe. Ten WYSIWYG tinyMCE edytor z WordPressa jest beznadziejny, przynajmniej je&#347;li chodzi o fromatowanie fragmentów kodu, a chyba bym umar&#322;, gdybym musia&#322; bezpo&#347;rednio wpisywa&#263; HTMLa do WordPressa. Czu&#322;em, &#380;e musi istnie&#263; lepszy sposób, rozgl&#261;dn&#261;&#322;em si&#281; za aplikacj&#261; zaspokajaj&#261;c&#261; moje potrzeby. Odrzuci&#322;em kilka edytorów, darmowych i komercyjnych, niektóre by&#322;y beznadziejne, niektóre prawie nadawa&#322;y si&#281; do u&#380;ytku, ale &#380;aden nie pozwala&#322; na po&#322;&#261;czenie Haskella i narracji tak &#322;atwo, jak to powinno by&#263; zrobione. Naprawd&#281; potrzebuj&#281; prostego sposobu na przekszta&#322;cenie Haskella w trybie literackim (wiecie, takich artyku&#322;ów z zupe&#322;nie nieznanych przyczyn nagle przerywanych</p>
<pre><code><span>&#62;</span> <span style="color:green;">{-# LANGUAGE DeriveDataTypeable #-}</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">module</span> <span>Main</span> <span style="color:blue;font-weight:bold;">where</span>
</code></pre>
<p>takimi dziwnymi wtr&#261;ceniami), by&#263; mo&#380;e z prostym tekstem w stylu <a href="http://daringfireball.net/projects/markdown/">markdown</a>. Potem niech taki tekst magicznie wrzuca na blog, z dobrym formatowaniem HTML i sekcjami kodu Haskella.</p>
<p>Teoretycznie Haskell posiada wszelakie biblioteki wykonuj&#261;cych najprzeró&#380;niejsze zadania. By&#263; mo&#380;e nie by&#322;oby zbyt trudno zmontowa&#263; z dostepnych bibliotek co&#347; takiego, co by robi&#322;o dok&#322;adnie to co mi potrzebne.</p>
<p>W niewyja&#347;niony sposób zaabsorbowa&#322;em przez osmoz&#281; z eteru, &#380;e isnieje haskellowe narz&#281;dzie nazywane <a href="http://johnmacfarlane.net/pandoc/">Pandoc</a>, autorstwa Johna McFairlanea, które potrafi zaj&#261;&#263; si&#281; markdownem, HTMLem i innymi formatami. Jest ono, jak wszystkie dobre rzeczy, dost&#281;pne na <a href="http://hackage.haskell.org/packages/hackage.html">Hackage</a>, jednocze&#347;nie jako program i jako biblioteka. Wygl&#261;da na dobry pocz&#261;tek.</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Text</span><span>.</span><span>Pandoc</span>
</code></pre>
<p>Przegl&#261;daj&#261;c dokumentacj&#281; Pandoc zauwazy&#322;em, &#380;e chocia&#380; potrafi&#322;o robi&#263; niesamowite rzeczy z ogromn&#261; ilo&#347;ci&#261; formatów, niestety nie potrafi&#322;o automatycznie przetwarza&#263; kodu Haskella. A ja chcia&#322;em, &#380;eby &#378;ród&#322;o wygl&#261;da&#322;o jak dokumentacja <a href="http://www.haskell.org/haddock/">Haddock</a>, dok&#322;adniej jak dokumentacja na Hackage. Haddock u&#380;ywa <a href="http://www.cs.york.ac.uk/fp/darcs/hscolour/">Hscoulour</a>, narz&#281;dzia napisanego przez Malcolma Wallace przeznaczonego do kolorowania kodu &#378;ród&#322;owego.</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Language</span><span>.</span><span>Haskell</span><span>.</span><span>HsColour</span><span style="color:red;">(</span><span>hscolour</span><span style="color:red;">,</span><span>Output</span><span style="color:red;">(</span><span style="color:red;">..</span><span style="color:red;">)</span><span style="color:red;">)</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Language</span><span>.</span><span>Haskell</span><span>.</span><span>HsColour</span><span>.</span><span>Colourise</span><span style="color:red;">(</span><span>defaultColourPrefs</span><span style="color:red;">)</span>
</code></pre>
<p>Zak&#322;adaj&#261;c, &#380;e Pandoc i hscolour mnie zadowol&#261;, b&#281;d&#281; jeszcze potrzebowa&#322; sposobu na publikacj&#281; na blogu. Po chwili googlowania znalaz&#322;em informacj&#281;, &#380;e mój blog wspiera co&#347; nazywanego <a href="http://www.xmlrpc.com/metaWeblogApi">MetaWeblog API</a>, czyli blogowy protokó&#322; bazowany na XML-RPC.</p>
<p>Istnieje biblioteka XML-RPC autorstwa Bjorna Bringerta nazwana <a href="http://www.haskell.org/haxr/">HaXR</a> (oczywi&#347;cie na <a href="http://hackage.haskell.org/package/haxr">Hackage</a>), która wydaje si&#281; by&#263; odpowiednia.</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Network</span><span>.</span><span>XmlRpc</span><span>.</span><span>Client</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Network</span><span>.</span><span>XmlRpc</span><span>.</span><span>Internals</span>
</code></pre>
<p>B&#281;d&#281; potrzebowa&#322; jeszcze kilku rzeczy. Poniewa&#380; tworz&#281; narz&#281;dzie obs&#322;ugiwane z linii polece&#324;, przyda si&#281; parser argumentów, a biblioteka Neila Mitchela <a href="http://community.haskell.org/~ndm/cmdargs/">CmdArgs</a> powinna by&#263; odpowiednia:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>System</span><span>.</span><span>Console</span><span>.</span><span>CmdArgs</span>
</code></pre>
<p>W ko&#324;cu b&#281;d&#281; te&#380; musia&#322; manipulowa&#263; formatem XHTML, wi&#281;c u&#380;yj&#281; biblioteki kombinatorów <a href="http://www.cs.york.ac.uk/fp/HaXml/">HaXml</a> Malcolma Wallacea:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Text</span><span>.</span><span>XML</span><span>.</span><span>HaXml</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Text</span><span>.</span><span>XML</span><span>.</span><span>HaXml</span><span>.</span><span>Verbatim</span>
</code></pre>
<p>Potrzebuj&#281; te&#380; wykona&#263; troch&#281; tekstowego wej&#347;cia wyj&#347;cia w kodowaniu UTF8, co prowadzi mnie do niezast&#261;pionej (a&#380; do GHC 6.12!) biblioteki Erica Martensa <a href="http://hackage.haskell.org/package/utf8-string">utf8-string</a>:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span style="color:blue;font-weight:bold;">qualified</span> <span>System</span><span>.</span><span>IO</span><span>.</span><span>UTF8</span> <span style="color:blue;font-weight:bold;">as</span> <span>U</span>
</code></pre>
<p>I jeszcze kilka drobniejszych rzeczy:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Control</span><span>.</span><span>Monad</span><span style="color:red;">(</span><span>liftM</span><span style="color:red;">,</span><span>unless</span><span style="color:red;">)</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Text</span><span>.</span><span>XHtml</span><span>.</span><span>Transitional</span><span style="color:red;">(</span><span>showHtml</span><span style="color:red;">)</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Text</span><span>.</span><span>ParserCombinators</span><span>.</span><span>Parsec</span>
<span>&#62;</span> <span style="color:blue;font-weight:bold;">import</span> <span>Debug</span><span>.</span><span>Trace</span>
</code></pre>
<p>Program, który sobie wyobra&#380;am, wczyta plika Haskella w formacie literackim, u&#380;yje Pandoc w tryie markdown, w jaki&#347; sposób znajdzie bloki kodu na wej&#347;ciu, u&#380;yje na nich hscolour. Pandoc przemienia swoje wej&#347;cie w struktur&#281; typu:</p>
<pre><code><span style="color:blue;font-weight:bold;">data</span> <span>Pandoc</span> <span style="color:red;">=</span> <span>Pandoc</span> <span>Meta</span> <span style="color:red;">[</span><span>Block</span><span style="color:red;">]</span></code></pre>
<p>gdzie <code>Block</code> (w ka&#380;dym razie jego interesuj&#261;ca cz&#281;&#347;&#263;) to:</p>
<pre><code><span style="color:green;">-- &#124; Block element.</span>
<span style="color:blue;font-weight:bold;">data</span> <span>Block</span>
    <span style="color:red;">=</span> <span>Plain</span> <span style="color:red;">[</span><span>Inline</span><span style="color:red;">]</span>        <span style="color:green;">-- ^ Tekst, ale nie paragraf</span>
    <span style="color:red;">&#124;</span> <span>Para</span> <span style="color:red;">[</span><span>Inline</span><span style="color:red;">]</span>         <span style="color:green;">-- ^ Paragraf</span>
    <span style="color:red;">&#124;</span> <span>CodeBlock</span> <span>Attr</span> <span>String</span> <span style="color:green;">-- ^ Fragment kodu (dosłownie) z atrybutami</span>
    <span style="color:red;">&#124;</span> <span>RawHtml</span> <span>String</span>        <span style="color:green;">-- ^ Surowy HTML</span>
    <span style="color:red;">&#124;</span> <span>BlockQuote</span> <span style="color:red;">[</span><span>Block</span><span style="color:red;">]</span>    <span style="color:green;">-- ^ Cytowanie blokowe</span>
    <span style="color:red;">&#124;</span> <span>OrderedList</span> <span>ListAttributes</span> <span style="color:red;">[</span><span style="color:red;">[</span><span>Block</span><span style="color:red;">]</span><span style="color:red;">]</span> <span style="color:green;">-- ^ Numerowana lista z atrybutami </span>
                            <span style="color:green;">-- i elementami (każdy to lista bloków)</span>
    <span style="color:red;">&#124;</span> <span>BulletList</span> <span style="color:red;">[</span><span style="color:red;">[</span><span>Block</span><span style="color:red;">]</span><span style="color:red;">]</span>  <span style="color:green;">-- ^ Punktowana lista (lista elementów, każdy z nich</span>
                            <span style="color:green;">-- to lista bloków)</span>
    <span style="color:red;">&#124;</span> <span>DefinitionList</span> <span style="color:red;">[</span><span style="color:red;">(</span><span style="color:red;">[</span><span>Inline</span><span style="color:red;">]</span><span style="color:red;">,</span><span style="color:red;">[</span><span>Block</span><span style="color:red;">]</span><span style="color:red;">)</span><span style="color:red;">]</span>  <span style="color:green;">-- ^ Lista definicyjna</span>
                            <span style="color:green;">-- (lista elementów, każdy to para tekstu i listy bloków)</span>
    <span style="color:red;">&#124;</span> <span>Header</span> <span>Int</span> <span style="color:red;">[</span><span>Inline</span><span style="color:red;">]</span>   <span style="color:green;">-- ^ Nagłówek - poziom (liczba) i tekst</span>
    <span style="color:red;">&#124;</span> <span>HorizontalRule</span>        <span style="color:green;">-- ^ Pozioma linia podziału</span>
    <span style="color:red;">&#124;</span> <span>Table</span> <span style="color:red;">[</span><span>Inline</span><span style="color:red;">]</span> <span style="color:red;">[</span><span>Alignment</span><span style="color:red;">]</span> <span style="color:red;">[</span><span>Double</span><span style="color:red;">]</span> <span style="color:red;">[</span><span style="color:red;">[</span><span>Block</span><span style="color:red;">]</span><span style="color:red;">]</span> <span style="color:red;">[</span><span style="color:red;">[</span><span style="color:red;">[</span><span>Block</span><span style="color:red;">]</span><span style="color:red;">]</span><span style="color:red;">]</span>  <span style="color:green;">-- ^ Tablica,</span>
                            <span style="color:green;">-- z tytułami, justowaniem kolumn,</span>
                            <span style="color:green;">-- relatywną szerokością kolumn i ich nagłówków</span>
                            <span style="color:green;">-- (każdy to lista bloków), i rzędów</span>
                            <span style="color:green;">-- (każdy to lista list bloków)</span>
    <span style="color:red;">&#124;</span> <span>Null</span>                  <span style="color:green;">-- ^ Puste</span>
    <span style="color:blue;font-weight:bold;">deriving</span> <span style="color:red;">(</span><span>Eq</span><span style="color:red;">,</span> <span>Read</span><span style="color:red;">,</span> <span>Show</span><span style="color:red;">,</span> <span>Typeable</span><span style="color:red;">,</span> <span>Data</span><span style="color:red;">)</span></code></pre>
<p>Literacki Haskell, który znajduje <code>Pandoc</code> w pliku trafia do ró&#380;nych elementów <code>CodeBlock</code> w dokumencie <code>Pandoc</code>. Inny kod równie&#380; mo&#380;e si&#281; tam znale&#378;&#263;, je&#347;li by&#322; normalnie sformatowanym markdownem. Literacki Haskell rozró&#380;niamy dzi&#281;ki innemu sk&#322;adnikowi <code>Attr</code>, który ma posta&#263;:</p>
<pre><code><span style="color:blue;font-weight:bold;">type</span> <span>Attr</span> <span style="color:red;">=</span> <span style="color:red;">(</span><span>String</span><span style="color:red;">,</span> <span style="color:red;">[</span><span>String</span><span style="color:red;">]</span><span style="color:red;">,</span> <span style="color:red;">[</span><span style="color:red;">(</span><span>String</span><span style="color:red;">,</span> <span>String</span><span style="color:red;">)</span><span style="color:red;">]</span><span style="color:red;">)</span></code></pre>
<p>Jak pokazuj&#261; eksperymenty, <code>CodeBlock</code> który ma <code>Attr</code> postaci <code>(_,[&#34;sourceCode&#34;,&#34;haskell&#34;],_)</code> jest literackim fragmentem kodu Haskella, natomiast inne elementy <code>CodeBlock</code> s&#261; markdownem. Chc&#281; pod&#347;wietlanie sk&#322;adni w obu rodzajach bloków, ale kiedy b&#281;d&#261; renderowane do HTMLa chc&#281; zachowa&#263; konwencj&#281; literackiego Haskella (czyli chc&#281; do&#322;o&#380;y&#263; znaczek &#62; na pocz&#261;tku ka&#380;dej linii). W&#322;a&#347;ciwie to nawet chc&#281; wi&#281;cej&#8230;</p>
<p>Gdy pisz&#281; literackiego Haskella, mog&#281; chcie&#263; za&#322;&#261;czy&#263; nie-Haskell, ale jednak kod w tek&#347;cie. Przyk&#322;ady jak ten sam fragment napisa&#263; w ML, albo przyk&#322;ady jak uruchomi&#263; program. Nie ka&#380;dy blok powinien by&#263; pod&#347;witlany przez hscolour, tylko kod Haskella. Markdown nie pozwala na opis jakiego j&#281;zyka jest dany fragment kodu, ale skoro i tak obrabiam poszczególne bloki, mog&#281; przyj&#261;&#263; prost&#261; konwencj&#281;. Je&#347;li fragmenty wygl&#261;da tak:</p>
<pre><code>[haskell]
foo :: String -&#62; String</code></pre>
<p>to jest to blok Haskella. Je&#347;li wygl&#261;da inaczej:</p>
<pre><code>[C++]
cout &#60;&#60; &#34;Hello World!&#34;;</code></pre>
<p>lub</p>
<pre><code>[other]
foo bar baz</code></pre>
<p>wtedy zak&#322;adamy, &#380;e jest to co&#347; innego.</p>
<p>Mog&#281; usun&#261;&#263; typ bloku z pocz&#261;tku ka&#380;dego bloku, który przygotowuj&#281; do pokolorowania. U&#380;ywam Parseca do rozpoznania tagu otwieraj&#261;cego:</p>
<pre><code><span>&#62;</span> <span>unTag</span> <span style="color:red;">::</span> <span>String</span> <span style="color:red;">-&#62;</span> <span style="color:red;">(</span><span>String</span><span style="color:red;">,</span> <span>String</span><span style="color:red;">)</span>
<span>&#62;</span> <span>unTag</span> <span>s</span> <span style="color:red;">=</span> <span>either</span> <span style="color:red;">(</span><span>const</span> <span style="color:red;">(</span><span style="color:teal;">""</span><span style="color:red;">,</span><span>s</span><span style="color:red;">)</span><span style="color:red;">)</span> <span>id</span> <span>$</span> <span>parse</span> <span>tag</span> <span style="color:teal;">""</span> <span>s</span>
<span>&#62;</span>    <span style="color:blue;font-weight:bold;">where</span> <span>tag</span> <span style="color:red;">=</span> <span style="color:blue;font-weight:bold;">do</span>
<span>&#62;</span>              <span>tg</span> <span style="color:red;">&#60;-</span> <span>between</span> <span style="color:red;">(</span><span>char</span> <span style="color:teal;">'['</span><span style="color:red;">)</span> <span style="color:red;">(</span><span>char</span> <span style="color:teal;">']'</span><span style="color:red;">)</span> <span>$</span> <span>many</span> <span>$</span> <span>noneOf</span> <span style="color:teal;">"[]"</span>
<span>&#62;</span>              <span>skipMany</span> <span>$</span> <span>oneOf</span> <span style="color:teal;">" t"</span>
<span>&#62;</span>              <span style="color:red;">(</span><span>string</span> <span style="color:teal;">"\r\n"</span> <span>&#60;&#124;&#62;</span> <span>string</span> <span style="color:teal;">"\n"</span><span style="color:red;">)</span>
<span>&#62;</span>              <span>txt</span> <span style="color:red;">&#60;-</span> <span>many</span> <span>$</span> <span>anyToken</span>
<span>&#62;</span>              <span>eof</span>
<span>&#62;</span>              <span>return</span> <span style="color:red;">(</span><span>tg</span><span style="color:red;">,</span><span>txt</span><span style="color:red;">)</span>
</code></pre>
<p>Aby pod&#347;wietli&#263; sk&#322;adni&#281; przy u&#380;yciu hscolour (który produkuje HTML), potrzebuj&#281; przetworzy&#263; <code>String</code> z elementu <code>CodeBlock</code> na <code>String</code> odpowiedni dla <code>RawHtml</code>. Pandoc usuwa znak &#62; z pocz&#261;tku ka&#380;dej linii, wi&#281;c musz&#281; go doda&#263; spowrotem, a tak&#380;e poinformowa&#263; hscolour czy jest to literacki Haskell czy te&#380; nie. Funkcja hscolour wygl&#261;da tak:</p>
<pre><code><span>hscolour</span> <span style="color:red;">::</span> <span>Output</span>      <span style="color:green;">-- ^ Format wyjściowy</span>
         <span style="color:red;">-&#62;</span> <span>ColourPrefs</span> <span style="color:green;">-- ^ Kolorystyka</span>
         <span style="color:red;">-&#62;</span> <span>Bool</span>        <span style="color:green;">-- ^ Czy generować odnośniki</span>
         <span style="color:red;">-&#62;</span> <span>Bool</span>        <span style="color:green;">-- ^ Czy wyściowy dokument jest częściowy czy zamknięty</span>
         <span style="color:red;">-&#62;</span> <span>String</span>      <span style="color:green;">-- ^ Tytuł</span>
         <span style="color:red;">-&#62;</span> <span>Bool</span>        <span style="color:green;">-- ^ Czy wejściowy dokument jest literacki czy nie</span>
         <span style="color:red;">-&#62;</span> <span>String</span>      <span style="color:green;">-- ^ Kod źródłowy Haskella</span>
         <span style="color:red;">-&#62;</span> <span>String</span>      <span style="color:green;">-- ^ Koloryzowany kod źródłowy Haskella</span></code></pre>
<p>Hscolour wspiera kilka styli HTMLa: <code>HTML</code>, <code>CSS</code> i <code>ICSS</code>. <code>HTML</code> to HTML z tagami font, które s&#261; narz&#281;dziem szatana, wi&#281;c omin&#261;&#322;em t&#281; opcj&#281; szerokim &#322;ukiem. <code>CSS</code> to formatowanie HTML przy u&#380;yciu styli, które pozwala na elastyczno&#347;&#263; u&#380;ycia osobnego arkusza stylu. <code>ICSS</code> to &#8216;inline-CSS&#8217;, czyli dok&#322;adnie to, czego potrzebuj&#281; dla mojego WordPressowego bloga, gdy&#380; nie zamierzam p&#322;aci&#263; $15 rocznie za przywilej posiadania w&#322;asnego cssa na ich stronie. Niestety, opcje styli hscolour dla trybu <code>ICSS</code> s&#261; dosy&#263; ograniczone, ale wymy&#347;li&#322;em nieco bardziej zagmatwany sposób na przerobienie CSSowo kolorowanego kodu &#378;ród&#322;owego na &#8216;inline-css&#8217; HTML. Zaczn&#281; wi&#281;c od u&#380;ycia hscolour w trybie <code>CSS</code> do przetwarzania mojego &#378;ród&#322;a:</p>
<pre><code><span>&#62;</span> <span>colourIt</span> <span>literate</span> <span>srcTxt</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span>hscolour</span> <span>CSS</span> <span>defaultColourPrefs</span> <span>False</span> <span>True</span> <span style="color:teal;">""</span> <span>literate</span> <span>src'</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">where</span> <span>src'</span> <span style="color:red;">&#124;</span> <span>literate</span> <span style="color:red;">=</span> <span>prepend</span> <span>srcTxt</span>
<span>&#62;</span>                <span style="color:red;">&#124;</span> <span>otherwise</span> <span style="color:red;">=</span> <span>srcTxt</span>
</code></pre>
<p>Do&#322;&#261;czenie znaczników literackiego Haskella na pocz&#261;tku ka&#380;dej linii jest trywialne:</p>
<pre><code><span>&#62;</span> <span>prepend</span> <span>s</span> <span style="color:red;">=</span> <span>unlines</span> <span>$</span> <span>map</span> <span>p</span> <span>$</span> <span>lines</span> <span>s</span> <span style="color:blue;font-weight:bold;">where</span> <span>p</span> <span>s</span> <span style="color:red;">=</span> <span style="color:teal;">'&#62;'</span><span>:</span><span style="color:teal;">' '</span><span>:</span><span>s</span>
</code></pre>
<p>Hscolour u&#380;ywa elementów <code>SPAN</code> w HTML i klas CSSa takich jak &#8216;hs-keyword&#8217; lub &#8216;hs-keyglyph&#8217;. Ja chc&#281; wzi&#261;&#263; ka&#380;dy oznaczony tak element <code>SPAN</code> i zamieni&#263; jego atrybut <code>class</code> na styl bezpo&#347;rednio na elemencie zgodnie z moim upodobaniem. Mo&#380;liwo&#347;ci stylu opisuje typ:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>StylePrefs</span> <span style="color:red;">=</span> <span>StylePrefs</span> <span style="color:red;">{</span>
<span>&#62;</span>     <span>keyword</span>  <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>keyglyph</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>layout</span>   <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>comment</span>  <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>conid</span>    <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>varid</span>    <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>conop</span>    <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>varop</span>    <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>str</span>      <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>chr</span>      <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>number</span>   <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>cpp</span>      <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>selection</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>variantselection</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>definition</span> <span style="color:red;">::</span> <span>String</span>
<span>&#62;</span>     <span style="color:red;">}</span> <span style="color:blue;font-weight:bold;">deriving</span> <span style="color:red;">(</span><span>Read</span><span style="color:red;">,</span><span>Show</span><span style="color:red;">)</span>
</code></pre>
<p>Ka&#380;de pole powy&#380;szego b&#281;dzie zawiera&#322;o oczekiwany styl dla klasy HTML, któr&#261; hscolour przypisze fragmentowi kodu. Domy&#347;lny styl, taki jak ma Hackage, wygl&#261;da tak:</p>
<pre><code><span>&#62;</span> <span>defaultStylePrefs</span> <span style="color:red;">=</span> <span>StylePrefs</span> <span style="color:red;">{</span>
<span>&#62;</span>     <span>keyword</span>  <span style="color:red;">=</span> <span style="color:teal;">"color: blue; font-weight: bold;"</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>keyglyph</span> <span style="color:red;">=</span> <span style="color:teal;">"color: red;"</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>layout</span>   <span style="color:red;">=</span> <span style="color:teal;">"color: red;"</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>comment</span>  <span style="color:red;">=</span> <span style="color:teal;">"color: green;"</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>conid</span>    <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>varid</span>    <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>conop</span>    <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>varop</span>    <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>str</span>      <span style="color:red;">=</span> <span style="color:teal;">"color: teal;"</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>chr</span>      <span style="color:red;">=</span> <span style="color:teal;">"color: teal;"</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>number</span>   <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>cpp</span>      <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>selection</span> <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>variantselection</span> <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">,</span> <span>definition</span> <span style="color:red;">=</span> <span style="color:teal;">""</span>
<span>&#62;</span>   <span style="color:red;">}</span>
</code></pre>
<p>Mo&#380;na wczyta&#263; preferencje stylu z pliku przy u&#380;yciu instancji <code>Read</code> dla <code>StylePrefs</code>. Mo&#380;naby lepiej zatroszczy&#263; si&#281; o b&#322;&#281;dy, ale poni&#380;sze powinno zadzia&#322;a&#263;:</p>
<pre><code><span>&#62;</span> <span>getStylePrefs</span> <span style="color:teal;">""</span> <span style="color:red;">=</span> <span>return</span> <span>defaultStylePrefs</span>
<span>&#62;</span> <span>getStylePrefs</span> <span>fname</span> <span style="color:red;">=</span> <span>liftM</span> <span>read</span> <span style="color:red;">(</span><span>U</span><span>.</span><span>readFile</span> <span>fname</span><span style="color:red;">)</span>
</code></pre>
<p>Hscolour zwraca HTML jako <code>String</code>. &#379;eby go przetworzy&#263;, trzeba sparsowa&#263;, przetworzy&#263;, potem znowu zrenderowa&#263; do <code>Stringa</code>. Teraz u&#380;yj&#281; HaXml:</p>
<pre><code><span>&#62;</span> <span>xformXml</span> <span style="color:red;">::</span> <span>StylePrefs</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span>
<span>&#62;</span> <span>xformXml</span> <span>prefs</span> <span>s</span> <span style="color:red;">=</span>  <span>verbatim</span> <span>$</span> <span>filtDoc</span> <span style="color:red;">(</span><span>xmlParse</span> <span style="color:teal;">"input"</span> <span>s</span><span style="color:red;">)</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>     <span style="color:green;">-- filter the document (an Hscoloured fragment of Haskell source)</span>
<span>&#62;</span>     <span>filtDoc</span> <span style="color:red;">(</span><span>Document</span> <span>p</span> <span>s</span> <span>e</span> <span>m</span><span style="color:red;">)</span> <span style="color:red;">=</span>  <span>c</span> <span style="color:blue;font-weight:bold;">where</span>
<span>&#62;</span>         <span style="color:red;">[</span><span>c</span><span style="color:red;">]</span> <span style="color:red;">=</span> <span>filts</span> <span style="color:red;">(</span><span>CElem</span> <span>e</span><span style="color:red;">)</span>
<span>&#62;</span>     <span style="color:green;">-- the filter is a fold of individual filters for each CSS class</span>
<span>&#62;</span>     <span>filts</span> <span style="color:red;">=</span> <span>foldXml</span> <span>$</span> <span>foldl</span> <span>o</span> <span>keep</span> <span style="color:red;">[</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"keyword"</span> <span>keyword</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"keyglyph"</span> <span>keyglyph</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"layout"</span> <span>layout</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"comment"</span> <span>comment</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"conid"</span> <span>conid</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"varid"</span> <span>varid</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"conop"</span> <span>conop</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"varop"</span> <span>varop</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"str"</span> <span>str</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"chr"</span> <span>chr</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"num"</span> <span>number</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"cpp"</span> <span>cpp</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"sel"</span> <span>selection</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"variantselection"</span> <span>variantselection</span><span style="color:red;">,</span>
<span>&#62;</span>             <span>filt</span> <span style="color:teal;">"definition"</span> <span>definition</span>
<span>&#62;</span>         <span style="color:red;">]</span>
<span>&#62;</span>     <span style="color:green;">-- an individual filter replaces the attributes of a tag with</span>
<span>&#62;</span>     <span style="color:green;">-- a style attribute when it has a specific 'class' attribute.</span>
<span>&#62;</span>     <span>filt</span> <span>lbl</span> <span>f</span> <span style="color:red;">=</span>
<span>&#62;</span>         <span>replaceAttrs</span> <span style="color:red;">[</span><span style="color:red;">(</span><span style="color:teal;">"style"</span><span style="color:red;">,</span><span>f</span> <span>prefs</span><span style="color:red;">)</span><span style="color:red;">]</span> <span>`when`</span>
<span>&#62;</span>             <span style="color:red;">(</span><span>attrval</span> <span>$</span> <span style="color:red;">(</span><span style="color:teal;">"class"</span><span style="color:red;">,</span><span>AttValue</span> <span style="color:red;">[</span><span>Left</span> <span style="color:red;">(</span><span style="color:teal;">"hs-"</span> <span>++</span> <span>lbl</span><span style="color:red;">)</span><span style="color:red;">]</span><span style="color:red;">)</span><span style="color:red;">)</span>
</code></pre>
<p>Aby w pe&#322;ni pokolorowa&#263; <code>CodeBlock</code> mo&#380;emy stworzy&#263; funkcj&#281; transformuj&#261;c&#261; <code>CodeBlock</code> do <code>RawHtml</code>, gdy zawarto&#347;&#263; zawiera kod &#378;ród&#322;owy Haskella:</p>
<pre><code><span>&#62;</span> <span>colouriseCodeBlock</span> <span>prefs</span> <span style="color:red;">(</span><span>CodeBlock</span> <span>attr</span><span style="color:red;">@</span><span style="color:red;">(</span><span style="color:blue;font-weight:bold;">_</span><span style="color:red;">,</span><span>inf</span><span style="color:red;">,</span><span style="color:blue;font-weight:bold;">_</span><span style="color:red;">)</span> <span>s</span><span style="color:red;">)</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">if</span> <span>tag</span> <span>==</span> <span style="color:teal;">"Haskell"</span> <span>&#124;&#124;</span> <span>lit</span>
<span>&#62;</span>         <span style="color:blue;font-weight:bold;">then</span> <span>RawHtml</span> <span>$</span> <span>xformXml</span> <span>prefs</span> <span>$</span> <span>colourIt</span> <span>lit</span> <span>s'</span>
<span>&#62;</span>         <span style="color:blue;font-weight:bold;">else</span> <span>CodeBlock</span> <span>attr</span> <span>s'</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">where</span> <span style="color:red;">(</span><span>tag</span><span style="color:red;">,</span><span>s'</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>trace</span> <span style="color:red;">(</span><span>show</span> <span>s</span><span style="color:red;">)</span> <span>$</span> <span>unTag</span> <span>s</span>
<span>&#62;</span>           <span>lit</span> <span style="color:red;">=</span> <span style="color:teal;">"sourceCode"</span> <span>`elem`</span> <span>inf</span> <span>&#38;&#38;</span> <span style="color:teal;">"haskell"</span> <span>`elem`</span> <span>inf</span>
<span>&#62;</span> <span>colouriseCodeBlock</span> <span style="color:blue;font-weight:bold;">_</span> <span>b</span> <span style="color:red;">=</span> <span>b</span>
</code></pre>
<p>A kolorowanie dokumentu <code>Pandoc</code> to po prostu:</p>
<pre><code><span>&#62;</span> <span>colourisePandoc</span> <span>prefs</span> <span style="color:red;">(</span><span>Pandoc</span> <span>m</span> <span>blocks</span><span style="color:red;">)</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span>Pandoc</span> <span>m</span> <span>$</span> <span>map</span> <span style="color:red;">(</span><span>colouriseCodeBlock</span> <span>prefs</span><span style="color:red;">)</span> <span>blocks</span>
</code></pre>
<p>Przetworzenie pe&#322;nego dokumentu na wej&#347;ciu do wyj&#347;cia HTML to:</p>
<pre><code><span>&#62;</span> <span>xformDoc</span> <span style="color:red;">::</span> <span>StylePrefs</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span>
<span>&#62;</span> <span>xformDoc</span> <span>prefs</span> <span>s</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span>showHtml</span>
<span>&#62;</span>     <span>$</span> <span>writeHtml</span> <span>writeOpts</span> <span style="color:green;">-- from Pandoc</span>
<span>&#62;</span>     <span>$</span> <span>colourisePandoc</span> <span>prefs</span>
<span>&#62;</span>     <span>$</span> <span>readMarkdown</span> <span>parseOpts</span> <span style="color:green;">-- from Pandoc</span>
<span>&#62;</span>     <span>$</span> <span>fixLineEndings</span> <span>s</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">where</span> <span>writeOpts</span> <span style="color:red;">=</span> <span>defaultWriterOptions</span> <span style="color:red;">{</span>
<span>&#62;</span>               <span>writerLiterateHaskell</span> <span style="color:red;">=</span> <span>True</span><span style="color:red;">,</span>
<span>&#62;</span>               <span>writerReferenceLinks</span> <span style="color:red;">=</span> <span>True</span> <span style="color:red;">}</span>
<span>&#62;</span>           <span>parseOpts</span> <span style="color:red;">=</span> <span>defaultParserState</span> <span style="color:red;">{</span>
<span>&#62;</span>               <span>stateLiterateHaskell</span> <span style="color:red;">=</span> <span>True</span> <span style="color:red;">}</span>
<span>&#62;</span>           <span style="color:green;">-- readMarkdown is picky about line endings</span>
<span>&#62;</span>           <span>fixLineEndings</span> <span>[]</span> <span style="color:red;">=</span> <span>[]</span>
<span>&#62;</span>           <span>fixLineEndings</span> <span style="color:red;">(</span><span style="color:teal;">'\r'</span><span>:</span><span style="color:teal;">'\n'</span><span>:</span><span>cs</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span style="color:teal;">'\n'</span><span>:</span><span>fixLineEndings</span> <span>cs</span>
<span>&#62;</span>           <span>fixLineEndings</span> <span style="color:red;">(</span><span>c</span><span>:</span><span>cs</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span>c</span><span>:</span><span>fixLineEndings</span> <span>cs</span>
</code></pre>
<p>Teraz, skoro ju&#380; potrafi&#281; stworzy&#263; dokument, mus&#380;e jeszcze umie&#263; wys&#322;a&#263; go na blog. MetaWeblog API definiuje metody <code>newPost</code> oraz <code>editPost</code>:</p>
<pre><code>metaWeblog.newPost (blogid, username, password, struct, publish) returns string
metaWeblog.editPost (postid, username, password, struct, publish) returns true</code></pre>
<p>Dla mojego blogu (WordPressowego), <code>blogid</code> jest domy&#347;lne. Nazwa u&#380;ytkownika i has&#322;o to po prostu napisy, a <code>publish</code> to flaga okre&#347;laj&#261;ca, czy od razu opublikowa&#263; wpis. <code>Postid</code> to identyfikator, który jest automatycznie nadawany nowemu wpisowi. Interesuj&#261;ce jest pole <code>struct</code>, które jest struktur&#261; XML-RPC opisuj&#261;c&#261; wpis &#322;&#261;cznie z paroma metadanymi, na przyk&#322;ad tytu&#322;em. Aby stworzy&#263; t&#281; struktur&#281; potrzebuj&#281; tytu&#322;u i tre&#347;ci:</p>
<pre><code><span>&#62;</span> <span>mkPost</span> <span>title</span> <span>text</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span style="color:red;">[</span><span style="color:red;">(</span><span style="color:teal;">"title"</span><span style="color:red;">,</span><span>title</span><span style="color:red;">)</span><span style="color:red;">,</span><span style="color:red;">(</span><span style="color:teal;">"description"</span><span style="color:red;">,</span><span>text</span><span style="color:red;">)</span><span style="color:red;">]</span>
</code></pre>
<p>Biblioteka HaXR zawiera funkcj&#281; do wykonania zdalnej procedury XML-RPC:</p>
<pre><code><span>remote</span> <span style="color:red;">::</span> <span>Remote</span> <span>a</span> <span style="color:red;">=&#62;</span>
    <span>String</span> <span style="color:green;">-- ^ Server URL. May contain username and password on</span>
           <span style="color:green;">--   the format username:password@ before the hostname.</span>
       <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:green;">-- ^ Remote method name.</span>
       <span style="color:red;">-&#62;</span> <span>a</span>      <span style="color:green;">-- ^ Any function </span>
     <span style="color:green;">-- @(XmlRpcType t1, ..., XmlRpcType tn, XmlRpcType r) =&#62; </span>
                 <span style="color:green;">-- t1 -&#62; ... -&#62; tn -&#62; IO r@</span></code></pre>
<p>Funkcja jako argumentów potrzebuje URLa i nazwy metody. Zwraca funkcj&#281; typu <code>Remote a =&#62; a</code>. Wnioskuj&#261;c z instancji klasy <code>Remote</code> mo&#380;emy u&#380;y&#263; dowolnej funkcji przyjmuj&#261;cej zero lub wi&#281;cej parametrów klasy <code>XmlRpcType</code> i zwracaj&#261;ca <code>XmlRpcType r =&#62; IO r</code>. Po prostu mo&#380;esz funkcj&#281; <code>remote</code> wywo&#322;a&#263; z dowoln&#261; ilo&#347;ci&#261; argumentów porzebnych procedurze zdalnej. Je&#347;li wywo&#322;anie zrobisz w kontek&#347;cie IO, nadany zostanie w&#322;a&#347;ciwy typ. Zatem &#380;eby wywo&#322;a&#263; <code>metaWeblog.newPost</code> trzeba u&#380;y&#263; nast&#281;puj&#261;cej procedury:</p>
<pre><code><span>&#62;</span> <span>postIt</span> <span style="color:red;">::</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>Bool</span> <span style="color:red;">-&#62;</span> <span>IO</span> <span>String</span>
<span>&#62;</span> <span>postIt</span> <span>url</span> <span>blogId</span> <span>user</span> <span>password</span> <span>title</span> <span>text</span> <span>publish</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span>remote</span> <span>url</span> <span style="color:teal;">"metaWeblog.newPost"</span> <span>blogId</span> <span>user</span> <span>password</span> <span style="color:red;">(</span><span>mkPost</span> <span>title</span> <span>text</span><span style="color:red;">)</span> <span>publish</span>
</code></pre>
<p>Procedura uaktualniaj&#261;ca (zamieniaj&#261;ca) wpis ma posta&#263;:</p>
<pre><code><span>&#62;</span> <span>updateIt</span> <span style="color:red;">::</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>String</span> <span style="color:red;">-&#62;</span> <span>Bool</span> <span style="color:red;">-&#62;</span> <span>IO</span> <span>Bool</span>
<span>&#62;</span> <span>updateIt</span> <span>url</span> <span>postId</span> <span>user</span> <span>password</span> <span>title</span> <span>text</span> <span>publish</span> <span style="color:red;">=</span>
<span>&#62;</span>     <span>remote</span> <span>url</span> <span style="color:teal;">"metaWeblog.editPost"</span> <span>postId</span> <span>user</span> <span>password</span> <span style="color:red;">(</span><span>mkPost</span> <span>title</span> <span>text</span><span style="color:red;">)</span> <span>publish</span>
</code></pre>
<p>Wi&#281;kszo&#347;&#263; puzzli jest ju&#380; na miejscu. Teraz trzeba ca&#322;o&#347;&#263; przekszta&#322;ci&#263; w program linii polece&#324;. Kontrol&#281; przy uzyciu opcji opisuje nast&#281;puj&#261;cy typ:</p>
<pre><code><span>&#62;</span> <span style="color:blue;font-weight:bold;">data</span> <span>BlogLiterately</span> <span style="color:red;">=</span> <span>BlogLiterately</span> <span style="color:red;">{</span>
<span>&#62;</span>        <span>style</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>    <span style="color:green;">-- name of a style file</span>
<span>&#62;</span>        <span>publish</span> <span style="color:red;">::</span> <span>Bool</span><span style="color:red;">,</span>    <span style="color:green;">-- an indication of whether the post should be</span>
<span>&#62;</span>                            <span style="color:green;">-- published, or loaded as a draft</span>
<span>&#62;</span>        <span>blogid</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>   <span style="color:green;">-- blog-specific identifier (e.g. for blogging</span>
<span>&#62;</span>                            <span style="color:green;">-- software handling multiple blogs)</span>
<span>&#62;</span>        <span>blog</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>     <span style="color:green;">-- blog xmlrpc URL</span>
<span>&#62;</span>        <span>user</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>     <span style="color:green;">-- blog user name</span>
<span>&#62;</span>        <span>password</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span> <span style="color:green;">-- blog password</span>
<span>&#62;</span>        <span>title</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>    <span style="color:green;">-- post title</span>
<span>&#62;</span>        <span>file</span> <span style="color:red;">::</span> <span>String</span><span style="color:red;">,</span>     <span style="color:green;">-- file to post</span>
<span>&#62;</span>        <span>postid</span> <span style="color:red;">::</span> <span>String</span>    <span style="color:green;">-- id of a post to updated</span>
<span>&#62;</span>     <span style="color:red;">}</span> <span style="color:blue;font-weight:bold;">deriving</span> <span style="color:red;">(</span><span>Show</span><span style="color:red;">,</span><span>Data</span><span style="color:red;">,</span><span>Typeable</span><span style="color:red;">)</span>
</code></pre>
<p>Przy u&#380;yciu <code>CmdArgs</code> i poni&#380;szej magii definiuj&#281; jak zachowuj&#261; si&#281; argumenty linii polece&#324;:</p>
<pre><code><span>&#62;</span> <span>bl</span> <span style="color:red;">=</span> <span>mode</span> <span>$</span> <span>BlogLiterately</span> <span style="color:red;">{</span>
<span>&#62;</span>     <span>style</span> <span style="color:red;">=</span> <span style="color:teal;">""</span> <span>&#38;=</span> <span>text</span> <span style="color:teal;">"Style Specification"</span> <span>&#38;</span> <span>typFile</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>publish</span> <span style="color:red;">=</span> <span>def</span> <span>&#38;=</span> <span>text</span> <span style="color:teal;">"Publish post"</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>blogid</span> <span style="color:red;">=</span> <span style="color:teal;">"default"</span> <span>&#38;=</span> <span>text</span> <span style="color:teal;">"Blog specific identifier"</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>blog</span> <span style="color:red;">=</span> <span>def</span> <span>&#38;=</span> <span>argPos</span> <span class="hs-num">0</span> <span>&#38;</span> <span>typ</span> <span style="color:teal;">"URL"</span>
<span>&#62;</span>         <span>&#38;</span> <span>text</span> <span style="color:teal;">"URL of blog's xmlrpc address (e.g. http://example.com/blog/xmlrpc.php)"</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>user</span> <span style="color:red;">=</span> <span>def</span> <span>&#38;=</span> <span>argPos</span> <span class="hs-num">1</span> <span>&#38;</span> <span>typ</span> <span style="color:teal;">"USER"</span> <span>&#38;</span> <span>text</span> <span style="color:teal;">"blog author's user name"</span> <span style="color:red;">,</span>
<span>&#62;</span>     <span>password</span> <span style="color:red;">=</span> <span>def</span> <span>&#38;=</span> <span>argPos</span> <span class="hs-num">2</span> <span>&#38;</span> <span>typ</span> <span style="color:teal;">"PASSWORD"</span> <span>&#38;</span> <span>text</span> <span style="color:teal;">"blog author's password"</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>title</span> <span style="color:red;">=</span> <span>def</span> <span>&#38;=</span> <span>argPos</span> <span class="hs-num">3</span> <span>&#38;</span> <span>typ</span> <span style="color:teal;">"TITLE"</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>file</span> <span style="color:red;">=</span> <span>def</span> <span>&#38;=</span>  <span>argPos</span> <span class="hs-num">4</span> <span>&#38;</span> <span>typ</span> <span style="color:teal;">"FILE"</span> <span>&#38;</span> <span>text</span> <span style="color:teal;">"literate haskell file"</span><span style="color:red;">,</span>
<span>&#62;</span>     <span>postid</span> <span style="color:red;">=</span> <span style="color:teal;">""</span> <span>&#38;=</span> <span>text</span> <span style="color:teal;">"Post to replace (if any)"</span><span style="color:red;">}</span>
</code></pre>
<p>G&#322;ówna funkcja bloguj&#261;ca u&#380;ywa informacji zawartej w powy&#380;szym typie, &#380;eby przeczyta&#263; styl z pliku, wprowadzi&#263; &#378;ród&#322;o w postaci literackiego Haskella, odpowiednio przetworzy&#263;, a na ko&#324;cu wys&#322;a&#263; bezpo&#347;rednio na bloga:</p>
<pre><code><span>&#62;</span> <span>blogLiterately</span> <span style="color:red;">(</span><span>BlogLiterately</span> <span>style</span> <span>pub</span> <span>blogid</span> <span>url</span> <span>user</span> <span>pw</span> <span>title</span> <span>file</span> <span>postid</span><span style="color:red;">)</span> <span style="color:red;">=</span> <span style="color:blue;font-weight:bold;">do</span>
<span>&#62;</span>     <span>prefs</span> <span style="color:red;">&#60;-</span> <span>getStylePrefs</span> <span>style</span>
<span>&#62;</span>     <span>html</span> <span style="color:red;">&#60;-</span> <span>liftM</span> <span style="color:red;">(</span><span>xformDoc</span> <span>prefs</span><span style="color:red;">)</span> <span>$</span> <span>U</span><span>.</span><span>readFile</span> <span>file</span>
<span>&#62;</span>     <span>U</span><span>.</span><span>writeFile</span> <span style="color:teal;">"output.html"</span> <span>html</span>
<span>&#62;</span>     <span style="color:blue;font-weight:bold;">if</span> <span>null</span> <span>postid</span>
<span>&#62;</span>         <span style="color:blue;font-weight:bold;">then</span> <span style="color:blue;font-weight:bold;">do</span>
<span>&#62;</span>             <span>postid</span> <span style="color:red;">&#60;-</span> <span>postIt</span> <span>url</span> <span>blogid</span> <span>user</span> <span>pw</span> <span>title</span> <span>html</span> <span>pub</span>
<span>&#62;</span>             <span>putStrLn</span> <span>$</span> <span style="color:teal;">"post Id: "</span> <span>++</span> <span>postid</span>
<span>&#62;</span>         <span style="color:blue;font-weight:bold;">else</span> <span style="color:blue;font-weight:bold;">do</span>
<span>&#62;</span>             <span>result</span> <span style="color:red;">&#60;-</span> <span>updateIt</span> <span>url</span> <span>postid</span> <span>user</span> <span>pw</span> <span>title</span> <span>html</span> <span>pub</span>
<span>&#62;</span>             <span>unless</span> <span>result</span> <span>$</span> <span>putStrLn</span> <span style="color:teal;">"update failed!"</span>
</code></pre>
<p>G&#322;owny program to po prostu:</p>
<pre><code><span>&#62;</span> <span>main</span> <span style="color:red;">=</span> <span>cmdArgs</span> <span style="color:teal;">"Blog Literately v0.1, (C) Robert Greayer 2009"</span> <span style="color:red;">[</span><span>bl</span><span style="color:red;">]</span> <span>&#62;&#62;=</span> <span>blogLiterately</span>
</code></pre>
<p>Uruchomienie bez opcji wy&#347;wietli pomoc:</p>
<pre><code> [cmdline]
 $ ./BlogLiterately --help
 Blog Literately v0.1, (C) Robert Greayer 2009

 blogliterately [FLAG] URL USER PASSWORD TITLE FILE

  -? --help[=FORMAT]  Show usage information (optional format)
  -V --version        Show version information
  -v --verbose        Higher verbosity
  -q --quiet          Lower verbosity
  -s --style=FILE     Style Specification
     --publish        Publish post
  -b --blogid=VALUE   Blog specific identifier (default=default)
     --postid=VALUE   Post to replace (if any)</code></pre>
<p>Czyli aby stworzy&#263; wpis nale&#380;y u&#380;y&#263;:</p>
<pre><code>$ ./BlogLiterately http://greayer.wordpress.com/xmlrpc.php myuser mypass
    "Blogging Literately in Haskell" BlogLiterately.lhs</code></pre>
<p>&#346;wietny pocz&#261;tek tego, co mi potrzebne. Obs&#322;uga b&#322;&#281;dów nie istnieje, po prostu trzymamy kciuki w nadzieji, &#380;e domy&#347;lne komunikaty o b&#322;&#281;dach b&#281;d&#261; wystarczaj&#261;co jasne. Przyda&#322;oby si&#281; te&#380; wsparcie dla autorów i kategorii wpisów. Ale dzia&#322;a takie jak wida&#263; i jest narz&#281;dziem, które z powodzeniem u&#380;y&#322;em do stworzenia niniejszego wpisu.</p>
<p>Przedstawione tutaj narz&#281;dzie mo&#380;na zainstalowa&#263; poleceniem:</p>
<pre><code>cabal install BlogLiterately</code></pre>
<p>A na Hackage dost&#281;pna jest ju&#380; nowsza wersja o ulepszonym dzia&#322;aniu.</p>
</div>]]></content:encoded>
</item>
<item>
<title><![CDATA[Past, Present and PEPM]]></title>
<link>http://ivanmiljenovic.wordpress.com/2009/11/15/past-present-and-pepm/</link>
<pubDate>Sun, 15 Nov 2009 13:14:15 +0000</pubDate>
<dc:creator>Ivan Miljenovic</dc:creator>
<guid>http://ivanmiljenovic.wordpress.com/2009/11/15/past-present-and-pepm/</guid>
<description><![CDATA[I was planning on posting semi-regularly here, but I&#8217;ve been procrastinating way too much. It]]></description>
<content:encoded><![CDATA[I was planning on posting semi-regularly here, but I&#8217;ve been procrastinating way too much. It]]></content:encoded>
</item>

</channel>
</rss>
