<?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"
	>

<channel>
	<title>Tupil Code Blog</title>
	<atom:link href="http://blog.tupil.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.tupil.com</link>
	<description>(Get up early, code often)</description>
	<pubDate>Thu, 23 Oct 2008 14:16:38 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<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>
		</item>
		<item>
		<title>Grid Computing using Javascript</title>
		<link>http://blog.tupil.com/grid-computing-using-javascript/</link>
		<comments>http://blog.tupil.com/grid-computing-using-javascript/#comments</comments>
		<pubDate>Tue, 02 Sep 2008 17:20:51 +0000</pubDate>
		<dc:creator>Chris Eidhof</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[cloud computing]]></category>

		<category><![CDATA[grid computing]]></category>

		<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=36</guid>
		<description><![CDATA[I recently had an idea that&#8217;s both really interesting and a bit disturbing.  Authors of websites could use clients&#8217; computers as a massive grid computer. If you have a problem that you can solve by using map-reduce, you could do the map step in the client&#8217;s web-browser, and let them send back the result. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently had an idea that&#8217;s both really interesting and a bit disturbing.  Authors of websites could use clients&#8217; computers as a massive grid computer. If you have a problem that you can solve by using map-reduce, you could do the map step in the client&#8217;s web-browser, and let them send back the result. Most clients would never know you&#8217;re doing this, and by only using a couple of seconds from their processor time, they also wouldn&#8217;t notice.</p>
<p>The problems that you can solve this way have some interesting properties: you must never send any private data to the clients and typically the solution should be expensive to find, but easy to verify.</p>
<p>I&#8217;m curious what kind of cool appliciations we can build using this technology.  If a major site like Facebook would include a tiny bit of javascript that takes 5 seconds of your processor time to help <a href="http://en.wikipedia.org/wiki/FightAIDS@Home">fight AIDS</a>, it would probably be a tremendous help.  </p>
<p>I would be very interested in your thoughts on this matter. Are there more problems that we could solve this way? I&#8217;m mainly interested in the technical implications, but there are lots of non-technical issues as well. For example: would you need the client&#8217;s permission to do this?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/grid-computing-using-javascript/feed/</wfw:commentRss>
		</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 small [...]]]></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">  ElementA<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #006600;">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: #006600;">next</span><span style="color: #009900;">&#40;</span>movePaddle<span style="color: #009900;">&#41;</span>
                    .<span style="color: #006600;">next</span><span style="color: #009900;">&#40;</span>Repeat<span style="color: #009900;">&#41;</span>.<span style="color: #006600;">repeat</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
                    .<span style="color: #006600;">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"><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: #006600;">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: #CC0000;">-4</span> <span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>event.<span style="color: #006600;">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: #006600;">style</span>.<span style="color: #006600;">left</span> <span style="color: #339933;">=</span> Math.<span style="color: #006600;">max</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> Math.<span style="color: #006600;">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">  ElementA<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'start'</span><span style="color: #009900;">&#41;</span>.<span style="color: #006600;">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: #006600;">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: #006600;">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"><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: #006600;">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">                   .<span style="color: #006600;">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: #006600;">next</span><span style="color: #009900;">&#40;</span>resetBall<span style="color: #009900;">&#41;</span>
                   .<span style="color: #006600;">next</span><span style="color: #009900;">&#40;</span>moveBall.<span style="color: #006600;">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"><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: #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: #006600;">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: #006600;">style</span>.<span style="color: #006600;">left</span> <span style="color: #339933;">=</span> startPos<span style="color: #339933;">;</span> ball.<span style="color: #006600;">style</span>.<span style="color: #006600;">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"><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: #006600;">style</span>.<span style="color: #006600;">left</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> dir.<span style="color: #006600;">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: #006600;">style</span>.<span style="color: #006600;">top</span><span style="color: #009900;">&#41;</span>  <span style="color: #339933;">+</span> dir.<span style="color: #006600;">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: #006600;">x</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">-</span> dir.<span style="color: #006600;">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: #006600;">y</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">-</span> dir.<span style="color: #006600;">y</span><span style="color: #339933;">;</span>
  ball.<span style="color: #006600;">style</span>.<span style="color: #006600;">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: #006600;">style</span>.<span style="color: #006600;">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: #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: #006600;">y</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">-</span> dir.<span style="color: #006600;">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">                   .<span style="color: #006600;">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: #006600;">next</span><span style="color: #009900;">&#40;</span>gameOver<span style="color: #009900;">&#41;</span>
                   .<span style="color: #006600;">next</span><span style="color: #009900;">&#40;</span>Repeat<span style="color: #009900;">&#41;</span>.<span style="color: #006600;">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>
		</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"> <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"> <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"> 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><span style="color: red;">1</span><span style="color: #339933; font-weight: bold;">..</span><span style="color: red;">12</span><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><span style="color: red;">1</span><span style="color: #339933; font-weight: bold;">..</span><span style="color: red;">31</span><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"> 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"> 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"> 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"> <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"> 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"> 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>
		</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
