<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Reiner Pope</title>
	<atom:link href="http://reinerp.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://reinerp.wordpress.com</link>
	<description>Thoughts about Haskell</description>
	<lastBuildDate>Sat, 10 Oct 2009 09:39:05 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='reinerp.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Reiner Pope</title>
		<link>http://reinerp.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://reinerp.wordpress.com/osd.xml" title="Reiner Pope" />
	<atom:link rel='hub' href='http://reinerp.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Instance Datatypes: a language extension</title>
		<link>http://reinerp.wordpress.com/2009/10/10/instance-datatypes-a-language-extension/</link>
		<comments>http://reinerp.wordpress.com/2009/10/10/instance-datatypes-a-language-extension/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 09:12:26 +0000</pubDate>
		<dc:creator>Reiner Pope</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[Instance-datatypes]]></category>

		<guid isPermaLink="false">http://reinerp.wordpress.com/?p=82</guid>
		<description><![CDATA[Consider: for any Applicative f and Num a, we could make (f a) a Num, using the declaration &#62; instance (Applicative f, Num a) =&#62; Num (f a) where &#62; (+) = liftA2 (+) &#62; (*) = liftA2 (*) &#62; ... However, we never actually want to declare such a general instance as the one [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=82&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Consider: for any Applicative <code>f</code> and Num <code>a</code>, we could make <code>(f a)</code> a <code>Num</code>, using the declaration</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> (Applicative f, Num a) <span style="color:red;">=&gt;</span> Num (f a) <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     (+) <span style="color:red;">=</span> liftA2 (+)
&gt;     (*) <span style="color:red;">=</span> liftA2 (*)
&gt;     ...
</pre>
<p>However, we never actually want to declare such a general instance as the one above, because it rules out instances which aren’t implemented via <code>Applicative</code>. Instead, a better approach is for some library to define</p>
<pre>&gt; applicativePlus  <span style="color:red;">=</span> liftA2 (+)
&gt; applicativeTimes <span style="color:red;">=</span> liftA2 (*)
&gt; ...
</pre>
<p>and then have everyone who wants the Applicative instance for their particular type (say, <code>Foo</code>) write</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Num (Foo a) <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     (+) <span style="color:red;">=</span> applicativePlus
&gt;     (*) <span style="color:red;">=</span> applicativeTimes
&gt;     ...
</pre>
<p>Unfortunately, each instance we declare still needs to mention all 6 functions in the <code>Num</code> class. What I would like to do is to say to Haskell, “use the <code>Applicative</code> instance for <code>Num</code>”, and say it just once.<a id="fnref1" class="footnoteRef" href="#fn1"><sup>1</sup></a></p>
<p>Here is a language extension that could allow you to do that. For want of a better name, I will refer to it as “Instance Datatypes” (ID).</p>
<div id="the-extension">
<h1>The extension</h1>
<p>For each class declaration</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">class</span></span> cxt <span style="color:red;">=&gt;</span> C a1 ... an <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;    v1 <span style="color:red;">::</span> ty1
&gt;    ...
&gt;    vn <span style="color:red;">::</span> tyn
</pre>
<p>we implicitly declare the following datatype:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> <span style="color:red;">@</span>C a1 ... an <span style="color:red;">=</span>
&gt;    <span style="color:red;">@</span>C {
&gt;       <span style="color:red;">@</span>v1 <span style="color:red;">::</span> ty1,
&gt;       ...
&gt;       <span style="color:red;">@</span>vn <span style="color:red;">::</span> tyn
&gt;     }
</pre>
<p>Note that superclasses are irrelevant as far as the datatype is concerned.</p>
<p>A new syntactic form for instance declarations is added:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> cxt <span style="color:red;">=&gt;</span> C ty1 ... tyn <span style="color:red;">=</span> expr
</pre>
<p>which is semantically equivalent to</p>
<pre>&gt; d <span style="color:red;">::</span> cxt <span style="color:red;">=&gt;</span> <span style="color:red;">@</span>C ty1 ... tyn
&gt; d <span style="color:red;">=</span> expr
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> cxt <span style="color:red;">=&gt;</span> C ty1 ... tyn <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;    v1 <span style="color:red;">=</span> <span style="color:red;">@</span>v1 d
&gt;    ...
&gt;    vn <span style="color:red;">=</span> <span style="color:red;">@</span>vn d
</pre>
<p>where <code>d</code> is some unused variable name.<a id="fnref2" class="footnoteRef" href="#fn2"><sup>2</sup></a></p>
<p>The <code>@C</code> values can be constructed and deconstructed just as ordinary record datatypes. So, for example, we could build an <code>@Eq</code> value:</p>
<pre>&gt; buildEq <span style="color:red;">::</span> (a <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> Bool) <span style="color:red;">-&gt;</span> <span style="color:red;">@</span>Eq a
&gt; buildEq eq <span style="color:red;">=</span> <span style="color:red;">@</span>Eq {
&gt;                    (@==) <span style="color:red;">=</span> eq,
&gt;                    (@/=) <span style="color:red;">=</span> <span style="color:red;">\</span>a b <span style="color:red;">-&gt;</span> not (a `eq` b)
&gt;                  }
</pre>
<p>Some more details of the extension are discussed later, but first I give some examples.</p>
</div>
<div id="examples">
<h1>Examples</h1>
<div id="the-Applicative-instance-for-Num-problem">
<h2>The “<code>Applicative</code> instance for <code>Num</code>” problem</h2>
<p>We solve the original problem:</p>
<pre>&gt; <span style="color:blue;"><em>-- in some library:</em></span>
&gt; applicativeNum <span style="color:red;">::</span> (Applicative f, Num a) <span style="color:red;">=&gt;</span> <span style="color:red;">@</span>Num (f a)
&gt; applicativeNum <span style="color:red;">=</span> <span style="color:red;">@</span>Num {
&gt;                     (@+) <span style="color:red;">=</span> liftA2 (+),
&gt;                     (@*) <span style="color:red;">=</span> liftA2 (*),
&gt;                     ...
&gt;                   }
&gt;
&gt; <span style="color:blue;"><em>-- when you actually want to declare an instance</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Num (MyApplicative Double) <span style="color:red;">=</span> applicativeNum
</pre>
</div>
<div id="generalized-newtype-deriving">
<h2>Generalized Newtype Deriving</h2>
<p>There is an intersection between Instance Datatypes and Generalized Newtype Deriving (GND). When it works, GND requires no additional code on the class designer’s part, and requires only a “deriving” clause on the class instantiator’s part. To support something like GND using ID, something like the following code would be required:</p>
<pre>&gt; <span style="color:blue;"><em>-- in some library:</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> Converter a b <span style="color:red;">=</span> (a <span style="color:red;">-&gt;</span> b, b <span style="color:red;">-&gt;</span> a)
&gt;
&gt; <span style="color:blue;"><em>-- in the class designer's library:</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">class</span></span> C a <span style="text-decoration:underline;"><span style="color:green;">where</span></span> ...
&gt; liftC <span style="color:red;">::</span> C a <span style="color:red;">=&gt;</span> Converter a b <span style="color:red;">-&gt;</span> <span style="color:red;">@</span>C b
&gt; liftC <span style="color:red;">=</span> ...
&gt;
&gt; <span style="color:blue;"><em>-- in the class instantiator's library:</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> MyType <span style="color:red;">=</span> Wrap { unwrap <span style="color:red;">::</span> SomeOtherType }
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> C MyType <span style="color:red;">=</span> liftC (Wrap,unwrap)
</pre>
<p>So, both the class designer, and the class instantiator would need to write more code than in GND: the class designer actually has to implement the lifter, and the class user has to write slightly more.</p>
<p>However, ID also has a few advantages over GND:</p>
<ul>
<li>more flexibility is afforded in the converter. For example, the type need not actually be a /newtype/; it could be convertible by some other mechanism. For example, we could use a <code>Converter (Complex a) (a,a)</code>.</li>
<li>more flexibility is afforded in the lifting. For example, the library designer can still make a lifter even if “the eta-reduction property does not hold”, which would cause GHC to give up.</li>
<li>It’s not broken, <a href="http://hackage.haskell.org/trac/ghc/ticket/1496">unlike GND</a>.</li>
</ul>
</div>
<div id="default-class-methods">
<h2>Default class methods</h2>
<p>ID would partly obsolete default class methods. Instead of providing default class methods, the class designer could just provide a function which creates the instance value given the minimal complete definition. For example:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">class</span></span> Eq a <span style="text-decoration:underline;"><span style="color:green;">where</span></span> ...
&gt; fromEquality <span style="color:red;">::</span> (a <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> Bool) <span style="color:red;">-&gt;</span> <span style="color:red;">@</span>Eq a
&gt; fromEquality (==) <span style="color:red;">=</span> ...
</pre>
<p>This has the advantage of moving the “minimal complete definition” statement from documentation to being patently obvious, and compiler-checkable.<a id="fnref3" class="footnoteRef" href="#fn3"><sup>3</sup></a></p>
</div>
<div id="extra-sharing">
<h2>Extra sharing</h2>
<p>In some cases, polymorphic instances can cause an unavoidable loss of sharing in Haskell98. For example, if we have<a id="fnref4" class="footnoteRef" href="#fn4"><sup>4</sup></a>:</p>
<pre>&gt; <span style="color:blue;"><em>{-# LANGUAGE UndecidableInstances #-}</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">class</span></span> C a <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     f <span style="color:red;">::</span> a
&gt;     g <span style="color:red;">::</span> a
</pre>
<pre>&gt; h <span style="color:red;">::</span> Num a <span style="color:red;">=&gt;</span> a
&gt; h <span style="color:red;">=</span> <span style="color:magenta;">5</span>^<span style="color:magenta;">100</span> <span style="color:blue;"><em>-- an "expensive" computatio</em></span></pre>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Num a <span style="color:red;">=&gt;</span> C a <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     f <span style="color:red;">=</span> ... h ...
&gt;     g <span style="color:red;">=</span> ... h ...
</pre>
<p>Since <code>h</code> is polymorphic, its result will not be cached, and <code>f</code> and <code>g</code> will not share the result of <code>h</code>. I know of no way to allow <code>f</code> and <code>g</code> to share the computation of <code>h</code> if the instance of <code>C</code> is to be polymorphic.</p>
<p>However, with instance datatypes, we might write</p>
<pre>&gt; mkC <span style="color:red;">::</span> Num a <span style="color:red;">=&gt;</span> <span style="color:red;">@</span>C a
&gt; mkC <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">let</span></span> h <span style="color:red;">=</span> <span style="color:magenta;">5</span>^<span style="color:magenta;">100</span> <span style="text-decoration:underline;"><span style="color:green;">in</span></span> <span style="color:red;">@</span>C { <span style="color:red;">@</span>f <span style="color:red;">=</span> ... h ... , <span style="color:red;">@</span>g <span style="color:red;">=</span> ... h ... }
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Num a <span style="color:red;">=&gt;</span> C a <span style="color:red;">=</span> mkC
</pre>
<p>In this case, the <code>h</code> in the let expression is monomorphic, so <code>f</code> and <code>g</code> should in fact share the computation. Although the desugaring given earlier will lose this sharing, a direct translation into GHC Core should keep it.</p>
</div>
</div>
<div id="details">
<h1>Details</h1>
<div id="special-scoping-rules">
<h2>Special scoping rules</h2>
<p>For this extension to be useful, we need to have access to the Prelude typeclasses, so we can build, for example, <code>@Num</code> values. However, the Prelude of course doesn’t (explicitly) export the <code>@Num</code> datatype. So, I propose the following rule to govern when the <code>@Num</code> datatype and its internals are in scope:</p>
<ul>
<li><code>@v</code> is in scope if and only <code>v</code> is in scope. Furthermore, <code>@v</code> may not be mentioned in any import or export lists.</li>
</ul>
</div>
<div id="collisions-with-current-identifier-names">
<h2>Collisions with current identifier names</h2>
<p>If <code>v</code> is a textual identifier (rather than a symbol), then <code>@v</code> is currently not a valid identifier. However, if <code>v</code> is symbol, then <code>@v</code> /is/ a valid identifier, and may collide with an existing identifier.</p>
</div>
<div id="associated-types">
<h2>Associated types</h2>
<p>If a class has associated datatypes or type synonyms, they can’t be declared in the datatype. As far as I can see, they must be declared at the actual instance declaration, so the syntax should perhaps be extended to</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> cxt <span style="color:red;">=&gt;</span> C ty1 ... tyn <span style="color:red;">=</span> expr <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     <span style="text-decoration:underline;"><span style="color:green;">type</span></span> TyFam1 ty1 ... tyn <span style="color:red;">=</span> tty1
&gt;     ...
&gt;     <span style="text-decoration:underline;"><span style="color:green;">type</span></span> TyFamk ty1 ... tyn <span style="color:red;">=</span> ttyk
</pre>
<p>At this point, the two instance declaration forms look very similar, and one wonders if they should in fact be merged. I believe not, because this could potentially make unclear how a class member is being defined: is it defined (a) by the declaration in the where, (b) by the @C data structure of the <code>=expr</code>, or (c) by the default class method?</p>
</div>
</div>
<div class="footnotes">
<hr />
<ol>
<li id="fn1">You already can do this, using the CPP macros of <a href="http://hackage.haskell.org/package/applicative-numbers">applicative-numbers</a>. However, while practical, it is not a particularly satisfying approach. <a class="footnoteBackLink" title="Jump back to footnote 1" href="#fnref1">↩</a></li>
<li id="fn2">Note that this desugaring may lose an opportunity for sharing. See the “Extra sharing” section for details. <a class="footnoteBackLink" title="Jump back to footnote 2" href="#fnref2">↩</a></li>
<li id="fn3">For an admittedly weak example, consider that if you write
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Eq Foo <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     <span style="color:blue;"><em>-- no definitions</em></span></pre>
<p>then GHC will not warn you that any method definitions are missing: <code>(==)</code> and <code>(/=)</code> are defined in terms of each other, so the compiler cannot tell that anything is actually missing. <a class="footnoteBackLink" title="Jump back to footnote 3" href="#fnref3">↩</a></li>
<li id="fn4">Note that the UndecidableInstances extension is far from necessary to construct examples of this sort. However, it is useful for giving a simple example. <a class="footnoteBackLink" title="Jump back to footnote 4" href="#fnref4">↩</a></li>
</ol>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/reinerp.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/reinerp.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/reinerp.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/reinerp.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/reinerp.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/reinerp.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/reinerp.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/reinerp.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/reinerp.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/reinerp.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/reinerp.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/reinerp.wordpress.com/82/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/reinerp.wordpress.com/82/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/reinerp.wordpress.com/82/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=82&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://reinerp.wordpress.com/2009/10/10/instance-datatypes-a-language-extension/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e7554bdaabd25dbf90752e4233b284f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">reinerpope</media:title>
		</media:content>
	</item>
		<item>
		<title>Making runSTArray more flexible; or, making unsafeFreeze safe.</title>
		<link>http://reinerp.wordpress.com/2009/09/18/making-runstarray-more-flexible/</link>
		<comments>http://reinerp.wordpress.com/2009/09/18/making-runstarray-more-flexible/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 16:57:10 +0000</pubDate>
		<dc:creator>Reiner Pope</dc:creator>
				<category><![CDATA[Haskell]]></category>
		<category><![CDATA[ST]]></category>

		<guid isPermaLink="false">http://reinerp.wordpress.com/?p=73</guid>
		<description><![CDATA[The code for this article is available on Hackage. Suppose I have an algorithm which imperatively builds two result arrays, and once I have built the result arrays, they will remain constant while I continue to read from them. I need to use a monad for the imperative part, but once I have finished that [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=73&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>The code for this article is available <a href="http://hackage.haskell.org/package/safe-freeze">on Hackage</a>.</p>
<p>Suppose I have an algorithm which imperatively builds two result arrays, and once I have built the result arrays, they will remain constant while I continue to read from them. I need to use a monad for the imperative part, but once I have finished that part, I will want to use the arrays as pure (immutable) arrays so that I don’t need to carry the monad around. I want my code to be efficient, so I won’t tolerate copying the data of the arrays: a mutable array and its corresponding immutable array must refer to the same data.</p>
<p>I don’t know how to do this with current array/ST libraries without using an “unsafe” function like <code>unsafeFreeze</code>. The difficulty comes from needing more than one result arrays: if we only needed one, we could use <code>runSTArray</code>, which has the following type signature<a id="fnref1" class="footnoteRef" href="#fn1"><sup>1</sup></a>:</p>
<pre><code>runSTArray :: (forall s. ST s (STArray s a)) -&gt; Array a
</code></pre>
<p>We can see the problem in this type signature: each time we run the <code>ST</code> monad, we can only produce one array.  I have found one way to address this problem. The main idea is to split the ST monad into two distinct stages: the “normal” stage, which is followed by the “freezing” stage. Reading and writing are permitted in the normal stage, and reading and freezing are permitted in the the freezing stage. This policy ensures that, once we have access to the immutable array, no further writing is permitted. Note that constructing a new array is safe in either stage, but rather pointless in the freezing stage as the array cannot be written to.  I rewrite <code>ST</code> as an indexed monad (from <a href="http://hackage.haskell.org/package/category-extras">category-extras</a>) to enforce the sequencing of the freezing stage after the normal stage:</p>
<pre>&gt; <span style="color:blue;"><em>{-# LANGUAGE EmptyDataDecls, Rank2Types #-}</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">import</span></span> Control.Monad.Indexed
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> ST s t a <span style="color:blue;"><em>-- = ...      -- exported abstract</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> IxFunctor ST
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> IxPointed ST
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> IxApplicative ST
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> IxMonad ST
</pre>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> STArray s a <span style="color:blue;"><em>-- = ...</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Array a <span style="color:blue;"><em>-- = ...</em></span></pre>
<p>I make two empty types to label the stages with:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Normal s
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Freezing s
</pre>
<p>We have construction, read, write, and freeze operations, each of which encode which stages they may be performed in:</p>
<pre>&gt; newArray <span style="color:red;">::</span> Int <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> ST (Normal s) (Normal s) (STArray s a)
&gt; readArray <span style="color:red;">::</span> STArray s a <span style="color:red;">-&gt;</span> Int <span style="color:red;">-&gt;</span> ST (stg s) (stg s) a
&gt; writeArray <span style="color:red;">::</span> STArray s a <span style="color:red;">-&gt;</span> Int <span style="color:red;">-&gt;</span> a <span style="color:red;">-&gt;</span> ST (Normal s) (Normal s) ()
&gt; freezeArray <span style="color:red;">::</span> STArray s a <span style="color:red;">-&gt;</span> ST (Freezing s) (Freezing s) (Array a)
</pre>
<p>The <code>readArray</code> is polymorphic in the stage, as it can be performed in either stage.</p>
<p>The following operation transitions from the first to the second phase:</p>
<pre>&gt; beginFreezeStage <span style="color:red;">::</span> ST (Normal s) (Freezing s) ()
</pre>
<p>Operationally, this is a no-op.</p>
<p>Finally, we have the new <code>runST</code>, which accepts <code>ST</code> operations starting and ending in either stage:</p>
<pre>&gt; runST <span style="color:red;">::</span> (<span style="text-decoration:underline;"><span style="color:green;">forall</span></span> s. ST (stg1 s) (stg2 s) a) <span style="color:red;">-&gt;</span> a
</pre>
<p>Using this interface, we can freeze both arrays safely in our initial problem, although this library would internally use <code>unsafeFreezeArray</code>:</p>
<pre>&gt; runAlgorithm <span style="color:red;">::</span> ST (Normal s) (Freezing s) (Array Double, Array Double)
&gt; runAlgorithm <span style="color:red;">=</span>
&gt;     newArray <span style="color:magenta;">10</span> (<span style="color:magenta;">0</span> <span style="color:red;">::</span> Double) &gt;&gt;&gt;= <span style="color:red;">\</span>a <span style="color:red;">-&gt;</span>
&gt;     newArray <span style="color:magenta;">20</span> (<span style="color:magenta;">0</span> <span style="color:red;">::</span> Double) &gt;&gt;&gt;= <span style="color:red;">\</span>b <span style="color:red;">-&gt;</span>
&gt;     writeArray a <span style="color:magenta;">5</span> <span style="color:magenta;">3</span> &gt;&gt;&gt;= <span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span>
&gt;     readArray b <span style="color:magenta;">4</span> &gt;&gt;&gt;= <span style="color:red;">\</span><strong><span style="color:magenta;">_val</span></strong> <span style="color:red;">-&gt;</span>
&gt;     <span style="color:blue;"><em>-- and do some more stuff with the array</em></span>
&gt;     beginFreezeStage &gt;&gt;&gt;= <span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span>
&gt;     freezeArray a &gt;&gt;&gt;= <span style="color:red;">\</span>fa <span style="color:red;">-&gt;</span>
&gt;     freezeArray b &gt;&gt;&gt;= <span style="color:red;">\</span>fb <span style="color:red;">-&gt;</span>
&gt;     ireturn (fa,fb)
</pre>
<p>Edit: I realise now that the <code>beginFreezeStage</code> operator isn’t necessary; by a small modification of the types, we can make the freeze stage start when some form of <code>freeze</code> is first called. This change is implemented in the Hackage package.</p>
<div class="footnotes">
<hr />
<ol>
<li id="fn1">I am using the types in <code>Data.Array.ST</code> but I’ve dropped the <code>Ix</code> parameters as they have no significance to this discussion. The parameter type also has no significance, but <code>Array</code> standing by itself as a type looks too odd to my eyes, so I keep that. <a class="footnoteBackLink" title="Jump back to footnote 1" href="#fnref1">↩</a></li>
</ol>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/reinerp.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/reinerp.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/reinerp.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/reinerp.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/reinerp.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/reinerp.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/reinerp.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/reinerp.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/reinerp.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/reinerp.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/reinerp.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/reinerp.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/reinerp.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/reinerp.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=73&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://reinerp.wordpress.com/2009/09/18/making-runstarray-more-flexible/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e7554bdaabd25dbf90752e4233b284f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">reinerpope</media:title>
		</media:content>
	</item>
		<item>
		<title>Building first-class patterns, continued.</title>
		<link>http://reinerp.wordpress.com/2009/07/19/building-first-class-patterns-continued/</link>
		<comments>http://reinerp.wordpress.com/2009/07/19/building-first-class-patterns-continued/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 01:50:07 +0000</pubDate>
		<dc:creator>Reiner Pope</dc:creator>
				<category><![CDATA[pattern-combinators]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://reinerp.wordpress.com/?p=69</guid>
		<description><![CDATA[This post is in Literate Haskell. The entire contents can be copied into a file called PatternMaybe.lhs and will be compilable by GHC. The code from this post is available on Hackage, in the first-class-patterns library. In my previous post I developed difference type-lists with non-recursive append. Using that framework, we can solve the efficiency [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=69&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is in Literate Haskell. The entire contents can be copied into a file called <code>PatternMaybe.lhs</code> and will be compilable by GHC.</p>
<p>The code from this post is available on Hackage, in the <a href="http://hackage.haskell.org/package/first-class-patterns">first-class-patterns</a> library.</p>
<p>In my <a href="http://reinerp.wordpress.com/2009/07/18/difference-type-list/">previous post</a> I developed difference type-lists with non-recursive append. Using that framework, we can solve the efficiency problem of my <a href="http://reinerp.wordpress.com/2009/06/29/nicer-types-for-type-safe-pattern-combinators/">first attempt</a> at nicer types for pattern combinators. At the same time, I find the implementation here easier to understand than the original one.</p>
<h1 id="preliminaries">Preliminaries</h1>
<pre>&gt; <span style="color:blue;"><em>{-# LANGUAGE TypeFamilies, TypeOperators, Rank2Types #-}</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">module</span></span> PatternMaybe (
&gt;     Tuple, zero, one, (&lt;&gt;),
&gt;     Fun,
&gt;     Pattern(<span style="color:red;">..</span>),
&gt;     Clause, (|||), match, (-&gt;&gt;),
&gt;     var, pair, mk1, left, right, cst,
&gt;     test1,
&gt;  ) <span style="text-decoration:underline;"><span style="color:green;">where</span></span></pre>
<p>We need the <code>D</code> type and the <code>Difference</code> class from the previous post</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">import</span></span> Difference
&gt; <span style="text-decoration:underline;"><span style="color:green;">import</span></span> Control.Monad(mplus)
&gt; <span style="text-decoration:underline;"><span style="color:green;">import</span></span> Data.Maybe(maybe)
&gt; <span style="text-decoration:underline;"><span style="color:green;">import</span></span> Control.Applicative</pre>
<h2 id="curried-functions">(Curried) Functions</h2>
<p>We define a type family of curried functions from <code>xs</code> to <code>r</code>, where <code>xs</code> is a type list. This is the same family as <code>CurryFunc</code> from my <a href="http://reinerp.wordpress.com/2009/06/29/nicer-types-for-type-safe-pattern-combinators/">first post</a>, but by a different name.</p>
<pre>&gt; <span style="color:blue;"><em>-- | Curried functions.</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> family   Fun xs r
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Fun Nil     r <span style="color:red;">=</span> r
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Fun (h<strong><span style="color:red;">:*:</span></strong>t) r <span style="color:red;">=</span> h <span style="color:red;">-&gt;</span> Fun t r</pre>
<h2 id="cpsed-tuples">(CPSed) Tuples</h2>
<p>We need tuples to store the variables bound by a pattern. If we CPS-encode the standard tuple type you get the following type, <code>Tuple'</code>, for tuples. We then use the <code>Difference</code> machinery (under the <code>D</code> type) we developed in the previous to give <code>Tuple'</code> an efficient append, which is the <code>Tuple</code> type.</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> Tuple' xs <span style="color:red;">=</span> Tuple' { runTuple' <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> r. Fun xs r <span style="color:red;">-&gt;</span> r }
&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> Tuple xs <span style="color:red;">=</span> Tuple (D Tuple' xs)</pre>
<p>The following functions manipulate <code>Tuple</code>s:</p>
<pre>&gt; zero <span style="color:red;">::</span> Tuple Nil
&gt; zero <span style="color:red;">=</span> Tuple zeroD</pre>
<pre>&gt; one <span style="color:red;">::</span> a <span style="color:red;">-&gt;</span> Tuple (a <strong><span style="color:red;">:*:</span></strong> Nil)
&gt; one a <span style="color:red;">=</span> Tuple (mkOneD (<span style="color:red;">\</span>(Tuple' t) <span style="color:red;">-&gt;</span> Tuple' (<span style="color:red;">\</span>k <span style="color:red;">-&gt;</span> t (k a))))</pre>
<pre>&gt; (&lt;&gt;) <span style="color:red;">::</span> Tuple xs <span style="color:red;">-&gt;</span> Tuple ys <span style="color:red;">-&gt;</span> Tuple (xs <strong><span style="color:red;">:++:</span></strong> ys)
&gt; (Tuple xs) &lt;&gt; (Tuple ys) <span style="color:red;">=</span> Tuple (xs `plusD` ys)</pre>
<pre>&gt; runTuple <span style="color:red;">::</span> Tuple xs <span style="color:red;">-&gt;</span> Fun xs r <span style="color:red;">-&gt;</span> r
&gt; runTuple (Tuple t) <span style="color:red;">=</span> runTuple' (evalD (Tuple' id) t)</pre>
<p>The first three are for building <code>Tuple</code>s; the last is for using <code>Tuple</code>s.</p>
<p>This representation of tuples as “differences” of CPS-encoded tuples is essentially the same as Morten Rhiger used in Section 3.2 of <a href="http://www.itu.dk/people/mir/typesafepatterns.pdf">Type-safe pattern combinators</a>.</p>
<h1 id="the-Pattern-type">The <code>Pattern</code> type</h1>
<p>We can now define the <code>Pattern</code> type and <code>Clause</code> types. Unlike in Morten’s code (which I used in my <a href="http://reinerp.wordpress.com/2009/06/29/nicer-types-for-type-safe-pattern-combinators/">first post</a>), we handle failure using the <code>Maybe</code> monad.</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> Pattern vars a <span style="color:red;">=</span> Pattern { runPattern <span style="color:red;">::</span> a <span style="color:red;">-&gt;</span> Maybe (Tuple vars) }
&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> Clause a r <span style="color:red;">=</span> Clause { runClause <span style="color:red;">::</span> a <span style="color:red;">-&gt;</span> Maybe r }</pre>
<p>In the export list, the <code>Pattern</code> type exposes its implementation. This is safe: the <code>Difference</code> module defined in the previous post contains the trusted kernel and the only unsafe code.</p>
<p>The <code>Clause</code> type is exported abstract. The following three combinators are sufficient for all uses of <code>Clause</code> I am currently aware of; if new needs arise, a user can always define their own <code>Clause</code> type, because the underlying <code>Pattern</code> type is fully exposed.</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">infix</span></span> <span style="color:magenta;">2</span> -&gt;&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">infixr</span></span> <span style="color:magenta;">1</span> |||
&gt; (-&gt;&gt;) <span style="color:red;">::</span> Pattern vars a <span style="color:red;">-&gt;</span> Fun vars r <span style="color:red;">-&gt;</span> Clause a r
&gt; (Pattern p) -&gt;&gt; k <span style="color:red;">=</span> Clause (<span style="color:red;">\</span>a <span style="color:red;">-&gt;</span> fmap (<span style="color:red;">\</span>f <span style="color:red;">-&gt;</span> runTuple f k) (p a))
&gt; (|||) <span style="color:red;">::</span> Clause a r <span style="color:red;">-&gt;</span> Clause a r <span style="color:red;">-&gt;</span> Clause a r
&gt; l ||| r <span style="color:red;">=</span> Clause (<span style="color:red;">\</span>a <span style="color:red;">-&gt;</span> runClause l a `mplus` runClause r a)
&gt; match <span style="color:red;">::</span> a <span style="color:red;">-&gt;</span> Clause a r <span style="color:red;">-&gt;</span> r
&gt; match a c <span style="color:red;">=</span> maybe (error <span style="color:magenta;">"match"</span>) id $ runClause c a</pre>
<h2 id="examples">Examples</h2>
<p>I’ll define just a few combinators, to give an example of <code>Pattern</code>’s use.</p>
<pre>&gt; var <span style="color:red;">::</span> Pattern (a <strong><span style="color:red;">:*:</span></strong> Nil) a
&gt; var <span style="color:red;">=</span> Pattern (Just . one)</pre>
<pre>&gt; pair <span style="color:red;">::</span> Pattern <span style="text-decoration:underline;"><span style="color:green;">as</span></span> a <span style="color:red;">-&gt;</span> Pattern bs b <span style="color:red;">-&gt;</span> Pattern (<span style="text-decoration:underline;"><span style="color:green;">as</span></span> <strong><span style="color:red;">:++:</span></strong> bs) (a,b)
&gt; pair (Pattern m) (Pattern n) <span style="color:red;">=</span> Pattern (<span style="color:red;">\</span>(a,b) <span style="color:red;">-&gt;</span> (&lt;&gt;) &lt;$&gt; (m a) &lt;*&gt; (n b))</pre>
<pre>&gt; <span style="color:blue;"><em>-- | Useful for building one-argument pattern combinators</em></span>
&gt; mk1 <span style="color:red;">::</span> (a <span style="color:red;">-&gt;</span> Maybe b) <span style="color:red;">-&gt;</span> (Pattern vars b <span style="color:red;">-&gt;</span> Pattern vars a)
&gt; mk1 g (Pattern p) <span style="color:red;">=</span> Pattern (<span style="color:red;">\</span>a <span style="color:red;">-&gt;</span> g a &gt;&gt;= p)</pre>
<pre>&gt; left <span style="color:red;">::</span> Pattern vars a <span style="color:red;">-&gt;</span> Pattern vars (Either a b)
&gt; left <span style="color:red;">=</span> mk1 (either Just (const Nothing))</pre>
<pre>&gt; right <span style="color:red;">::</span> Pattern vars b <span style="color:red;">-&gt;</span> Pattern vars (Either a b)
&gt; right <span style="color:red;">=</span> mk1 (either (const Nothing) Just)</pre>
<pre>&gt; cst <span style="color:red;">::</span> (Eq a) <span style="color:red;">=&gt;</span> a <span style="color:red;">-&gt;</span> Pattern Nil a
&gt; cst x <span style="color:red;">=</span> Pattern (<span style="color:red;">\</span>a <span style="color:red;">-&gt;</span> <span style="text-decoration:underline;"><span style="color:green;">if</span></span> a==x <span style="text-decoration:underline;"><span style="color:green;">then</span></span> Just zero <span style="text-decoration:underline;"><span style="color:green;">else</span></span> Nothing)</pre>
<p>Now, we can put all of this together in a test example.</p>
<pre>&gt; test1 <span style="color:red;">::</span> Either Int (Int, Int) <span style="color:red;">-&gt;</span> Int
&gt; test1 a <span style="color:red;">=</span> match a $
&gt;       left (cst <span style="color:magenta;">4</span>)         -&gt;&gt; <span style="color:magenta;">0</span>
&gt;   ||| left var             -&gt;&gt; id
&gt;   ||| right (pair var var) -&gt;&gt; (+)</pre>
<pre>&gt; ex2 <span style="color:red;">::</span> Num a <span style="color:red;">=&gt;</span> Either a (a,a) <span style="color:red;">-&gt;</span> a
&gt; ex2 a <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">case</span></span> a <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;        Left <span style="color:magenta;">4</span>      <span style="color:red;">-&gt;</span> <span style="color:magenta;">0</span>
&gt;        Left x      <span style="color:red;">-&gt;</span> x
&gt;        Right (x,y) <span style="color:red;">-&gt;</span> x+y</pre>
<p>If we compile this module with <code>-O2</code> and look at the GHC Core output, we see that <code>test1</code> is compiled to the following Core code:</p>
<pre>PatternMaybe<span style="color:cyan;">.$</span>wtest1 <span style="color:red;">::</span> Data<span style="color:cyan;">.</span>Either<span style="color:cyan;">.</span>Either
                          Int <span style="color:cyan;">(</span>Int<span style="color:cyan;">,</span> Int<span style="color:cyan;">)</span>
                        <span style="color:red;">-&gt;</span> Int<span style="color:magenta;"><em>#</em></span>
PatternMaybe<span style="color:cyan;">.$</span>wtest1 <span style="color:red;">=</span>
  <span style="color:red;">\</span> <span style="color:cyan;">(</span>a <span style="color:red;">::</span> Data<span style="color:cyan;">.</span>Either<span style="color:cyan;">.</span>Either
                 Int <span style="color:cyan;">(</span>Int<span style="color:cyan;">,</span> Int<span style="color:cyan;">)</span><span style="color:cyan;">)</span> <span style="color:red;">-&gt;</span>
    <span style="color:green;"><span style="text-decoration:underline;">case</span></span> a <span style="color:green;"><span style="text-decoration:underline;">of</span></span> a' <span style="color:cyan;">{</span>
      Data<span style="color:cyan;">.</span>Either<span style="color:cyan;">.</span>Left x <span style="color:red;">-&gt;</span>
        <span style="color:green;"><span style="text-decoration:underline;">case</span></span> x <span style="color:green;"><span style="text-decoration:underline;">of</span></span> x' <span style="color:cyan;">{</span> I<span style="color:magenta;"><em>#</em></span> x1 <span style="color:red;">-&gt;</span>
        <span style="color:green;"><span style="text-decoration:underline;">case</span></span> x1 <span style="color:green;"><span style="text-decoration:underline;">of</span></span> x1' <span style="color:cyan;">{</span> <strong><span style="color:magenta;">__DEFAULT</span></strong> <span style="color:red;">-&gt;</span> x1'<span style="color:cyan;">;</span> <span style="color:magenta;">4</span> <span style="color:red;">-&gt;</span> <span style="color:magenta;">0</span> <span style="color:cyan;">}</span>
        <span style="color:cyan;">}</span><span style="color:cyan;">;</span>
      Data<span style="color:cyan;">.</span>Either<span style="color:cyan;">.</span>Right y <span style="color:red;">-&gt;</span>
        <span style="color:green;"><span style="text-decoration:underline;">case</span></span> y <span style="color:green;"><span style="text-decoration:underline;">of</span></span> y' <span style="color:cyan;">{</span> <span style="color:cyan;">(</span>a3<span style="color:cyan;">,</span> b<span style="color:cyan;">)</span> <span style="color:red;">-&gt;</span>
        <span style="color:green;"><span style="text-decoration:underline;">case</span></span> a3 <span style="color:green;"><span style="text-decoration:underline;">of</span></span> a3' <span style="color:cyan;">{</span> I<span style="color:magenta;"><em>#</em></span> x <span style="color:red;">-&gt;</span>
        <span style="color:green;"><span style="text-decoration:underline;">case</span></span> b <span style="color:green;"><span style="text-decoration:underline;">of</span></span> b' <span style="color:cyan;">{</span> I<span style="color:magenta;"><em>#</em></span> y <span style="color:red;">-&gt;</span>
        <span style="color:cyan;">+#</span> x y
        <span style="color:cyan;">}</span>
        <span style="color:cyan;">}</span>
        <span style="color:cyan;">}</span>
    <span style="color:cyan;">}</span></pre>
<p>So, <code>test1</code> has been compiled to a standard Haskell pattern match. So the overhead has been completely optimised away, as we wanted.</p>
<p>The <a href="http://hackage.haskell.org/package/first-class-patterns">first-class-patterns</a> library on Hackage is based on this implementation, and has more combinators. Have a look there for more.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/reinerp.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/reinerp.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/reinerp.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/reinerp.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/reinerp.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/reinerp.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/reinerp.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/reinerp.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/reinerp.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/reinerp.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/reinerp.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/reinerp.wordpress.com/69/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/reinerp.wordpress.com/69/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/reinerp.wordpress.com/69/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=69&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://reinerp.wordpress.com/2009/07/19/building-first-class-patterns-continued/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e7554bdaabd25dbf90752e4233b284f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">reinerpope</media:title>
		</media:content>
	</item>
		<item>
		<title>Building first-class patterns. The &#8220;Difference type-list&#8221;.</title>
		<link>http://reinerp.wordpress.com/2009/07/18/difference-type-list/</link>
		<comments>http://reinerp.wordpress.com/2009/07/18/difference-type-list/#comments</comments>
		<pubDate>Sat, 18 Jul 2009 09:54:24 +0000</pubDate>
		<dc:creator>Reiner Pope</dc:creator>
				<category><![CDATA[pattern-combinators]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://reinerp.wordpress.com/?p=65</guid>
		<description><![CDATA[This post is in Literate Haskell. The entire contents can be copied into a file called Difference.lhs and will be compilable by GHC. In my previous post I used type families to simplify the types in Morten Rhiger’s “Type safe pattern combinators”. Unfortunately, in order to convince GHC that various types were in fact equal [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=65&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is in Literate Haskell. The entire contents can be copied into a file called <code>Difference.lhs</code> and will be compilable by GHC.</p>
<p>In my <a href="http://reinerp.wordpress.com/2009/06/29/nicer-types-for-type-safe-pattern-combinators/">previous post</a> I used type families to simplify the types in Morten Rhiger’s “Type safe pattern combinators”. Unfortunately, in order to convince GHC that various types were in fact equal (such as <code>(a :++: b) :++: c</code> and <code>a :++: (b :++: c)</code>) we needed to (recursively) build type equality witnesses. In doing this, we prevented GHC optimising away all the overhead, since GHC will never inline a recursive function.</p>
<p>In this post I start to solve the efficiency problem by using <code>unsafeCoerce</code>. By carefully choosing the exports from the module, we can ensure that the API presented is never-the-less safe.</p>
<h1 id="type-lists-again">Type lists, again</h1>
<p>These are the same as defined in the previous post, so I give no explanation of them.</p>
<pre>&gt; <span style="color:blue;"><em>{-# LANGUAGE TypeFamilies, EmptyDataDecls, TypeOperators, ScopedTypeVariables, Rank2Types, GADTs, GeneralizedNewtypeDeriving #-}</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">module</span></span> Difference(
&gt;     Nil,
&gt;     (<strong><span style="color:red;">:*:</span></strong>),
&gt;     (<strong><span style="color:red;">:++:</span></strong>),
&gt;     Difference(<span style="color:red;">..</span>),
&gt;     D,
&gt;  ) <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">import</span></span> Unsafe.Coerce
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Nil
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> h <strong><span style="color:red;">:*:</span></strong> t
&gt; <span style="text-decoration:underline;"><span style="color:green;">infixr</span></span> <strong><span style="color:red;">:*:</span></strong>
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> family (<strong><span style="color:red;">:++:</span></strong>) a b
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Nil     <strong><span style="color:red;">:++:</span></strong> xs <span style="color:red;">=</span> xs
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> (h<strong><span style="color:red;">:*:</span></strong>t) <strong><span style="color:red;">:++:</span></strong> xs <span style="color:red;">=</span> h <strong><span style="color:red;">:*:</span></strong> (t <strong><span style="color:red;">:++:</span></strong> xs)
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Proxy a
&gt; proxy <span style="color:red;">::</span> Proxy a
&gt; proxy <span style="color:red;">=</span> undefined</pre>
<h1 id="difference-type-lists">Difference type-lists</h1>
<p>It will be (also, has been) a common theme in building the pattern combinators to define a type inductively for lists. For instance, in the previous post, we defined <code>Tuple xs</code> and <code>CurryFunc xs</code> as types on lists, essentially as folds on the list structure: e.g. with Tuple, replace every <code>(:*:)</code> with a <code>(,)</code>, and every <code>Nil</code> with a <code>()</code>.</p>
<p>We can efficiently (read: non-recursively) build objects of these types when we only build the types using <code>Nil</code> and <code>(:*:)</code>; however, we have more difficulties when we want to efficiently construct such types using <code>(:++:)</code>. For instance, suppose we wanted to construct a function</p>
<pre><code>f :: Tuple xs -&gt; Tuple ys -&gt; Tuple (xs :++: ys)
</code></pre>
<p>With the definition of <code>Tuple</code> used in the previous post, we would find it difficult (impossible?) to define such a function non-recursively.</p>
<p>In the previous post, this problem was solved by the “difference list” technique, which we used for the <code>DConv</code> type. It will be convenient to use difference list technique again. Here we package the technique in a single convenient type, <code>D</code>, which adds efficient (non-recursive) concatenation to datatypes defined on type-lists.</p>
<p>We put the operations we will need in a type-class, <code>Difference</code>, which is defined below. The idea is that, if <code>d</code> is an instance of <code>Difference</code>, and <code>t</code> is some datatype defined inductively on lists, then <code>d t</code> is the “difference list converted” version of this type — that is, it contains the same data, but with an efficient append.</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">class</span></span> Difference d <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     <span style="color:blue;"><em>-- | constructs the empty `d t`.</em></span>
&gt;     zeroD <span style="color:red;">::</span> d t Nil
&gt;     <span style="color:blue;"><em>-- | appends two `d t`s.</em></span>
&gt;     plusD <span style="color:red;">::</span> d t xs <span style="color:red;">-&gt;</span> d t ys <span style="color:red;">-&gt;</span> d t (xs <strong><span style="color:red;">:++:</span></strong> ys)
&gt;     <span style="color:blue;"><em>-- | given a "cons" operation, constructs the singleton `d t`.</em></span>
&gt;     mkOneD <span style="color:red;">::</span> (<span style="text-decoration:underline;"><span style="color:green;">forall</span></span> ys. t ys <span style="color:red;">-&gt;</span> t (a <strong><span style="color:red;">:*:</span></strong> ys)) <span style="color:red;">-&gt;</span> d t (a <strong><span style="color:red;">:*:</span></strong> Nil)
&gt;     <span style="color:blue;"><em>-- | given a "nil" value, "runs" the `d t`.</em></span>
&gt;     evalD <span style="color:red;">::</span> t Nil <span style="color:red;">-&gt;</span> d t xs <span style="color:red;">-&gt;</span> t xs</pre>
<p>It is interesting that <code>zeroD</code> and <code>plusD</code> can be defined without any knowledge of the underlying type: internally, they will be implemented just as <code>id</code> and <code>(.)</code>. All the knowledge is contained within <code>mkOneD</code> and <code>evalD</code>.</p>
<p>As a demonstration of its use, we can define difference tuples. Note that the <code>t</code> mentioned in the typeclass above must have kind <code>(* -&gt; *)</code>. This means that <code>t</code> cannot be a type family. However, it can be a <em>data</em> family, so this is how we define tuples. First, we define tuples inductively:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> family Tuple' xs
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Tuple' Nil <span style="color:red;">=</span> TupleEmpty
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Tuple' (h<strong><span style="color:red;">:*:</span></strong>t) <span style="color:red;">=</span> TupleCons h !(Tuple' t)</pre>
<p>The <code>zeroD</code> and <code>plusD</code> functions need no work. However, we need a little work for the singleton and evaluation functions, <code>mkOneD</code> and <code>evalD</code>:</p>
<pre>&gt; singletonTuple <span style="color:red;">::</span> Difference d <span style="color:red;">=&gt;</span> a <span style="color:red;">-&gt;</span> d Tuple' (a <strong><span style="color:red;">:*:</span></strong> Nil)
&gt; singletonTuple a <span style="color:red;">=</span> mkOneD (<span style="color:red;">\</span>t <span style="color:red;">-&gt;</span> TupleCons a t)
&gt; evalTuple <span style="color:red;">::</span> Difference d <span style="color:red;">=&gt;</span> d Tuple' xs <span style="color:red;">-&gt;</span> Tuple' xs
&gt; evalTuple <span style="color:red;">=</span> evalD TupleEmpty</pre>
<p>There we have it: tuples with efficient append.</p>
<p>Now we actually need to define an instance of <code>Difference</code>.</p>
<h1 id="instances">Instances</h1>
<p>The basic idea of the implementation is just</p>
<pre><code>type D t xs = forall ys. t ys -&gt; t (xs :++: ys)
</code></pre>
<p>However, to implement <code>plusD</code>, we will need to convince GHC of the equality of the types <code>(a :++: b) :++ c</code> and <code>a :++: (b :++: c)</code>. I give two instances of <code>Difference</code>, which differ in how they prove this equality: one uses GADTs and a <code>List</code> type-class (as in the previous post); the other uses <code>unsafeCoerce</code>. As opposed to the <code>unsafeCoerce</code> approach, the GADT approach is guaranteed to be safe, but is recursive. The <code>unsafeCoerce</code> is non-recursive but circumvents the type system; however, the existence of the GADT implementation should convince us that the use of <code>unsafeCoerce</code> here is actually a safe one.</p>
<h2 id="the-gadt-instance">The GADT instance</h2>
<p>This is very similar to the previous post, so I don’t give much explanation.</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> GadtD t xs <span style="color:red;">=</span> List xs <span style="color:red;">=&gt;</span> GadtD (<span style="text-decoration:underline;"><span style="color:green;">forall</span></span> ys. t ys <span style="color:red;">-&gt;</span> t (xs <strong><span style="color:red;">:++:</span></strong> ys))
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Difference GadtD <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     zeroD <span style="color:red;">=</span> GadtD id
&gt;     plusD (GadtD fx <span style="color:red;">::</span> GadtD t xs) (GadtD fy <span style="color:red;">::</span> GadtD t ys) <span style="color:red;">=</span>
&gt;         <span style="text-decoration:underline;"><span style="color:green;">case</span></span> closure (proxy <span style="color:red;">::</span> Proxy xs) (proxy <span style="color:red;">::</span> Proxy ys) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;           ListD <span style="color:red;">-&gt;</span> GadtD (<span style="color:red;">\</span>(zs <span style="color:red;">::</span> t zs) <span style="color:red;">-&gt;</span>
&gt;             <span style="text-decoration:underline;"><span style="color:green;">case</span></span> assoc (proxy <span style="color:red;">::</span> Proxy xs) (proxy <span style="color:red;">::</span> Proxy ys) (proxy <span style="color:red;">::</span> Proxy zs) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;               Equal <span style="color:red;">-&gt;</span> fx (fy zs))
&gt;     mkOneD f <span style="color:red;">=</span> GadtD f
&gt;     evalD nil (GadtD f <span style="color:red;">::</span> GadtD t xs) <span style="color:red;">=</span>
&gt;         <span style="text-decoration:underline;"><span style="color:green;">case</span></span> rightIdent (proxy <span style="color:red;">::</span> Proxy xs) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;           Equal <span style="color:red;">-&gt;</span> f nil
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">class</span></span> List a <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     closure <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> b. List b <span style="color:red;">=&gt;</span>
&gt;        Proxy a <span style="color:red;">-&gt;</span> Proxy b <span style="color:red;">-&gt;</span>
&gt;         ListD (a <strong><span style="color:red;">:++:</span></strong> b)
&gt;     assoc <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> b c.
&gt;        Proxy a <span style="color:red;">-&gt;</span> Proxy b <span style="color:red;">-&gt;</span> Proxy c <span style="color:red;">-&gt;</span>
&gt;         ((a <strong><span style="color:red;">:++:</span></strong> (b <strong><span style="color:red;">:++:</span></strong> c)) <strong><span style="color:red;">:==:</span></strong> ((a <strong><span style="color:red;">:++:</span></strong> b) <strong><span style="color:red;">:++:</span></strong> c))
&gt;     rightIdent <span style="color:red;">::</span> Proxy a <span style="color:red;">-&gt;</span>
&gt;         (a <strong><span style="color:red;">:++:</span></strong> Nil) <strong><span style="color:red;">:==:</span></strong> a
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> List Nil <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     closure <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span>  <span style="color:red;">=</span> ListD
&gt;     assoc <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span>  <span style="color:red;">=</span> Equal
&gt;     rightIdent <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">=</span> Equal
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> List t <span style="color:red;">=&gt;</span> List (h <strong><span style="color:red;">:*:</span></strong> t) <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     closure <span style="text-decoration:underline;"><span style="color:green;">_</span></span> b  <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">case</span></span> closure (proxy <span style="color:red;">::</span> Proxy t) b <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;                      ListD <span style="color:red;">-&gt;</span> ListD
&gt;     assoc <span style="text-decoration:underline;"><span style="color:green;">_</span></span> b c  <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">case</span></span> assoc (proxy <span style="color:red;">::</span> Proxy t) b c <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;                      Equal <span style="color:red;">-&gt;</span> Equal
&gt;     rightIdent <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">case</span></span> rightIdent (proxy <span style="color:red;">::</span> Proxy t) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;                      Equal <span style="color:red;">-&gt;</span> Equal
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> a <strong><span style="color:red;">:==:</span></strong> b <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     Equal <span style="color:red;">::</span> a <strong><span style="color:red;">:==:</span></strong> a
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> ListD a <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     ListD <span style="color:red;">::</span> List a <span style="color:red;">=&gt;</span> ListD a</pre>
<h2 id="the-unsafeCoerce-instance">The <code>unsafeCoerce</code> instance</h2>
<p>This instance is a lightweight one. It is the same as the GADT one except that, whenever we needed an equality proof before, we use unsafeCoerce.</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> CoerceD t xs <span style="color:red;">=</span> CoerceD (<span style="text-decoration:underline;"><span style="color:green;">forall</span></span> ys. t ys <span style="color:red;">-&gt;</span> t (xs <strong><span style="color:red;">:++:</span></strong> ys))
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Difference CoerceD <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     zeroD <span style="color:red;">=</span> CoerceD id
&gt;     plusD (CoerceD fx <span style="color:red;">::</span> CoerceD t xs) (CoerceD fy <span style="color:red;">::</span> CoerceD t ys) <span style="color:red;">=</span>
&gt;         CoerceD (<span style="color:red;">\</span>(zs <span style="color:red;">::</span> t zs) <span style="color:red;">-&gt;</span>
&gt;             <span style="text-decoration:underline;"><span style="color:green;">case</span></span> assoc2 (proxy <span style="color:red;">::</span> Proxy xs) (proxy <span style="color:red;">::</span> Proxy ys) (proxy <span style="color:red;">::</span> Proxy zs) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;               Equal <span style="color:red;">-&gt;</span> fx (fy zs))
&gt;     mkOneD f <span style="color:red;">=</span> CoerceD f
&gt;     evalD nil (CoerceD f <span style="color:red;">::</span> CoerceD t xs) <span style="color:red;">=</span>
&gt;         <span style="text-decoration:underline;"><span style="color:green;">case</span></span> rightIdent2 (proxy <span style="color:red;">::</span> Proxy xs) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;           Equal <span style="color:red;">-&gt;</span> f nil
&gt;
&gt; assoc2 <span style="color:red;">::</span> Proxy a <span style="color:red;">-&gt;</span> Proxy b <span style="color:red;">-&gt;</span> Proxy c <span style="color:red;">-&gt;</span> (a <strong><span style="color:red;">:++:</span></strong> (b <strong><span style="color:red;">:++:</span></strong> c)) <strong><span style="color:red;">:==:</span></strong> ((a <strong><span style="color:red;">:++:</span></strong> b) <strong><span style="color:red;">:++:</span></strong> c)
&gt; assoc2 <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">=</span> unsafeCoerce Equal
&gt;
&gt; rightIdent2 <span style="color:red;">::</span> Proxy a <span style="color:red;">-&gt;</span> (a <strong><span style="color:red;">:++:</span></strong> Nil) <strong><span style="color:red;">:==:</span></strong> a
&gt; rightIdent2 <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">=</span> unsafeCoerce Equal</pre>
<p>The only equalities we prove with <code>unsafeCoerce</code> are <code>a :++: (b :++: c) ~ (a :++: b) :++: c</code> and <code>a :++: Nil ~ a</code>. These equalities are certainly true for all instances of the <code>List</code> class given in the GADT implementation. The GADT implementation also shows that, for any value of type <code>d t xs</code> constructible using the API of the <code>Difference</code> class, <code>xs</code> will be an instance of <code>List</code>. So the equalities used are true (safe) for any <code>CoerceD</code>s constructed using only the <code>Difference</code> interface. So our use of <code>unsafeCoerce</code> is safe if we export only the <code>Difference</code> class, and the name of the type <code>CoerceD</code>. If you look at the imports, this is what I have done.</p>
<h1 id="wrapping-up">Wrapping up</h1>
<p>Finally, I also export the type <code>D</code>, which is just a newtype of <code>CoerceD</code>, with a derived instance of <code>Difference</code>:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> D t xs <span style="color:red;">=</span> D (CoerceD t xs) <span style="text-decoration:underline;"><span style="color:green;">deriving</span></span>(Difference)</pre>
<p>This exposes an instance of <code>Difference</code> to the outside world, but hides which one it is. This gives us a single place to change the implementation from <code>CoerceD</code> to <code>GadtD</code> if we so desire.</p>
<p>It turns out that this module encapsulates all the uses of GADTs that we will need.</p>
<p>I’ll stop here for now, but we will see in later posts how this type is used, and we will see the efficiency it allows.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/reinerp.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/reinerp.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/reinerp.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/reinerp.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/reinerp.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/reinerp.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/reinerp.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/reinerp.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/reinerp.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/reinerp.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/reinerp.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/reinerp.wordpress.com/65/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/reinerp.wordpress.com/65/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/reinerp.wordpress.com/65/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=65&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://reinerp.wordpress.com/2009/07/18/difference-type-list/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e7554bdaabd25dbf90752e4233b284f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">reinerpope</media:title>
		</media:content>
	</item>
		<item>
		<title>Nicer types for Type-safe pattern combinators</title>
		<link>http://reinerp.wordpress.com/2009/06/29/nicer-types-for-type-safe-pattern-combinators/</link>
		<comments>http://reinerp.wordpress.com/2009/06/29/nicer-types-for-type-safe-pattern-combinators/#comments</comments>
		<pubDate>Mon, 29 Jun 2009 12:29:32 +0000</pubDate>
		<dc:creator>Reiner Pope</dc:creator>
				<category><![CDATA[pattern-combinators]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://reinerp.wordpress.com/?p=5</guid>
		<description><![CDATA[This post is in Literate Haskell. The entire contents can be copied into a file called Pattern.lhs and will be compilable by GHC. I recently read Morten Rhiger’s Functional Pearl, Type-safe pattern combinators. He develops a library of combinators for pattern matching, allowing user code such as match (5, (3, 4)) $ pair (cst 5) [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=5&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is in Literate Haskell. The entire contents can be copied into a file called <code>Pattern.lhs</code> and will be compilable by GHC.</p>
<p>I recently read Morten Rhiger’s Functional Pearl, <a href="http://www.itu.dk/people/mir/typesafepatterns.pdf">Type-safe pattern combinators</a>. He develops a library of combinators for pattern matching, allowing user code such as</p>
<pre><code>match (5, (3, 4)) $
    pair (cst 5) (pair var var) -&gt;&gt; \ x y → x + y
</code></pre>
<p>where the equivalent code using Haskell’s own pattern matching is</p>
<pre><code>case (5, (3, 4)) of
    (5, (x, y)) -&gt; x + y
</code></pre>
<p>The pattern combinator library has various features we want from a pattern matching library: type-checking of patterns, and a lightweight/efficient implementation. The system is also clearly flexible enough to support all of Haskell’s built-in pattern-matching capabilities, and then some.</p>
<p>However, I found the library confusing to work with, because the type signatures give me no clue about what is going on. For instance, consider the type of <code>var</code>, the “variable pattern” combinator, given by GHCi:</p>
<pre><code>ghci&gt; :type var
var ::
  ((t -&gt; t1 -&gt; t2) -&gt; (t3 -&gt; t) -&gt; (t3, t1) -&gt; t2,
   t4 -&gt; ((t4, t5) -&gt; t6) -&gt; t7 -&gt; t5 -&gt; t6)
</code></pre>
<p>There are tuples and functions everywhere, and it is hard to see what is going on — never mind that GHCi helpfully names all the type variables <code>t</code>.</p>
<p>In this post, I attempt to tame the types of the pattern combinators, while leaving the internal code as much the same as possible. In the final result, <code>var</code> has type</p>
<pre><code>var :: Pattern (a :*: Nil) a
</code></pre>
<p>The first type parameter lists the types of the variables bound by the pattern, and the second gives the type of the overall pattern to be matched.</p>
<h1 id="preliminaries">Preliminaries</h1>
<h2 id="lists-of-types">Lists of types</h2>
<p>We keep track of the variables bound by a pattern by listing their types. To do that, we use the following type-level list:</p>
<pre>&gt; <span style="color:blue;"><em>{-# LANGUAGE EmptyDataDecls, TypeFamilies,
&gt;   TypeOperators, RankNTypes, GADTs,
&gt;   ScopedTypeVariables, NoMonomorphismRestriction #-}</em></span>
&gt; <span style="text-decoration:underline;"><span style="color:green;">module</span></span> Pattern <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">import</span></span> Prelude hiding(succ,fail,any, (||))
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Nil
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> h <strong><span style="color:red;">:*:</span></strong> t
&gt; <span style="text-decoration:underline;"><span style="color:green;">infixr</span></span> <strong><span style="color:red;">:*</span></strong></pre>
<p>The main operation we do on this is concatenating two lists, <code>(:++:)</code>:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> family (<strong><span style="color:red;">:++:</span></strong>) a b
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Nil     <strong><span style="color:red;">:++:</span></strong> xs <span style="color:red;">=</span> xs
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> (h<strong><span style="color:red;">:*:</span></strong>t) <strong><span style="color:red;">:++:</span></strong> xs <span style="color:red;">=</span> h <strong><span style="color:red;">:*:</span></strong> (t <strong><span style="color:red;">:++:</span></strong> xs)</pre>
<p>We have two different ways of expressing functions of multiple arguments: curried and uncurried. We can express both with type functions:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> family Tuple xs
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Tuple Nil <span style="color:red;">=</span> ()
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> Tuple (h<strong><span style="color:red;">:*:</span></strong>t) <span style="color:red;">=</span> (h, Tuple t)
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> UncurryFunc xs r <span style="color:red;">=</span> Tuple xs <span style="color:red;">-&gt;</span> r
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> family   CurryFunc xs r
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> CurryFunc Nil r <span style="color:red;">=</span> r
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> CurryFunc (h<strong><span style="color:red;">:*:</span></strong>t) r <span style="color:red;">=</span> h <span style="color:red;">-&gt;</span> CurryFunc t r</pre>
<p>Both representations of multi-argument functions are used by Morten’s code: internally, uncurried functions are used, but the curried form is presented to the user as it is more idiomatic. Some of the code is hence devoted to conversions between these forms. We define the type of converters from curried to uncurried form:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> Conv vs r <span style="color:red;">=</span> CurryFunc vs r <span style="color:red;">-&gt;</span> UncurryFunc vs r</pre>
<p>It might seem at first that it would just be simpler to use the curried form internally and avoid the fuss of conversion; however, this is unfortunately not possible: it turns out that the uncurried form is necessary in order to support proper handling of pattern-match failure.</p>
<h2 id="resolving-the-ambiguity">Resolving the ambiguity</h2>
<p>Since we are using type families, which are not guaranteed to be injective, a number of type signatures will be ambiguous. We will resolve these by adding a proxy parameter which fixes the ambiguity. For this, we use the (empty) <code>Proxy</code> type:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Proxy a
&gt; proxy <span style="color:red;">::</span> Proxy a
&gt; proxy <span style="color:red;">=</span> undefined</pre>
<p>Values of type <code>Proxy</code> contain no data, and should not be used by any functions; their only purpose is to fix the types.</p>
<p>As an example of how the disambiguation works, consider the type <code>Conv vars r</code>. The variable <code>vars</code> is only ever mentioned inside type functions, so it would be possible to have two types <code>vars1</code> and <code>vars2</code> such that <code>Conv vars1 r ~ Conv vars2 r</code> but not <code>vars1 ~ vars2</code>. Hence, if we fix the type of <code>Conv vars r</code>, then we don’t know what <code>vars</code> is, i.e. <code>vars</code> is ambiguous in <code>Conv vars r</code>. To fix this ambiguity, we add a parameter which fixes <code>vs</code>, to get the new type</p>
<pre><code>Proxy vars -&gt; Conv vars r
</code></pre>
<p>Since <code>Proxy</code> is injective, we can find <code>vars</code> unambiguously by looking at the first parameter.</p>
<h2 id="the-List-class">The <code>List</code> class</h2>
<p>It will turn out that Morten’s code implicitly uses various properties of list concatenation: in fact, precisely the property that lists form a monoid under (<code>(:++:)</code>,<code>Nil</code>). In his code, there is no need to prove that this is true, since his types don’t mention lists explicitly. However, we are using type families, so GHC will need to know these properties in order to type-check our code. Since type families are open, these properties cannot be guaranteed to be true of all instances of <code>(:++:)</code>: there is nothing to stop someone else defining instances for which the monoid laws fail. Ideally, we would solve this by using <a href="http://tomschrijvers.blogspot.com/2008/11/type-invariants-for-haskell.html">Type Invariants for Haskell</a>, but this has not been implemented in GHC. Instead, we encode these axioms as GADTs in a type-class:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">class</span></span> List a <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     closure <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> b. List b <span style="color:red;">=&gt;</span>
&gt;        Proxy a <span style="color:red;">-&gt;</span> Proxy b <span style="color:red;">-&gt;</span>
&gt;         ListD (a <strong><span style="color:red;">:++:</span></strong> b)
&gt;     assoc <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> b c.
&gt;        Proxy a <span style="color:red;">-&gt;</span> Proxy b <span style="color:red;">-&gt;</span> Proxy c <span style="color:red;">-&gt;</span>
&gt;         ((a <strong><span style="color:red;">:++:</span></strong> (b <strong><span style="color:red;">:++:</span></strong> c)) <strong><span style="color:red;">:==:</span></strong> ((a <strong><span style="color:red;">:++:</span></strong> b) <strong><span style="color:red;">:++:</span></strong> c))
&gt;     rightIdent <span style="color:red;">::</span> Proxy a <span style="color:red;">-&gt;</span>
&gt;         (a <strong><span style="color:red;">:++:</span></strong> Nil) <strong><span style="color:red;">:==:</span></strong> a</pre>
<p>(In comparison to the monoid laws, this is missing the <code>leftIdent</code> law. This is because GHC can derive that itself from the type family instance <code>Nil :++: xs</code>.) This class relies on the types <code>(:==:)</code> and <code>ListD</code>, which we have not yet defined, with the following intended meanings: an value of type <code>a :==: b</code> means that <code>a</code> and <code>b</code> are equal types; an value of type <code>ListD a</code> means that <code>a</code> is an instance of <code>List</code>. Both of these types can straightforwardly be defined using GADTs:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> a <strong><span style="color:red;">:==:</span></strong> b <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     Equal <span style="color:red;">::</span> a <strong><span style="color:red;">:==:</span></strong> a
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> ListD a <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     ListD <span style="color:red;">::</span> List a <span style="color:red;">=&gt;</span> ListD a</pre>
<p>We can also define instances for the lists we are interested in (i.e. the ones constructed with <code>Nil</code> and <code>:*:</code>). We need to tell GHC where to use induction, but it can prove the rest.</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> List Nil <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     closure <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span>  <span style="color:red;">=</span> ListD
&gt;     assoc <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="text-decoration:underline;"><span style="color:green;">_</span></span>  <span style="color:red;">=</span> Equal
&gt;     rightIdent <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">=</span> Equal
&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">instance</span></span> List t <span style="color:red;">=&gt;</span> List (h <strong><span style="color:red;">:*:</span></strong> t) <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;     closure <span style="text-decoration:underline;"><span style="color:green;">_</span></span> b  <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">case</span></span> closure (proxy <span style="color:red;">::</span> Proxy t) b <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;                      ListD <span style="color:red;">-&gt;</span> ListD
&gt;     assoc <span style="text-decoration:underline;"><span style="color:green;">_</span></span> b c  <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">case</span></span> assoc (proxy <span style="color:red;">::</span> Proxy t) b c <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;                      Equal <span style="color:red;">-&gt;</span> Equal
&gt;     rightIdent <span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">case</span></span> rightIdent (proxy <span style="color:red;">::</span> Proxy t) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;                      Equal <span style="color:red;">-&gt;</span> Equal</pre>
<h1 id="types-for-mortens-primitives">Types for Morten’s primitives</h1>
<p>If we look at Morten’s code, we see that the pattern combinators are all 2-tuples. When larger pattern combinators are built from smaller ones, the first components are always built using only the first components of the smaller combinators, and similarly for the second. In other words, the first and second components of the pattern combinators can be constructed independently. So, instead of jumping straight to a type for patterns, we first give types to the first and second components and their combinators.</p>
<h2 id="the-first-component-curried-to-uncurried-converter-builders">The first component: curried-to-uncurried-converter-builders</h2>
<p>Morten manipulates the first components with the function</p>
<pre>&gt; succ n f    <span style="color:red;">=</span> <span style="color:red;">\</span>(x,xs) <span style="color:red;">-&gt;</span> n (f x) xs</pre>
<p>and the Prelude functions <code>id</code> and <code>(.)</code>. The type of <code>succ</code> inferred by GHCi is:</p>
<pre><code>ghci&gt; :type succ
succ :: (t2 -&gt; t1 -&gt; t3) -&gt; (t -&gt; t2) -&gt; (t, t1) -&gt; t3
</code></pre>
<p>which is not very helpful. Although the types of <code>id</code> and <code>(.)</code> are simpler, they also don’t give much information about the use in building pattern combinators. Our first aim will be to give meaningful types to these combinators.</p>
<p>Using a rough understanding of Morten’s code and a bit of guesswork, we can define the following type synonym</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> DConv1 vars <span style="color:red;">=</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> vars' r.
&gt;     Conv vars' r <span style="color:red;">-&gt;</span> Conv (vars <strong><span style="color:red;">:++:</span></strong> vars') r</pre>
<p>as the type of the first components of Morten’s pattern combinators. Then, we can give <code>succ</code> and <code>id</code> the following types:</p>
<pre>&gt; id1 <span style="color:red;">::</span> DConv1 Nil
&gt; id1 <span style="color:red;">=</span> id
&gt; succ1 <span style="color:red;">::</span> DConv1 (a <strong><span style="color:red;">:*:</span></strong> Nil)
&gt; succ1 <span style="color:red;">=</span> succ</pre>
<p>The type for <code>(.)</code> is a bit harder, so I will pause now to discuss the interpretation of the <code>DConv1</code> type. The type <code>Conv vars r</code> is the type of converters from curried to uncurried form with arguments <code>vars</code> and result <code>r</code>. The type <code>DConv1</code> builds larger converters from smaller converters, so it is a curried-to-uncurried-converter-builder. It is closely analogous to <a title="Difference lists on Hackage" href="http://hackage.haskell.org/package/dlist-0.5">Difference Lists</a><a id="fnref1" class="footnoteRef" href="#fn1"><sup>1</sup></a>: a <code>DConv1</code> accepts a tail (<code>vars'</code>) as a parameter, and sticks its own list of variables onto the front. (This gives us a non-recursive implementation of append, which is what allows the pattern combinators to be completely optimised away by GHC.) So <code>DConv1</code> is best thought of as the type of curried-to-uncurried converters but with an efficient append.</p>
<p>Under this intepretation, <code>id1</code> is converter for no parameters, and <code>succ1</code> is the converter for a single parameter.</p>
<p>Back to <code>(.)</code>. This functions as the append operation (just like it does for <code>DList</code>s), so it should have type</p>
<pre><code>(.) :: DConv1 as -&gt; DConv1 bs -&gt; DConv1 (as :++: bs)
</code></pre>
<p>However, GHC won’t accept that type, for two reasons: <code>DConv1 vars</code> is ambiguous with respect to <code>vars</code> and <code>vars'</code>; and we need to use the associativity of <code>(:++:)</code>, but we don’t yet have a list constraint.</p>
<p>We fix the ambiguity of <code>DConv1</code> by making it a newtype (which fixes <code>vars</code>) and adding a proxy parameter (which fixes <code>vars'</code>):</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> DConv vars <span style="color:red;">=</span> DConv { runDConv <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> vars' r.
&gt;     Proxy vars' <span style="color:red;">-&gt;</span> Conv vars' r <span style="color:red;">-&gt;</span> Conv (vars <strong><span style="color:red;">:++:</span></strong> vars') r }</pre>
<p>Then the combinators can be typed as</p>
<pre>&gt; idC <span style="color:red;">::</span> DConv Nil
&gt; idC <span style="color:red;">=</span> DConv (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> id)
&gt; succC <span style="color:red;">::</span> DConv (a <strong><span style="color:red;">:*:</span></strong> Nil)
&gt; succC <span style="color:red;">=</span> DConv (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> succ)
&gt; appendC <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> <span style="text-decoration:underline;"><span style="color:green;">as</span></span> bs. List <span style="text-decoration:underline;"><span style="color:green;">as</span></span> <span style="color:red;">=&gt;</span> DConv <span style="text-decoration:underline;"><span style="color:green;">as</span></span> <span style="color:red;">-&gt;</span> DConv bs <span style="color:red;">-&gt;</span> DConv (<span style="text-decoration:underline;"><span style="color:green;">as</span></span> <strong><span style="color:red;">:++:</span></strong> bs)
&gt; appendC (DConv fa) (DConv fb) <span style="color:red;">=</span>
&gt;   DConv (<span style="color:red;">\</span>(<span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">::</span> Proxy vars') <span style="color:red;">-&gt;</span>
&gt;     <span style="text-decoration:underline;"><span style="color:green;">case</span></span> assoc (proxy <span style="color:red;">::</span> Proxy <span style="text-decoration:underline;"><span style="color:green;">as</span></span>) (proxy <span style="color:red;">::</span> Proxy bs) (proxy <span style="color:red;">::</span> Proxy vars') <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;       Equal <span style="color:red;">-&gt;</span> fa (proxy <span style="color:red;">::</span> Proxy (bs <strong><span style="color:red;">:++:</span></strong> vars')) . fb (proxy <span style="color:red;">::</span> Proxy vars'))</pre>
<p>Now, <code>appendC</code> is considerably longer than the other two functions, but most of the length is just in the proxy types and GADT matches, to satisfy the typechecker. The actual data manipulation is still done by <code>(.)</code>, which is hidden on the last line of its definition.</p>
<p>These are the only functions Morten uses to manipulate the first components, so we are done with the first component.</p>
<h2 id="the-second-component-the-actual-matcher">The second component: the actual matcher</h2>
<p>The process here is similar to the process for the first component, only more complicated. First we find a type which the simple combinators unify with, then we fix the ambiguity problems, and then we discuss the interpretation of the type.</p>
<p>Other than ambiguity and type family problems, the second component of the patterns unifies with this type</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> Component2 vars pat <span style="color:red;">=</span>
&gt;    <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> vars' r.
&gt;      pat                               <span style="color:blue;"><em>-- pattern to match</em></span>
&gt;   <span style="color:red;">-&gt;</span> (UncurryFunc (vars <strong><span style="color:red;">:++:</span></strong> vars') r) <span style="color:blue;"><em>-- success continuation</em></span>
&gt;   <span style="color:red;">-&gt;</span> (() <span style="color:red;">-&gt;</span> r)                         <span style="color:blue;"><em>-- failure continuation</em></span>
&gt;   <span style="color:red;">-&gt;</span> Tuple vars'                       <span style="color:blue;"><em>-- already-pushed bindings</em></span>
&gt;   <span style="color:red;">-&gt;</span> r                                 <span style="color:blue;"><em>-- continuation result</em></span></pre>
<p>We can cleanly separate the parts of the type mentioning <code>pat</code> from the parts mentioning <code>vars</code> to get</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> Component2' vars pat <span style="color:red;">=</span> pat <span style="color:red;">-&gt;</span> Push1 vars
&gt; <span style="text-decoration:underline;"><span style="color:green;">type</span></span> Push1 vars <span style="color:red;">=</span>
&gt;    <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> vars' r.
&gt;      (UncurryFunc (vars <strong><span style="color:red;">:++:</span></strong> vars') r) <span style="color:blue;"><em>-- success continuation</em></span>
&gt;   <span style="color:red;">-&gt;</span> (() <span style="color:red;">-&gt;</span> r)                         <span style="color:blue;"><em>-- failure continuation</em></span>
&gt;   <span style="color:red;">-&gt;</span> Tuple vars'                       <span style="color:blue;"><em>-- already-pushed bindings</em></span>
&gt;   <span style="color:red;">-&gt;</span> r                                 <span style="color:blue;"><em>-- continuation result</em></span></pre>
<p>The failure continuation has an odd-looking type, <code>() -&gt; r</code>. This is similar to the simpler type <code>r</code>, and one might wonder why the failure continuation isn’t just defined like that. It turns out that the reason is the same as the reason that the success continuation must be uncurried internally: there are times when the success and failure continuations are swapped, so they must have unifiable types, so they must both be a type with a single function arrow. However, they still won’t unify, since that would require unifying <code>()</code> with <code>Tuple (vars :++: vars')</code>, and those types might not be equal. Hence we change the failure continuation’s type to <code>(forall s. s -&gt; r)</code>. This makes <code>Push1</code> a rank–3 type.</p>
<p>Making this change, and fixing the ambiguity of <code>vars</code> and <code>vars'</code> like we did before, we get the type</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> Push vars <span style="color:red;">=</span> Push { runPush <span style="color:red;">::</span>
&gt;    <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> vars' r.
&gt;       Proxy vars'
&gt;    <span style="color:red;">-&gt;</span> (UncurryFunc (vars <strong><span style="color:red;">:++:</span></strong> vars') r)
&gt;    <span style="color:red;">-&gt;</span> (<span style="text-decoration:underline;"><span style="color:green;">forall</span></span> s. s <span style="color:red;">-&gt;</span> r)
&gt;    <span style="color:red;">-&gt;</span> Tuple vars'
&gt;    <span style="color:red;">-&gt;</span> r
&gt;   }</pre>
<p>A value of type <code>Push vars</code> is something which does the appropriate plumbing: it either pushes the variables in <code>vars</code> onto the success continuation, or it calls the failure continuation. Below are the 5 functions Morten uses to manipulate (the equivalent of) <code>Push</code> values. I give their equivalents in the <code>Push</code> type (these are the functions with the <code>P</code> suffix). All of them other than <code>catchP</code> are defined using Morten’s function; in <code>catchP</code> I needed to modify the failure continuation so that it accepts any parameter rather than just <code>()</code>, as discussed above.</p>
<pre>&gt; <span style="color:blue;"><em>-- | succeeds without pushing any variables</em></span>
&gt; nil         <span style="color:red;">=</span> <span style="color:red;">\</span>ks kf ac <span style="color:red;">-&gt;</span> ks ac
&gt; nilP <span style="color:red;">::</span> Push Nil
&gt; nilP <span style="color:red;">=</span> Push (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> nil)</pre>
<pre>&gt; <span style="color:blue;"><em>-- | succeeds and pushes one variable</em></span>
&gt; one v       <span style="color:red;">=</span> <span style="color:red;">\</span>ks kf ac <span style="color:red;">-&gt;</span> ks (v,ac)
&gt; oneP <span style="color:red;">::</span> a <span style="color:red;">-&gt;</span> Push (a <strong><span style="color:red;">:*:</span></strong> Nil)
&gt; oneP v <span style="color:red;">=</span> Push (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> one v)</pre>
<pre>&gt; <span style="color:blue;"><em>-- | Pushes the variables of the first, then the variables of the second (assuming the first succeeds).</em></span>
&gt; m <em><span style="color:magenta;">#</span></em> n       <span style="color:red;">=</span> <span style="color:red;">\</span>ks kf ac <span style="color:red;">-&gt;</span> n (m ks kf) kf ac
&gt; appendP <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> <span style="text-decoration:underline;"><span style="color:green;">as</span></span> bs. List <span style="text-decoration:underline;"><span style="color:green;">as</span></span> <span style="color:red;">=&gt;</span> Push <span style="text-decoration:underline;"><span style="color:green;">as</span></span> <span style="color:red;">-&gt;</span> Push bs <span style="color:red;">-&gt;</span> Push (<span style="text-decoration:underline;"><span style="color:green;">as</span></span> <strong><span style="color:red;">:++:</span></strong> bs)
&gt; appendP (Push m) (Push n) <span style="color:red;">=</span>
&gt;    Push (<span style="color:red;">\</span>(<span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">::</span> Proxy vars') <span style="color:red;">-&gt;</span>
&gt;       <span style="text-decoration:underline;"><span style="color:green;">case</span></span> assoc (proxy <span style="color:red;">::</span> Proxy <span style="text-decoration:underline;"><span style="color:green;">as</span></span>) (proxy <span style="color:red;">::</span> Proxy bs) (proxy <span style="color:red;">::</span> Proxy vars') <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;          Equal <span style="color:red;">-&gt;</span> m (proxy <span style="color:red;">::</span> Proxy (bs <strong><span style="color:red;">:++:</span></strong> vars')) <em><span style="color:magenta;">#</span></em> n (proxy <span style="color:red;">::</span> Proxy vars'))</pre>
<pre>&gt; <span style="color:blue;"><em>-- | Calls the failure continuation immediately</em></span>
&gt; fail        <span style="color:red;">=</span> <span style="color:red;">\</span>ks kf ac <span style="color:red;">-&gt;</span> kf ()
&gt; failP <span style="color:red;">::</span> Push <span style="text-decoration:underline;"><span style="color:green;">as</span></span>
&gt; failP <span style="color:red;">=</span> Push (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> <span style="color:red;">\</span>ks kf <span style="color:red;">-&gt;</span> fail ks kf)</pre>
<pre>&gt; <span style="color:blue;"><em>-- | Recovers from @m@'s failure by running @n@.</em></span>

&gt; m `catch` n <span style="color:red;">=</span> <span style="color:red;">\</span>ks kf ac <span style="color:red;">-&gt;</span> m ks (<span style="color:red;">\</span>() <span style="color:red;">-&gt;</span> n ks kf ac) ac
&gt; catchP <span style="color:red;">::</span> Push <span style="text-decoration:underline;"><span style="color:green;">as</span></span> <span style="color:red;">-&gt;</span> Push <span style="text-decoration:underline;"><span style="color:green;">as</span></span> <span style="color:red;">-&gt;</span> Push <span style="text-decoration:underline;"><span style="color:green;">as</span></span>
&gt; catchP (Push m) (Push n) <span style="color:red;">=</span> Push (<span style="color:red;">\</span>p ks kf ac <span style="color:red;">-&gt;</span> (m p) ks (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> (n p) ks kf ac) ac)</pre>
<p>I have omitted the types of Morten’s functions, as they are rather messy and not particularly informative. In contrast, the types of the <code>Push</code> versions are quite informative: they give a list of variables pushed. In the case of <code>failP</code>, it can claim that any number of variables can be pushed: like _|_, it doesn’t have to justify that claim, as it simply fails when run.</p>
<h1 id="types-for-patterns">Types for patterns</h1>
<p>Now we can (finally) give types to patterns. A pattern has a first component and a second component, and it also requires that <code>vars</code> is a list (and it contains the evidence of that).</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">data</span></span> Pattern vars pat <span style="color:red;">=</span> List vars <span style="color:red;">=&gt;</span>
&gt;     Pattern (DConv vars) (pat <span style="color:red;">-&gt;</span> Push vars)</pre>
<p>We can define all of Morten’s patterns almost as he defined them, since we have typed all of Morten’s primitive manipulation functions. I give the first few of them here:</p>
<pre>&gt; var <span style="color:red;">::</span> Pattern (a <strong><span style="color:red;">:*:</span></strong> Nil) a
&gt; var <span style="color:red;">=</span> Pattern succC oneP</pre>
<pre>&gt; cst <span style="color:red;">::</span> (Eq pat) <span style="color:red;">=&gt;</span> pat <span style="color:red;">-&gt;</span> Pattern Nil pat
&gt; cst v' <span style="color:red;">=</span> Pattern idC (<span style="color:red;">\</span>v <span style="color:red;">-&gt;</span> <span style="text-decoration:underline;"><span style="color:green;">if</span></span> v == v' <span style="text-decoration:underline;"><span style="color:green;">then</span></span> nilP <span style="text-decoration:underline;"><span style="color:green;">else</span></span> failP)</pre>
<pre>&gt; pair <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> <span style="text-decoration:underline;"><span style="color:green;">as</span></span> a bs b. Pattern <span style="text-decoration:underline;"><span style="color:green;">as</span></span> a <span style="color:red;">-&gt;</span> Pattern bs b <span style="color:red;">-&gt;</span> Pattern (<span style="text-decoration:underline;"><span style="color:green;">as</span></span> <strong><span style="color:red;">:++:</span></strong> bs) (a,b)
&gt; pair (Pattern pC pP) (Pattern qC qP) <span style="color:red;">=</span>
&gt;     <span style="text-decoration:underline;"><span style="color:green;">case</span></span> closure (proxy <span style="color:red;">::</span> Proxy <span style="text-decoration:underline;"><span style="color:green;">as</span></span>) (proxy <span style="color:red;">::</span> Proxy bs) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;       ListD <span style="color:red;">-&gt;</span> Pattern (appendC pC qC) (<span style="color:red;">\</span>(a,b) <span style="color:red;">-&gt;</span> pP a `appendP` qP b)</pre>
<pre>&gt; none <span style="color:red;">::</span> Pattern Nil pat
&gt; none <span style="color:red;">=</span> Pattern idC (<span style="color:red;">\</span>v <span style="color:red;">-&gt;</span> failP)</pre>
<pre>&gt; (\/) <span style="color:red;">::</span> Pattern t pat <span style="color:red;">-&gt;</span> Pattern t pat <span style="color:red;">-&gt;</span> Pattern t pat
&gt; (Pattern pC pP) \/ (Pattern qC qP) <span style="color:red;">=</span>
&gt;     Pattern pC (<span style="color:red;">\</span>v <span style="color:red;">-&gt;</span> pP v `catchP` qP v)</pre>
<pre>&gt; any <span style="color:red;">::</span> Pattern Nil pat
&gt; any <span style="color:red;">=</span> Pattern idC (<span style="color:red;">\</span>v <span style="color:red;">-&gt;</span> nilP)</pre>
<pre>&gt; (/\) <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> <span style="text-decoration:underline;"><span style="color:green;">as</span></span> bs a. Pattern <span style="text-decoration:underline;"><span style="color:green;">as</span></span> a <span style="color:red;">-&gt;</span> Pattern bs a <span style="color:red;">-&gt;</span> Pattern (<span style="text-decoration:underline;"><span style="color:green;">as</span></span> <strong><span style="color:red;">:++:</span></strong> bs) a

&gt; (Pattern pC pP) /\ (Pattern qC qP) <span style="color:red;">=</span>
&gt;     <span style="text-decoration:underline;"><span style="color:green;">case</span></span> closure (proxy <span style="color:red;">::</span> Proxy <span style="text-decoration:underline;"><span style="color:green;">as</span></span>) (proxy <span style="color:red;">::</span> Proxy bs) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;       ListD <span style="color:red;">-&gt;</span> Pattern (appendC pC qC) (<span style="color:red;">\</span>v <span style="color:red;">-&gt;</span> pP v `appendP` qP v)</pre>
<p>In <code>pair</code> and <code>(/\)</code> we unfortunately still need to use GADTs to prove the closure rule, but we can define all the other combinators without any cleverness. All the functions have informative types.</p>
<h1 id="types-for-clauses">Types for clauses</h1>
<p>We now have a nicely-typed way to construct patterns, but we still have no way to run them. There are three more primitive functions we need to define: <code>match</code>, <code>(-&gt;&gt;)</code> and <code>(||)</code>. Their use is best demonstrated by an example:</p>
<pre><code>match ((3,4),5) $
    pair (pair var var) cst 4        -&gt;&gt; \x y -&gt; x + y
 || pair (pair (cst 3) (cst 4)) var  -&gt;&gt; \x -&gt; x
</code></pre>
<p>We first give the types that these functions should have. The <code>(-&gt;&gt;)</code> function should accept a pattern and an RHS and yield something which <code>match</code> can be called on (call it a “clause”). The <code>(||)</code> function should take two clauses and give a clause which tries the first clause, and then the second if the first failed. The match function should accept a value to match, and a clause which matches values of that type, and it should yield the value yielded by the clause. A clause’s type should say two things: what values it can match, and what the result value is.</p>
<p>So, the types are:</p>
<pre>&gt; (-&gt;&gt;) <span style="color:red;">::</span> <span style="text-decoration:underline;"><span style="color:green;">forall</span></span> vars a r.
&gt;    Pattern vars a <span style="color:red;">-&gt;</span> CurryFunc vars r <span style="color:red;">-&gt;</span> Clause a r
&gt; (||) <span style="color:red;">::</span> Clause a r <span style="color:red;">-&gt;</span> Clause a r <span style="color:red;">-&gt;</span> Clause a r

&gt; match <span style="color:red;">::</span> a <span style="color:red;">-&gt;</span> Clause a r <span style="color:red;">-&gt;</span> r</pre>
<p>An implementation satisfying these types and semantics is below:</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">newtype</span></span> Clause pat res <span style="color:red;">=</span> Clause {
&gt;   runClause <span style="color:red;">::</span> pat <span style="color:red;">-&gt;</span> (<span style="text-decoration:underline;"><span style="color:green;">forall</span></span> s. s <span style="color:red;">-&gt;</span> res) <span style="color:red;">-&gt;</span> res
&gt;  }</pre>
<pre>&gt; (Pattern c p) -&gt;&gt; k <span style="color:red;">=</span> Clause
&gt;     (<span style="text-decoration:underline;"><span style="color:green;">case</span></span> rightIdent (proxy <span style="color:red;">::</span> Proxy vars) <span style="text-decoration:underline;"><span style="color:green;">of</span></span>
&gt;         Equal <span style="color:red;">-&gt;</span> <span style="color:red;">\</span>v kf <span style="color:red;">-&gt;</span> runPush (p v) (proxy <span style="color:red;">::</span> Proxy Nil) (runDConv c (proxy <span style="color:red;">::</span> Proxy Nil) zero k) kf ()) <span style="text-decoration:underline;"><span style="color:green;">where</span></span>
&gt;             zero   f <span style="color:red;">=</span> <span style="color:red;">\</span>() <span style="color:red;">-&gt;</span> f</pre>
<pre>&gt; p1 || p2 <span style="color:red;">=</span> Clause (<span style="color:red;">\</span>pat kf <span style="color:red;">-&gt;</span> runClause p1 pat (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> runClause p2 pat kf))</pre>
<pre>&gt; match a p <span style="color:red;">=</span> runClause p a (<span style="color:red;">\</span><span style="text-decoration:underline;"><span style="color:green;">_</span></span> <span style="color:red;">-&gt;</span> error <span style="color:magenta;">"match failed"</span>)</pre>
<p>The precedences of the operators are</p>
<pre>&gt; <span style="text-decoration:underline;"><span style="color:green;">infix</span></span> <span style="color:magenta;">2</span> -&gt;&gt;
&gt; <span style="text-decoration:underline;"><span style="color:green;">infixr</span></span> <span style="color:magenta;">1</span> ||</pre>
<p>This is all the code we need to use our patterns in a nicely-typed way. As an example, we can write</p>
<pre>&gt; foo <span style="color:red;">=</span>
&gt;     pair (cst <span style="color:magenta;">2</span> \/ cst <span style="color:magenta;">3</span>) any -&gt;&gt; <span style="color:magenta;">"The tuple has either 2 or 3 as the first component"</span>
&gt;  || pair any var              -&gt;&gt; (<span style="color:red;">\</span>v <span style="color:red;">-&gt;</span> <span style="color:magenta;">"The second component has value "</span> ++ show v)
&gt;  || var                       -&gt;&gt; (<span style="color:red;">\</span>v <span style="color:red;">-&gt;</span> <span style="color:magenta;">"The tuple is "</span> ++ show v)</pre>
<p>GHC will infer the type of this (under <code>NoMonomorphismRestriction</code>) as</p>
<pre>&gt; foo <span style="color:red;">::</span> (Num t, Show b) <span style="color:red;">=&gt;</span> Clause (t, b) <span style="color:red;">[</span>Char<span style="color:red;">]</span></pre>
<h1 id="wrapping-up">Wrapping up</h1>
<p>Giving better types to the pattern combinators has benefits. These new types are “more static” than the original ones, which gives us the advantages of stronger typing.</p>
<p>The first advantage is that the code is more modular: we can define a pattern combinator independently of the others; if it has the desired type, we have quite good assurance that we have written it correctly. This was not the case for the original types, because it was hard to tell what the desired type actually was.</p>
<p>We can also provide an easier API for the user; the types of the pattern combinators actually give a lot of information about what they do. We are able to export the <code>Pattern</code> type abstract, which we couldn’t do for Morten’s code, because there was no datatype.</p>
<p>One disadvantage is that we have lost Haskell98 compatibility: Type Families play a key role in assigning nicer types to the combinators. For my purposes, trading Haskell98 compatibility for nicer types is a good compromise.</p>
<p>One feature of Morten’s code is that all his functions are implemented non-recursively, so GHC is able to inline all the pattern combinators, and completely optimise away all the overhead. Unfortunately, the <code>closure</code> function in the <code>(h:*:t)</code> instance of <code>List</code> is recursive; this recursion prevents GHC from inlining everything. So, we have lost some of the efficiency of Morten’s code. This is particularly unfortunate, because the actual working code is identical: the recursive code exists only to convince GHC that the types are correct. I have been working on an alternative implementation which uses <code>unsafeCoerce</code> in appropriate places; I will post about this sometime in the future.</p>
<div class="footnotes">
<hr />
<ol>
<li><a id="fn1"></a>Hence the choice of name for <code>DConv</code>. <a class="footnoteBackLink" title="Jump back to footnote 1" href="#fnref1">↩</a></li>
</ol>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/reinerp.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/reinerp.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/reinerp.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/reinerp.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/reinerp.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/reinerp.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/reinerp.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/reinerp.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/reinerp.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/reinerp.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/reinerp.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/reinerp.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/reinerp.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/reinerp.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=reinerp.wordpress.com&amp;blog=8344434&amp;post=5&amp;subd=reinerp&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://reinerp.wordpress.com/2009/06/29/nicer-types-for-type-safe-pattern-combinators/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/6e7554bdaabd25dbf90752e4233b284f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">reinerpope</media:title>
		</media:content>
	</item>
	</channel>
</rss>
