<?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>lablog &#187; Haskell</title>
	<atom:link href="http://blog.silkapp.com/category/haskell/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.silkapp.com</link>
	<description>Silk Blog</description>
	<lastBuildDate>Tue, 23 Feb 2010 09:40:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Writing a generic XML pickler</title>
		<link>http://blog.silkapp.com/2009/11/writing-a-generic-xml-pickler/</link>
		<comments>http://blog.silkapp.com/2009/11/writing-a-generic-xml-pickler/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 07:57:31 +0000</pubDate>
		<dc:creator>Erik</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blog.typlab.com/?p=102</guid>
		<description><![CDATA[In a previous post, Sebas explained that we use so-called XML picklers to convert Haskell data types to XML. Since these picklers have a regular structure, we don&#8217;t write them by hand, but derive them automatically using generic programming techniques. In this post, I&#8217;ll explain how our generic XML pickler works. The code shown here [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://blog.typlab.com/2009/09/haskell-data-types-and-xml/">previous post</a>, Sebas explained that we use so-called XML picklers to convert Haskell data types to XML. Since these picklers have a regular structure, we don&#8217;t write them by hand, but derive them automatically using generic programming techniques. In this post, I&#8217;ll explain how our generic XML pickler works. The code shown here has been made <a href="http://hackage.haskell.org/package/regular-xmlpickler">available on hackage</a>.<br />
<span id="more-102"></span><br />
We use the <a href="http://hackage.haskell.org/package/regular">regular library</a> to represent data types generically. It allows you to build a structure for your type that is isomorphic to your type, but built up from standard building blocks, called functors. This is possible because Haskell data types have a standard structure: a choice of one of several constructors (this is often called a sum), each having a number of fields (this is often called a product).</p>
<p>As an example, we will represent a simple user data type:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">data</span> User <span style="color: #339933; font-weight: bold;">=</span> User<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: green;">&#123;</span> name &nbsp;<span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">,</span> email <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">,</span> admin <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">Bool</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: green;">&#125;</span></div></div>
</pre>
<p>The generic representation of this type is called a pattern functor. For the user data type, it will look like this:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">type</span> <span style="color: #06c; font-weight: bold;">instance</span> PF User <span style="color: #339933; font-weight: bold;">=</span> C User<span style="color: #339933; font-weight: bold;">_</span>User<span style="color: #339933; font-weight: bold;">_</span><br />
&nbsp; <span style="color: green;">&#40;</span> &nbsp; S User<span style="color: #339933; font-weight: bold;">_</span>User<span style="color: #339933; font-weight: bold;">_</span>name<span style="color: #339933; font-weight: bold;">_</span> &nbsp;<span style="color: green;">&#40;</span>K <span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#41;</span><br />
&nbsp; :<span style="color: #339933; font-weight: bold;">*</span>: S User<span style="color: #339933; font-weight: bold;">_</span>User<span style="color: #339933; font-weight: bold;">_</span>email<span style="color: #339933; font-weight: bold;">_</span> <span style="color: green;">&#40;</span>K <span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#41;</span><br />
&nbsp; :<span style="color: #339933; font-weight: bold;">*</span>: S User<span style="color: #339933; font-weight: bold;">_</span>User<span style="color: #339933; font-weight: bold;">_</span>admin &nbsp;<span style="color: green;">&#40;</span>K <span style="color: #cccc00; font-weight: bold;">Bool</span><span style="color: green;">&#41;</span><br />
&nbsp; <span style="color: green;">&#41;</span></div></div>
</pre>
<p>Here we see a few of the functors that are the building blocks of our generic representation: The <code class="codecolorer text mac-classic"><span class="text">C</span></code> type marks constructors, the <code class="codecolorer text mac-classic"><span class="text">S</span></code> type marks record labels, <code class="codecolorer text mac-classic"><span class="text">K</span></code> marks the types that make up the fields of our record, and <code class="codecolorer text mac-classic"><span class="text">(:*:)</span></code> is the product mentioned earlier, and is very similar to the <code class="codecolorer text mac-classic"><span class="text">(,)</span></code> used for constructing tuples. There are three more functors in regular: <code class="codecolorer text mac-classic"><span class="text">I</span></code>, which marks recursive positions in a type; <code class="codecolorer text mac-classic"><span class="text">(:+:)</span></code>, which sums together different constructors; and <code class="codecolorer text mac-classic"><span class="text">U</span></code>, for constructors without fields.</p>
<p>To write a generic function, we define a type class which contains this generic function, and give an instance for each of these functors. If we then also define conversion functions from our data type to the generic representation and back, we can apply the function to our data type. Note that for regular, these conversion functions, and the representation given above, can all be generated using Template Haskell.</p>
<p>Since we want to write a generic XML pickler for use with the <a href="http://hackage.haskell.org/package/hxt">HXT library</a>, we&#8217;ll define a type class containing such a pickler:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">class</span> GXmlPickler f <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef <span style="color: #339933; font-weight: bold;">::</span> PU a <span style="color: #339933; font-weight: bold;">-&gt;</span> PU <span style="color: green;">&#40;</span>f a<span style="color: green;">&#41;</span></div></div>
</pre>
<p>This says that we can give a generic pickler for one of the functors <code class="codecolorer text mac-classic"><span class="text">f</span></code>, containing <code class="codecolorer text mac-classic"><span class="text">a</span></code>&#8216;s at the recursive positions, if we have a pickler for <code class="codecolorer text mac-classic"><span class="text">a</span></code>&#8216;s. I&#8217;ll now show the instances for all the functors, and explain them one by one.</p>
<p>The first is the instance for <code class="codecolorer text mac-classic"><span class="text">I</span></code>, marking recursive positions. Since we get a pickler for the resursive positions, all we have to do is wrap it in the <code class="codecolorer text mac-classic"><span class="text">I</span></code> constructor when unpickling, and remove that constructor when pickling. HXT provides the <code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code> function to transform a pickler like this.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">instance</span> GXmlPickler I <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef <span style="color: #339933; font-weight: bold;">=</span> xpWrap <span style="color: green;">&#40;</span>I<span style="color: #339933; font-weight: bold;">,</span> unI<span style="color: green;">&#41;</span></div></div>
</pre>
<p>Next, we&#8217;ll tackle <code class="codecolorer text mac-classic"><span class="text">K</span></code>. Here, we require that the type of the field has its own pickler, and use that. We again use <code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code> to add and remove the constructor of the functor. We provide a special instance for <code class="codecolorer text mac-classic"><span class="text">String</span></code>, since it doesn&#8217;t have a standard pickler. We choose to use the pickler that allows empty strings.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">instance</span> XmlPickler a <span style="color: #339933; font-weight: bold;">=&gt;</span> GXmlPickler <span style="color: green;">&#40;</span>K a<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef <span style="color: #339933; font-weight: bold;">_</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>K<span style="color: #339933; font-weight: bold;">,</span> unK<span style="color: green;">&#41;</span> `xpWrap` xpickle<br />
<br />
<span style="color: #06c; font-weight: bold;">instance</span> GXmlPickler <span style="color: green;">&#40;</span>K <span style="color: #cccc00; font-weight: bold;">String</span><span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef <span style="color: #339933; font-weight: bold;">_</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>K<span style="color: #339933; font-weight: bold;">,</span> unK<span style="color: green;">&#41;</span> `xpWrap` xpText0</div></div>
</pre>
<p><code class="codecolorer text mac-classic"><span class="text">U</span></code> works similarly. We use the pickler for <code class="codecolorer text mac-classic"><span class="text">()</span></code>, and use xpWrap to go from a <code class="codecolorer text mac-classic"><span class="text">()</span></code> to a <code class="codecolorer text mac-classic"><span class="text">U</span></code> and back.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">instance</span> GXmlPickler U <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef <span style="color: #339933; font-weight: bold;">_</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span><span style="font-weight: bold;">const</span> U<span style="color: #339933; font-weight: bold;">,</span> <span style="font-weight: bold;">const</span> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> `xpWrap` xpUnit</div></div>
</pre>
<p>The case for <code class="codecolorer text mac-classic"><span class="text">(:+:)</span></code> is interesting. Remember that <code class="codecolorer text mac-classic"><span class="text">(:+:)</span></code> represents a choice between two functors. If we have picklers for both of these, we can define a pickler for the sum as follows: during conversion to XML, we can pattern match on <code class="codecolorer text mac-classic"><span class="text">L</span></code> or <code class="codecolorer text mac-classic"><span class="text">R</span></code> (the constructors of <code class="codecolorer text mac-classic"><span class="text">(:+:)</span></code>) and choose the left or right pickler appropriately. During conversion from XML, we try the first pickler. If it fails (an unpickler returns a <code class="codecolorer text mac-classic"><span class="text">Maybe</span></code> value) we try the second. Since HXT doesn&#8217;t seem to have a combinator that follows this logic, let&#8217;s define one ourselves:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">xpEither <span style="color: #339933; font-weight: bold;">::</span> PU <span style="color: green;">&#40;</span>f r<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> PU <span style="color: green;">&#40;</span>g r<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> PU <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>f :<span style="color: #339933; font-weight: bold;">+</span>: g<span style="color: green;">&#41;</span> r<span style="color: green;">&#41;</span><br />
xpEither <span style="color: green;">&#40;</span>PU fl tl sa<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>PU fr tr sb<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> PU<br />
&nbsp; <span style="color: green;">&#40;</span>\<span style="color: green;">&#40;</span>x<span style="color: #339933; font-weight: bold;">,</span> st<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #06c; font-weight: bold;">case</span> x <span style="color: #06c; font-weight: bold;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;L y <span style="color: #339933; font-weight: bold;">-&gt;</span> fl <span style="color: green;">&#40;</span>y<span style="color: #339933; font-weight: bold;">,</span> st<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;R y <span style="color: #339933; font-weight: bold;">-&gt;</span> fr <span style="color: green;">&#40;</span>y<span style="color: #339933; font-weight: bold;">,</span> st<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><br />
&nbsp; <span style="color: green;">&#40;</span>\x <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #06c; font-weight: bold;">case</span> tl x <span style="color: #06c; font-weight: bold;">of</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: green;">&#40;</span>Nothing<span style="color: #339933; font-weight: bold;">,</span> <span style="color: #339933; font-weight: bold;">_</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> lmap <span style="color: green;">&#40;</span><span style="font-weight: bold;">fmap</span> R<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>tr x<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;r &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933; font-weight: bold;">-&gt;</span> lmap <span style="color: green;">&#40;</span><span style="font-weight: bold;">fmap</span> L<span style="color: green;">&#41;</span> r<span style="color: green;">&#41;</span><br />
&nbsp; <span style="color: green;">&#40;</span>sa `scAlt` sb<span style="color: green;">&#41;</span><br />
&nbsp; <span style="color: #06c; font-weight: bold;">where</span> lmap f <span style="color: green;">&#40;</span>a<span style="color: #339933; font-weight: bold;">,</span> b<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>f a<span style="color: #339933; font-weight: bold;">,</span> b<span style="color: green;">&#41;</span></div></div>
</pre>
<p>Note that we take apart the <code class="codecolorer text mac-classic"><span class="text">PU</span></code> type, and create a pretty printer, a parser and a schema separately. We can use this function in the <code class="codecolorer text mac-classic"><span class="text">GXmlPickler</span></code> instance by supplying it with two picklers, created by recursive calls to <code class="codecolorer text mac-classic"><span class="text">gxpicklef</span></code>.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>GXmlPickler f<span style="color: #339933; font-weight: bold;">,</span> GXmlPickler g<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> GXmlPickler <span style="color: green;">&#40;</span>f :<span style="color: #339933; font-weight: bold;">+</span>: g<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef f <span style="color: #339933; font-weight: bold;">=</span> xpEither <span style="color: green;">&#40;</span>gxpicklef f<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>gxpicklef f<span style="color: green;">&#41;</span></div></div>
</pre>
<p>The instance for <code class="codecolorer text mac-classic"><span class="text">(:*:)</span></code> is easy again. Since <code class="codecolorer text mac-classic"><span class="text">(:*:)</span></code> combines two functors, we can require that these two have a pickler. We use <code class="codecolorer text mac-classic"><span class="text">xpPair</span></code> to combine these into a pickler for a pair, and then use <code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code> again to convert it into a pickler for <code class="codecolorer text mac-classic"><span class="text">(:*:)</span></code>.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>GXmlPickler f<span style="color: #339933; font-weight: bold;">,</span> GXmlPickler g<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> GXmlPickler <span style="color: green;">&#40;</span>f :<span style="color: #339933; font-weight: bold;">*</span>: g<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef f <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span><span style="font-weight: bold;">uncurry</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>a :<span style="color: #339933; font-weight: bold;">*</span>: b<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;">,</span> b<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; `xpWrap`<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span>gxpicklef f `xpPair` gxpicklef f<span style="color: green;">&#41;</span></div></div>
</pre>
<p>Note that so far, we haven&#8217;t created any XML tags ourselves. We&#8217;ve only combined picklers. Now we come to the instances for constructors and record selectors. Here, we&#8217;ll use the constructor or selector name (converted to lowercase) to generate and parse xml tags. This is done with the <code class="codecolorer text mac-classic"><span class="text">xpElem</span></code> combinator.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>Constructor c<span style="color: #339933; font-weight: bold;">,</span> GXmlPickler f<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> GXmlPickler <span style="color: green;">&#40;</span>C c f<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef f <span style="color: #339933; font-weight: bold;">=</span> xpElem <span style="color: green;">&#40;</span><span style="font-weight: bold;">map</span> toLower <span style="color: #339933; font-weight: bold;">$</span> conName <span style="color: green;">&#40;</span><span style="font-weight: bold;">undefined</span> <span style="color: #339933; font-weight: bold;">::</span> C c f r<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>C<span style="color: #339933; font-weight: bold;">,</span> unC<span style="color: green;">&#41;</span> `xpWrap` gxpicklef f<span style="color: green;">&#41;</span><br />
<br />
<span style="color: #06c; font-weight: bold;">instance</span> <span style="color: green;">&#40;</span>Selector s<span style="color: #339933; font-weight: bold;">,</span> GXmlPickler f<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> GXmlPickler <span style="color: green;">&#40;</span>S s f<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; gxpicklef f <span style="color: #339933; font-weight: bold;">=</span> xpElem <span style="color: green;">&#40;</span><span style="font-weight: bold;">map</span> toLower <span style="color: #339933; font-weight: bold;">$</span> selName <span style="color: green;">&#40;</span><span style="font-weight: bold;">undefined</span> <span style="color: #339933; font-weight: bold;">::</span> S s f r<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>S<span style="color: #339933; font-weight: bold;">,</span> unS<span style="color: green;">&#41;</span> `xpWrap` gxpicklef f<span style="color: green;">&#41;</span></div></div>
</pre>
<p>We now have picklers for all generic representations built from the standard functors in regular. We still need a top level function that works on our real data types, though. Regular provides the two functions <code class="codecolorer text mac-classic"><span class="text">to</span></code> and <code class="codecolorer text mac-classic"><span class="text">from</span></code> to convert between data types and their generic representation. We can use these together with <code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code> to change our generic pickler into a pickler for real data types. Another matter we have not addressed is the first argument to <code class="codecolorer text mac-classic"><span class="text">gpicklef</span></code>, which is a pickler for the recursive positions. Here we pass the top level function, since the recursive position contains our original data type again.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">gxpickle <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>Regular a<span style="color: #339933; font-weight: bold;">,</span> GXmlPickler <span style="color: green;">&#40;</span>PF a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> PU a<br />
gxpickle <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>to<span style="color: #339933; font-weight: bold;">,</span> from<span style="color: green;">&#41;</span> `xpWrap` gxpicklef gxpickle</div></div>
</pre>
<p>And that&#8217;s all for the generic XML pickler. Using it is very simple. To use it for our user data type above, we import <code class="codecolorer text mac-classic"><span class="text">Generic.Regular</span></code>, <code class="codecolorer text mac-classic"><span class="text">Generic.Regular.TH</span></code>, <code class="codecolorer text mac-classic"><span class="text">Generic.Regular.XmlPickler</span></code> and <code class="codecolorer text mac-classic"><span class="text">Text.XML.HXT.Arrow.Pickle</span></code>. We can then derive the <code class="codecolorer text mac-classic"><span class="text">Regular</span></code> instance for user (note that we need a little bit of extra code, since Template Haskell cannot generate type family instances yet), and make an <code class="codecolorer text mac-classic"><span class="text">XmlPickler</span></code> instance:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933; font-weight: bold;">$</span><span style="color: green;">&#40;</span>deriveAll ''User <span style="background-color: #3cb371;">&quot;PFUser&quot;</span><span style="color: green;">&#41;</span><br />
<span style="color: #06c; font-weight: bold;">type</span> <span style="color: #06c; font-weight: bold;">instance</span> PF User <span style="color: #339933; font-weight: bold;">=</span> PFUser<br />
<br />
<span style="color: #06c; font-weight: bold;">instance</span> XmlPickler User <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; xpickle <span style="color: #339933; font-weight: bold;">=</span> gxpickle</div></div>
</pre>
<p>And that&#8217;s it! The package is available as <a href="http://hackage.haskell.org/package/regular-xmlpickler">regular-xmlpickler</a> on hackage, and the source can also be found on <a href="http://github.com/typLAB/regular-xmlpickler">github</a>. The packages <a href="http://hackage.haskell.org/package/regular">regular</a> and <a href="http://hackage.haskell.org/package/hxt">HXT</a> can also be found on hackage.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.silkapp.com/2009/11/writing-a-generic-xml-pickler/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Haskell data types and XML</title>
		<link>http://blog.silkapp.com/2009/09/haskell-data-types-and-xml/</link>
		<comments>http://blog.silkapp.com/2009/09/haskell-data-types-and-xml/#comments</comments>
		<pubDate>Thu, 24 Sep 2009 06:42:28 +0000</pubDate>
		<dc:creator>Sebas</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blog.typlab.com/?p=15</guid>
		<description><![CDATA[Here at typLAB it wasn&#8217;t evident from the beginning what would be the best choice for a storage back-end. We knew that we were about to build a web based editor and would be dealing with a lot of HTML5 documents with lots of meta data. After some careful consideration we decided to go for [...]]]></description>
			<content:encoded><![CDATA[<p>Here at typ<span class="lab">LAB</span> it wasn&#8217;t evident from the beginning what would be the best choice for a storage back-end. We knew that we were about to build a web based editor and would be dealing with a lot of <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/">HTML5</a> documents with lots of meta data. After some careful consideration we decided to go for an XML database. More specifically, the <a href="http://www.oracle.com/database/berkeley-db/xml/index.html">Berkeley XML Database</a>, lovingly called DBXML by its authors.</p>
<p>We figured that using DBXML would give us some important advantages:</p>
<ul>
<li>Collections of HTML5 documents will form the basis of data model. Only one trivial conversion from HTML5 to syntactically valid XML is needed to get our documents into the XML database. Once stored we can perform some interesting queries over our data.</li>
<li>XML databases allow for the storage of complex data layouts without having a strict schema. Without a schema it will be easier to adjust our data model over time without instantly breaking our software.</li>
<li><a href="http://www.w3.org/TR/xquery/">XQuery</a> is a very expressive (almost-purely functional) querying language which is at least as powerful as SQL and far more flexible in the structure of the data to target.</li>
<li>XML can be used to both encode strictly defined datatypes and store free-form documents in the same document collection. This will enable us to put both our meta data and our documents in the same database.</li>
<li>A quick look on Hackage revealed there is an out-of-the-box easy-to-use <a href="http://hackage.haskell.org/package/BerkeleyDBXML">Haskell binding</a> available for the Berkeley XML database. No need to create custom bindings ourselves.</li>
<li>We are in the advantage (or disadvantage) of having Haskell as our language of choice for our server software. Because of the hierarchical nature of both XML and Haskell algebraic datatypes, an XML database feels like a perfect fit.</li>
</ul>
<p>Once we decided to go for an DBXML back-end we had to figure out how to easily get values form our Haskell program in and out of the database. The rest of this post will be dealing with the last point of our enumeration: how to get a nice mapping from Haskell&#8217;s algebraic datatypes to our DBXML back-end.</p>
<p><span id="more-15"></span></p>
<h2>XML queries</h2>
<p>The DBXML binding for Haskell is a shallow wrapper around the existing C++ API. This library allows us to perform the common create, read, update and delete queries for entire XML documents or parts of it. Communication with the XML database happens mainly via XQuery. Queries and query parameters are passed into the API (and results will come out) using Haskell <a href="http://hackage.haskell.org/packages/archive/bytestring/0.9.1.4/doc/html/Data-ByteString.html#1"><code class="codecolorer text mac-classic"><span class="text">ByteString</span></code></a>s. It is up to the programmer to setup the queries with the right XML structure and encoding. Take for example the (somewhat simplified) type signature of the <code class="codecolorer text mac-classic"><span class="text">query</span></code> function:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">query <span style="color: #339933; font-weight: bold;">::</span> Collection <span style="color: #339933; font-weight: bold;">-&gt;</span> Query <span style="color: #339933; font-weight: bold;">-&gt;</span> Parameters <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#91;</span>ByteString<span style="color: green;">&#93;</span></div></div>
</pre>
<p>This function takes an identification of the XML collection, which is somewhat like a database handle, an XML query, a set of query parameters and returns a possibly empty list of XML snippets as <code class="codecolorer text mac-classic"><span class="text">ByteString</span></code>s. Too bad that all our domain objects are well-typed Haskell algebraic datatypes and not raw sequences of bytes. We need a simple XML (de)serialization tool for this.</p>
<h2>XML picklers</h2>
<p>The <a href="http://hackage.haskell.org/package/hxt">Haskell XML Toolbox</a> (HXT) is a library containing a (quite extended) collection of XML processing tools. The library has support for XML parsing, pretty printing, XPath queries, XSL stylesheets, DTD, XSD and RelaxNG schemas and a lot more. Interestingly, HXT exposes a type class and an accompanying set of combinators called XML picklers. XML picklers can be used to build conversion functions from Haskell datatypes to XML and vice versa. The type class looks like this:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; <span style="color: #06c; font-weight: bold;">class</span> XmlPickler a <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; &nbsp; xpickle <span style="color: #339933; font-weight: bold;">::</span> PU a</div></div>
</pre>
<p>So for every type in the <a href="http://hackage.haskell.org/packages/archive/hxt/8.3.1/doc/html/Text-XML-HXT-Arrow-Pickle.html#t%3AXmlPickler"><code class="codecolorer text mac-classic"><span class="text">XmlPickler</span></code></a> type class there is some <a href="http://hackage.haskell.org/packages/archive/hxt/8.3.1/doc/html/Text-XML-HXT-Arrow-Pickle.html#t%3APU"><code class="codecolorer text mac-classic"><span class="text">PU</span></code></a> available. The <code class="codecolorer text mac-classic"><span class="text">PU</span></code> datatype is composed of a pair of pickle (serialize) and unpickle (deserialize) functions together with a schema description. Because we won&#8217;t be using the schema definitions we will ignore them for now. There is probably no need to ever touch the functions inside the <code class="codecolorer text mac-classic"><span class="text">PU</span></code> type, because the library supplies a vast amount of basic pickler combinators to be used instead.</p>
<p>To illustrate the usage of HXT picklers take this simple Haskell datatype representing a single user in our system:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">data</span> User <span style="color: #339933; font-weight: bold;">=</span> User<br />
&nbsp; <span style="color: green;">&#123;</span> name &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><br />
&nbsp; <span style="color: #339933; font-weight: bold;">,</span> email &nbsp; &nbsp;<span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><br />
&nbsp; <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><br />
&nbsp; <span style="color: #339933; font-weight: bold;">,</span> openID &nbsp; <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">String</span><br />
&nbsp; <span style="color: green;">&#125;</span></div></div>
</pre>
<p>Using some of the basic pickler combinators from the library it is very easy to come up with a suitable <code class="codecolorer text mac-classic"><span class="text">XmlPickler</span></code> instance:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #06c; font-weight: bold;">class</span> XmlPickler User <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; userPickle <span style="color: #339933; font-weight: bold;">=</span><br />
&nbsp; &nbsp; xpElem <span style="background-color: #3cb371;">&quot;user&quot;</span><br />
&nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">$</span> xpWrap<br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span> <span style="color: green;">&#40;</span>\<span style="color: green;">&#40;</span>a<span style="color: #339933; font-weight: bold;">,</span> b<span style="color: #339933; font-weight: bold;">,</span> c<span style="color: #339933; font-weight: bold;">,</span> d<span style="color: #339933; font-weight: bold;">,</span> e<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> User a b c d e<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">,</span> <span style="color: green;">&#40;</span>\<span style="color: green;">&#40;</span>User a b c d e<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;">,</span> b<span style="color: #339933; font-weight: bold;">,</span> c<span style="color: #339933; font-weight: bold;">,</span> d<span style="color: #339933; font-weight: bold;">,</span> e<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">$</span> xp5Tuple<br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span>xpElem <span style="background-color: #3cb371;">&quot;username&quot;</span> xpText<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span>xpElem <span style="background-color: #3cb371;">&quot;name&quot;</span> &nbsp; &nbsp; xpText<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span>xpElem <span style="background-color: #3cb371;">&quot;password&quot;</span> xpText<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span>xpElem <span style="background-color: #3cb371;">&quot;email&quot;</span> &nbsp; &nbsp;xpText<span style="color: green;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: green;">&#40;</span>xpElem <span style="background-color: #3cb371;">&quot;openid&quot;</span> &nbsp; xpText0<span style="color: green;">&#41;</span></div></div>
</pre>
<p>This instance uses the <a href="http://hackage.haskell.org/packages/archive/hxt/8.3.1/doc/html/Text-XML-HXT-Arrow-Pickle.html#v%3Axp5Tuple"><code class="codecolorer text mac-classic"><span class="text">xp5Tuple</span></code></a> function to pickle five sub-picklers into a big tuple. The five fields will be appropriately named elements from which the text value will be used. The tuple will be converted into a value of the <code class="codecolorer text mac-classic"><span class="text">User</span></code> datatype using the <a href="http://hackage.haskell.org/packages/archive/hxt/8.3.1/doc/html/Text-XML-HXT-Arrow-Pickle.html#v%3AxpWrap"><code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code></a> function. This is all you to need to manually write XML serialization and deserialization code.</p>
<p>A bit off topic but interesting to note is the fact that the <code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code> function can be seen as a pickler specific and bidirectional version of the well known <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><code class="codecolorer text mac-classic"><span class="text">fmap</span></code></a> for <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t%3AFunctor"><code class="codecolorer text mac-classic"><span class="text">Functor</span></code></a>s. The <code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code> is used to define true isomorphisms. When we generalize the type of <code class="codecolorer text mac-classic"><span class="text">xpWrap</span></code> to work arbitrary containers, lets call this function <code class="codecolorer text mac-classic"><span class="text">bifmap</span></code>, and compare the type signatures this similarity becomes obvious:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="font-weight: bold;">fmap</span> &nbsp; <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">-&gt;</span> b<span style="color: green;">&#41;</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933; font-weight: bold;">-&gt;</span> f a <span style="color: #339933; font-weight: bold;">-&gt;</span> f b<br />
bifmap <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>a <span style="color: #339933; font-weight: bold;">-&gt;</span> b<span style="color: #339933; font-weight: bold;">,</span> b <span style="color: #339933; font-weight: bold;">-&gt;</span> a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> f a <span style="color: #339933; font-weight: bold;">-&gt;</span> f b</div></div>
</pre>
<p>So, taking the <code class="codecolorer text mac-classic"><span class="text">XmlPickler</span></code> instance for our <code class="codecolorer text mac-classic"><span class="text">User</span></code> datatype we can now easily convert users into XML and read them back in, like the following example:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">User <span style="background-color: #3cb371;">&quot;jd&quot;</span> <span style="background-color: #3cb371;">&quot;John Doe&quot;</span> <span style="background-color: #3cb371;">&quot;secret&quot;</span> <span style="background-color: #3cb371;">&quot;john@doe&quot;</span> <span style="background-color: #3cb371;">&quot;none&quot;</span></div></div>
</pre>
<pre>
<div class="codecolorer-container xml mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="xml codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;user<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;username<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>jd<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/username<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>John Doe<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;password<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>secret<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/password<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;email<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>john@doe<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/email<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
&nbsp; <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;openid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>none<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/openid<span style="color: #000000; font-weight: bold;">&gt;</span></span></span><br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/user<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></div></div>
</pre>
<p>Using the <a href="http://hackage.haskell.org/packages/archive/hxt/8.3.1/doc/html/Text-XML-HXT-Arrow-Pickle.html#t%3AXmlPickler"><code class="codecolorer text mac-classic"><span class="text">xpickle</span></code></a> function from the type class and the <a href="http://hackage.haskell.org/packages/archive/hxt/8.3.1/doc/html/Text-XML-HXT-Arrow-Pickle.html#v%3AxunpickleVal"><code class="codecolorer text mac-classic"><span class="text">xunpickleVal</span></code></a> from the HXT library we can now write a more suitable query function on top of the raw version. This version does not return <code class="codecolorer text mac-classic"><span class="text">ByteString</span></code>s, but values of any type we can convert to. Off course, the information in the database should match your datatype, otherwise the unpickler function will just produce parse errors resulting in an empty list.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">query <span style="color: #339933; font-weight: bold;">::</span> XmlPickler a <span style="color: #339933; font-weight: bold;">=&gt;</span> Collection <span style="color: #339933; font-weight: bold;">-&gt;</span> Query <span style="color: #339933; font-weight: bold;">-&gt;</span> Parameters <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span></div></div>
</pre>
<p>Although this pickler example for our user is a very simple one, even more complicated datatypes, including multi-constructor and possibly mutual recursive datatypes, can quite easily be made an instance of the <code class="codecolorer text mac-classic"><span class="text">XmlPickler</span></code> class. Unfortunately we still have to write them all by hand.</p>
<h2>Going generic</h2>
<p>After a few of years at the University of Utrecht we learned at least one valuable lesson, never write functions by hand when they can be <a href="http://www.cs.uu.nl/wiki/GenericProgramming">derived generically</a>. We decided to write a generic XML pickler function using the generic programming library <a href="http://hackage.haskell.org/package/regular">Regular</a>, developed (not entirely coincidentally) at the University of Utrecht. Regular is a relatively simple but powerful tool for writing data type generic functions. The library has support for deriving embedding projection pairs (conversions from and to a generic representation) using <a href="http://www.haskell.org/th/">Template Haskell</a> and provides enough reflection to inspect constructor names and record labels.</p>
<p>The generic representation is encoded as a type family (the pattern functor, or <code class="codecolorer text mac-classic"><span class="text">PF</span></code>) over the original data type. The generic pickler function we developed has the following signature:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">gxpickle <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span>Regular a<span style="color: #339933; font-weight: bold;">,</span> GXmlPickler <span style="color: green;">&#40;</span>PF a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> PU a</div></div>
</pre>
<p>This means that for every type that we can convert to a generic representation (indicated by the <code class="codecolorer text mac-classic"><span class="text">Regular</span></code> type class) and for every type that has a <code class="codecolorer text mac-classic"><span class="text">GXmlPickler</span></code> instance for its generic representation, we can deliver a <code class="codecolorer text mac-classic"><span class="text">PU</span></code>. The <code class="codecolorer text mac-classic"><span class="text">regular-xmlpickler</span></code> package implements the <code class="codecolorer text mac-classic"><span class="text">GXmlPickler</span></code> type class and the instances for the types of which the representations are composed. So, all we need now for our <code class="codecolorer text mac-classic"><span class="text">User</span></code> datatype is to derive a generic representation and use the generic implementation for the <code class="codecolorer text mac-classic"><span class="text">XmlPickler</span></code> instance.</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933; font-weight: bold;">$</span><span style="color: green;">&#40;</span>deriveAll ''User <span style="background-color: #3cb371;">&quot;PFUser&quot;</span><span style="color: green;">&#41;</span><br />
<span style="color: #06c; font-weight: bold;">type</span> <span style="color: #06c; font-weight: bold;">instance</span> PF User <span style="color: #339933; font-weight: bold;">=</span> PFUser<br />
<br />
<span style="color: #06c; font-weight: bold;">instance</span> XmlPickler User <span style="color: #06c; font-weight: bold;">where</span><br />
&nbsp; xpickle <span style="color: #339933; font-weight: bold;">=</span> gxpickle</div></div>
</pre>
<p>Using this automatically derived XML pickler and the query function described above we can now query the DBXML backend for all users that satisfy a certain property:</p>
<pre>
<div class="codecolorer-container haskell mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="haskell codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">jd <span style="color: #339933; font-weight: bold;">::</span> <span style="color: #cccc00; font-weight: bold;">IO</span> <span style="color: green;">&#91;</span>User<span style="color: green;">&#93;</span><br />
jd <span style="color: #339933; font-weight: bold;">=</span> query myCollection <span style="background-color: #3cb371;">&quot;/user[username=$name]&quot;</span> <span style="color: green;">&#91;</span><span style="color: green;">&#40;</span><span style="background-color: #3cb371;">&quot;name&quot;</span><span style="color: #339933; font-weight: bold;">,</span> <span style="background-color: #3cb371;">&quot;jd&quot;</span><span style="color: green;">&#41;</span><span style="color: green;">&#93;</span></div></div>
</pre>
<p>Now we&#8217;re able to query a database for pieces of XML and reify these as true Haskell values with almost no boilerplate involved! Because of the bidirectional behavior of the <code class="codecolorer text mac-classic"><span class="text">XmlPickler</span></code> type class it shouldn&#8217;t be difficult to imagine that the same trick is applicable to inserting and updating database entries.</p>
<p>We will discuss writing generic functions using the Regular library in a later post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.silkapp.com/2009/09/haskell-data-types-and-xml/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Why we use Haskell</title>
		<link>http://blog.silkapp.com/2009/09/why-we-use-haskell/</link>
		<comments>http://blog.silkapp.com/2009/09/why-we-use-haskell/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 13:42:43 +0000</pubDate>
		<dc:creator>Erik</dc:creator>
				<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://blog.typlab.com/?p=68</guid>
		<description><![CDATA[As a newly started company, we have a lot of technical decisions to make. One of the important ones is the choice of a programming language. Since we&#8217;re building a web application, this goes for both the client (i.e. the web browser) and the server. On the client, there wasn&#8217;t much discussion. Javascript is the [...]]]></description>
			<content:encoded><![CDATA[<p>As a newly started company, we have a lot of technical decisions to make. One of the important ones is the choice of a programming language. Since we&#8217;re building a web application, this goes for both the client (i.e. the web browser) and the server.</p>
<p>On the client, there wasn&#8217;t much discussion. Javascript is the only viable choice, unless you want to use Flash or similar plugin-based models. But on the server, we had more freedom. Popular choices for web applications are dynamically typed languages like Ruby, Python and PHP, and statically typed languages like Java and C#.</p>
<p>However, there was another option. Two of us (me and Sebas) are enrolled in the Software Technology master program at Utrecht University, where we often use the programming language Haskell. Haskell is a functional programming language, which means that a program is composed of expressions instead of statements, as is the case in an imperative programming language.</p>
<p>As you might have guessed from the title of this post, we decided to use Haskell for our server side programming. What are the features that made us choose Haskell?<br />
<span id="more-68"></span><br />
First, we like the functional programming model. Modeling programs based on what values are, instead of what bits to move where, is much closer to the way we think. We write down what we mean, and let the compiler figure out how to calculate it. This also leads to shorter code: Haskell is often surprisingly concise.</p>
<p>Another important consideration is the strong type system that Haskell has. It has powerful features that prevent you from running incorrect programs, while not getting in the way, as is often the case in traditional statically typed languages like Java or C#. This is due to the fact that Haskell has type inference: it can deduce the types of variables and functions without programmer specifications.</p>
<p>Something that sets Haskell apart from almost all other programming languages, is its purity: an expression in Haskell is not allowed to do anything on evaluation other than return its value (functions are not allowed to have side-effects). This has many implications. For example, data is immutable: if you modify a list, for example, you create a new copy (although smart compilers share duplicate parts for efficiency). This means that you never have to think about other parts of the code changing your data: you can always reason locally. Another implication is that your language can be lazy (and in fact, Haskell is). This means that expressions are not evaluated unless their results are needed. This can lead to performance improvements, and allows you to use infinite data structures.</p>
<p>If we disallow side effects, how do we perform I/O, for example? Haskell uses an abstraction called a monad to do this. A monad shows up in the type, indicating that we are performing side effects. The I/O monad allows us to force an ordering on actions, allowing us to safely perform the actions in a lazy setting. We can also use monads to keep state, have mutable variables, and many other things.</p>
<p>Purity also makes concurrency a lot easier: if data is immutable, there is no risk in sharing it between different threads. If you need to share mutable data between different threads, Haskell offers a few ways of dealing with this, the most interesting of which is software transactional memory (STM), a lock-free way of building composable atomic actions.</p>
<p>Since Haskell is a functional language, functions are first class: you can create them on the fly, pass them as arguments, return them as results, store them in a data structure, etc. This allows you to easily create powerful abstractions. For example, one often-used Haskell function is map. It takes an argument that turns a value of type a into a value of type b, and uses this to transform a list of a&#8217;s into a list of b&#8217;s by applying it to each element. This function abstracts away looping over a list. In a similar way we can create our own abstractions. This often leads to the creation of lightweight EDSLs (embedded domain specific languages), especially since Haskell allows the creation of (infix) operators as well.</p>
<p>The combination of conciseness, locality of data, strong types and explicit side-effects has a very important consequence: it makes refactoring easy and risk-free. You can change your code, and if it still type checks, you can often be sure that it still works. Combined with the power of abstraction this means we can quickly develop programs that can be easily understood and modified by others.</p>
<p>Finally, another positive aspect of Haskell is its community. There is an <a title="planet haskell" href="http://planet.haskell.org/">active blog community</a>, a large and helpful IRC channel (#haskell) and an <a title="Hackage" href="http://hackage.haskell.org/">online package repository</a>. There is an <a title="GHC" href="http://www.haskell.org/ghc/">industrial strength compiler</a>, a <a title="Cabal" href="http://www.haskell.org/cabal/">dependency tracking package manager</a> and built-in tools like code coverage.</p>
<p>Of course, there are also a few risks involved in choosing a language like Haskell. Since it doesn&#8217;t have a user base as large as some other languages, there are less libraries available. This is alleviated in part by a strong C interface that Haskell provides. Because of laziness, performance problems can be harder to diagnose and fix. And of course, there are less programmers who have experience with Haskell, so finding people to help you can be harder.</p>
<p>But all in all, we feel that the benefits Haskell can bring us outweigh the risks. And most of all, Haskell makes programming fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.silkapp.com/2009/09/why-we-use-haskell/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
	</channel>
</rss>
