<?xml version="1.0" encoding="UTF-8"?>
<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/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tupil Code Blog &#187; Haskell</title>
	<atom:link href="http://blog.tupil.com/tag/haskell/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tupil.com</link>
	<description>(Get up early, code often)</description>
	<lastBuildDate>Fri, 27 Aug 2010 10:50:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Running Happstack applications with FastCGI</title>
		<link>http://blog.tupil.com/running-happstack-applications-with-fastcgi/</link>
		<comments>http://blog.tupil.com/running-happstack-applications-with-fastcgi/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 14:20:46 +0000</pubDate>
		<dc:creator>Eelco Lempsink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[hackathon]]></category>
		<category><![CDATA[Happstack]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[library]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=57</guid>
		<description><![CDATA[This weekend  the 5th Haskell Hackathon happened.  It was hosted by Utrecht University and organized by people from the university and us. Together with Galois and Microsoft Research we sponsored the event. Between running around, listening to interesting presentations and talking to cool people we were able to code up a module enabling us to [...]]]></description>
			<content:encoded><![CDATA[<p>This weekend  the <a href="http://haskell.org/haskellwiki/Hac5">5th Haskell Hackathon</a> happened.  It was hosted by <a href="http://www.uu.nl">Utrecht University</a> and organized by people from the university and us. Together with <a href="http://www.galois.com">Galois</a> and <a href="http://research.microsoft.com">Microsoft Research</a> we sponsored the event.</p>
<p>Between running around, listening to interesting presentations and talking to cool people we were able to code up a module enabling us to use <a href="http://www.happstack.com">Happstack</a> through <a href="http://www.fastcgi.com">FastCGI</a>. This scratches an itch we&#8217;ve had for some time: we&#8217;re running a couple of HAppS/Happstack servers on our server but they&#8217;re configured to work through mod_proxy, which means having to choose an unique port for each application and doing (re)starting the servers by hand.</p>
<p>We just released <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/happstack-fastcgi">happstack-fastcgi on Hackage</a>. This post gives an example of how to use it with Apache and mod_fastcgi.  We assume you configured the extension &#8216;.fcgi&#8217; for FastCGI scripts.</p>
<h2>Converting your Happstack code</h2>
<p>Let&#8217;s look at a &#8216;normal&#8217; Happstack application. Usually, it has a <code>main</code> function that looks something like this&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> Happstack<span style="color: #339933; font-weight: bold;">.</span>Server
&nbsp;
main <span style="color: #339933; font-weight: bold;">=</span> simpleHTTP nullConf server
&nbsp;
<span style="color: #339933; font-weight: bold;">...</span></pre></div></div>

<p>Where the &#8220;server&#8221; part is something of the type <code>ServerPart a</code>.  To make this work with FastCGI, we need to convert the server parts so that they talk FastCGI.</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> Happstack<span style="color: #339933; font-weight: bold;">.</span>Server
<span style="color: #06c; font-weight: bold;">import</span> Happstack<span style="color: #339933; font-weight: bold;">.</span>Server<span style="color: #339933; font-weight: bold;">.</span>FastCGI
&nbsp;
simpleCGI <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>ToMessage a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> ServerPartT <span style="color: #cccc00; font-weight: bold;">IO</span> a <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
simpleCGI <span style="color: #339933; font-weight: bold;">=</span> runFastCGIConcurrent <span style="color: red;">10</span> <span style="color: #339933; font-weight: bold;">.</span> serverPartToCGI
&nbsp;
main <span style="color: #339933; font-weight: bold;">=</span> simpleCGI server
&nbsp;
<span style="color: #339933; font-weight: bold;">...</span></pre></div></div>

<p>Assuming the above code is placed in a script called Main.hs, you can compile it with</p>
<pre>
ghc -threaded --make Main.hs -o main.fcgi
</pre>
<p>Notice the &#8216;-threaded&#8217;, because else we won&#8217;t be able to serve request concurrently (other than having FastCGI start an extra instance of our program, which we don&#8217;t want when we&#8217;re working with happstack-state, for example).</p>
<p>So, let&#8217;s fill something in for <code>server</code>, for example</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">server <span style="color: #339933; font-weight: bold;">=</span> withRequest <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">return</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">show</span></pre></div></div>

<p>This will simple dump the request as it has been translated from a CGI request to a Happstack request.</p>
<h2>Running it with Apache</h2>
<p>Just for reference, the <a href='http://www.fastcgi.com/drupal/node/25'>FastCGI documentation</a> is your friend, but he might be a bit long-winded, so I will do a short recap of the basic things.</p>
<p>Let&#8217;s first do the easy thing. If you set up FastCGI correctly and made it the handler for .fcgi scripts, you can just throw the .fcgi file (like we just compiled) anywhere within your document root (provided that the ExecCGI option is enabled for that directory) and go to the correct URL with your browser.</p>
<p>Using scripts in this way is called &#8216;dynamic&#8217; in FastCGI-speak. With a bit more configuration (unfortunately on server/virtual host config level) we can run the script &#8216;statically&#8217;, which means it will be started when Apache is started and (by default) gets one process.  This is particularly important when using happstack-state, things might very well go wrong otherwise. To set up a &#8216;static&#8217; FastCGI script, you must use FastCGI&#8217;s <code>FastCgiServer</code> configuration directive.</p>
<p>Make sure you restart Apache when you change the script (or use FastCGI&#8217;s autoreload setting, which introduces a bit of overhead but is much more convenient).</p>
<h2>Nice URLs and serving static files</h2>
<p>Now you have the FastCGI file running, you might want to do something about the URLs, because doing requests to http://example.com/main.fcgi/some/url doesn&#8217;t really look that nice. As an added advantage, you can now use Apache to serve your static files, reducing the work your Happstack server needs to do.</p>
<p>The traditional .htaccess trickery looks something like this:</p>
<pre>
Options ExecCGI
DirectoryIndex main.fcgi

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) main.fcgi/$1 [PT,L]
</pre>
<p>(If your application is running in a subdirectory, you also need the <code>RewriteBase</code> configuration directive.)</p>
<h2>Closing words</h2>
<p>We did some really simple benchmarks that show that using Happstack through FastCGI, either dynamic or static, is about as fast as using Happstack directly or even mod_proxy (which is pretty fast, but a hassle).  That means the overhead is (as expected) quite small.</p>
<p>At first, we wanted to demo it with Gitit, but unfortunately Gitit or some library that uses Gitit tries to get the PATH environment variable and gives an error when it doesn&#8217;t succeed&#8230; So, if your Happstack application doesn&#8217;t (seem to) work with FastCGI, keep an eye on your logs. </p>
<p>Patches and bugreports are very welcome. You can clone <a href="http://github.com/chriseidhof/happstack-fastcgi">the repository</a> from Github, enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/running-happstack-applications-with-fastcgi/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>On unit testing and type checking</title>
		<link>http://blog.tupil.com/on-unit-testing-and-type-checking/</link>
		<comments>http://blog.tupil.com/on-unit-testing-and-type-checking/#comments</comments>
		<pubDate>Thu, 23 Oct 2008 14:16:38 +0000</pubDate>
		<dc:creator>Chris Eidhof</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Types]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=44</guid>
		<description><![CDATA[As most software developers know, it&#8217;s hard to create robust software. There is a lot of software out there that&#8217;s got bugs and a lot of time the developer doesn&#8217;t know about it and the users of the software run in to them. This is of course a very frustrating thing for both developers and [...]]]></description>
			<content:encoded><![CDATA[<p>As most software developers know, it&#8217;s hard to create robust software. There is a lot of software out there that&#8217;s got bugs and a lot of time the developer doesn&#8217;t know about it and the users of the software run in to them. This is of course a very frustrating thing for both developers and users.</p>
<p>Even for skilled developers, if a project grows big enough it becomes a lot harder to understand and maintain. Changes in one part may influence a seemingly unrelated part in the software. For example, in a language like Javascript, if you add a parameter to a method, it&#8217;s easy to forget to update one or two other functions that call it, but you&#8217;ll find out at runtime. Hopefully. Or else your customer will find it out for you.</p>
<p>It would be great if software developers could say with confidence that they have working software. Most of the bright Ruby developers I know strongly advocate test-driven development, not only to verify their programs but also to help them <i>design</i> the program. Programmers in a strongly typed language like Haskell often do the same thing: they&#8217;ll first write down the type, which forces them to really think about the function. The type of a function states what the input is, and in a pure language, you even have to state the kind of side-effects that can occur.</p>
<p>Both unit testing and strongly typed programming forces you to build your software in such a way that it is easily testable. They encourage you to write small functions that perform one specific task. Your program will almost automatically be broken down into small bits. I hardly find myself writing functions that are longer than a couple of lines, which also helps me to understand the functions even if I haven&#8217;t looked at them in a while.</p>
<p>In both unit testing and purely function programming you have to be explicit about state. What needs to be set up before you can call a function? Will there be side-effects? What should the state be like afterward?</p>
<p>Over time, programs will also evolve, and at some point, you&#8217;ll have to do refactoring. If you have correctly specified your unit tests, you can easily change a method and the tests will show you where it breaks. In Haskell, I very often change a method&#8217;s type signature and implementation, knowing that the compiler will tell me what I broke.</p>
<p>To summarize: unit testing and strongly typed (pure) programming overlap a lot.  With unit testing you can specify a lot of things that you can&#8217;t always easily do in your type system. Most notably, you can inspect the results of functions, which is something that you can not do in, for example, Haskell. There are other type systems that do allow you to do this, but that&#8217;s beyond the scope of this article. On the other hand, when working in Haskell, you&#8217;ll get the types for free most of the time. Instead of starting with a type, you can also start with the implementation and let the type-checker infer the type for you.</p>
<p>Both test-driven development and type-driven development can help you to make your code more understandable and better designed. I believe that, although there are a lot of differences, both approaches will help you build programs that are more safe and easier to understand. I guess all the unit-testing rubyists and purely functional Haskellers are not so different after all.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/on-unit-testing-and-type-checking/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Look ma, no callbacks!</title>
		<link>http://blog.tupil.com/look-ma-no-callbacks/</link>
		<comments>http://blog.tupil.com/look-ma-no-callbacks/#comments</comments>
		<pubDate>Mon, 25 Aug 2008 20:46:02 +0000</pubDate>
		<dc:creator>Chris Eidhof</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[arrows]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[game]]></category>
		<category><![CDATA[gui]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=27</guid>
		<description><![CDATA[In this article, we will see how we can use arrows in Javascript. Arrows are a concept from functional programming, and we&#8217;ll see how they can make our life in Javascript a lot easier. Our code uses the excellent Arrowlets library. It&#8217;s still alpha code, but it&#8217;s already quite useful. We&#8217;re going to build a [...]]]></description>
			<content:encoded><![CDATA[<p>In this article, we will see how we can use arrows in Javascript. Arrows are a concept from functional programming, and we&#8217;ll see how they can make our life in Javascript a lot easier. Our code uses the excellent <a href="http://www.cs.umd.edu/projects/PL/arrowlets/">Arrowlets</a> library. It&#8217;s still alpha code, but it&#8217;s already quite useful.</p>
<p>We&#8217;re going to build a small paddle game, where you can control the paddle with your keyboard. The first thing we&#8217;re going to build is the paddle. This is straightforward, if the user presses a key, we&#8217;ll move sideways, depending on the key that&#8217;s pressed. First, listening to a key press:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  ElementA<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>EventA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'keypress'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                    .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>movePaddle<span style="color: #009900;">&#41;</span>
                    .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>Repeat<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
                    .<span style="color: #660066;">run</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>You should read the first two lines of the code like this: if the &#8216;keypress&#8217; event happens on the document, we&#8217;re going to move the paddle. This is very different from regular javascript events, because there you attach an event and do the movePaddle every time there is a keypress. However, using arrowlets, the event is only caught once. Therefore we also need to have the next line that says: do this forever. The last line actually starts the code.</p>
<p>The body of the movePaddle function is only two lines:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> movePaddle<span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> offset <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>event.<span style="color: #660066;">keyCode</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">37</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">4</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>event.<span style="color: #660066;">keyCode</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">39</span> <span style="color: #339933;">?</span> <span style="color: #CC0000;">4</span> <span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  paddle.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> Math.<span style="color: #660066;">max</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> Math.<span style="color: #660066;">min</span><span style="color: #009900;">&#40;</span>paddleLeft<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> offset<span style="color: #339933;">,</span> <span style="color: #CC0000;">230</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;px&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>When the user presses a button &#8220;Start&#8221; that will start the game. Before we actually start animating, we&#8217;ll have to reset the field and place the ball. The ElementA function will find an element in the DOM, and the next resetGameOver updates the status.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">  ElementA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'start'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>EventA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'click'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                   .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>ElementA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gameOver'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>resetGameOver<span style="color: #009900;">&#41;</span></pre></div></div>

<p>The function resetGameOver code looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> resetGameOver <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> el.<span style="color: #660066;">innerHTML</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Next, we&#8217;ll reset the position of the ball and tell it to start moving every 30ms:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">                   .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>ElementA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ball'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
                   .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>resetBall<span style="color: #009900;">&#41;</span>
                   .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>moveBall.<span style="color: #660066;">animate</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">30</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>The code for resetBall simply resets the position and direction of the ball:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> resetBall <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ball<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  dir <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>x<span style="color: #339933;">:</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> y<span style="color: #339933;">:</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#125;</span>
  startPos <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #CC0000;">100</span> <span style="color: #339933;">+</span> Math.<span style="color: #660066;">random</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> <span style="color: #CC0000;">40</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;px&quot;</span><span style="color: #339933;">;</span>
  ball.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> startPos<span style="color: #339933;">;</span> ball.<span style="color: #660066;">style</span>.<span style="color: #660066;">top</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;120px&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> ball<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Note that it returns the ball, so the next function can make use of it:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> moveBall <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ball<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> newLeft <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>ball.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> dir.<span style="color: #660066;">x</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> newTop  <span style="color: #339933;">=</span> parseInt<span style="color: #009900;">&#40;</span>ball.<span style="color: #660066;">style</span>.<span style="color: #660066;">top</span><span style="color: #009900;">&#41;</span>  <span style="color: #339933;">+</span> dir.<span style="color: #660066;">y</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>newLeft <span style="color: #339933;">&lt;=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">||</span> newLeft <span style="color: #339933;">&gt;=</span> <span style="color: #CC0000;">260</span><span style="color: #009900;">&#41;</span> dir.<span style="color: #660066;">x</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">-</span> dir.<span style="color: #660066;">x</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>newTop  <span style="color: #339933;">&lt;=</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> dir.<span style="color: #660066;">y</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">-</span> dir.<span style="color: #660066;">y</span><span style="color: #339933;">;</span>
  ball.<span style="color: #660066;">style</span>.<span style="color: #660066;">left</span> <span style="color: #339933;">=</span> newLeft <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;px&quot;</span><span style="color: #339933;">;</span>
  ball.<span style="color: #660066;">style</span>.<span style="color: #660066;">top</span> <span style="color: #339933;">=</span> newTop <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;px&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>newTop <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">240</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>newLeft <span style="color: #339933;">&gt;</span> paddleLeft<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">5</span> <span style="color: #339933;">&amp;&amp;</span> newLeft <span style="color: #339933;">&lt;</span> paddleLeft<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #CC0000;">45</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#123;</span> 
      dir.<span style="color: #660066;">y</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">-</span> dir.<span style="color: #660066;">y</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">return</span> Repeat<span style="color: #009900;">&#40;</span>ball<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
    <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">return</span> Done  <span style="color: #009900;">&#40;</span>ball<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">return</span> Repeat<span style="color: #009900;">&#40;</span>ball<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The first two lines calculate a new left and top. If the ball bounces against one of the side walls, we invert the x-direction. Similarly for the top. If, however, we reach the bottom of the screen, things a bit more complicated: if the ball hits the paddle, we invert the y-direction and return Repeat(ball). The Repeat means that we&#8217;re not finished with our animation. If the ball misses the paddle, we return Done(ball). This means our animation is finished an the user&#8217;s game is over.</p>
<p>Now we can go on with the next part of our game handling code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">                   .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>ElementA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'gameOver'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>gameOver<span style="color: #009900;">&#41;</span>
                   .<span style="color: #660066;">next</span><span style="color: #009900;">&#40;</span>Repeat<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">repeat</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>We show the gameOver status message, and then repeat this infinitely, so the user can start a new game. And that&#8217;s it, that&#8217;s all the code. Here&#8217;s a link to <a href="http://code.tupil.com/arrowlets">the game</a>, and also a link to <a href="http://code.tupil.com/arrowlets/paddle.js">the source code.</a>.</p>
<p>Disclaimer: The code only works in Firefox and Opera. In Safari there&#8217;s no keypress event for the arrow keys, and the arrowlets library currently doesn&#8217;t support IE.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/look-ma-no-callbacks/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Formlets in Haskell</title>
		<link>http://blog.tupil.com/formlets-in-haskell/</link>
		<comments>http://blog.tupil.com/formlets-in-haskell/#comments</comments>
		<pubDate>Wed, 30 Jul 2008 13:00:44 +0000</pubDate>
		<dc:creator>Chris Eidhof</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[abstraction]]></category>
		<category><![CDATA[applicative]]></category>
		<category><![CDATA[formlets]]></category>
		<category><![CDATA[HAppS]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=25</guid>
		<description><![CDATA[One of the most low-level parts of web development is building forms. You need to code to both build forms and handle them, and manually sync that code to make sure the names match up. In this post, we will use formlets and HAppS-Server to solve those problems. Formlets are a way to compose parts [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most low-level parts of web development is building forms. You need to code to both build forms and handle them, and manually sync that code to make sure the names match up. In this post, we will use <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/formlets">formlets</a> and <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/HAppS-Server">HAppS-Server</a> to solve those problems. Formlets are a way to compose parts of a form into a complete form, without having to worry about names, types and validations.</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> <span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span>
 <span style="color: #06c; font-weight: bold;">import</span> HAppS<span style="color: #339933; font-weight: bold;">.</span>Server
 <span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Applicative
 <span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Applicative<span style="color: #339933; font-weight: bold;">.</span>Error
 <span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Applicative<span style="color: #339933; font-weight: bold;">.</span>State
 <span style="color: #06c; font-weight: bold;">import</span> Text<span style="color: #339933; font-weight: bold;">.</span>Formlets
 <span style="color: #06c; font-weight: bold;">import</span> Text<span style="color: #339933; font-weight: bold;">.</span>XHtml<span style="color: #339933; font-weight: bold;">.</span>Strict <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">+++</span><span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">&lt;&lt;</span><span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">!</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
 <span style="color: #06c; font-weight: bold;">import</span> <span style="color: #06c; font-weight: bold;">qualified</span> Text<span style="color: #339933; font-weight: bold;">.</span>XHtml<span style="color: #339933; font-weight: bold;">.</span>Strict <span style="color: #06c; font-weight: bold;">as</span> X
 <span style="color: #06c; font-weight: bold;">import</span> <span style="color: #06c; font-weight: bold;">qualified</span> Data<span style="color: #339933; font-weight: bold;">.</span>Map <span style="color: #06c; font-weight: bold;">as</span> M</pre></div></div>

<p>First of all, we are going to build a form that accepts a date (consisting of two parts: a month and a day). Our datatype reflects this:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> <span style="color: #06c; font-weight: bold;">data</span> Date <span style="color: #339933; font-weight: bold;">=</span> Date <span style="color: green;">&#123;</span>month <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Integer</span><span style="color: #339933; font-weight: bold;">,</span> day <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Integer</span><span style="color: green;">&#125;</span> <span style="color: #06c; font-weight: bold;">deriving</span> <span style="color: #cccc00; font-weight: bold;">Show</span></pre></div></div>

<p>We want to prevent the user from entering weird dates, so</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> validDate <span style="color: #339933; font-weight: bold;">::</span> Date <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">Bool</span>
 validDate <span style="color: green;">&#40;</span>Date m d<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> m `<span style="font-weight: bold;">elem</span>` <span style="color: green;">&#91;</span>1<span style="color: #339933; font-weight: bold;">..</span>12<span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">&amp;&amp;</span> d `<span style="font-weight: bold;">elem</span>` <span style="color: green;">&#91;</span>1<span style="color: #339933; font-weight: bold;">..</span>31<span style="color: green;">&#93;</span></pre></div></div>

<p>Now we are going to write a FailingForm that reads two integers, and uses them to create a real Date. Using applicative style, we can nicely express this:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> dateComponent <span style="color: #339933; font-weight: bold;">::</span> FailingForm Date
 dateComponent <span style="color: #339933; font-weight: bold;">=</span> Date <span style="color: #339933; font-weight: bold;">&lt;$&gt;</span> inputIntegerF <span style="color: green;">&#40;</span>Just <span style="color: red;">1</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">&lt;*&gt;</span> inputIntegerF <span style="color: green;">&#40;</span>Just <span style="color: red;">16</span><span style="color: green;">&#41;</span></pre></div></div>

<p>We can now combine dateComponent and validDate to create a validating Date component:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> dateFull <span style="color: #339933; font-weight: bold;">::</span> FailingForm Date
 dateFull   <span style="color: #339933; font-weight: bold;">=</span> dateComponent `check` ensure validDate <span style="">&quot;This is not a valid date&quot;</span></pre></div></div>

<p>Finally, if we use some helper functions we can create a ServerPart, which is everything HAppS needs in order to run:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> handleDate <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#91;</span>ServerPart Response<span style="color: green;">&#93;</span>
 handleDate <span style="color: #339933; font-weight: bold;">=</span> withForm <span style="">&quot;date&quot;</span> dateFull showErrorsInline <span style="color: green;">&#40;</span>\d <span style="color: #339933; font-weight: bold;">-&gt;</span> okHtml <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">show</span> d<span style="color: green;">&#41;</span></pre></div></div>

<p>This will show a form, and if you press &#8220;Submit&#8221;, it will make sure all validations pass, and show you the value. If the form doesn&#8217;t get validated, it will show a list of errors, and you can change your previously entered values.</p>
<p>To demonstrate the compositionality of formlets, we will create a User datatype, and use the date-formlet to let the user enter a birthDate:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> <span style="color: #06c; font-weight: bold;">data</span> User <span style="color: #339933; font-weight: bold;">=</span> User <span style="color: green;">&#123;</span>name <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><span style="color: #339933; font-weight: bold;">,</span> password <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><span style="color: #339933; font-weight: bold;">,</span> birthdate <span style="color: #339933; font-weight: bold;">::</span> Date<span style="color: green;">&#125;</span> <span style="color: #06c; font-weight: bold;">deriving</span> <span style="color: #cccc00; font-weight: bold;">Show</span>
&nbsp;
 userFull <span style="color: #339933; font-weight: bold;">::</span> FailingForm User
 userFull <span style="color: #339933; font-weight: bold;">=</span> User <span style="color: #339933; font-weight: bold;">&lt;$&gt;</span> inputF Nothing <span style="color: #339933; font-weight: bold;">&lt;*&gt;</span> passwordF Nothing <span style="color: #339933; font-weight: bold;">&lt;*&gt;</span> dateFull</pre></div></div>

<p>And that&#8217;s all there is to it! We now have user form that asks for a name, a password and a birthdate. We can use the withForm function again to handle the GET and POST:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> handleUser <span style="color: #339933; font-weight: bold;">=</span> withForm <span style="">&quot;user&quot;</span> userFull showErrorsInline <span style="color: green;">&#40;</span>\u <span style="color: #339933; font-weight: bold;">-&gt;</span> okHtml <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">show</span> u<span style="color: green;">&#41;</span></pre></div></div>

<p>Finally, here are all the helper functions we used:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"> withForm <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> FailingForm a <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>Html <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span>ServerPart Response<span style="color: green;">&#93;</span>
 withForm name frm handleErrors handleOk <span style="color: #339933; font-weight: bold;">=</span> 
   <span style="color: green;">&#91;</span>dir name 
      <span style="color: green;">&#91;</span> method GET           <span style="color: #339933; font-weight: bold;">$</span> okHtml <span style="color: #339933; font-weight: bold;">$</span> createForm <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> frm
      <span style="color: #339933; font-weight: bold;">,</span> withDataFn lookPairs <span style="color: #339933; font-weight: bold;">$</span> \d <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span>method POST <span style="color: #339933; font-weight: bold;">$</span> handleOk' d<span style="color: green;">&#93;</span>
      <span style="color: green;">&#93;</span>
   <span style="color: green;">&#93;</span>
   <span style="color: #06c; font-weight: bold;">where</span> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>extractor<span style="color: #339933; font-weight: bold;">,</span> html<span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> endState<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> runFormState <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> frm <span style="color: red;">0</span>
         handleOk' d <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">case</span> extractor d <span style="color: #06c; font-weight: bold;">of</span>
                         Failure faults <span style="color: #339933; font-weight: bold;">-&gt;</span> handleErrors <span style="color: green;">&#40;</span>createForm d frm<span style="color: green;">&#41;</span> faults
                         Success s      <span style="color: #339933; font-weight: bold;">-&gt;</span> handleOk s
&nbsp;
 showErrorsInline <span style="color: #339933; font-weight: bold;">::</span> X<span style="color: #339933; font-weight: bold;">.</span>Html <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response
 showErrorsInline renderedForm errors <span style="color: #339933; font-weight: bold;">=</span>
   okHtml <span style="color: #339933; font-weight: bold;">$</span> X<span style="color: #339933; font-weight: bold;">.</span>toHtml <span style="color: green;">&#40;</span><span style="font-weight: bold;">show</span> errors<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+++</span> renderedForm
&nbsp;
 createForm <span style="color: #339933; font-weight: bold;">::</span> Env <span style="color: #339933; font-weight: bold;">-&gt;</span> FailingForm a <span style="color: #339933; font-weight: bold;">-&gt;</span> X<span style="color: #339933; font-weight: bold;">.</span>Html
 createForm env frm <span style="color: #339933; font-weight: bold;">=</span>
   X<span style="color: #339933; font-weight: bold;">.</span>form <span style="color: #339933; font-weight: bold;">!</span> <span style="color: green;">&#91;</span>X<span style="color: #339933; font-weight: bold;">.</span>method <span style="">&quot;POST&quot;</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">&lt;&lt;</span> <span style="color: green;">&#40;</span>xml <span style="color: #339933; font-weight: bold;">+++</span> X<span style="color: #339933; font-weight: bold;">.</span>submit <span style="">&quot;submit&quot;</span> <span style="">&quot;Submit&quot;</span><span style="color: green;">&#41;</span>
    <span style="color: #06c; font-weight: bold;">where</span> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>extractor<span style="color: #339933; font-weight: bold;">,</span> xml<span style="color: green;">&#41;</span><span style="color: #339933; font-weight: bold;">,</span> endState<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> runFormState env frm <span style="color: red;">0</span>
&nbsp;
 okHtml <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>HTML a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> a <span style="color: #339933; font-weight: bold;">-&gt;</span> Web Response
 okHtml content <span style="color: #339933; font-weight: bold;">=</span> ok <span style="color: #339933; font-weight: bold;">$</span> toResponse <span style="color: #339933; font-weight: bold;">$</span> htmlPage <span style="color: #339933; font-weight: bold;">$</span> content
&nbsp;
 htmlPage <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>HTML a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> a <span style="color: #339933; font-weight: bold;">-&gt;</span> X<span style="color: #339933; font-weight: bold;">.</span>Html
 htmlPage content <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>header  <span style="color: #339933; font-weight: bold;">&lt;&lt;</span>  <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>thetitle <span style="color: #339933; font-weight: bold;">&lt;&lt;</span> <span style="">&quot;Testing forms&quot;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+++</span> <span style="color: green;">&#40;</span>X<span style="color: #339933; font-weight: bold;">.</span>body    <span style="color: #339933; font-weight: bold;">&lt;&lt;</span>  content<span style="color: green;">&#41;</span>
&nbsp;
 main <span style="color: #339933; font-weight: bold;">=</span> simpleHTTP <span style="color: green;">&#40;</span>nullConf <span style="color: green;">&#123;</span>port <span style="color: #339933; font-weight: bold;">=</span> <span style="color: red;">5000</span><span style="color: green;">&#125;</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>handleDate <span style="color: #339933; font-weight: bold;">++</span> handleUser<span style="color: green;">&#41;</span></pre></div></div>

<p>For the full code, see <a href='http://blog.tupil.com/wp-content/uploads/2008/07/main.lhs'>Main.lhs</a>. Make sure you have installed HAppS-Server and formlets from hackage. Enjoy!</p>
<p><b>Update</b>: There is now a wiki page on <a href="http://haskell.org/haskellwiki/Formlets">Formlets</a> which we try to keep up to date with examples that compile with the latest version. The example above only works with an old version of formlets.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/formlets-in-haskell/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Stemming with Haskell reloaded</title>
		<link>http://blog.tupil.com/stemming-with-haskell-reloaded/</link>
		<comments>http://blog.tupil.com/stemming-with-haskell-reloaded/#comments</comments>
		<pubDate>Sat, 19 Jul 2008 14:46:48 +0000</pubDate>
		<dc:creator>Eelco Lempsink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[stemmer]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=23</guid>
		<description><![CDATA[Thanks to the nice discussion with Reinier Lamers of the previous post, I&#8217;ve updated and released the stemmer library with a more Haskell-like interface. As a point of reference, here&#8217;s a new version of the example of the previous post. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to the nice discussion with Reinier Lamers of the <a href="http://blog.tupil.com/?p=22">previous post</a>, I&#8217;ve updated and <a href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/stemmer'>released</a> the stemmer library with a more Haskell-like interface. <span id="more-23"></span> As a point of reference, here&#8217;s a new version of the example of the previous post.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> NLP<span style="color: #339933; font-weight: bold;">.</span>Stemmer
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">Monad</span> <span style="color: green;">&#40;</span>unless<span style="color: green;">&#41;</span>
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span>hSetBuffering<span style="color: #339933; font-weight: bold;">,</span> stdout<span style="color: #339933; font-weight: bold;">,</span> BufferMode<span style="color: green;">&#40;</span>NoBuffering<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
main <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    <span style="font-weight: bold;">putStrLn</span> <span style="">&quot;Enter a sentence to stem, an empty line to stop.&quot;</span>
    hSetBuffering stdout NoBuffering <span style="color: #5d478b; font-style: italic;">-- to print a prompt</span>
    stemUserInput
&nbsp;
stemUserInput <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
stemUserInput <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    <span style="font-weight: bold;">putStr</span> <span style="">&quot;&gt; &quot;</span>
    string <span style="color: #339933; font-weight: bold;">&lt;-</span> <span style="font-weight: bold;">getLine</span>
    unless <span style="color: green;">&#40;</span>string <span style="color: #339933; font-weight: bold;">==</span> <span style="">&quot;&quot;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span> 
        <span style="font-weight: bold;">putStrLn</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">++</span><span style="color: green;">&#41;</span> <span style="">&quot;&lt; &quot;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">unwords</span> <span style="color: #339933; font-weight: bold;">$</span> 
                               stemWords English <span style="color: #339933; font-weight: bold;">$</span> 
                               <span style="font-weight: bold;">words</span> string
        stemUserInput</pre></td></tr></table></div>

<p>You see?  Much nicer, no more C-like pointer adminstration cruft that you wouldn&#8217;t expect in Haskell, just a simple (pure) function &#8216;stemWords&#8217; (line 17) which, given an algorithm, stems a list of strings.  (I suppose a next version of the library should have an implementation for bytestrings as well.)</p>
<p>As the attentive reader might have noticed, the example above is not semantically equal to the previous one, since there is no sign the stemmer is constructed only once and deleted at the very end. To explain the implementation of the library, I&#8217;d like to show how you can still use the more C-like interface, minus the tedious pointer administration.</p>
<p>Let me introduce <code>withStemmer</code>, inspired by <a href='http://www.haskell.org/pipermail/glasgow-haskell-users/2002-July/003681.html'>withHMatrix</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">withStemmer <span style="color: #339933; font-weight: bold;">::</span> Algorithm <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>Stemmer <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> a
withStemmer algorithm action <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    stemmer <span style="color: #339933; font-weight: bold;">&lt;-</span> new algorithm
    result  <span style="color: #339933; font-weight: bold;">&lt;-</span> action stemmer
    delete stemmer
    <span style="font-weight: bold;">return</span> result</pre></div></div>

<p>Using <code>withStemmer</code> I can now repeat the example above, but with the semantics of the example of the <a href="http://blog.tupil.com/?p=22">previous post</a>.  (For a quick scan: only line 1, 9, 16 and 17 changed.)</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> NLP<span style="color: #339933; font-weight: bold;">.</span>Stemmer<span style="color: #339933; font-weight: bold;">.</span>C
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">Monad</span> <span style="color: green;">&#40;</span>unless<span style="color: green;">&#41;</span>
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span>hSetBuffering<span style="color: #339933; font-weight: bold;">,</span> stdout<span style="color: #339933; font-weight: bold;">,</span> BufferMode<span style="color: green;">&#40;</span>NoBuffering<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
main <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    <span style="font-weight: bold;">putStrLn</span> <span style="">&quot;Enter a sentence to stem, an empty line to stop.&quot;</span>
    hSetBuffering stdout NoBuffering <span style="color: #5d478b; font-style: italic;">-- to print a prompt</span>
    withStemmer English stemUserInput
&nbsp;
stemUserInput <span style="color: #339933; font-weight: bold;">::</span> Stemmer <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
stemUserInput stemmer <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    <span style="font-weight: bold;">putStr</span> <span style="">&quot;&gt; &quot;</span>
    string <span style="color: #339933; font-weight: bold;">&lt;-</span> <span style="font-weight: bold;">getLine</span>
    unless <span style="color: green;">&#40;</span>string <span style="color: #339933; font-weight: bold;">==</span> <span style="">&quot;&quot;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span>
        string' <span style="color: #339933; font-weight: bold;">&lt;-</span> <span style="font-weight: bold;">mapM</span> <span style="color: green;">&#40;</span>stem stemmer<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">words</span> string
        <span style="font-weight: bold;">putStrLn</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">++</span><span style="color: green;">&#41;</span> <span style="">&quot;&lt; &quot;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">unwords</span> string'
        stemUserInput stemmer</pre></td></tr></table></div>

<p>Notice that I&#8217;m using <code>NLP.Stemmer.C</code> (line 1) and that the stemming now must be done inside the IO monad (line 16).  In practice this is probably a mere inconvenience, but a pure Haskell interface is of course much nicer&#8230; Introducing to the stage <code>unsafePerformIO</code> (organ sounds: dum, dum, duuum).</p>
<p>I&#8217;ve defined a nice &#8216;unsafe&#8217; version of withStemmer as a helper:</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #5d478b; font-style: italic;">{-# NOINLINE withStemmer #-}</span>
withStemmer <span style="color: #339933; font-weight: bold;">::</span> Algorithm <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>C<span style="color: #339933; font-weight: bold;">.</span>Stemmer <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> a
withStemmer algorithm action <span style="color: #339933; font-weight: bold;">=</span> unsafePerformIO <span style="color: #339933; font-weight: bold;">$</span> 
    C<span style="color: #339933; font-weight: bold;">.</span>withStemmer algorithm action</pre></div></div>

<p>And now I can easily define two very nice functions</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">stem <span style="color: #339933; font-weight: bold;">::</span> Algorithm <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">String</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">String</span>
stem algorithm input <span style="color: #339933; font-weight: bold;">=</span> 
    withStemmer algorithm <span style="color: green;">&#40;</span>\stemmer <span style="color: #339933; font-weight: bold;">-&gt;</span> C<span style="color: #339933; font-weight: bold;">.</span>stem stemmer input<span style="color: green;">&#41;</span>
&nbsp;
stemWords <span style="color: #339933; font-weight: bold;">::</span> Algorithm <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span><span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#93;</span>
stemWords algorithm input <span style="color: #339933; font-weight: bold;">=</span> 
    withStemmer algorithm <span style="color: green;">&#40;</span>\stemmer <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="font-weight: bold;">mapM</span> <span style="color: green;">&#40;</span>C<span style="color: #339933; font-weight: bold;">.</span>stem stemmer<span style="color: green;">&#41;</span> input<span style="color: green;">&#41;</span></pre></div></div>

<p><code>stemWords</code> is there for efficiency reasons, since I suppose stemming a list of words is a common action. It&#8217;s much nicer (and a bit faster) to &#8216;keep the stemmer alive&#8217; and use a <code>mapM</code> internally, than letting the user do <code>map stem ...</code>.</p>
<p>So, <code>unsafePerformIO</code>, eh? It took me a couple of tries to get to this interface, but I think it turned out pretty okay.  Word of advice, make sure that you read the <a href='http://www.haskell.org/haskellwiki/GHC:FAQ#When_is_it_safe_to_use_unsafe_functions_such_as_unsafePerformIO.3F'>tips</a> and <a href='http://haskell.org/ghc/docs/latest/html/libraries/base/System-IO-Unsafe.html#v%3AunsafePerformIO'>docs</a> carefully.  Also, don&#8217;t mix multiple unsafePerformIO calls, that was at least a sure recipe for segfaults in my case ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/stemming-with-haskell-reloaded/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Stemming with Haskell</title>
		<link>http://blog.tupil.com/stemming-with-haskell/</link>
		<comments>http://blog.tupil.com/stemming-with-haskell/#comments</comments>
		<pubDate>Mon, 14 Jul 2008 14:55:41 +0000</pubDate>
		<dc:creator>Eelco Lempsink</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[Snowball]]></category>
		<category><![CDATA[stemmer]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=22</guid>
		<description><![CDATA[Last week we worked on building a small search engine with Haskell. As you might know, when searching you&#8217;ll need some index you&#8217;ll search and possibly stemming to allow people to search for variants of a word and still come up with accurate results. Fortunately for us, there are already good libraries and tools out [...]]]></description>
			<content:encoded><![CDATA[<p>Last week we worked on building a small search engine with Haskell. As you might know, when searching you&#8217;ll need some <em>index</em> you&#8217;ll search and possibly <a href='http://en.wikipedia.org/wiki/Stemming'>stemming</a> to allow people to search for variants of a word and still come up with accurate results.</p>
<p>Fortunately for us, there are already good libraries and tools out there to help us. So instead of trying to write everything from scratch, we made a small library based on <a href='http://snowball.tartarus.org/'>Snowball&#8217;s libstemmer_c</a> and a very (very!) rough start of a <a href='http://www.sphinxsearch.com/'>Sphinx</a> client (more about that in a later post).</p>
<p>We&#8217;ve released the library on <a href='http://hackage.haskell.org/'>Hackage</a> so check out <a href='http://hackage.haskell.org/cgi-bin/hackage-scripts/package/stemmer'>stemmer 0.1</a></p>
<p>A small code example to give you a taste&#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">import</span> <span style="color: #06c; font-weight: bold;">qualified</span> NLP<span style="color: #339933; font-weight: bold;">.</span>Stemmer <span style="color: #06c; font-weight: bold;">as</span> Stemming
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">Monad</span> <span style="color: green;">&#40;</span>unless<span style="color: green;">&#41;</span>
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span>hSetBuffering<span style="color: #339933; font-weight: bold;">,</span> stdout<span style="color: #339933; font-weight: bold;">,</span> BufferMode<span style="color: green;">&#40;</span>NoBuffering<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span>
&nbsp;
main <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    stemmer <span style="color: #339933; font-weight: bold;">&lt;-</span> Stemming<span style="color: #339933; font-weight: bold;">.</span>new Stemming<span style="color: #339933; font-weight: bold;">.</span>English
    <span style="font-weight: bold;">putStrLn</span> <span style="">&quot;Enter a sentence to stem, an empty line to stop.&quot;</span>
    hSetBuffering stdout NoBuffering <span style="color: #5d478b; font-style: italic;">-- to print a prompt</span>
    stemUserInput stemmer
    Stemming<span style="color: #339933; font-weight: bold;">.</span>delete stemmer
&nbsp;
stemUserInput <span style="color: #339933; font-weight: bold;">::</span> Stemming<span style="color: #339933; font-weight: bold;">.</span>Stemmer <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span>
stemUserInput stemmer <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
    <span style="font-weight: bold;">putStr</span> <span style="">&quot;&gt; &quot;</span>
    string <span style="color: #339933; font-weight: bold;">&lt;-</span> <span style="font-weight: bold;">getLine</span>
    unless <span style="color: green;">&#40;</span>string <span style="color: #339933; font-weight: bold;">==</span> <span style="">&quot;&quot;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span> 
        string' <span style="color: #339933; font-weight: bold;">&lt;-</span> <span style="font-weight: bold;">mapM</span> <span style="color: green;">&#40;</span>Stemming<span style="color: #339933; font-weight: bold;">.</span>stem stemmer<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="font-weight: bold;">words</span> string
        <span style="font-weight: bold;">putStrLn</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="">&quot;&lt; &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> <span style="font-weight: bold;">unwords</span> string'
        stemUserInput stemmer</pre></div></div>

<p>Save this to Main.hs and then do something like<br />
<code><br />
$ ghc --make Main.hs -o stemmer<br />
[1 of 1] Compiling Main             ( Main.hs, Main.o )<br />
Linking stemmer ...<br />
$ ./stemmer<br />
Enter a sentence to stem, an empty line to stop.<br />
> The fishes worked forever with their fins<br />
< The fish work forev with their fin<br />
> Stemming with Haskell<br />
< Stem with Haskel<br />
</code></p>
<p>It was pretty easy to implement this library and also a nice exercise in using <a href='http://www.cse.unsw.edu.au/~chak/haskell/ffi/'>Haskell's Foreign Function Interface</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/stemming-with-haskell/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>A small mashup of Upcoming and Last.fm, in Haskell</title>
		<link>http://blog.tupil.com/a-small-mashup-of-upcoming-and-lastfm-in-haskell/</link>
		<comments>http://blog.tupil.com/a-small-mashup-of-upcoming-and-lastfm-in-haskell/#comments</comments>
		<pubDate>Mon, 02 Jun 2008 12:06:56 +0000</pubDate>
		<dc:creator>Chris Eidhof</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[lastfm]]></category>
		<category><![CDATA[mashup]]></category>
		<category><![CDATA[upcoming]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=5</guid>
		<description><![CDATA[I wanted to play around with the recent XML and Curl libraries that were recently released by Galois, so I decided to write a mashup of Upcoming and Last.fm. In order for this code to run, you&#8217;ll also need to install the csv package for this. The code is relatively straightforward: fetch the top artists [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to play around with the recent <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/xml">XML</a> and <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/curl">Curl</a> libraries that were recently released by <a href="http://galois.com/">Galois</a>, so I decided to write a mashup of <a href="http://upcoming.yahoo.com">Upcoming</a> and <a href="http://last.fm">Last.fm</a>. In order for this code to run, you&#8217;ll also need to install the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/csv">csv</a> package for this.</p>
<p>The code is relatively straightforward: fetch the top artists for a given username, parse that csv-file, read the events in The Netherlands for every artist, and output every event. It works on the command line. Save this code as Upcoming.hs, then do <code>runhaskell Upcoming.hs chrisflip</code>, and replace <code>chrisflip</code> by your own last.fm username. </p>
<p>Enjoy!</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">module</span> Main <span style="color: #06c; font-weight: bold;">where</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>Curl
<span style="color: #06c; font-weight: bold;">import</span> Text<span style="color: #339933; font-weight: bold;">.</span>CSV
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>CGI <span style="color: green;">&#40;</span>urlEncode<span style="color: green;">&#41;</span>
<span style="color: #06c; font-weight: bold;">import</span> Text<span style="color: #339933; font-weight: bold;">.</span>XML<span style="color: #339933; font-weight: bold;">.</span>Light
<span style="color: #06c; font-weight: bold;">import</span> Data<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">Maybe</span> <span style="color: green;">&#40;</span>fromMaybe<span style="color: #339933; font-weight: bold;">,</span> fromJust<span style="color: green;">&#41;</span>
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><span style="color: #cccc00; font-weight: bold;">Monad</span>
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span>Environment <span style="color: green;">&#40;</span>getArgs<span style="color: green;">&#41;</span>
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- The top artists of last.fm</span>
url u <span style="color: #339933; font-weight: bold;">=</span> <span style="">&quot;http://ws.audioscrobbler.com/1.0/user/&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> u <span style="color: #339933; font-weight: bold;">++</span> <span style="">&quot;/topartists.txt&quot;</span>
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Upcomings's country_id for The Netherlands </span>
country<span style="color: #339933; font-weight: bold;">_</span>id <span style="color: #339933; font-weight: bold;">=</span> <span style="">&quot;9&quot;</span>
upcoming<span style="color: #339933; font-weight: bold;">_</span>url artist <span style="color: #339933; font-weight: bold;">=</span>  <span style="">&quot;http://upcoming.yahooapis.com/services/rest/?api_key=&quot;</span> 
                    <span style="color: #339933; font-weight: bold;">++</span> apikey <span style="color: #339933; font-weight: bold;">++</span> <span style="">&quot;&amp;method=event.search&amp;search_text=&quot;</span> 
                    <span style="color: #339933; font-weight: bold;">++</span> urlEncode artist <span style="color: #339933; font-weight: bold;">++</span> <span style="">&quot;&amp;country_id=&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> country<span style="color: #339933; font-weight: bold;">_</span>id
apikey <span style="color: #339933; font-weight: bold;">=</span> <span style="">&quot;ee395ae6dd&quot;</span>
&nbsp;
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
  <span style="color: green;">&#91;</span>username<span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs
  text <span style="color: #339933; font-weight: bold;">&lt;-</span> unsafeCurlGetString <span style="color: green;">&#40;</span>url username<span style="color: green;">&#41;</span>
  <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>Right a'<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> parseCSV <span style="color: green;">&#40;</span>url username<span style="color: green;">&#41;</span> text
      artists <span style="color: #339933; font-weight: bold;">=</span> getArtists a'
  <span style="font-weight: bold;">mapM_</span> getEvents artists
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- The artist is always in the 3rd column of the csv-file</span>
getArtists <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">map</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">2</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">filter</span> <span style="color: green;">&#40;</span>\x <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="font-weight: bold;">length</span> x <span style="color: #339933; font-weight: bold;">==</span> <span style="color: red;">3</span><span style="color: green;">&#41;</span>
&nbsp;
getEvents artist <span style="color: #339933; font-weight: bold;">=</span> unsafeCurlGetString <span style="color: green;">&#40;</span>upcoming<span style="color: #339933; font-weight: bold;">_</span>url artist<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> processArtist artist
&nbsp;
processArtist artist contents <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span>
  <span style="color: #06c; font-weight: bold;">let</span> eventEls <span style="color: #339933; font-weight: bold;">=</span> elChildren <span style="color: #339933; font-weight: bold;">$</span> fromJust <span style="color: #339933; font-weight: bold;">$</span> parseXMLDoc contents
  when <span style="color: green;">&#40;</span><span style="font-weight: bold;">length</span> eventEls <span style="color: #339933; font-weight: bold;">&gt;</span> <span style="color: red;">0</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span>
    <span style="font-weight: bold;">putStrLn</span> artist
    <span style="font-weight: bold;">putStrLn</span> <span style="color: green;">&#40;</span>replicate <span style="color: green;">&#40;</span><span style="font-weight: bold;">length</span> artist<span style="color: green;">&#41;</span> '<span style="color: #339933; font-weight: bold;">-</span>'<span style="color: green;">&#41;</span>
    <span style="font-weight: bold;">mapM_</span> processEvent eventEls
    <span style="font-weight: bold;">putStrLn</span> <span style="">&quot;&quot;</span>
&nbsp;
processEvent evt <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">putStrLn</span> <span style="color: #339933; font-weight: bold;">$</span> title <span style="color: #339933; font-weight: bold;">++</span> <span style="">&quot; @ &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> location <span style="color: #339933; font-weight: bold;">++</span> <span style="">&quot; [&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> date <span style="color: #339933; font-weight: bold;">++</span> <span style="">&quot;]&quot;</span>
 <span style="color: #06c; font-weight: bold;">where</span> <span style="color: green;">&#91;</span>title<span style="color: #339933; font-weight: bold;">,</span> location<span style="color: #339933; font-weight: bold;">,</span> date<span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="font-weight: bold;">map</span> fa <span style="color: green;">&#91;</span><span style="">&quot;name&quot;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="">&quot;venue_name&quot;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="">&quot;start_date&quot;</span><span style="color: green;">&#93;</span>
       fa n <span style="color: #339933; font-weight: bold;">=</span> fromJust <span style="color: #339933; font-weight: bold;">$</span> findAttr <span style="color: green;">&#40;</span>unqual n<span style="color: green;">&#41;</span> evt
&nbsp;
unsafeCurlGetString url <span style="color: #339933; font-weight: bold;">=</span> curlGetString url <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> <span style="font-weight: bold;">return</span> <span style="color: #339933; font-weight: bold;">.</span> <span style="font-weight: bold;">snd</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/a-small-mashup-of-upcoming-and-lastfm-in-haskell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