16
17
18
19
import NLP.Stemmer
import Control.Monad &#40;unless&#41;
import System.IO &#40;hSetBuffering, stdout, BufferMode&#40;NoBuffering&#41;&#41;
&#160;
main :: IO &#40;&#41;
main = do
   [...]]]></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"><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 &#8217;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">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"><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"><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">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>
		</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 there [...]]]></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"><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 &#8230;<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&#8217;s Foreign Function Interface</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/stemming-with-haskell/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Add attachments to Mail.app from the command line</title>
		<link>http://blog.tupil.com/add-attachments-to-mailapp-from-the-command-line/</link>
		<comments>http://blog.tupil.com/add-attachments-to-mailapp-from-the-command-line/#comments</comments>
		<pubDate>Sat, 07 Jun 2008 07:20:19 +0000</pubDate>
		<dc:creator>Eelco Lempsink</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[AppleScript]]></category>

		<category><![CDATA[mailfile]]></category>

		<category><![CDATA[OS X]]></category>

		<guid isPermaLink="false">http://blog.tupil.com/?p=14</guid>
		<description><![CDATA[If you spend a large part of your day in the console, like we do, you&#8217;d like to have all sorts of nifty tools to be able to direct your complete OS from there. Fortunately, we&#8217;re on OS X and AppleScript makes this pretty easy. Despite its somewhat unruly looking syntax, which (quite succesfully) tries [...]]]></description>
			<content:encoded><![CDATA[<p>If you spend a large part of your day in the console, like we do, you&#8217;d like to have all sorts of nifty tools to be able to direct your complete OS from there. Fortunately, we&#8217;re on OS X and <a href="http://developer.apple.com/documentation/ScriptingAutomation/AppleScript-date.html">AppleScript</a> makes this pretty easy. Despite its somewhat unruly looking syntax, which (quite succesfully) tries to be as close to normal English as possible, I still like to toy around with it once in a while.</p>
<p>The &#8216;toy&#8217; I&#8217;ve written today however is pretty useful. It lets you attach files to an email from the console.  Instead of having to reach for the mouse and navigate to the folder you&#8217;re already in, you can just do <code>mailfile checkthis.tar.gz</code>.  If you already started on an email the file will be attached to the draft, else it will open up a new compose window and you&#8217;re good to go!</p>

<div class="wp_syntax"><div class="code"><pre class="applescript">#!<span style="color: #66cc66;">/</span>usr<span style="color: #66cc66;">/</span>bin<span style="color: #66cc66;">/</span>osascript
&nbsp;
<span style="color: #b1b100;">on</span> <span style="color: #000066;">run</span> argv
  <span style="color: #b1b100;">if</span> argv <span style="color: #b1b100;">is</span> <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span> <span style="color: #b1b100;">then</span>
    <span style="color: #b1b100;">return</span> <span style="color: #ff0000;">&quot;Pass at least one filename as an argument!&quot;</span>
  <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">if</span>
&nbsp;
  <span style="color: #b1b100;">set</span> pwd <span style="color: #b1b100;">to</span> system attribute <span style="color: #ff0000;">&quot;PWD&quot;</span>
&nbsp;
  <span style="color: #b1b100;">tell</span> application <span style="color: #ff0000;">&quot;Mail&quot;</span>
    <span style="color: #b1b100;">try</span>
      <span style="color: #b1b100;">set</span> composeMessage <span style="color: #b1b100;">to</span> <span style="color: #000000; font-weight: bold;">first</span> outgoing messages <span style="color: #000000; font-weight: bold;">where</span> visible <span style="color: #b1b100;">is</span> <span style="color: #000066;">equal</span> <span style="color: #b1b100;">to</span> <span style="color: #000066;">true</span>
    <span style="color: #b1b100;">on</span> <span style="color: #b1b100;">error</span>
      <span style="color: #b1b100;">set</span> composeMessage <span style="color: #b1b100;">to</span> <span style="color: #000066;">make</span> new outgoing message at <span style="color: #000000; font-weight: bold;">beginning</span> <span style="color: #b1b100;">with</span> properties <span style="color: #66cc66;">&#123;</span>visible:<span style="color: #000066;">true</span><span style="color: #66cc66;">&#125;</span>
    <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">try</span>
&nbsp;
    <span style="color: #b1b100;">tell</span> composeMessage
      <span style="color: #b1b100;">repeat</span> <span style="color: #b1b100;">with</span> fileName <span style="color: #b1b100;">in</span> argv
        <span style="color: #b1b100;">if</span> <span style="color: #000066;">not</span> fileName starts <span style="color: #b1b100;">with</span> <span style="color: #ff0000;">&quot;/&quot;</span> <span style="color: #b1b100;">then</span>
          <span style="color: #b1b100;">set</span> fileName <span style="color: #b1b100;">to</span> pwd <span style="color: #66cc66;">&amp;</span> <span style="color: #ff0000;">&quot;/&quot;</span> <span style="color: #66cc66;">&amp;</span> fileName
        <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">if</span>
        <span style="color: #b1b100;">tell</span> content
          <span style="color: #000066;">make</span> new attachment <span style="color: #b1b100;">with</span> properties <span style="color: #66cc66;">&#123;</span>file name: fileName<span style="color: #66cc66;">&#125;</span> at <span style="color: #000000; font-weight: bold;">after</span> <span style="color: #000000; font-weight: bold;">the</span> <span style="color: #000000; font-weight: bold;">last</span> paragraph
        <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">tell</span>
      <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">repeat</span>
    <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">tell</span>
&nbsp;
    activate
&nbsp;
  <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">tell</span>
<span style="color: #b1b100;">end</span> <span style="color: #000066;">run</span></pre></div></div>

<p>Place this code for in <code>/usr/local/bin/mailfile</code> (or some other &#8216;bin&#8217; dir that&#8217;s in your path), and make it executable. You can also <a href='http://github.com/eelco/mailfile/tree/master%2Fmailfile?raw=true'>download it</a> from github.</p>
<p>I think the code is pretty readable.  You might notice that attachments are just added to the content of the email, there is no concept of attachments outside of the content. You might also notice how I totally inappropriately abuse the exception catching mechanism for something I could have tested before. In my defense I&#8217;d like to say this is just a simple script and it uses less code this way ;)</p>
<p>Something that took me a while to figure out was how to get the current working directory, which I needed because else it could only handle full paths.  Turns out the script needs a bit of help from the environment variables or &#8217;system attributes&#8217; as they are called in AppleScript.</p>
<p>My first try was to find the directory the script itself is in, which is not the way to go when you want to put it somewhere central. But because there is a lot of bad/old information on how to do that online, I&#8217;d still like to share the following code snippet</p>

<div class="wp_syntax"><div class="code"><pre class="applescript">  <span style="color: #b1b100;">tell</span> application <span style="color: #ff0000;">&quot;System Events&quot;</span>
    <span style="color: #b1b100;">set</span> pwd <span style="color: #b1b100;">to</span> POSIX path <span style="color: #b1b100;">of</span> container <span style="color: #b1b100;">of</span> <span style="color: #66cc66;">&#40;</span>path <span style="color: #b1b100;">to</span> <span style="color: #000066;">me</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">end</span> <span style="color: #b1b100;">tell</span></pre></div></div>

<p>Note that I&#8217;m using &#8220;System Events&#8221; here and not the Finder.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.tupil.com/add-attachments-to-mailapp-from-the-command-line/feed/</wfw:commentRss>
		</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 for [...]]]></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"><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>
		</item>
	</channel>
</rss>
