<?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>Martijn&#039;s Journal</title>
	<atom:link href="http://martijn.van.steenbergen.nl/journal/feed/" rel="self" type="application/rss+xml" />
	<link>http://martijn.van.steenbergen.nl/journal</link>
	<description>Just another WordPress site</description>
	<lastBuildDate>Sun, 08 May 2011 21:11:52 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.1</generator>
		<item>
		<title>Introducing JsonGrammar</title>
		<link>http://martijn.van.steenbergen.nl/journal/2011/05/08/introducing-jsongrammar/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2011/05/08/introducing-jsongrammar/#comments</comments>
		<pubDate>Sun, 08 May 2011 21:11:52 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=540</guid>
		<description><![CDATA[The first version of JsonGrammar has just been released on Hackage! JsonGrammar offers an API for converting between your own datatypes and JSON ASTs. &#8220;What, another JSON library? Don&#8217;t we have enough already?&#8221; It&#8217;s true that there are already a few JSON libraries out there. These libraries, however, require you to write fromJson and toJson [...]]]></description>
			<content:encoded><![CDATA[<p>The first version of JsonGrammar <a href="http://hackage.haskell.org/package/JsonGrammar">has just been released on Hackage</a>! JsonGrammar offers an API for converting between your own datatypes and <a href="http://en.wikipedia.org/wiki/JSON">JSON</a> ASTs.</p>
<p><em>&#8220;What, another JSON library? Don&#8217;t we have enough already?&#8221;</em></p>
<p>It&#8217;s true that there are already a few JSON libraries out there. These libraries, however, require you to write <code>fromJson</code> and <code>toJson</code> separately.</p>
<p><em>&#8220;Uhm, yes&#8230; is that bad?&#8221;</em></p>
<p>Yes. It violates the <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY principle</a>. If I show you an implementation of <code>fromJson</code> for a certain type, you can write a corresponding <code>toJson</code> without requiring any further information. Similarly, if I show you an implementation of <code>toJson</code>, you can write the accompanying <code>fromJson</code>. Writing down the same thing twice is tedious and opens up the possibility to make mistakes.</p>
<p><em>&#8220;But most of these libraries offer Template Haskell support that does this work for you!&#8221;</em></p>
<p>This is true, but they also make all the choices for you about how your datatypes should map to JSON. Usually they assume the names of your record fields map directly to JSON property names. The shapes of your family of datatypes need to correspond to how the objects in JSON are nested. These libraries give you the choice: either you write out <code>fromJson</code> and <code>toJson</code> by hand and have full control over the mapping, or you give up this control and let Template Haskell do all the work for you.</p>
<p>JsonGrammar gives you the best of both worlds: it gives you full control over what the mapping should be, with an API that lets you define <code>fromJson</code> and <code>toJson</code> at the same time. It achieves this by separating the constructing/destructing of datatype constructors and its fields from the description of the JSON values. The former is derived by Template Haskell, the latter is provided by the programmer.</p>
<h2>An example</h2>
<p>Suppose we have these two datatypes describing people and their current location:</p>
<pre><code>data Person = Person
  { name   :: String
  , gender :: Gender
  , age    :: Int
  , lat    :: Float
  , lng    :: Float
  }

data Gender = Male | Female
</code></pre>
<p>Sadly, the JSON source we are communicating with is using JSON with Dutch property names and values, so we cannot use Template Haskell to derive the JSON mapping for us, like we would do with other JSON libraries. Neither do we want to use Dutch names for our record selectors; nobody would be able to understand our code anymore! Fortunately this isn&#8217;t a problem with JsonGrammar.</p>
<p>The first step is to have Template Haskell derive the constructor-destructor pairs:</p>
<pre><code>person         = $(deriveIsos ''Person)
(male, female) = $(deriveIsos ''Gender)
</code></pre>
<p>For the latter to work, you need to enable <code>-XNoMonoPatBinds</code>.</p>
<p>Then we write instances of the <code>Json</code> type class to define the mapping from/to Json. The order in which the properties are listed matches that of the fields in the datatype:</p>
<pre>
instance Json Person where
  grammar = person . object
    ( prop "naam"
    . prop "geslacht"
    . prop "leeftijd"
    . prop "lat"
    . prop "lng"
    )

instance Json Gender where
  grammar =  male   . litJson "man"
          &lt;&gt; female . litJson "vrouw"
</pre>
<p>The <code>.</code> operator is from <code>Control.Category</code>. The <code>&lt;&gt;</code> is just another name for <code>mappend</code> from <code>Data.Monoid</code> and denotes choice.</p>
<p>That&#8217;s all! We have just defined both <code>fromJson</code> and <code>toJson</code> in one simple definition. Here&#8217;s how you can use these grammars:</p>
<pre><code>ghci&gt; let anna = Person "Anna" Female 36 53.0163038 5.1993053

ghci&gt; let Just annaJson = toJson anna

ghci&gt; annaJson
Object (fromList [("geslacht",String "vrouw"),("lat",Number
53.01630401611328),("leeftijd",Number 36),("lng",Number
5.199305534362793),("naam",String "Anna")])

ghci&gt; fromJson annaJson :: Maybe Person
Just (Person {name = "Anna", gender = Female, age = 36, lat = 53.016304,
lng = 5.1993055})
</code></pre>
<h2>Show me the types!</h2>
<p>The library is based on <em>partial isomorphisms</em>:</p>
<pre><code>data Iso a b = Iso (a -&gt; Maybe b) (b -&gt; Maybe a)

instance Category Iso
instance Monoid (Iso a b)
</code></pre>
<p>A value of type <code>Iso a b</code> gives you a function that converts an <code>a</code> into a <code>Maybe b</code>, and a function that converts a <code>b</code> into a <code>Maybe a</code>. This composes beautifully as a <code>Category</code>. The <code>Monoid</code> instance denotes choice: first try the left-hand conversion function, and if it fails, try the right-hand side.</p>
<p>A JSON <code>grammar</code> for some type <code>a</code> is nothing more than a value of type <code>Iso Value a</code>, where <code>Value</code> is the type of a JSON AST from the <a href="http://hackage.haskell.org/package/aeson">aeson</a> package. That is, it&#8217;s a pair of conversion functions between JSON trees and your own datatype. Building JSON grammars like the one above is about composing isomorphisms that translate between intermediate types.</p>
<p>The isomorphisms <code>person</code>, <code>male</code> and <code>female</code> translate between constructors and their individual fields. For example:</p>
<pre><code>person :: Iso (String, Gender, Int, Float, Float) Person</code></pre>
<p>Converting from a constructor to its fields might fail, because the value that is passed to the conversion function might be a different constructor of the same datatype. This is why the <code>Monoid</code> instance is so useful: we can give multiple grammars, usually one for each constructor, and they will be tried in sequence. They are effectively <em>composable pattern matches</em>.</p>
<h2>Stack isomorphisms</h2>
<p>There is a problem with encoding the fields of such a constructor as an n-tuple: if we want to compose it with other isomorphisms that handle the individual fields, we have to use complicated tuple projections to select the fields that we&#8217;re interested in. Basically we have unwrapped the fields from one constructor only to wrap them in another one!</p>
<p>The solution is to use heterogenous stacks of values. They are reminiscent of continuation-passing style, because in the way we use them they usually have a polymorphic tail:</p>
<pre><code>person :: Iso (String :- Gender :- Int :- Float :- Float :- t) (Person :- t)</code></pre>
<p>Read <code>:-</code> as &#8216;cons&#8217;, but then for types instead of values. Its definition is simple:</p>
<pre><code>data h :- t = h :- t</code></pre>
<p>The polymorphic tail says that <code>person</code> doesn&#8217;t care what&#8217;s on the stack below the two <code>Floats</code>; it will simply pass that part of the stack on to the right-hand side. And vice versa, if we&#8217;re working with the isomorphism in the opposite direction.</p>
<p>Have you thought about what the types of <code>male</code> and <code>female</code> would be in the non-stack versions of the isomorphisms? They don&#8217;t have any fields; we would have to leave the first type parameter of <code>Iso</code> empty somehow, for example by choosing <code>()</code>. Stack isomorphisms have no such problem; we simply make the first type argument the polymorphic tail on its own, without any values on top:</p>
<pre><code>male   :: Iso t (Gender :- t)
female :: Iso t (Gender :- t)
</code></pre>
<p>Stack isomorphisms compose beautifully using <code>.</code>, often without needing any special projection functions. To get a feeling for it, try compiling the example Json grammars and looking at the types of the individual components.</p>
<p>I lied when I wrote that grammars have type <code>Iso Value a</code>; they actually use stacks themselves, too. Here is the true definition of the <code>Json</code> type class:</p>
<pre><code>class Json a where
  grammar :: Iso (Value :- t) (a :- t)
</code></pre>
<h2>Different tree shapes</h2>
<p>Let&#8217;s take our Person example and make a small modification. We decide that because (lat, lng)-pairs are so common together, we&#8217;d like to put them together in their own datatype:</p>
<pre><code>data Coords = Coords { lat :: Float, lng :: Float }
  deriving (Eq, Show)

data Person = Person
  { name     :: String
  , gender   :: Gender
  , age      :: Int
  , location :: Coords
  } deriving (Eq, Show)
</code></pre>
<p>However, in this example we have no control over the JSON format and cannot change it to match our new structure. With JsonGrammar we can express mappings where the nesting is not one-to-one:</p>
<pre><code>instance Json Person where
  grammar = person . object
    ( prop "naam"
    . prop "geslacht"
    . prop "leeftijd"
    . coordsProps
    )

coordsProps :: Iso (Object :- t) (Object :- Coords :- t)
coordsProps = duck coords . prop "lat" . prop "lng"
</code></pre>
<p>Here <code>duck coords</code> wraps (or unwraps, depending on the direction) the two matched <code>Float</code> properties in their own <code>Coords</code> constructor before continuing matching the other properties in an object. Function <code>duck</code> is a combinator that makes a grammar (<code>coords</code> in this case) work one element down the stack. Here it makes sure the top values can remain <code>Object</code>s, which is needed by <code>prop</code> to build/destruct JSON objects one property at a time.</p>
<p>What is important to note here is that not only can we express mappings with different nestings, we can also capture this behaviour in its own grammar for reuse. JsonGrammar allows this level of modularity in everything it does.</p>
<h2>History and related work</h2>
<p>The ideas behind JsonGrammar go back a bit. They are based on <a href="https://github.com/MedeaMelana/Zwaluw">Zwaluw</a>, a library that Sjoerd Visscher and I worked on. The library aids in writing bidirectional parsers/pretty-printers for type-safe URLs, also in a DRY manner. Zwaluw, too, uses stacks to achieve a high level of modularity. In turn, Zwaluw was inspired by <a href="http://hackage.haskell.org/package/HoleyMonoid">HoleyMonoid</a>, which shows that the CPS-like manner of using polymorphic stack tails allows combinators to build up a list of expected arguments for use in printf-like functionality.</p>
<p>The <code>Iso</code> datatype comes from <a href="http://hackage.haskell.org/package/partial-isomorphisms">partial-isomorphisms</a> and is described in more detail in <a href="http://www.informatik.uni-marburg.de/~rendel/unparse/">Invertible syntax descriptions: Unifying parsing and pretty printing</a> by Tillmann Rendel and Klaus Ostermann. They also use stacks (in the form of nested binary tuples), but they are not using the trick with the polymorphic tail (yet?).</p>
<h2>Future work</h2>
<p>Although JsonGrammar is usable, there is still work to be done:</p>
<ul>
<li>
<strong>Supporting new use cases</strong>. JsonGrammar has not been used in the wild much yet. If you find any use cases that the library currently does not support, please let me know!</li>
<li>
<strong>Benchmarking</strong>. No performance testing or memory usage profiling has been done yet.</li>
<li>
<strong>Improved error messages</strong>. The <code>Maybe</code> return values indicate whenever conversion has failed, but never <em>how</em> it has failed. The <code>aeson</code> package gives nice error message when for example an expected property was not found. Such error reporting still has to be added to JsonGrammar.</li>
<li>
<strong>Other experiments</strong>. Perhaps a library can be written on top of JsonGrammar that allows grammars to be specified that also compile to JSON Schema.</li>
</ul>
<p>If you have any questions, comments, ideas or bug reports, feel to leave a comment or <a href="https://github.com/MedeaMelana/JsonGrammar/issues/new">open a ticket on GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2011/05/08/introducing-jsongrammar/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Replication schemes</title>
		<link>http://martijn.van.steenbergen.nl/journal/2011/01/16/replication-schemes/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2011/01/16/replication-schemes/#comments</comments>
		<pubDate>Sun, 16 Jan 2011 15:48:36 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=522</guid>
		<description><![CDATA[A new package ReplicateEffects is available, exposing module Control.Replicate. The source code is available on GitHub. In this post I will explain what it does and how to use it. Module Control.Applicative not only defines the Applicative and Alternative type classes, it also offers some useful combinators to express how often an action should be [...]]]></description>
			<content:encoded><![CDATA[<p>A new package <a href="http://hackage.haskell.org/package/ReplicateEffects">ReplicateEffects</a> is available, exposing module <a href="http://hackage.haskell.org/packages/archive/ReplicateEffects/0.2/doc/html/Control-Replicate.html"><code>Control.Replicate</code></a>. The source code is <a href="https://github.com/MedeaMelana/ReplicateEffects">available on GitHub</a>. In this post I will explain what it does and how to use it.</p>
<p>Module <code>Control.Applicative</code> not only defines the <code>Applicative</code> and <code>Alternative</code> type classes, it also offers some useful combinators to express how often an action should be run: <code>many</code> takes an action and runs it zero or more times, collecting the results in a list. Function <code>some</code> does the same but performs the action at least once. Finally, there is <code>optional</code> which performs its argument action zero or one time, returning a <code>Maybe</code> value.</p>
<p>Module <code>Control.Replicate</code> separates such replication schemes from the actual action. It, too, defines a <code>many</code>, <code>some</code>, and <code>opt</code>, but to actually run an action <code>x</code> that many times, we give the scheme and the action in question to the run operator <code>*!</code> (read: times) like so: <code>many *! x</code>, <code>some *! x</code>, <code>opt *! x</code>.</p>
<p>Why is this useful? Well, it turns out that these replication schemes are highly composable, in standard ways. They themselves are instances of <code>Applicative</code>, <code>Category</code> and <code>Alternative</code>. With these combinators, we can sum them, multiply them, and indicate choice, respectively. Let&#8217;s look at some examples.</p>
<h2>Atomic building blocks</h2>
<p>The primitive, atomic building blocks are <code>zero</code> and <code>one</code>. If we pass these to <code>*!</code>, the action is not run at all, or run exactly once. Their types are:</p>
<pre>
zero :: b -> Replicate a b
one  :: Replicate a a
(*!) :: Alternative f => Replicate a b -> f a -> f b
</pre>
<p>The schemes are represented by type constructor <code>Replicate</code>. If we look at the type of <code>*!</code>, we can see that <code>Replicate</code>&#8216;s first type parameter indicates the result type of the action, while its second type parameter indicates the type of the result after running that action so many times. In the case of <code>one</code>, the two arguments are identical. In the case of <code>zero</code>, the scheme will not run the action at all but it still needs to produce a <code>b</code>. This is why <code>zero</code> takes an argument of type <code>b</code>.</p>
<h2>Summing schemes</h2>
<p>Schemes are <code>Applicative</code>. We can create <code>two</code> and <code>three</code>, the schemes that run an action exactly two and three times, using <code>one</code> as building block:</p>
<pre>
two :: Replicate a (a, a)
two = (,) &lt;$&gt; one &lt;*&gt; one

three :: Replicate a (a, a, a)
three = (,,) &lt;$&gt; one &lt;*&gt; one &lt;*&gt; one
</pre>
<p>Look at their result types: the tuples indicate precisely how many times the action is run. You can read <code>&lt;*&gt;</code> as plus: 2 = 1 + 1, 3 = 1 + 1 + 1.</p>
<p>Of course <code>pure</code> is also defined for schemes. The identity element of addition is 0, and this is exactly what <code>pure</code> means. It is a synonym for the <code>zero</code> we saw earlier.</p>
<h2>Multiplying schemes</h2>
<p>Schemes also form a <code>Category</code>. We can use it to multiply them. Here are two examples:</p>
<pre>
twiceThree :: Replicate a ((a, a, a), (a, a, a))
twiceThree = two . three

thriceTwo :: Replicate a ((a, a), (a, a), (a, a))
thriceTwo = three . two
</pre>
<p>In both cases an action is run six times, but their results are nested differently. We will see another multiplication example in a moment.</p>
<p>The identity element for multiplication is 1. Scheme <code>one</code> exactly matches the type of function <code>id</code> in the <code>Category</code> type class.</p>
<h2>Choice</h2>
<p>Until now the examples have only seen schemes for running an action exactly so many times. But schemes are <code>Alternative</code> and can encode multiple frequencies. This is how <code>opt</code>, the scheme that runs an action zero or one times, is defined:</p>
<pre>
opt :: Replicate a (Maybe a)
opt = zero Nothing &lt;|&gt; Just &lt;$&gt; one
</pre>
<p>Schemes <code>many</code> and <code>some</code> also use choice:</p>
<pre>
many :: Replicate a [a]
many = zero [] &lt;|&gt; some

some :: Replicate a [a]
some = (:) &lt;$&gt; one &lt;*&gt; many
</pre>
<p>We now have many ways to combine replication schemes, and if we use choice together with sums or products, it&#8217;s not always immediately clear what the resulting scheme means. That&#8217;s why the module also exposes a function <code>sizes</code> which lists the frequencies a scheme allows:</p>
<pre>
&gt; sizes one
[1]
&gt; sizes two
[2]
&gt; sizes opt
[0,1]
&gt; take 10 (sizes many)
[0,1,2,3,4,5,6,7,8,9]
&gt; take 10 (sizes some)
[1,2,3,4,5,6,7,8,9,10]
</pre>
<p>In this sense, the schemes encode sets of Peano literals, and <code>&lt;|&gt;</code> computes the union of two sets.</p>
<p>Now it&#8217;s also clear what the <code>empty</code> scheme is: the scheme that doesn&#8217;t allow an action to occur with any frequency; not even zero times.</p>
<pre>
&gt; sizes empty
[]
</pre>
<p>As promised, another example that uses multiplication:</p>
<pre>
even :: Replicate a [(a, a)]
even = many . two

> take 10 (sizes even)
[0,2,4,6,8,10,12,14,16,18]
</pre>
<p>This scheme allows all even occurrences of an action, and its type reflects that exactly: there is no way to capture an odd number of <code>a</code>s in <code>[(a, a)]</code>.</p>
<h2>Dice</h2>
<p>Another combinator available in the module is <code>between :: Int -> Int -> Replicate a [a]</code>, which limits the frequency of an action to a lower and upper bound:</p>
<pre>
&gt; sizes (between 5 10)
[5,6,7,8,9,10]
</pre>
<p>What frequencies does <code>(,) &lt;$&gt; between 3 5 &lt;*&gt; two</code> allow? Let&#8217;s check:</p>
<pre>
&gt; sizes ((,) &lt;$&gt; between 3 5 &lt;*&gt; two)
[5,6,7]
</pre>
<p>This makes sense: if we run an action 3, 4 or 5 times and then another two times, we&#8217;ve run it 5, 6 or 7 times.</p>
<p>What does <code>between 7 9 . three</code> mean? What about <code>three . between 7 9</code>?</p>
<pre>
&gt; sizes (between 7 9 . three)
[21,24,27]
&gt; sizes (three . between 7 9)
[21,22,23,24,25,26,27]
</pre>
<p>If the schemes become a bit more involved, it can be helpful to think about them as dice throws. Then <code>between 7 9 . three</code> means: throw a die with 7, 8 and 9 eyes on it, and use the outcome to decide how many times to throw a die with exactly 3 eyes. This has possible outcomes [9,12,15].</p>
<p>In the other case, we throw die <code>between 7 9</code> three times, ending up with the full range 21-27 as possible outcomes.</p>
<h2>Open questions</h2>
<p>Currently if you try to evaluate <code>sizes (many . opt)</code>, the program hangs. This is true not for just <code>opt</code> but for any scheme that allows frequency zero. Is there a bug in the definitions of the combinators, or is it unreasonable to expect the library to produce output in this case?</p>
<p>Another problem is that <code>sizes (id . r)</code> takes longer than just <code>r</code> for no apparent good reason. (Try <code>r = exactly 1000</code>.) Perhaps some profiling will show what the problem here is.</p>
]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2011/01/16/replication-schemes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>The ReverseT monad transformer</title>
		<link>http://martijn.van.steenbergen.nl/journal/2010/11/19/the-reverset-monad-transformer/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2010/11/19/the-reverset-monad-transformer/#comments</comments>
		<pubDate>Fri, 19 Nov 2010 18:59:44 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=512</guid>
		<description><![CDATA[{-# LANGUAGE DoRec #-} import Control.Monad.Fix import Control.Monad.State import Control.Monad.Trans In a two-year-old post Luke Palmer shows an implementation of the Fibonacci sequence using the reverse state monad: a state monad where the results flow forward but the state flows backward. Similar results can be achieved using the ReverseT monad transformer which reverses the effects [...]]]></description>
			<content:encoded><![CDATA[<pre>
{-# LANGUAGE DoRec #-}

import Control.Monad.Fix
import Control.Monad.State
import Control.Monad.Trans
</pre>
<p>In a two-year-old post Luke Palmer shows <a href="http://lukepalmer.wordpress.com/mindfuck-the-reverse-state-monad/">an implementation of the Fibonacci sequence</a> using the reverse state monad: a state monad where the results flow forward but the state flows backward.</p>
<p>Similar results can be achieved using the <code>ReverseT</code> monad transformer which reverses the effects of any monad for which the monadic fixpoint <code>mfix :: MonadFix m => (a -> m a) -> m a</code> is defined:</p>
<pre>
newtype ReverseT m a = ReverseT { runReverseT :: m a }

instance MonadFix m => Monad (ReverseT m) where
  return            = ReverseT . return
  ReverseT m >>= f  =
    ReverseT $ do
      rec
        b <- runReverseT (f a)
 a <- m
 return b

instance MonadTrans ReverseT where
 lift = ReverseT</pre>
<p>With this transformer we can write Luke's <code>computeFibs</code> as follows:</p>
<pre>
cumulativeSums = scanl (+) 0

computeFibs =
  flip evalState [] . runReverseT $ do
    fibs <- lift get
    lift $ modify cumulativeSums
    lift $ put (1:fibs)
    return fibs
</pre>
<p>Are there any other monads <code>m</code> for which <code>ReverseT m</code> is interesting?</p>
]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2010/11/19/the-reverset-monad-transformer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>BelHac 2010</title>
		<link>http://martijn.van.steenbergen.nl/journal/2010/11/07/belhac-2010/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2010/11/07/belhac-2010/#comments</comments>
		<pubDate>Sun, 07 Nov 2010 09:49:42 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=507</guid>
		<description><![CDATA[Some pictures from the Belgium Haskell Hackathon in Ghent! It is very well organised: pretty city, nice venue, enough fruit and drinks available and very yummy Italian sandwiches for lunch. Many thanks to Jasper for taking such good care of us.]]></description>
			<content:encoded><![CDATA[<p>Some pictures from the <a href="http://www.haskell.org/haskellwiki/Ghent_Functional_Programming_Group/BelHac">Belgium Haskell Hackathon</a> in Ghent! It is very well organised: pretty city, nice venue, enough fruit and drinks available and very yummy Italian sandwiches for lunch. Many thanks to <a href="http://jaspervdj.be/">Jasper</a> for taking such good care of us.</p>
<table cellspacing="0" cellpadding="0" class="dbg_gallery">
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2611.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2611.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2611.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2612.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2612.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2612.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2628.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2628.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2628.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2633.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2633.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2633.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2637.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2637.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2637.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2648.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2648.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2648.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2651.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2651.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2651.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2657.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2657.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2657.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2660.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2660.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2660.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2664.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2664.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2664.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2665.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2665.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2665.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2666.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2666.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2666.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2667.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2667.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2667.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2670.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2670.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2670.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2674.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2674.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2674.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/belhac-saturday/DSC_2678.jpg" rel="lightbox[belhac-saturday]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2678.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/belhac-saturday/DSC_2678.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
</tr>
</table>

]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2010/11/07/belhac-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Master&#8217;s Diploma</title>
		<link>http://martijn.van.steenbergen.nl/journal/2010/07/02/masters-diploma/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2010/07/02/masters-diploma/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 23:04:51 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=501</guid>
		<description><![CDATA[Today Chris Eidhof, Sebastiaan Visser and I got our master&#8217;s diplomas, all on Haskell-related generic programming subjects. The diploma speeches, given by Andres Löh, Johan Jeuring, and José Pedro Magalhães, were very flattering. The picture above, taken by my sister Tamar, shows yours truly signing his diploma. Next week I start working full-time at Q42 [...]]]></description>
			<content:encoded><![CDATA[<img class="dbg_single" src="http://martijn.van.steenbergen.nl/galleries/singles/DSC_1675.jpg" alt="DSC_1675.jpg" />
<p>Today Chris Eidhof, Sebastiaan Visser and I got our master&#8217;s diplomas, all on Haskell-related generic programming subjects. The diploma speeches, given by Andres Löh, Johan Jeuring, and José Pedro Magalhães, were very flattering. <img src='http://martijn.van.steenbergen.nl/journal/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  The picture above, taken by my sister Tamar, shows yours truly signing his diploma.</p>
<p>Next week I start working full-time at <a href="http://q42.nl/">Q42</a> in The Hague. I hope to move a bit closer to work somewhere in the next few months. Right now I spend over 3 hours travelling each day to get to and from work; that has to change. <img src='http://martijn.van.steenbergen.nl/journal/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2010/07/02/masters-diploma/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Generically adding position information to a datatype</title>
		<link>http://martijn.van.steenbergen.nl/journal/2010/06/24/generically-adding-position-information-to-a-datatype/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2010/06/24/generically-adding-position-information-to-a-datatype/#comments</comments>
		<pubDate>Thu, 24 Jun 2010 12:06:31 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=482</guid>
		<description><![CDATA[Every now and then datatype fixpoints come up, especially in the context of generic programming: newtype Fix f = In { out :: f (Fix f) } Most explanations of this datatype I have read or heard start with this definition and then proceed to explain it, using various examples. In today&#8217;s post I will [...]]]></description>
			<content:encoded><![CDATA[<p>Every now and then datatype fixpoints come up, especially in the context of generic programming:</p>
<pre>
newtype Fix f = In { out :: f (Fix f) }
</pre>
<p>Most explanations of this datatype I have read or heard start with this definition and then proceed to explain it, using various examples. In today&#8217;s post I will also introduce you to this datatype, but I want to take a different approach: I will show you a problem to which the Fix datatype is the natural solution, <em>deriving</em> its definition along the way.</p>
<p>The Haskell code in this post does not use very advanced features: there are no type functions or even type classes, only datatypes and parameters. If you are familiar with datatypes, type parameters and their syntax, it should not be hard to follow. If you have any questions, feel free to post them!</p>
<h2>The problem</h2>
<p>Let&#8217;s take our trusty old friend the arithmetic expression datatype:</p>
<pre>
data BareExpr
  = Num Int
  | Add BareExpr BareExpr
  | Sub BareExpr BareExpr
  | Mul BareExpr BareExpr
  | Div BareExpr BareExpr
</pre>
<p>I&#8217;ve called it <code>BareExpr</code> here for a reason: we are going to change it in such a way that we can also store position information in it, resulting in type <code>PosExpr</code>, so that when a <code>PosExpr</code> is produced by a parser, we can trace back where in the original source code the tree nodes were. This is useful in various applications. For example, compilers that output error messages generally provide position information about where the error occurred exactly. It is also useful in tools that need to understand text selections in the source code, such as editors that feature refactoring.</p>
<p>Adding position information to a single datatype is not very difficult. After we have done so for <code>BareExpr</code>, we will look at the real problem: how to do this for <em>any</em> datatype.</p>
<h2>Expressions with positions</h2>
<p>There are several ways to add position information to a datatype. In our case we will couple every <em>occurrence</em> of <code>BareExpr</code> with a location. Let&#8217;s call the type of locations <code>SrcSpan</code> and the annotated version of the expression datatype <code>PosExpr</code>:</p>
<pre>
type PosExpr = (SrcSpan, PosExpr’)
data PosExpr'
  = Num Intr’
  | Add PosExpr PosExpr
  | Sub PosExpr PosExpr
  | Mul PosExpr PosExpr
  | Div PosExpr PosExpr
</pre>
<p>In a series of steps, we will reach our final solution.</p>
<h2>Step 1: Capture the similarities between BareExpr and PosExpr</h2>
<p><code>BareExpr</code> and <code>PosExpr'</code> are very similar: they both contain five constructors, and each constructor has the same number of fields. Can we capture this structure somehow? Yes, we can: the two types only differ in the types of their recursive positions, and in a very regular way. We can do here what we would do in any similar case: make the parts that differ arguments, and then express the original entities in terms of this new, general entity by providing specific arguments.</p>
<p>Haskell allows us to do that with datatypes: simply introduce a new type argument <code>r</code>. We call the resulting type <code>ExprF</code>:</p>
<pre>
data ExprF r
  = Num Int
  | Add r r
  | Sub r r
  | Mul r r
  | Div r r
</pre>
<p>The <code>F</code> in <code>ExprF</code> stands for functor, and such a datatype is usually called a <em>base functor</em>. Base functors determine the shape of the top level of a tree, but the shape of their children is determined by the type argument.</p>
<h2>Step 2: Express BareExpr in terms of ExprF</h2>
<p>Now we need to recover <code>BareExpr</code> and <code>PosExpr</code> by expressing them in terms of <code>ExprF</code>. For <code>BareExpr</code>, we want the child positions of <code>ExprF</code> also to be bare expressions. This leads to an infinite type:</p>
<pre>
BareExpr ~ ExprF (ExprF (ExprF ...))
</pre>
<p>This says that to get bare expressions back, we want to take <code>ExprF</code> and have its children be <code>ExprF</code>s again, and those children&#8217;s children to be <code>ExprF</code>s again, and so on. In Haskell we can encode infinite types by introducing new datatypes (we reuse the name <code>BareExpr</code> here):</p>
<pre>
newtype BareExpr = BareExpr { runBareExpr :: ExprF BareExpr }
</pre>
<p>If you repeatedly expand this definition, you will see that it results in the infinite type above.</p>
<h2>Step 3: Express PosExpr in terms of ExprF</h2>
<p>For <code>PosExpr</code> we can think of a similar infinite type:</p>
<pre>
PosExpr ~ (SrcSpan, ExprF (SrcSpan, ExprF ...))
</pre>
<p>Again, we write this down using a new datatype:</p>
<pre>
newtype PosExpr = PosExpr  { runPosExpr  :: (SrcSpan, ExprF PosExpr) }
</pre>
<h2>Step 4: Generalize BareExpr</h2>
<p>Currently <code>BareExpr</code> works only for the <code>ExprF</code> shape. Let&#8217;s create such a &#8216;bare&#8217; version for any shape instead of just <code>ExprF</code>s. We can do this by making the base functor an argument:</p>
<pre>
newtype BareExpr f = BareExpr { runBareExpr :: f (BareExpr f) }
</pre>
<p>On the right-hand side, we have replaced <code>ExprF</code> by the argument <code>f</code>. In step 2 we supplied the type we were defining as argument to <code>ExprF</code>; in this new version we do the same to <code>f</code>, but since this new version has a type argument, we need to supply this argument in the recursive position as well.</p>
<p>But&#8230; this datatype is no longer specific for arithmetic expressions, so the name <code>BareExpr</code> is not very appropriate. In fact, the type we have just defined is the famous <code>Fix</code> disguised under a different name!</p>
<pre>
newtype Fix f = In { out :: f (Fix f) }
</pre>
<p>So now you know what <code>Fix</code> does: it takes a base functor, such as <code>ExprF</code>, and recursively applies it to itself, creating a tree that is of the same shape at every level.</p>
<p>Our new definition of <code>BareExpr</code> doesn&#8217;t need to introduce any new datatypes but can now be a simple type synonym:</p>
<pre>
type BareExpr = Fix ExprF
</pre>
<h2>Step 5: Generalize PosExpr</h2>
<p>For <code>PosExpr</code> we can make two generalizations. The first is to not just store source locations, but allow any type of annotation:</p>
<pre>
newtype AnnExpr x = AnnExpr { runAnnExpr :: (x, ExprF (AnnExpr x)) }
</pre>
<p>The second is similar to the one we made to <code>BareExpr</code>: have it work for any base functor instead of just <code>ExprF</code>s:</p>
<pre>
newtype AnnFix x f = AnnFix { runAnnFix	:: (x, f (AnnFix x f)) }
</pre>
<p>To recover <code>PosExpr</code>, we give <code>AnnFix</code> the two appropriate type arguments:</p>
<pre>
type PosExpr = AnnFix SrcSpan ExprF
</pre>
<h2>Step 6: Express AnnFix in terms of Fix</h2>
<p>The <code>Fix</code> type captured the idea of take a functor and applying it to itself recursively. <code>AnnFix</code> does something similar. Can we perhaps express <code>AnnFix</code> in terms of <code>Fix</code> to make this explicit?</p>
<p>It turns out we can, if we introduce a helper datatype <code>Ann</code>:</p>
<pre>
data Ann x f a = Ann x (f a)
type AnnFix x f	= Fix (Ann x f)
</pre>
<p><code>Ann</code> couples an annotation <code>x</code> with a functor value. It&#8217;s kind of a tuple type, lifted to a higher order on the right side.</p>
<h2>Summing up</h2>
<p>We have seen many (intermediate) definitions of datatypes, but in the end only two of them matter:</p>
<pre>
newtype Fix f     = In { out :: f (Fix f) }
data    Ann x f a = Ann x (f a)
</pre>
<p>And of course, we have our expression example expressed in terms of these two building blocks:</p>
<pre>
type BareExpr = Fix ExprF
type PosExpr  = Fix (Ann SrcSpan ExprF)
</pre>
<p>With just these two building blocks, we can express generically annotated trees and unannotated trees. What is the point of generalizing this far? Well, by making these types not specific to a particular tree shape (such as <code>ExprF</code>), you can build all sorts of tools that work on many kinds of trees. In <a href="http://martijn.van.steenbergen.nl/projects/Selections.pdf">my Masters thesis</a> I explore this concept further, developing parser combinators that automatically insert the position information for you at the appropriate places, catamorphisms that automatically couple errors with position information, conversions between text selections and tree selections and a couple of other things.</p>
<h2>Read more</h2>
<p>If you&#8217;re interested in datatype fixpoints and would like to know more, here is a collection of interesting tutorials, applications and papers:</p>
<ul>
<li>Mark Dominus explains <a href="http://blog.plover.com/prog/springschool95-2.html">data Mu f = In (f (Mu f)) </a></il>
<li><a href="http://www.haskell.org/haskellwiki/Indirect_composite">Indirect composite</a> on the Haskell wiki</li>
<li>A <a href="http://knol.google.com/k/edward-kmett/catamorphisms">more formal description</a> by Edward Kmett</li>
<li>The classic 1990 <a href="http://homepages.inf.ed.ac.uk/wadler/papers/free-rectypes/free-rectypes.txt">Recursive types for free!</a> by Philip Wadler
<li>Another classic: the 1991 <a href="http://wwwhome.cs.utwente.nl/~fokkinga/mmf91m.ps">Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire</a> by Erik Meijer, Maarten Fokkinga and Ross Paterson
</ul>
]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2010/06/24/generically-adding-position-information-to-a-datatype/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Üetliberg</title>
		<link>http://martijn.van.steenbergen.nl/journal/2010/03/20/uetliberg/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2010/03/20/uetliberg/#comments</comments>
		<pubDate>Sat, 20 Mar 2010 10:43:29 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Trips]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=479</guid>
		<description><![CDATA[Erik, Tom, Sebas, Chris, Sjoerd and I are in Zürich, attending the Haskell Hackathon. Yesterday we climbed the Üetliberg, a mountain (hill?) right next to the city. The view from there is spectacular; we&#8217;re especially liking the snow-topped mountains in the background. Right now we&#8217;re all in the Google HQ, enjoying hacking in a spacious [...]]]></description>
			<content:encoded><![CDATA[<p>Erik, Tom, Sebas, Chris, Sjoerd and I are in Zürich, attending the <a href="http://www.haskell.org/haskellwiki/ZuriHac">Haskell Hackathon</a>. Yesterday we climbed the Üetliberg, a mountain (hill?) right next to the city. The view from there is spectacular; we&#8217;re especially liking the snow-topped mountains in the background.</p>
<p>Right now we&#8217;re all in the Google HQ, enjoying hacking in a spacious room with a fridge full of drinks. Thanks, Google!</p>
<table cellspacing="0" cellpadding="0" class="dbg_gallery">
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0640.jpg" rel="lightbox[zurich-uetliberg]" title="Erik, Tom, Sebas, Chris and Sjoerd.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0640.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0640.jpg"/></a></div></div>
<div class="dbg_caption">Erik, Tom, Sebas, Chris and Sjoerd.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0648.jpg" rel="lightbox[zurich-uetliberg]" title="River Limmat seen from the Lindenhof. In the background us the Predigerkirche.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0648.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0648.jpg"/></a></div></div>
<div class="dbg_caption">River Limmat seen from the Lindenhof. In the background us the Predigerkirche.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0654.jpg" rel="lightbox[zurich-uetliberg]" title="Z&uuml;rich Gro&szlig;m&uuml;nster seen from the Lindenhof.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0654.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0654.jpg"/></a></div></div>
<div class="dbg_caption">Z&uuml;rich Gro&szlig;m&uuml;nster seen from the Lindenhof.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0657.jpg" rel="lightbox[zurich-uetliberg]" title="...">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0657.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0657.jpg"/></a></div></div>
<div class="dbg_caption">...</div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0665.jpg" rel="lightbox[zurich-uetliberg]" title="A brook in the forests around the &Uuml;etliberg.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0665.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0665.jpg"/></a></div></div>
<div class="dbg_caption">A brook in the forests around the &Uuml;etliberg.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0669.jpg" rel="lightbox[zurich-uetliberg]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0669.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0669.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0676.jpg" rel="lightbox[zurich-uetliberg]" title="Sitting on top of a ruin on the slope of the &Uuml;etliberg.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0676.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0676.jpg"/></a></div></div>
<div class="dbg_caption">Sitting on top of a ruin on the slope of the &Uuml;etliberg.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0679.jpg" rel="lightbox[zurich-uetliberg]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0679.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0679.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0686.jpg" rel="lightbox[zurich-uetliberg]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0686.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0686.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/zurich-uetliberg/DSC_0693.jpg" rel="lightbox[zurich-uetliberg]" title="View from the top of the mountain, near the station.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0693.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/zurich-uetliberg/DSC_0693.jpg"/></a></div></div>
<div class="dbg_caption">View from the top of the mountain, near the station.</div>
</td>
</tr>
</table>

]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2010/03/20/uetliberg/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Colors in GHCi</title>
		<link>http://martijn.van.steenbergen.nl/journal/2010/02/27/colors-in-ghci/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2010/02/27/colors-in-ghci/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 11:10:47 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=467</guid>
		<description><![CDATA[Whenever you load a Haskell file into GHCi, it will either tell you your modules loaded fine, or that there were some errors. Sebas came with the awesome idea of coloring these messages green and red, respectively. Here is how to do this: Create a script that looks like this: #!/usr/bin/env bash GREEN=`echo -e '33[92m'` [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever you load a Haskell file into GHCi, it will either tell you your modules loaded fine, or that there were some errors. <a href="http://twitter.com/sfvisser">Sebas</a> came with the awesome idea of coloring these messages green and red, respectively. Here is how to do this:</p>
<p>Create a script that looks like this:</p>
<pre style="overflow: auto; margin-right: 120px">
#!/usr/bin/env bash

GREEN=`echo -e ' 33[92m'`
RED=`echo -e ' 33[91m'`
RESET=`echo -e ' 33[0m'`

/usr/bin/ghci "${@}" |
  sed "s/^Failed, modules loaded:/${RED}&#038;${RESET}/g;s/^Ok, modules loaded:/${GREEN}&#038;${RESET}/g"
</pre>
<p>If your <code>ghci</code> is not located in <code>/usr/bin</code>, change the path in the script accordingly. If you want, you can name your script <code>ghci</code> so that it takes over the original one. Just make sure its location appears in your <code>PATH</code> variable before the location of the true <code>ghci</code>.</p>
<p>If all goes well, you should now see colors whenever you load your modules:</p>
<pre style="background-color: #333; color: #a3bd84;">
% ghci Sirenial.Merge
...
<span style="color:#fd3a1e">Failed, modules loaded:</span> Sirenial.Query.
</pre>
<p>And then when the bug has been fixed:</p>
<pre style="background-color: #333; color: #a3bd84;">
% ghci Sirenial.Merge
...
<span style="color:#2fe424">Ok, modules loaded:</span> Sirenial.Merge, Sirenial.Query.
</pre>
<p>This has only been tested on Terminal.app in Snow Leopard. If it doesn&#8217;t work for your system, please leave a comment, with—if possible—a fix.</p>
<p>There is a small issue: sometimes <code>sed</code> delays the colored parts a bit, causing your prompt to be printed <em>before</em> the success or error message. Again, if you know a fix, please comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2010/02/27/colors-in-ghci/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Sneeuw at Warande</title>
		<link>http://martijn.van.steenbergen.nl/journal/2009/12/21/sneeuw-at-warande/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2009/12/21/sneeuw-at-warande/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 23:07:47 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=458</guid>
		<description><![CDATA[With the whole of the Netherlands covered in snow, the traffic is completely jammed. But that didn&#8217;t bother my flatmates and me, because we stayed home all day. In the afternoon we rolled the biggest snowball in the street; at the end it reached a meter in diameter and it took three of us to [...]]]></description>
			<content:encoded><![CDATA[<img class="dbg_single" src="http://martijn.van.steenbergen.nl/galleries/singles/DSC_0309.jpg" alt="DSC_0309.jpg" />
<p>With the whole of the Netherlands covered in snow, the traffic is completely jammed. But that didn&#8217;t bother my flatmates and me, because we stayed home all day. In the afternoon we rolled the biggest snowball in the street; at the end it reached a meter in diameter and it took three of us to push it around. We guessed it weighed approximately 250 kg at that point.</p>
<p>While <a href="http://www.ah.nl/recepten/recept?id=8478">dinner</a> was cooking I went outside again to take some pictures.</p>
<table cellspacing="0" cellpadding="0" class="dbg_gallery">
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/sneeuw-warande/DSC_0296.jpg" rel="lightbox[sneeuw-warande]" title="Our giant snowball. At the end it took 3 people to push it around.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0296.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0296.jpg"/></a></div></div>
<div class="dbg_caption">Our giant snowball. At the end it took 3 people to push it around.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/sneeuw-warande/DSC_0297.jpg" rel="lightbox[sneeuw-warande]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0297.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0297.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/sneeuw-warande/DSC_0301.jpg" rel="lightbox[sneeuw-warande]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0301.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0301.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/sneeuw-warande/DSC_0305.jpg" rel="lightbox[sneeuw-warande]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0305.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0305.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/sneeuw-warande/DSC_0309.jpg" rel="lightbox[sneeuw-warande]" title="In the background is the orange-lit road.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0309.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0309.jpg"/></a></div></div>
<div class="dbg_caption">In the background is the orange-lit road.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/sneeuw-warande/DSC_0313.jpg" rel="lightbox[sneeuw-warande]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0313.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0313.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/sneeuw-warande/DSC_0316.jpg" rel="lightbox[sneeuw-warande]" title="Looking up at the snowy foliage. Some stars are visible in the sky.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0316.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/sneeuw-warande/DSC_0316.jpg"/></a></div></div>
<div class="dbg_caption">Looking up at the snowy foliage. Some stars are visible in the sky.</div>
</td>
</tr>
</table>

]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2009/12/21/sneeuw-at-warande/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Midwinter Fair 2009</title>
		<link>http://martijn.van.steenbergen.nl/journal/2009/12/13/midwinter-fair-2009/</link>
		<comments>http://martijn.van.steenbergen.nl/journal/2009/12/13/midwinter-fair-2009/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 22:55:33 +0000</pubDate>
		<dc:creator>Martijn</dc:creator>
				<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://martijn.van.steenbergen.nl/journal/?p=454</guid>
		<description><![CDATA[Vandaag nam de Midwinter Fair 2009 plaats in het Archeon in Alphen aan den Rijn. Muziek, dans, markt, vechtshows, ambachten, lezingen en speltoernooien kwamen bijeen op deze zeer succesvolle en gezellige dag. Beter weer hadden de bezoekers zich niet kunnen wensen: winters koud, blauwe lucht en prachtige zonsopkomst en -ondergang. Erica van Brenk, Lies Sommer [...]]]></description>
			<content:encoded><![CDATA[<p>Vandaag nam de Midwinter Fair 2009 plaats in het Archeon in Alphen aan den Rijn. Muziek, dans, markt, vechtshows, ambachten, lezingen en speltoernooien kwamen bijeen op deze zeer succesvolle en gezellige dag. Beter weer hadden de bezoekers zich niet kunnen wensen: winters koud, blauwe lucht en prachtige zonsopkomst en -ondergang.</p>
<table cellspacing="0" cellpadding="0" class="dbg_gallery">
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9841.jpg" rel="lightbox[midwinterfair2009]" title="Erica van Brenk, Lies Sommer en Marco van Asperen van de folkband Orfeo.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9841.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9841.jpg"/></a></div></div>
<div class="dbg_caption">Erica van Brenk, Lies Sommer en Marco van Asperen van de folkband Orfeo.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9857.jpg" rel="lightbox[midwinterfair2009]" title="Lies Sommer bespeelt de draailier; in de achtergrond Marco van Asperen op de gitaar.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9857.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9857.jpg"/></a></div></div>
<div class="dbg_caption">Lies Sommer bespeelt de draailier; in de achtergrond Marco van Asperen op de gitaar.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9866.jpg" rel="lightbox[midwinterfair2009]" title="Paul van de folkband Orfeo op de contrabas.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9866.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9866.jpg"/></a></div></div>
<div class="dbg_caption">Paul van de folkband Orfeo op de contrabas.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9876.jpg" rel="lightbox[midwinterfair2009]" title="Er werd flink gedanst in de kloosterzaal van het Archeon.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9876.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9876.jpg"/></a></div></div>
<div class="dbg_caption">Er werd flink gedanst in de kloosterzaal van het Archeon.</div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9877.jpg" rel="lightbox[midwinterfair2009]" title="E&eacute;n van de vele marktkraampjes.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9877.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9877.jpg"/></a></div></div>
<div class="dbg_caption">E&eacute;n van de vele marktkraampjes.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9881.jpg" rel="lightbox[midwinterfair2009]" title="Modellen in het zwart en wit tonen graag hun mooie kleding.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9881.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9881.jpg"/></a></div></div>
<div class="dbg_caption">Modellen in het zwart en wit tonen graag hun mooie kleding.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9898.jpg" rel="lightbox[midwinterfair2009]" title="Laag, warm zonlicht valt op de muren van deze schuur.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9898.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9898.jpg"/></a></div></div>
<div class="dbg_caption">Laag, warm zonlicht valt op de muren van deze schuur.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9901.jpg" rel="lightbox[midwinterfair2009]" title="Tussen de huizen in &eacute;&eacute;n van de straten in het Archeon.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9901.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9901.jpg"/></a></div></div>
<div class="dbg_caption">Tussen de huizen in &eacute;&eacute;n van de straten in het Archeon.</div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9908.jpg" rel="lightbox[midwinterfair2009]" title="Verkoop van stenen in een winkeltje.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9908.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9908.jpg"/></a></div></div>
<div class="dbg_caption">Verkoop van stenen in een winkeltje.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9913.jpg" rel="lightbox[midwinterfair2009]" title="">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9913.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9913.jpg"/></a></div></div>
<div class="dbg_caption"></div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9972.jpg" rel="lightbox[midwinterfair2009]" title="Vuurspuwers zorgen voor een spetterende vuurshow.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9972.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9972.jpg"/></a></div></div>
<div class="dbg_caption">Vuurspuwers zorgen voor een spetterende vuurshow.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_9991.jpg" rel="lightbox[midwinterfair2009]" title="Vuurspuwers zorgen voor een spetterende vuurshow.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9991.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_9991.jpg"/></a></div></div>
<div class="dbg_caption">Vuurspuwers zorgen voor een spetterende vuurshow.</div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_0083.jpg" rel="lightbox[midwinterfair2009]" title="Met brandende pijlen werd getracht een haard aan te steken.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0083.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0083.jpg"/></a></div></div>
<div class="dbg_caption">Met brandende pijlen werd getracht een haard aan te steken.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_0028.jpg" rel="lightbox[midwinterfair2009]" title="De haard vat vlam en vuurpijlen schieten omhoog.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0028.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0028.jpg"/></a></div></div>
<div class="dbg_caption">De haard vat vlam en vuurpijlen schieten omhoog.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_0091.jpg" rel="lightbox[midwinterfair2009]" title="E&eacute;n van de winkeltjes.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0091.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0091.jpg"/></a></div></div>
<div class="dbg_caption">E&eacute;n van de winkeltjes.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_0095.jpg" rel="lightbox[midwinterfair2009]" title="Het verlichte klooster bij het vallen van de avond.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0095.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0095.jpg"/></a></div></div>
<div class="dbg_caption">Het verlichte klooster bij het vallen van de avond.</div>
</td>
</tr>
<tr>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_0102.jpg" rel="lightbox[midwinterfair2009]" title="Maca&eacute;l van de Keltische folkband Rapalje.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0102.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0102.jpg"/></a></div></div>
<div class="dbg_caption">Maca&eacute;l van de Keltische folkband Rapalje.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_0110.jpg" rel="lightbox[midwinterfair2009]" title="Dieb en William van de Keltische folkband Rapalje.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0110.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0110.jpg"/></a></div></div>
<div class="dbg_caption">Dieb en William van de Keltische folkband Rapalje.</div>
</td>
<td>
<div class="dbg_picture_outer"><div class="dbg_picture_inner"><a href="http://martijn.van.steenbergen.nl/galleries/midwinterfair2009/DSC_0114.jpg" rel="lightbox[midwinterfair2009]" title="William van de Keltische folkband Rapalje.">
<img src="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0114.jpg" alt="http://martijn.van.steenbergen.nl/thumbnails/midwinterfair2009/DSC_0114.jpg"/></a></div></div>
<div class="dbg_caption">William van de Keltische folkband Rapalje.</div>
</td>
</tr>
</table>

]]></content:encoded>
			<wfw:commentRss>http://martijn.van.steenbergen.nl/journal/2009/12/13/midwinter-fair-2009/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
