<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Conal Elliott</title>
	
	<link>http://conal.net/blog</link>
	<description>Inspirations &amp; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Mon, 24 Dec 2012 18:58:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/conal" /><feedburner:info uri="conal" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><geo:lat>38.192823</geo:lat><geo:long>-120.642852</geo:long><feedburner:emailServiceId>conal</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item>
		<title>Reimagining matrices</title>
		<link>http://feedproxy.google.com/~r/conal/~3/8Yt6DAQKEtY/reimagining-matrices</link>
		<comments>http://conal.net/blog/posts/reimagining-matrices#comments</comments>
		<pubDate>Mon, 17 Dec 2012 02:45:42 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[category]]></category>
		<category><![CDATA[denotational design]]></category>
		<category><![CDATA[linear algebra]]></category>
		<category><![CDATA[type class morphism]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=503</guid>
		<description><![CDATA[The function of the imagination is notto make strange things settled, so much asto make settled things strange.- G.K. Chesterton

Why is matrix multiplication defined so very differently from matrix addition? If we didn’t know these procedures, could we derive them from first principles? What might those principles be?
This post gives a simple semantic model ...]]></description>
			<content:encoded><![CDATA[<!-- LaTeX macros -->

<!-- teaser -->

<div class=flushright>
<em>The function of the imagination is not<br />to make strange things settled, so much as<br />to make settled things strange.</em><br />- G.K. Chesterton
</div>

<p>Why is matrix multiplication defined so very differently from matrix addition? If we didn’t know these procedures, could we derive them from first principles? What might those principles be?</p>

<p>This post gives a simple semantic model for matrices and then uses it to systematically <em>derive</em> the implementations that we call matrix addition and multiplication. The development illustrates what I call “denotational design”, particularly with type class morphisms. On the way, I give a somewhat unusual formulation of matrices and accompanying definition of matrix “multiplication”.</p>

<p>For more details, see the <a href="https://github.com/conal/linear-map-gadt" title="github repository">linear-map-gadt</a> source code.</p>

<p><strong>Edits:</strong></p>

<ul>
<li>2012–12–17: Replaced lost <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>B</mi></mrow></math> entries in description of matrix addition. Thanks to Travis Cardwell.</li>
<li>2012–12018: Added note about math/browser compatibility.</li>
</ul>

<p><strong>Note:</strong> I’m using MathML for the math below, which appears to work well on Firefox but on neither Safari nor Chrome. I use Pandoc to generate the HTML+MathML from markdown+lhs+LaTeX. There’s probably a workaround using different Pandoc settings and requiring some tweaks to my WordPress installation. If anyone knows how (especially the WordPress end), I’d appreciate some pointers.</p>

<p><span id="more-503"></span></p>

<h3 id="matrices">Matrices</h3>

<p>For now, I’ll write matrices in the usual form: <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mrow><mn>1</mn><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow></mrow></math></p>

<h4 id="addition">Addition</h4>

<p>To add two matrices, we add their corresponding components. If <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mrow><mtext mathvariant="normal">and </mtext><mspace width="0.333em"></mspace></mrow><mi>B</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>B</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>B</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>,</mo></mrow></math> then <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>+</mo><mi>B</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub><mo>+</mo><msub><mi>B</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>.</mo></mrow></math> More succinctly, <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>+</mo><mi>B</mi><msub><mo stretchy="false">)</mo><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>=</mo><msub><mi>A</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>+</mo><msub><mi>B</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>.</mo></mrow></math></p>

<h4 id="multiplication">Multiplication</h4>

<p>Multiplication, on the other hand, works quite differently. If <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mrow><mtext mathvariant="normal">and </mtext><mspace width="0.333em"></mspace></mrow><mi>B</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>B</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mn>1</mn><mi>p</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>B</mi><mrow><mi>m</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>B</mi><mrow><mi>m</mi><mi>p</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>,</mo></mrow></math> then <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>∙</mo><mi>B</mi><msub><mo stretchy="false">)</mo><mrow><mi>i</mi><mi>j</mi></mrow></msub><mo>=</mo><munderover><mo>∑</mo><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></munderover><msub><mi>A</mi><mrow><mi>i</mi><mi>k</mi></mrow></msub><mo>⋅</mo><msub><mi>B</mi><mrow><mi>k</mi><mi>j</mi></mrow></msub><mo>.</mo></mrow></math> This time, we form the dot product of each <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi></mrow></math> row and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>B</mi></mrow></math> column.</p>

<p>Why are these two matrix operations defined so differently? Perhaps these two operations are <em>implementations</em> of more fundamental <em>specifications</em>. If so, then making those specifications explicit could lead us to clear and compelling explanations of matrix addition and multiplication.</p>

<h4 id="transforming-vectors">Transforming vectors</h4>

<p>Simplifying from matrix multiplication, we have transformation of a vector by a matrix. If <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mn>11</mn></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd><mo>⋱</mo></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub></mtd><mtd><mo>⋯</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mrow><mtext mathvariant="normal">and </mtext><mspace width="0.333em"></mspace></mrow><mi>x</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>x</mi><mn>1</mn></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>x</mi><mi>m</mi></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow><mo>,</mo></mrow></math> then <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>A</mi><mo>⋅</mo><mi>x</mi><mo>=</mo><mrow><mo stretchy="true">(</mo><mtable><mtr><mtd><msub><mi>A</mi><mrow><mn>1</mn><mn>1</mn></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mn>1</mn></msub></mtd><mtd><mo>+</mo></mtd><mtd><mo>⋯</mo></mtd><mtd><mo>+</mo></mtd><mtd><msub><mi>A</mi><mrow><mn>1</mn><mi>m</mi></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mi>m</mi></msub></mtd></mtr><mtr><mtd><mo>⋮</mo></mtd><mtd></mtd><mtd><mo>⋱</mo></mtd><mtd></mtd><mtd><mo>⋮</mo></mtd></mtr><mtr><mtd><msub><mi>A</mi><mrow><mi>n</mi><mn>1</mn></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mn>1</mn></msub></mtd><mtd><mo>+</mo></mtd><mtd><mo>⋯</mo></mtd><mtd><mo>+</mo></mtd><mtd><msub><mi>A</mi><mrow><mi>n</mi><mi>m</mi></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mi>m</mi></msub></mtd></mtr></mtable><mo stretchy="true">)</mo></mrow></mrow></math> More succinctly, <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>⋅</mo><mi>x</mi><msub><mo stretchy="false">)</mo><mi>i</mi></msub><mo>=</mo><munderover><mo>∑</mo><mrow><mi>k</mi><mo>=</mo><mn>1</mn></mrow><mi>m</mi></munderover><msub><mi>A</mi><mrow><mi>i</mi><mi>k</mi></mrow></msub><mo>⋅</mo><msub><mi>x</mi><mi>k</mi></msub><mo>.</mo></mrow></math></p>

<h3 id="whats-it-all-about">What’s it all about?</h3>

<p>We can interpret matrices <em>as</em> transformations. Matrix addition then <em>adds</em> transformations:</p>

<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>+</mo><mi>B</mi><mo stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>x</mi><mo>=</mo><mi>A</mi><mspace width="0.167em"></mspace><mi>x</mi><mo>+</mo><mi>B</mi><mspace width="0.167em"></mspace><mi>x</mi></mrow></math></p>

<p>Matrix “multiplication” <em>composes</em> transformations:</p>

<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>A</mi><mo>∙</mo><mi>B</mi><mo stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>x</mi><mo>=</mo><mi>A</mi><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>B</mi><mspace width="0.167em"></mspace><mi>x</mi><mo stretchy="false">)</mo></mrow></math></p>

<p>What kinds of transformations?</p>

<h4 id="linear-transformations">Linear transformations</h4>

<p>Matrices represent <em>linear</em> transformations. To say that a transformation (or “function” or “map”) <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi></mrow></math> is “linear” means that <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi></mrow></math> preserves the structure of addition and scalar multiplication. In other words, <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mtable><mtr><mtd columnalign="right"><mi>f</mi><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo stretchy="false">)</mo></mtd><mtd columnalign="center"><mo>=</mo></mtd><mtd columnalign="left"><mi>f</mi><mspace width="0.167em"></mspace><mi>x</mi><mo>+</mo><mi>f</mi><mspace width="0.167em"></mspace><mi>y</mi></mtd></mtr><mtr><mtd columnalign="right"><mi>f</mi><mspace width="0.167em"></mspace><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>c</mi><mo>⋅</mo><mi>x</mi><mo stretchy="false">)</mo></mtd><mtd columnalign="center"><mo>=</mo></mtd><mtd columnalign="left"><mi>c</mi><mo>⋅</mo><mi>f</mi><mspace width="0.167em"></mspace><mi>x</mi></mtd></mtr></mtable></mrow></math> Equivalently, <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi></mrow></math> preserves all <em>linear combinations</em>: <math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><msub><mi>c</mi><mn>1</mn></msub><mo>⋅</mo><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><mo>⋯</mo><mo>+</mo><msub><mi>c</mi><mi>m</mi></msub><mo>⋅</mo><msub><mi>x</mi><mi>m</mi></msub><mo stretchy="false">)</mo><mo>=</mo><msub><mi>c</mi><mn>1</mn></msub><mo>⋅</mo><mi>f</mi><mspace width="0.167em"></mspace><msub><mi>x</mi><mn>1</mn></msub><mo>+</mo><mo>⋯</mo><mo>+</mo><msub><mi>c</mi><mi>m</mi></msub><mo>⋅</mo><mi>f</mi><mspace width="0.167em"></mspace><msub><mi>x</mi><mi>m</mi></msub></mrow></math></p>

<p>What does it mean to say that “matrices represent linear transformations”? As we saw in the previous section, we can use a matrix to transform a vector. Our semantic function will exactly be this use, i.e., the <em>meaning</em> of matrix is as a function (map) from vectors to vectors. Moreover, these functions will satisfy the linearity properties above.</p>

<h4 id="representation">Representation</h4>

<p>For simplicity, I’m going structure matrices in a unconventional way. Instead of a rectangular arrangement of numbers, use the following generalized algebraic data type (GADT):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">data</span> a ⊸ b <span class="kw">where</span>
  <span class="dt">Dot</span>   <span class="ot">∷</span> <span class="dt">InnerSpace</span> b <span class="ot">⇒</span>
          b <span class="ot">→</span> (b ⊸ <span class="dt">Scalar</span> b)
  (<span class="fu">:&amp;&amp;</span>) <span class="ot">∷</span> <span class="dt">VS3</span> a c d <span class="ot">⇒</span>  <span class="co">-- vector spaces with same scalar field</span>
          (a ⊸ c) <span class="ot">→</span> (a ⊸ d) <span class="ot">→</span> (a ⊸ c × d)</code></pre>

<p>I’m using the notation “<code>c × d</code>” in place of the usual “<code>(c,d)</code>”. Precedences are such that “<code>×</code>” binds more tightly than “<code>⊸</code>”, which binds more tightly than “<code>→</code>”.</p>

<p>This definition builds on the <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-VectorSpace.html#t:VectorSpace" title="Hackage documentation"><code>VectorSpace</code></a> class, with its associated <code>Scalar</code> type and <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-VectorSpace.html#t:InnerSpace" title="Hackage documentation"><code>InnerSpace</code></a> subclass. Using <code>VectorSpace</code> is overkill for linear maps. It suffices to use <a href="http://en.wikipedia.org/wiki/Module_%28mathematics%29" title="Wikipedia entry">module</a>s over <a href="http://en.wikipedia.org/wiki/Semiring" title="Wikipedia entry">semiring</a>s, which means that we don’t assume multiplicative or additive inverses. The more general setting enables many more useful applications than vector spaces do, some of which I will describe in future posts.</p>

<p>The idea here is that a linear map results in either (a) a scalar, in which case it’s equivalent to <code>dot v</code> (partially applied dot product) for some <code>v</code>, or (b) a product, in which case it can be decomposed into two linear maps with simpler range types. Each row in a conventional matrix corresponds to <code>Dot v</code> for some vector <code>v</code>, and the stacking of rows corresponds to nested applications of <code>(:&amp;&amp;)</code>.</p>

<h4 id="semantics">Semantics</h4>

<p>The semantic function, <code>apply</code>, interprets a representation of a linear map as a function (satisfying linearity):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply <span class="ot">∷</span> (a ⊸ b) <span class="ot">→</span> (a <span class="ot">→</span> b)
apply (<span class="dt">Dot</span> b)   <span class="fu">=</span> dot b
apply (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> apply f <span class="fu">&amp;&amp;&amp;</span> apply g</code></pre>

<p>where, <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Arrow.html#v:-38--38--38-" title="Hackage documentation"><code>(&amp;&amp;&amp;)</code></a> is from <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Arrow.html" title="Hackage documentation"><code>Control.Arrow</code></a>.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(<span class="fu">&amp;&amp;&amp;</span>) <span class="ot">∷</span> <span class="dt">Arrow</span> (↝) <span class="ot">⇒</span> (a ↝ b) <span class="ot">→</span> (a ↝ c) <span class="ot">→</span> (a ↝ (b,c))</code></pre>

<p>For functions,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">&amp;&amp;&amp;</span> g) a <span class="fu">=</span> (f a, g a)</code></pre>

<h3 id="functions-linearity-and-multilinearity">Functions, linearity, and multilinearity</h3>

<p>Functions form a vector space, with scaling and addition defined “pointwise”. Instances from the <a href="http://hackage.haskell.org/package/vector-space" title="Hackage package">vector-space</a> package:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">AdditiveGroup</span> v <span class="ot">⇒</span> <span class="dt">AdditiveGroup</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  zeroV   <span class="fu">=</span> pure   zeroV
  (<span class="fu">^+^</span>)   <span class="fu">=</span> liftA2 (<span class="fu">^+^</span>)
  negateV <span class="fu">=</span> <span class="fu">fmap</span>   negateV

<span class="kw">instance</span> <span class="dt">VectorSpace</span> v <span class="ot">⇒</span> <span class="dt">VectorSpace</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  <span class="kw">type</span> <span class="dt">Scalar</span> (a <span class="ot">→</span> v) <span class="fu">=</span> a <span class="ot">→</span> <span class="dt">Scalar</span> v
  (<span class="fu">*^</span>) s <span class="fu">=</span> <span class="fu">fmap</span> (s <span class="fu">*^</span>)</code></pre>

<p>I wrote the definitions in this form to fit a template for applicative functors in general. Inlining the definitions of <code>pure</code>, <code>liftA2</code>, and <code>fmap</code> on functions, we get the following equivalent instances:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">AdditiveGroup</span> v <span class="ot">⇒</span> <span class="dt">AdditiveGroup</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  zeroV     <span class="fu">=</span> λ _ <span class="ot">→</span> zeroV
  f <span class="fu">^+^</span> g   <span class="fu">=</span> λ a <span class="ot">→</span> f a <span class="fu">^+^</span> g a
  negateV f <span class="fu">=</span> λ a <span class="ot">→</span> negateV (f a)

<span class="kw">instance</span> <span class="dt">VectorSpace</span> v <span class="ot">⇒</span> <span class="dt">VectorSpace</span> (a <span class="ot">→</span> v) <span class="kw">where</span>
  <span class="kw">type</span> <span class="dt">Scalar</span> (a <span class="ot">→</span> v) <span class="fu">=</span> a <span class="ot">→</span> <span class="dt">Scalar</span> v
  s <span class="fu">*^</span> f <span class="fu">=</span> λ a <span class="ot">→</span> s <span class="fu">*^</span> f a</code></pre>

<p>In math, we usually say that dot product is “bilinear”, or “linear in each argument”, i.e.,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (s <span class="fu">*^</span> u,v) ≡ s <span class="fu">*^</span> dot (u,v)
dot (u <span class="fu">^+^</span> w, v) ≡ dot (u,v) <span class="fu">^+^</span> dot (w,v)</code></pre>

<p>Similarly for the second argument:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (u,s <span class="fu">*^</span> v) ≡ s <span class="fu">*^</span> dot (u,v)
dot (u, v <span class="fu">^+^</span> w) ≡ dot (u,v) <span class="fu">^+^</span> dot (u,w)</code></pre>

<p>Now recast the first of these properties in a curried form:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (s <span class="fu">*^</span> u) v ≡ s <span class="fu">*^</span> dot u v</code></pre>

<p>i.e.,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (s <span class="fu">*^</span> u)
 ≡ <span class="co">{- η-expand -}</span>
λ v <span class="ot">→</span> dot (s <span class="fu">*^</span> u) v
 ≡ <span class="co">{- &quot;bilinearity&quot; -}</span>
λ v <span class="ot">→</span> s <span class="fu">*^</span> dot u v
 ≡ <span class="co">{- (*^) on functions -}</span>
λ v <span class="ot">→</span> (s <span class="fu">*^</span> dot u) v
 ≡ <span class="co">{- η-contract -}</span>
s <span class="fu">*^</span> dot u</code></pre>

<p>Likewise,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (u <span class="fu">^+^</span> v)
 ≡ <span class="co">{- η-expand -}</span>
λ w <span class="ot">→</span> dot (u <span class="fu">^+^</span> v) w
 ≡ <span class="co">{- &quot;bilinearity&quot; -}</span>
λ w <span class="ot">→</span> dot u w <span class="fu">^+^</span> dot v w
 ≡ <span class="co">{- (^+^) on functions -}</span>
dot u <span class="fu">^+^</span> dot v</code></pre>

<p>Thus, when “bilinearity” is recast in terms of curried functions, it becomes just linearity. (The same reasoning applies more generally to multilinearity.)</p>

<p>Note that we could also define function addition as follows:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">f <span class="fu">^+^</span> g <span class="fu">=</span> add ∘ (f <span class="fu">&amp;&amp;&amp;</span> g)</code></pre>

<p>where</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add <span class="fu">=</span> <span class="fu">uncurry</span> (<span class="fu">^+^</span>)</code></pre>

<p>This uncurried form will come in handy in derivations below.</p>

<h3 id="deriving-matrix-operations">Deriving matrix operations</h3>

<h4 id="addition-1">Addition</h4>

<p>We’ll add two linear maps using the <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-AdditiveGroup.html#v:-94--43--94-" title="Hackage documentation"><code>(^+^)</code></a> operation from <a href="http://hackage.haskell.org/packages/archive/vector-space/latest/doc/html/Data-AdditiveGroup.html" title="Hackage documentation"><code>Data.AdditiveGroup</code></a>.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(<span class="fu">^+^</span>) <span class="ot">∷</span> (a ⊸ b) <span class="ot">→</span> (a ⊸ b) <span class="ot">→</span> (a ⊸ b)</code></pre>

<p>Following the principle of semantic <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms">type class morphism</a>s, the specification simply says that the meaning of the sum is the sum of the meanings:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">^+^</span> g) ≡ apply f <span class="fu">^+^</span> apply g</code></pre>

<p>which is half of the definition of “linearity” for <code>apply</code>.</p>

<p>The game plan (as always) is to use the semantic specification to derive (or “calculate”) a correct implementation of each operation. For addition, this goal means we want to come up with a definition like</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">f <span class="fu">^+^</span> g <span class="fu">=</span> <span class="fu">&lt;</span>rhs<span class="fu">&gt;</span></code></pre>

<p>where <code>&lt;rhs&gt;</code> is some expression in terms of <code>f</code> and <code>g</code> whose <em>meaning</em> is the same as the meaning as <code>f ^+^ g</code>, i.e., where</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">^+^</span> g) ≡ apply <span class="fu">&lt;</span>rhs<span class="fu">&gt;</span></code></pre>

<p>Since Haskell has convenient pattern matching, we’ll use it for our definition of <code>(^+^)</code> above. Addition has two arguments, and our data type has two constructors, there are at most four different cases to consider.</p>

<p>First, add <code>Dot</code> and <code>Dot</code>. The specification</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">^+^</span> g) ≡ apply f <span class="fu">^+^</span> apply g</code></pre>

<p>specializes to</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c) ≡ apply (<span class="dt">Dot</span> b) <span class="fu">^+^</span> apply (<span class="dt">Dot</span> c)</code></pre>

<p>Now simplify the right-hand side (RHS):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> b) <span class="fu">^+^</span> apply (<span class="dt">Dot</span> c)
 ≡ <span class="co">{- apply definition -}</span>
dot b <span class="fu">^+^</span> dot c
 ≡ <span class="co">{- (bi)linearity of dot, as described above -}</span>
dot (b <span class="fu">^+^</span> c)
 ≡ <span class="co">{- apply definition -}</span>
apply (<span class="dt">Dot</span> (b <span class="fu">^+^</span> c))</code></pre>

<p>So our specialized specification becomes</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c) ≡ apply (<span class="dt">Dot</span> (b <span class="fu">^+^</span> c))</code></pre>

<p>which is implied by</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c ≡ <span class="dt">Dot</span> (b <span class="fu">^+^</span> c)</code></pre>

<p>and easily satisfied by the following partial definition (replacing “<code>≡</code>” by “<code>=</code>”):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="dt">Dot</span> b <span class="fu">^+^</span> <span class="dt">Dot</span> c <span class="fu">=</span> <span class="dt">Dot</span> (b <span class="fu">^+^</span> c)</code></pre>

<p>Now consider the case of addition with two <code>(:&amp;&amp;)</code> constructors:</p>

<p>The specification specializes to</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply ((f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">:&amp;&amp;</span> k)) ≡ apply (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> apply (h <span class="fu">:&amp;&amp;</span> k)</code></pre>

<p>As with <code>Dot</code>, simplify the RHS:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> apply (h <span class="fu">:&amp;&amp;</span> k)
 ≡ <span class="co">{- apply definition -}</span>
(apply f <span class="fu">&amp;&amp;&amp;</span> apply g) <span class="fu">^+^</span> (apply h <span class="fu">&amp;&amp;&amp;</span> apply k)
 ≡ <span class="co">{- See below -}</span>
(apply f <span class="fu">^+^</span> apply h) <span class="fu">&amp;&amp;&amp;</span> (apply g <span class="fu">^+^</span> apply k)
 ≡ <span class="co">{- induction -}</span>
apply (f <span class="fu">^+^</span> h) <span class="fu">&amp;&amp;&amp;</span> apply (g <span class="fu">^+^</span> k)
 ≡ <span class="co">{- apply definition -}</span>
apply ((f <span class="fu">^+^</span> h) <span class="fu">:&amp;&amp;</span> (g <span class="fu">^+^</span> k))</code></pre>

<p>I used the following property (on functions):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">&amp;&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">&amp;&amp;&amp;</span> k) ≡ (f <span class="fu">^+^</span> h) <span class="fu">&amp;&amp;&amp;</span> (g <span class="fu">^+^</span> k)</code></pre>

<p>Proof:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">&amp;&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">&amp;&amp;&amp;</span> k)
 ≡ <span class="co">{- η-expand -}</span>
λ x <span class="ot">→</span> ((f <span class="fu">&amp;&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">&amp;&amp;&amp;</span> k)) x
 ≡ <span class="co">{- (&amp;&amp;&amp;) definition for functions -}</span>
λ x <span class="ot">→</span> (f x, g x) <span class="fu">^+^</span> (h x, k x)
 ≡ <span class="co">{- (^+^) definition for pairs -}</span>
λ x <span class="ot">→</span> (f x <span class="fu">^+^</span> h x, g x <span class="fu">^+^</span> k x)
 ≡ <span class="co">{- (^+^) definition for functions -}</span>
λ x <span class="ot">→</span> ((f <span class="fu">^+^</span> h) x, (g <span class="fu">^+^</span> k) x)
 ≡ <span class="co">{- (&amp;&amp;&amp;) definition for functions -}</span>
(f <span class="fu">^+^</span> h) <span class="fu">&amp;&amp;&amp;</span> (g <span class="fu">^+^</span> k)</code></pre>

<p>The specification becomes</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply ((f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">:&amp;&amp;</span> k)) ≡ apply ((f <span class="fu">^+^</span> h) <span class="fu">:&amp;&amp;</span> (g <span class="fu">^+^</span> k))</code></pre>

<p>which is easily satisfied by the following partial definition</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">:&amp;&amp;</span> g) <span class="fu">^+^</span> (h <span class="fu">:&amp;&amp;</span> k) <span class="fu">=</span> (f <span class="fu">^+^</span> h) <span class="fu">:&amp;&amp;</span> (g <span class="fu">^+^</span> k)</code></pre>

<p>The other two cases are (a) <code>Dot</code> and <code>(:&amp;&amp;)</code>, and (b) <code>(:&amp;&amp;)</code> and <code>Dot</code>, but they don’t type-check (assuming that pairs are not scalars).</p>

<h3 id="composing-linear-maps">Composing linear maps</h3>

<p>I’ll write linear map composition as “<code>g ∘ f</code>”, with type</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(∘) <span class="ot">∷</span> (b ⊸ c) <span class="ot">→</span> (a ⊸ b) <span class="ot">→</span> (a ⊸ c)</code></pre>

<p>This notation is thanks to a <code>Category</code> instance, which depends on a generalized <code>Category</code> class that uses the recent <code>ConstraintKinds</code> language extension. (See the <a href="https://github.com/conal/linear-map-gadt" title="github repository">source code</a>.)</p>

<p>Following the semantic <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms">type class morphism</a> principle again, the specification says that the meaning of the composition is the composition of the meanings:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (g ∘ f) ≡ apply g ∘ apply f</code></pre>

<p>In the following, note that the <code>∘</code> operator binds more tightly than <code>&amp;&amp;&amp;</code>, so <code>f ∘ h &amp;&amp;&amp; g ∘ h</code> means <code>(f ∘ h) &amp;&amp;&amp; (g ∘ h)</code>.</p>

<h4 id="derivation">Derivation</h4>

<p>Again, since there are two constructors, we have four possible cases cases. We can handle two of these cases together, namely <code>(:&amp;&amp;)</code> and anything. The specification:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply ((f <span class="fu">:&amp;&amp;</span> g) ∘ h) ≡ apply (f <span class="fu">:&amp;&amp;</span> g) ∘ apply h</code></pre>

<p>Reasoning proceeds as above, simplifying the RHS of the constructor-specialized specification.</p>

<p>Simplify the RHS:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">:&amp;&amp;</span> g) ∘ apply h
 ≡ <span class="co">{- apply definition -}</span>
(apply f <span class="fu">&amp;&amp;&amp;</span> apply g) ∘ apply h
 ≡ <span class="co">{- see below -}</span>
apply f ∘ apply h <span class="fu">&amp;&amp;&amp;</span> apply g ∘ apply h
 ≡ <span class="co">{- induction -}</span>
apply (f ∘ h) <span class="fu">&amp;&amp;&amp;</span> apply (g ∘ h)
 ≡ <span class="co">{- apply definition -}</span>
apply (f ∘ h <span class="fu">:&amp;&amp;</span> g ∘ h)</code></pre>

<p>This simplification uses the following property of functions:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(p <span class="fu">&amp;&amp;&amp;</span> q) ∘ r ≡ p ∘ r <span class="fu">&amp;&amp;&amp;</span> q ∘ r</code></pre>

<p>Sufficient definition:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(f <span class="fu">:&amp;&amp;</span> g) ∘ h <span class="fu">=</span> f ∘ h <span class="fu">:&amp;&amp;</span> g ∘ h</code></pre>

<p>We have two more cases, specified as follows:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> c ∘ <span class="dt">Dot</span> b) ≡ apply (<span class="dt">Dot</span> c) ∘ apply (<span class="dt">Dot</span> b)

apply (<span class="dt">Dot</span> c ∘ (f <span class="fu">:&amp;&amp;</span> g)) ≡ apply (<span class="dt">Dot</span> c) ∘ apply (f <span class="fu">:&amp;&amp;</span> g)</code></pre>

<p>Based on types, <code>c</code> must be a scalar in the first case and a pair in the second. (<code>Dot b</code> produces a scalar, while <code>f :&amp;&amp; g</code> produces a pair.) Thus, we can write these two cases more specifically:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (<span class="dt">Dot</span> s ∘ <span class="dt">Dot</span> b) ≡ apply (<span class="dt">Dot</span> s) ∘ apply (<span class="dt">Dot</span> b)

apply (<span class="dt">Dot</span> (a,b) ∘ (f <span class="fu">:&amp;&amp;</span> g)) ≡ apply (<span class="dt">Dot</span> (a,b)) ∘ apply (f <span class="fu">:&amp;&amp;</span> g)</code></pre>

<p>In the derivation, I won’t spell out as many details as before. Simplify the RHSs:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply (<span class="dt">Dot</span> s) ∘ apply (<span class="dt">Dot</span> b)
≡ dot s ∘ dot b
≡ dot (s <span class="fu">*^</span> b)
≡ apply (<span class="dt">Dot</span> (s <span class="fu">*^</span> b))</code></pre>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply (<span class="dt">Dot</span> (a,b)) ∘ apply (f <span class="fu">:&amp;&amp;</span> g)
≡ dot (a,b) ∘ (apply f <span class="fu">&amp;&amp;&amp;</span> apply g)
≡ add ∘ (dot a ∘ apply f <span class="fu">&amp;&amp;&amp;</span> dot b ∘ apply g)
≡ dot a ∘ apply f <span class="fu">^+^</span> dot b ∘ apply g
≡ apply (<span class="dt">Dot</span> a ∘ f <span class="fu">^+^</span> <span class="dt">Dot</span> b ∘ g)</code></pre>

<p>I’ve used the following properties of functions:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot (a,b)             ≡ add ∘ (dot a <span class="fu">***</span> dot b)

(r <span class="fu">***</span> s) ∘ (p <span class="fu">&amp;&amp;&amp;</span> q) ≡ r ∘ p <span class="fu">&amp;&amp;&amp;</span> s ∘ q

add ∘ (p <span class="fu">&amp;&amp;&amp;</span> q)       ≡ p <span class="fu">^+^</span> q

apply (f <span class="fu">^+^</span> g)       ≡ apply f <span class="fu">^+^</span> apply g</code></pre>

<p>Implementation:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"> <span class="dt">Dot</span> s     ∘ <span class="dt">Dot</span> b     <span class="fu">=</span> <span class="dt">Dot</span> (s <span class="fu">*^</span> b)
 <span class="dt">Dot</span> (a,b) ∘ (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> <span class="dt">Dot</span> a ∘ f <span class="fu">^+^</span> <span class="dt">Dot</span> b ∘ g</code></pre>

<h3 id="cross-products">Cross products</h3>

<p>Another <code>Arrow</code> operation handy for linear maps is the parallel composition (product):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">(<span class="fu">***</span>) <span class="ot">∷</span> (a ⊸ c) <span class="ot">→</span> (b ⊸ d) <span class="ot">→</span> (a × b ⊸ c × d)</code></pre>

<p>The specification says that <code>apply</code> distributes over <code>(***)</code>. In other words, the meaning of the product is the product of the meanings.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (f <span class="fu">***</span> g) <span class="fu">=</span> apply f <span class="fu">***</span> apply g</code></pre>

<p>Where, on functions,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">p <span class="fu">***</span> q <span class="fu">=</span> λ (a,b) <span class="ot">→</span> (p a, q b)
        ≡ p ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> q ∘ <span class="fu">snd</span></code></pre>

<p>Simplify the specifications RHS:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply f <span class="fu">***</span> apply g
≡ apply f ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> apply g ∘ <span class="fu">snd</span></code></pre>

<p>If we knew how to represent <code>fst</code> and <code>snd</code> via our linear map constructors, we’d be nearly done. Instead, let’s suppose we have the following functions.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">compFst <span class="ot">∷</span> <span class="dt">VS3</span> a b c <span class="ot">⇒</span> a ⊸ c <span class="ot">→</span> a × b ⊸ c
compSnd <span class="ot">∷</span> <span class="dt">VS3</span> a b c <span class="ot">⇒</span> b ⊸ c <span class="ot">→</span> a × b ⊸ c</code></pre>

<p>specified as follows:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">apply (compFst f) ≡ apply f ∘ <span class="fu">fst</span>
apply (compSnd g) ≡ apply g ∘ <span class="fu">snd</span></code></pre>

<p>With these two functions (to be defined) in hand, let’s try again.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">  apply f <span class="fu">***</span> apply g
≡ apply f ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> apply g ∘ <span class="fu">snd</span>
≡ apply (compFst f) <span class="fu">&amp;&amp;&amp;</span> apply (compSnd g)
≡ apply (compFst f <span class="fu">:&amp;&amp;</span> compSnd g)</code></pre>

<h4 id="composing-with-fst-and-snd">Composing with <code>fst</code> and <code>snd</code></h4>

<p>I’ll elide even more of the derivation this time, focusing reasoning on the meanings. Relating to the representation is left as an exercise. The key steps in the derivation:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">dot a     ∘ <span class="fu">fst</span> ≡ dot (a,<span class="dv">0</span>)

(f <span class="fu">&amp;&amp;&amp;</span> g) ∘ <span class="fu">fst</span> ≡ f ∘ <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> g ∘ <span class="fu">fst</span>

dot b     ∘ <span class="fu">snd</span> ≡ dot (<span class="dv">0</span>,b)

(f <span class="fu">&amp;&amp;&amp;</span> g) ∘ <span class="fu">snd</span> ≡ f ∘ <span class="fu">snd</span> <span class="fu">&amp;&amp;&amp;</span> g ∘ <span class="fu">snd</span></code></pre>

<p>Implementation:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">compFst (<span class="dt">Dot</span> a)   <span class="fu">=</span> <span class="dt">Dot</span> (a,zeroV)
compFst (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> compFst f <span class="fu">&amp;&amp;&amp;</span> compFst g

compSnd (<span class="dt">Dot</span> b)   <span class="fu">=</span> <span class="dt">Dot</span> (zeroV,b)
compSnd (f <span class="fu">:&amp;&amp;</span> g) <span class="fu">=</span> compSnd f <span class="fu">&amp;&amp;&amp;</span> compSnd g</code></pre>

<p>where <code>zeroV</code> is the zero vector.</p>

<p>Given <code>compFst</code> and <code>compSnd</code>, we can implement <code>fst</code> and <code>snd</code> as linear maps simply as <code>compFst id</code> and <code>compSnd id</code>, where <code>id</code> is the (polymorphic) identity linear map.</p>

<h3 id="reflections">Reflections</h3>

<p>This post reflects an approach to programming that I apply wherever I’m able. As a summary:</p>

<ul>
<li>Look for an elegant <em>what</em> behind a familiar <em>how</em>.</li>
<li><em>Define</em> a semantic function for each data type.</li>
<li><em>Derive</em> a correct implementation from the semantics.</li>
</ul>

<p>You can find more examples of this methodology elsewhere in this blog and in the paper <a href="http://conal.net/papers/type-class-morphisms/"><em>Denotational design with type class morphisms</em></a>.</p>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=503&amp;md5=061f6fb371675342c9a006b8ec5376e9" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/8Yt6DAQKEtY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/reimagining-matrices/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/reimagining-matrices</feedburner:origLink></item>
		<item>
		<title>Parallel speculative addition via memoization</title>
		<link>http://feedproxy.google.com/~r/conal/~3/mAovu7cdI0I/parallel-speculative-addition-via-memoization</link>
		<comments>http://conal.net/blog/posts/parallel-speculative-addition-via-memoization#comments</comments>
		<pubDate>Tue, 27 Nov 2012 23:39:42 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[parallelism]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=493</guid>
		<description><![CDATA[I’ve been thinking much more about parallel computation for the last couple of years, especially since starting to work at Tabula a year ago. Until getting into parallelism explicitly, I’d naïvely thought that my pure functional programming style was mostly free of sequential bias. After all, functional programming lacks the implicit accidental dependencies imposed ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p>I’ve been thinking much more about parallel computation for the last couple of years, especially since starting to work at <a href="http://www.tabula.com">Tabula</a> a year ago. Until getting into parallelism explicitly, I’d naïvely thought that my pure functional programming style was mostly free of sequential bias. After all, functional programming lacks the implicit accidental dependencies imposed by the imperative model. Now, however, I’m coming to see that designing parallel-friendly algorithms takes attention to minimizing the depth of the remaining, explicit data dependencies.</p>

<p>As an example, consider binary addition, carried out from least to most significant bit (as usual). We can immediately compute the first (least significant) bit of the result, but in order to compute the second bit, we’ll have to know whether or not a carry resulted from the first addition. More generally, the <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></math><em>th</em> sum &amp; carry require knowing the <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math><em>th</em> carry, so this algorithm does not allow parallel execution. Even if we have one processor per bit position, only one processor will be able to work at a time, due to the linear chain of dependencies.</p>

<p>One general technique for improving parallelism is <em>speculation</em>—doing more work than might be needed so that we don’t have to wait to find out exactly what <em>will</em> be needed. In this post, we’ll see a progression of definitions for bitwise addition. We’ll start with a linear-depth chain of carry dependencies and end with logarithmic depth. Moreover, by making careful use of abstraction, these versions will be simply different type specializations of a single polymorphic definition with an extremely terse definition.</p>

<p><span id="more-493"></span></p>

<h3 id="a-full-adder">A full adder</h3>

<p>Let’s start with an adder for two one-bit numbers. Because of the possibility of overflow, the result will be two bits, which I’ll call “sum” and “carry”. So that we can chain these one-bit adders, we’ll also add a carry input.</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addB <span class="ot">∷</span> (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> <span class="dt">Bool</span> <span class="ot">→</span> (<span class="dt">Bool</span>,<span class="dt">Bool</span>)</code></pre>

<p>In the result, the first <code>Bool</code> will be the sum, and the second will be the carry. I’ve curried the carry input to make it stand out from the (other) addends.</p>

<p>There are a few ways to define <code>addB</code> in terms of logic operations. I like the following definition, as it shares a little work between sum &amp; carry:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addB (a,b) cin <span class="fu">=</span> (axb ≠ cin, anb ∨ (cin ∧ axb))
 <span class="kw">where</span>
   axb <span class="fu">=</span> a ≠ b
   anb <span class="fu">=</span> a ∧ b</code></pre>

<p>I’m using <code>(≠)</code> on <code>Bool</code> for exclusive or.</p>

<h3 id="a-ripple-carry-adder">A ripple carry adder</h3>

<p>Now suppose we have not just two bits, but two <em>sequences</em> of bits, interpreted as binary numbers arranged from least to most significant bit. For simplicity, I’d like to assume that these sequences to have the same length, so rather than taking a pair of bit lists, let’s take a list of bit pairs:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add <span class="ot">∷</span> [(<span class="dt">Bool</span>,<span class="dt">Bool</span>)] <span class="ot">→</span> <span class="dt">Bool</span> <span class="ot">→</span> ([<span class="dt">Bool</span>],<span class="dt">Bool</span>)</code></pre>

<p>To implement <code>add</code>, traverse the list of bit pairs, threading the carries:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add [] c     <span class="fu">=</span> ([]  , c)
add (p<span class="fu">:</span>ps) c <span class="fu">=</span> (s<span class="fu">:</span>ss, c&#39;&#39;)
 <span class="kw">where</span>
   (s ,c&#39; ) <span class="fu">=</span> addB p c
   (ss,c&#39;&#39;) <span class="fu">=</span> add ps c&#39;</code></pre>

<h3 id="state">State</h3>

<p>This <code>add</code> definition contains a familiar pattern. The carry values act as a sort of <em>state</em> that gets updated in a linear (non-branching) way. The <code>State</code> monad captures this pattern of computation:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">State</span> s a <span class="fu">=</span> <span class="dt">State</span> (s <span class="ot">→</span> (a,s))</code></pre>

<p>By using <code>State</code> and its <code>Monad</code> instance, we can shorten our <code>add</code> definition. First we’ll need a new full adder definition, tweaked for <code>State</code>:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addB <span class="ot">∷</span> (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> <span class="dt">State</span> <span class="dt">Bool</span> <span class="dt">Bool</span>
addB (a,b) <span class="fu">=</span> <span class="kw">do</span> cin <span class="ot">←</span> get
                put (anb ∨ cin ∧ axb)
                <span class="fu">return</span> (axb ≠ cin)
 <span class="kw">where</span>
   anb <span class="fu">=</span> a ∧ b
   axb <span class="fu">=</span> a ≠ b</code></pre>

<p>And then the multi-bit adder:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add <span class="ot">∷</span> [(<span class="dt">Bool</span>,<span class="dt">Bool</span>)] <span class="ot">→</span> <span class="dt">State</span> <span class="dt">Bool</span> [<span class="dt">Bool</span>]
add []     <span class="fu">=</span> <span class="fu">return</span> []
add (p<span class="fu">:</span>ps) <span class="fu">=</span> <span class="kw">do</span> s  <span class="ot">←</span> addB p
                ss <span class="ot">←</span> add ps
                <span class="fu">return</span> (s<span class="fu">:</span>ss)</code></pre>

<p>We don’t really need the <code>Monad</code> interface to define <code>add</code>. The simpler and more general <code>Applicative</code> interface suffices:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add []     <span class="fu">=</span> pure []
add (p<span class="fu">:</span>ps) <span class="fu">=</span> liftA2 (<span class="fu">:</span>) (addB p) (add ps)</code></pre>

<p>This pattern also looks familiar. Oh — the <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Traversable.html#t:Traversable"><code>Traversable</code></a> instance for lists makes for a very compact definition:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add <span class="fu">=</span> traverse addB</code></pre>

<p>Wow. The definition is now so simple that it doesn’t depend on the specific choice of lists. To find out the most general type <code>add</code> can have (with this definition), remove the type signature, turn off the monomorphism restriction, and see what GHCi has to say:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add <span class="ot">∷</span> <span class="kw">Traversable</span> t <span class="ot">⇒</span> t (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> <span class="dt">State</span> <span class="dt">Bool</span> (t <span class="dt">Bool</span>)</code></pre>

<p>This constraint is <em>very</em> lenient. <code>Traversable</code> can be derived automatically for <em>all</em> algebraic data types, including nested/non-regular ones.</p>

<p>For instance,</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Tree</span> a <span class="fu">=</span> <span class="dt">Leaf</span> a <span class="fu">|</span> <span class="dt">Branch</span> (<span class="dt">Tree</span> a) (<span class="dt">Tree</span> a)
  <span class="kw">deriving</span> (<span class="kw">Functor</span>,<span class="kw">Foldable</span>,<span class="kw">Traversable</span>)</code></pre>

<p>We can now specialize this general <code>add</code> back to lists:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addLS <span class="ot">∷</span> [(<span class="dt">Bool</span>,<span class="dt">Bool</span>)] <span class="ot">→</span> <span class="dt">State</span> <span class="dt">Bool</span> [<span class="dt">Bool</span>]
addLS <span class="fu">=</span> add</code></pre>

<p>We can also specialize for trees:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addTS <span class="ot">∷</span> <span class="dt">Tree</span> (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> <span class="dt">State</span> <span class="dt">Bool</span> (<span class="dt">Tree</span> <span class="dt">Bool</span>)
addTS <span class="fu">=</span> add</code></pre>

<p>Or for depth-typed perfect trees (e.g., as described in <a href="http://conal.net/blog/posts/from-tries-to-trees/" title="blog post"><em>From tries to trees</em></a>):</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addTnS <span class="ot">∷</span> <span class="dt">IsNat</span> n <span class="ot">⇒</span>
         <span class="dt">T</span> n (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> <span class="dt">State</span> <span class="dt">Bool</span> (<span class="dt">T</span> n <span class="dt">Bool</span>)
addTnS <span class="fu">=</span> add</code></pre>

<p>Binary trees are often better than lists for parallelism, because they allow quick recursive splitting and joining. In the case of ripple adders, we don’t really get parallelism, however, because of the single-threaded (linear) nature of <code>State</code>. Can we get around this unfortunate linearization?</p>

<h3 id="speculation">Speculation</h3>

<p>The linearity of carry propagation interferes with parallel execution even when using a tree representation. The problem is that each <code>addB</code> (full adder) invocation must access the carry out from the previous (immediately less significant) bit position and so must wait for that carry to be computed. Since each bit addition must wait for the previous one to finish, we get linear running time, even with unlimited parallel processing available. If we didn’t have to wait for carries, we could instead get logarithmic running time using the tree representation, since subtrees could be added in parallel.</p>

<p>A way out of this dilemma is to speculatively compute the bit sums for <em>both</em> possibilities, i.e., for carry and no carry. We’ll do more work, but much less waiting.</p>

<h3 id="state-memoization">State memoization</h3>

<p>Recall the <code>State</code> definition:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">State</span> s a <span class="fu">=</span> <span class="dt">State</span> (s <span class="ot">→</span> (a,s))</code></pre>

<p>Rather than using a <em>function</em> of <code>s</code>, let’s use a <em>table</em> indexed by <code>s</code>. Since <code>s</code> is <code>Bool</code> in our use, a table is simply a uniform pair, so we could replace <code>State Bool a</code> with the following:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">BoolStateTable</span> a <span class="fu">=</span> <span class="dt">BST</span> ((a,<span class="dt">Bool</span>), (a,<span class="dt">Bool</span>))</code></pre>

<p><em>Exercise:</em> define <code>Functor</code>, <code>Applicative</code>, and <code>Monad</code> instances for <code>BoolStateTable</code>.</p>

<p>Rather than defining such a specialized type, let’s stand back and consider what’s going on. We’re replacing a function by an isomorphic data type. This replacement is exactly what memoization is about. So let’s define a general <em>memoizing state monad</em>:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">StateTrie</span> s a <span class="fu">=</span> <span class="dt">StateTrie</span> (s ⇰ (a,s))</code></pre>

<p>Note that the definition of memoizing state is nearly identical to <code>State</code>. I’ve simply replaced “<code>→</code>” by “<code>⇰</code>”, i.e., <a href="http://conal.net/blog/tag/memoization/" title="Posts on memoization">memo</a> <a href="http://conal.net/blog/tag/trie/" title="Posts on tries">tries</a>. For the (simple) source code of <code>StateTrie</code>, see <a href="http://github.com/conal/state-trie.git">the github project</a>. (Poking around on Hackage, I just found <a href="http://hackage.haskell.org/package/monad-memo">monad-memo</a>, which looks related.)</p>

<p>The full-adder function <code>addB</code> is restricted to <code>State</code>, but unnecessarily so. The most general type is inferred as</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addB <span class="ot">∷</span> <span class="dt">MonadState</span> <span class="dt">Bool</span> m <span class="ot">⇒</span> (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> m <span class="dt">Bool</span></code></pre>

<p>where the <a href="http://hackage.haskell.org/packages/archive/mtl/latest/doc/html/Control-Monad-State-Class.html#t:MonadState"><code>MonadState</code></a> class comes from the mtl package.</p>

<p>With the type-generalized <code>addB</code>, we get a more general type for <code>add</code> as well:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">add <span class="ot">∷</span> (<span class="kw">Traversable</span> t, <span class="kw">Applicative</span> m, <span class="dt">MonadState</span> <span class="dt">Bool</span> m) <span class="ot">⇒</span>
      t (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> m (t <span class="dt">Bool</span>)
add <span class="fu">=</span> traverse addB</code></pre>

<p>Now we can specialize <code>add</code> to work with memoized state:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addLM <span class="ot">∷</span> [(<span class="dt">Bool</span>,<span class="dt">Bool</span>)] <span class="ot">→</span> <span class="dt">StateTrie</span> <span class="dt">Bool</span> [<span class="dt">Bool</span>]
addLM <span class="fu">=</span> add

addTM <span class="ot">∷</span> <span class="dt">Tree</span> (<span class="dt">Bool</span>,<span class="dt">Bool</span>) <span class="ot">→</span> <span class="dt">StateTrie</span> <span class="dt">Bool</span> (<span class="dt">Tree</span> <span class="dt">Bool</span>)
addTM <span class="fu">=</span> add</code></pre>

<h3 id="what-have-we-done">What have we done?</h3>

<p>The essential tricks in this post are to (a) boost parallelism by speculative evaluation (an old idea) and (b) express speculation as memoization (new, to me at least). The technique wins for binary addition thanks to the small number of possible states, which then makes memoization (full speculation) affordable.</p>

<p>I’m not suggesting that the code above has impressive parallel execution when compiled under GHC. Perhaps it could with some <a href="http://www.haskell.org/ghc/docs/latest/html/users_guide/lang-parallel.html#id653837"><code>par</code> and <code>pseq</code> annotations</a>. I haven’t tried. This exploration helps me understand a little of the space of hardware-oriented algorithms.</p>

<p>The <a href="http://www.aoki.ecei.tohoku.ac.jp/arith/mg/algorithm.html#fsa_csu">conditional sum adder</a> looks quite similar to the development above. It has the twist, however, of speculating carries on blocks of a few bits rather than single bits. It’s astonishingly easy to adapt the development above for such a hybrid scheme, forming traversable structures of sequences of bits:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">addH <span class="ot">∷</span> <span class="dt">Tree</span> [(<span class="dt">Bool</span>,<span class="dt">Bool</span>)] <span class="ot">→</span> <span class="dt">StateTrie</span> <span class="dt">Bool</span> (<span class="dt">Tree</span> [<span class="dt">Bool</span>])
addH <span class="fu">=</span> traverse (fromState ∘ add)</code></pre>

<p>I’m using the adapter <code>fromState</code> so that the inner list additions will use <code>State</code> while the outer tree additions will use <code>StateTrie</code>, thanks to type inference. This adapter memoizes and rewraps the state transition function:</p>

<pre class="sourceCode literate haskell"><code class="sourceCode haskell">fromState <span class="ot">∷</span> <span class="dt">HasTrie</span> s <span class="ot">⇒</span> <span class="dt">State</span> s a <span class="ot">→</span> <span class="dt">StateTrie</span> s a
fromState <span class="fu">=</span> <span class="dt">StateTrie</span> ∘ trie ∘ runState</code></pre>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=493&amp;md5=0136cef7713a1f1858ef9075530a873c" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/mAovu7cdI0I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/parallel-speculative-addition-via-memoization/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/parallel-speculative-addition-via-memoization</feedburner:origLink></item>
		<item>
		<title>A third view on trees</title>
		<link>http://feedproxy.google.com/~r/conal/~3/luD0iiQTAc4/a-third-view-on-trees</link>
		<comments>http://conal.net/blog/posts/a-third-view-on-trees#comments</comments>
		<pubDate>Sat, 04 Jun 2011 02:46:20 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[functor]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=460</guid>
		<description><![CDATA[A few recent posts have played with trees from two perspectives. The more commonly used I call &#34;top-down&#34;, because the top-level structure is most immediately apparent. A top-down binary tree is either a leaf or a pair of such trees, and that pair can be accessed without wading through intervening structure. Much less commonly ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p>A few recent posts have played with trees from two perspectives. The more commonly used I call &quot;top-down&quot;, because the top-level structure is most immediately apparent. A top-down binary tree is either a leaf or a pair of such trees, and that pair can be accessed without wading through intervening structure. Much less commonly used are &quot;bottom-up&quot; trees. A bottom-up binary tree is either a leaf or a single such tree of pairs. In the non-leaf case, the pair structure of the tree elements is accessible by operations like mapping, folding, or scanning. The difference is between a pair of trees and a tree of pairs.</p>

<p>As an alternative to the top-down and bottom-up views on trees, I now want to examine a third view, which is a hybrid of the two. Instead of pairs of trees or trees of pairs, this hybrid view is of trees of trees, and more specifically of bottom-up trees of top-down trees. As we&#8217;ll see, these hybrid trees emerge naturally from the top-down and bottom-up views. A later post will show how this third view lends itself to an <em>in-place</em> (destructive) scan algorithm, suitable for execution on modern GPUs.</p>

<p><strong>Edits:</strong></p>

<ul>
<li>2011-06-04: &quot;Suppose we have a bottom-up tree of top-down trees, i.e., <code>t ∷ TB (TT a)</code>. Was backwards. (Thanks to Noah Easterly.)</li>
<li>2011-06-04: Notation: &quot;<code>f ➶ n</code>&quot; and &quot;<code>f ➴ n</code>&quot;.</li>
</ul>

<p><span id="more-460"></span></p>

<p>The post <a href="http://conal.net/blog/posts/parallel-tree-scanning-by-composition/" title="blog post"><em>Parallel tree scanning by composition</em></a> defines &quot;top-down&quot; and a &quot;bottom-up&quot; binary trees as follows (modulo type and constructor names):</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">TT</span> a <span class="fu">=</span> <span class="kw">LT</span> a <span class="fu">|</span> <span class="dt">BT</span> { unBT <span class="ot">&#8759;</span> <span class="dt">Pair</span> (<span class="dt">TT</span> a) } <span class="kw">deriving</span> <span class="kw">Functor</span><br /><br /><span class="kw">data</span> <span class="dt">TB</span> a <span class="fu">=</span> <span class="dt">LB</span> a <span class="fu">|</span> <span class="dt">BB</span> { unBB <span class="ot">&#8759;</span> <span class="dt">TB</span> (<span class="dt">Pair</span> a) } <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>So, while a non-leaf <code>TT</code> (top-down tree) has a pair at the top (outside), a non-leaf <code>TB</code> (bottom-up tree) has pairs at the bottom (inside).</p>

<p>Combining these two observations leads to an interesting possibility. Suppose we have a bottom-up tree of top-down trees, i.e., <code>t ∷ TB (TT a)</code>. If <code>t</code> is not a leaf, then <code>t ≡ BB tt</code> where <code>tt</code> is a bottom-up tree whose leaves are pairs of top-down trees, i.e., <code>tt ∷ TB (Pair (TT a))</code>. Each of those leaves of type <code>Pair (TT a)</code> can be converted to type <code>TT a</code> (single tree), simply by applying the <code>BT</code> constructor. Moreover, this transformation is invertible. For convenience, define a type alias for hybrid trees:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">type</span> <span class="dt">TH</span> a <span class="fu">=</span> <span class="dt">TB</span> (<span class="dt">TT</span> a)</code></pre>

<p>Then the two conversions:</p>

<pre class="sourceCode"><code class="sourceCode haskell">upT   <span class="ot">&#8759;</span> <span class="dt">TH</span> a <span class="ot">&#8594;</span> <span class="dt">TH</span> a<br />upT   <span class="fu">=</span> <span class="fu">fmap</span> <span class="dt">BT</span> &#8728; unBB<br /><br />downT <span class="ot">&#8759;</span> <span class="dt">TH</span> a <span class="ot">&#8594;</span> <span class="dt">TH</span> a<br />downT <span class="fu">=</span> <span class="dt">BB</span> &#8728; <span class="fu">fmap</span> unBT</code></pre>

<div class=exercise>

<p><em>Exercise:</em> Prove <code>upT</code> and <code>downT</code> are inverses where defined.</p>
<p>Answer:</p>

<div class=toggle>

<pre class="sourceCode"><code class="sourceCode haskell">  upT &#8728; downT<br />&#8801; <span class="fu">fmap</span> <span class="dt">BT</span> &#8728; unBB &#8728; <span class="dt">BB</span> &#8728; <span class="fu">fmap</span> unBT<br />&#8801; <span class="fu">fmap</span> <span class="dt">BT</span> &#8728; <span class="fu">fmap</span> unBT<br />&#8801; <span class="fu">fmap</span> (<span class="dt">BT</span> &#8728; unBT)<br />&#8801; <span class="fu">fmap</span> <span class="fu">id</span><br />&#8801; <span class="fu">id</span><br /><br />  downT &#8728; upT<br />&#8801; <span class="dt">BB</span> &#8728; <span class="fu">fmap</span> unBT &#8728; <span class="fu">fmap</span> <span class="dt">BT</span> &#8728; unBB<br />&#8801; <span class="dt">BB</span> &#8728; <span class="fu">fmap</span> (unBT &#8728; <span class="dt">BT</span>) &#8728; unBB<br />&#8801; <span class="dt">BB</span> &#8728; <span class="fu">fmap</span> <span class="fu">id</span> &#8728; unBB<br />&#8801; <span class="dt">BB</span> &#8728; <span class="fu">id</span> &#8728; unBB<br />&#8801; <span class="dt">BB</span> &#8728; unBB<br />&#8801; <span class="fu">id</span></code></pre>

</div>


</div>

<p>Consider a perfect binary leaf tree of depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math>, i.e., an <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math>-deep binary tree with each level full and data only at the leaves (where a leaf is depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mn>0</mn></mrow></math> tree.) We can view such a tree as top-down, or bottom-up, or as a hybrid.</p>

<p>Each of these three views is really <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>+</mo><mn>1</mn></mrow></math> views:</p>

<ul>
<li>Top-down: a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math> tree, or a pair of depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>-</mo><mn>1</mn></mrow></math> trees, or a pair of pairs of depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>-</mo><mn>2</mn></mrow></math> trees, etc.</li>
<li>Bottom-up: a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math> tree, or a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>-</mo><mn>1</mn></mrow></math> tree of pairs, or a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>-</mo><mn>2</mn></mrow></math> tree of pairs of pairs, etc.</li>
<li>Hybrid: a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math> tree of depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mn>0</mn></mrow></math> trees, or a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>-</mo><mn>1</mn></mrow></math> tree of depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mn>1</mn></mrow></math> trees, or, &#8230;, or a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mn>0</mn></mrow></math> tree of depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math> trees.</li>
</ul>

<p>In the hybrid case, counting from <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mn>0</mn></mrow></math> to <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math>, the <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><msup><mi>k</mi><mrow><mi>t</mi><mi>h</mi></mrow></msup></mrow></math> such view is a depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>-</mo><mi>k</mi></mrow></math> bottom-up tree whose elements (leaf values) are depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>k</mi></mrow></math> top-down trees. When <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>k</mi><mo>=</mo><mi>n</mi></mrow></math>, we have a bottom-up tree whose leaves are all single-leaf trees, and when <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>k</mi><mo>=</mo><mn>0</mn></mrow></math>, we have a single-leaf bottom-up tree containing a top-down tree. Imagine a horizontal line at depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>k</mi></mrow></math>, dividing the bottom-up outer structure from the top-down inner structure. The <code>downT</code> function moves the dividing line downward, and the <code>upT</code> function moves the line upward. Both functions are partial.</p>

<h3 id="generalizing">Generalizing</h3>

<p>The role of <code>Pair</code> in the tree types above is simple and regular. We can abstract out this particular type constructor, generalizing to an arbitrary functor. I&#8217;ll call this generalization &quot;functor trees&quot;. Again, there are top-down and bottom-up versions:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">FT</span> f a <span class="fu">=</span> <span class="dt">FLT</span> a <span class="fu">|</span> <span class="dt">FBT</span> { unFBT <span class="ot">&#8759;</span> f (<span class="dt">FT</span> f a) } <span class="kw">deriving</span> <span class="kw">Functor</span><br /><br /><span class="kw">data</span> <span class="dt">FB</span> f a <span class="fu">=</span> <span class="dt">FLB</span> a <span class="fu">|</span> <span class="dt">FBB</span> { unFBB <span class="ot">&#8759;</span> <span class="dt">FB</span> f (f a) } <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>And a hybrid version, with generalized versions of <code>upT</code> and <code>downT</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">type</span> <span class="dt">FH</span> f a <span class="fu">=</span> <span class="dt">FB</span> f (<span class="dt">FT</span> f a)<br /><br />upH   <span class="ot">&#8759;</span> <span class="kw">Functor</span> f <span class="ot">&#8658;</span> <span class="dt">FH</span> f a <span class="ot">&#8594;</span> <span class="dt">FH</span> f a<br />upH   <span class="fu">=</span> <span class="fu">fmap</span> <span class="dt">FBT</span> &#8728; unFBB<br /><br />downH <span class="ot">&#8759;</span> <span class="kw">Functor</span> f <span class="ot">&#8658;</span> <span class="dt">FH</span> f a <span class="ot">&#8594;</span> <span class="dt">FH</span> f a<br />downH <span class="fu">=</span> <span class="dt">FBB</span> &#8728; <span class="fu">fmap</span> unFBT</code></pre>

<p>These definitions specialize to the ones (for binary trees) by substituting <code>Pair</code> for the parameter <code>f</code>.</p>

<h3 id="depth-typing">Depth-typing</h3>

<p>The upward and downward view-changing functions above are partial, as they can fail at extreme tree views (at depth <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mn>0</mn></mrow></math> or <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math>). We could make this partiality explicit by changing the result type to <code>Maybe (TH a)</code> for binary hybrid trees and to <code>Maybe (FH f a)</code> for the functor generalization. Alternatively, make the tree sizes <em>explicit</em> in the types, as in a few recent posts, including <a href="http://conal.net/blog/posts/a-trie-for-length-typed-vectors/" title="blog post"><em>A trie for length-typed vectors</em></a>. (In those posts, I used the terms &quot;right-folded&quot; and &quot;left-folded&quot; in place of &quot;top-down&quot; and &quot;bottom-up&quot;, reflecting the right- or left-folding of functor composition. The &quot;folded&quot; terms led to some confusion, especially in the context of data type folds and scans.) In the depth-typed versions, &quot;leaves&quot; are zero-ary compositions, and &quot;branches&quot; are <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>m</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></math>-ary compositions for some <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>m</mi></mrow></math>.</p>

<p>Top-down:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> (&#10164;) <span class="ot">&#8759;</span> (<span class="fu">*</span> <span class="ot">&#8594;</span> <span class="fu">*</span>) <span class="ot">&#8594;</span> <span class="fu">*</span> <span class="ot">&#8594;</span> (<span class="fu">*</span> <span class="ot">&#8594;</span> <span class="fu">*</span>) <span class="kw">where</span><br />  <span class="dt">ZeroT</span> <span class="ot">&#8759;</span> a <span class="ot">&#8594;</span> (f &#10164; <span class="dt">Z</span>) a<br />  <span class="dt">SuccT</span> <span class="ot">&#8759;</span> <span class="dt">IsNat</span> n <span class="ot">&#8658;</span> f ((f &#10164; n) a) <span class="ot">&#8594;</span> (f &#10164; <span class="dt">S</span> n) a<br /><br />unZeroT <span class="ot">&#8759;</span> (f &#10164; <span class="dt">Z</span>) a <span class="ot">&#8594;</span> a<br />unZeroT (<span class="dt">ZeroT</span> a) <span class="fu">=</span> a<br /><br />unSuccT <span class="ot">&#8759;</span> (f &#10164; <span class="dt">S</span> n) a <span class="ot">&#8594;</span> f ((f &#10164; n) a)<br />unSuccT (<span class="dt">SuccT</span> fsa) <span class="fu">=</span> fsa<br /><br /><span class="kw">instance</span> <span class="kw">Functor</span> f <span class="ot">&#8658;</span> <span class="kw">Functor</span> (f &#10164; n) <span class="kw">where</span><br />  <span class="fu">fmap</span> h (<span class="dt">ZeroT</span> a)  <span class="fu">=</span> <span class="dt">ZeroT</span> (h a)<br />  <span class="fu">fmap</span> h (<span class="dt">SuccT</span> fs) <span class="fu">=</span> <span class="dt">SuccT</span> ((fmap&#8728;fmap) h fs)</code></pre>

<p>Bottom-up:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> (&#10166;) <span class="ot">&#8759;</span> (<span class="fu">*</span> <span class="ot">&#8594;</span> <span class="fu">*</span>) <span class="ot">&#8594;</span> <span class="fu">*</span> <span class="ot">&#8594;</span> (<span class="fu">*</span> <span class="ot">&#8594;</span> <span class="fu">*</span>) <span class="kw">where</span><br />  <span class="dt">ZeroB</span> <span class="ot">&#8759;</span> a <span class="ot">&#8594;</span> (f &#10166; <span class="dt">Z</span>) a<br />  <span class="dt">SuccB</span> <span class="ot">&#8759;</span> <span class="dt">IsNat</span> n <span class="ot">&#8658;</span> (f &#10166; n) (f a) <span class="ot">&#8594;</span> (f &#10166; <span class="dt">S</span> n) a<br /><br />unZeroB <span class="ot">&#8759;</span> (f &#10166; <span class="dt">Z</span>) a <span class="ot">&#8594;</span> a<br />unZeroB (<span class="dt">ZeroB</span> a) <span class="fu">=</span> a<br /><br />unSuccB <span class="ot">&#8759;</span> (f &#10166; <span class="dt">S</span> n) a <span class="ot">&#8594;</span> (f &#10166; n) (f a)<br />unSuccB (<span class="dt">SuccB</span> fsa) <span class="fu">=</span> fsa<br /><br /><span class="kw">instance</span> <span class="kw">Functor</span> f <span class="ot">&#8658;</span> <span class="kw">Functor</span> (f &#10166; n) <span class="kw">where</span><br />  <span class="fu">fmap</span> h (<span class="dt">ZeroB</span> a)  <span class="fu">=</span> <span class="dt">ZeroB</span> (h a)<br />  <span class="fu">fmap</span> h (<span class="dt">SuccB</span> fs) <span class="fu">=</span> <span class="dt">SuccB</span> ((fmap&#8728;fmap) h fs)</code></pre>

<p>Hybrid:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">type</span> <span class="dt">H</span> p q f a <span class="fu">=</span> (f &#10166; p) ((f &#10164; q) a)</code></pre>

<p>Upward and downward shift become total functions, and their types explicitly describe how the line shifts between <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo stretchy="false">(</mo><mi>p</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo><mo>/</mo><mi>q</mi></mrow></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>p</mi><mo>/</mo><mo stretchy="false">(</mo><mi>q</mi><mo>+</mo><mn>1</mn><mo stretchy="false">)</mo></mrow></math>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">up   <span class="ot">&#8759;</span> (<span class="kw">Functor</span> f, <span class="dt">IsNat</span> q) <span class="ot">&#8658;</span> <span class="dt">H</span> (<span class="dt">S</span> p) q f a <span class="ot">&#8594;</span> <span class="dt">H</span> p (<span class="dt">S</span> q) f a<br />up   <span class="fu">=</span> <span class="fu">fmap</span> <span class="dt">SuccT</span> &#8728; unSuccB<br /><br />down <span class="ot">&#8759;</span> (<span class="kw">Functor</span> f, <span class="dt">IsNat</span> p) <span class="ot">&#8658;</span> <span class="dt">H</span> p (<span class="dt">S</span> q) f a <span class="ot">&#8594;</span> <span class="dt">H</span> (<span class="dt">S</span> p) q f a<br />down <span class="fu">=</span> <span class="dt">SuccB</span> &#8728; <span class="fu">fmap</span> unSuccT</code></pre>

<h3 id="so-what">So what?</h3>

<p>Why care about the multitude of views on trees?</p>

<ul>
<li>It&#8217;s pretty.</li>
<li>A future post will show how these hybrid trees enable an elegant formulation of parallel scanning that lends itself to an in-place, GPU-friendly implementation.</li>
</ul>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=460&amp;md5=3a9aceb3d722783b8e463cbfc78be6e4" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/luD0iiQTAc4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/a-third-view-on-trees/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/a-third-view-on-trees</feedburner:origLink></item>
		<item>
		<title>Parallel tree scanning by composition</title>
		<link>http://feedproxy.google.com/~r/conal/~3/a_XgXE8HynQ/parallel-tree-scanning-by-composition</link>
		<comments>http://conal.net/blog/posts/parallel-tree-scanning-by-composition#comments</comments>
		<pubDate>Tue, 24 May 2011 20:31:23 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[program derivation]]></category>
		<category><![CDATA[scan]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=429</guid>
		<description><![CDATA[My last few blog posts have been on the theme of scans, and particularly on parallel scans. In Composable parallel scanning, I tackled parallel scanning in a very general setting. There are five simple building blocks out of which a vast assortment of data structures can be built, namely constant (no value), identity (one ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p>My last few blog posts have been on the theme of <em>scans</em>, and particularly on <em>parallel</em> scans. In <a href="http://conal.net/blog/posts/composable-parallel-scanning/" title="blog post"><em>Composable parallel scanning</em></a>, I tackled parallel scanning in a very general setting. There are five simple building blocks out of which a vast assortment of data structures can be built, namely constant (no value), identity (one value), sum, product, and composition. The post defined parallel prefix and suffix scan for each of these five &quot;functor combinators&quot;, in terms of the same scan operation on each of the component functors. Every functor built out of this basic set thus has a parallel scan. Functors defined more conventionally can be given scan implementations simply by converting to a composition of the basic set, scanning, and then back to the original functor. Moreover, I expect this implementation could be generated automatically, similarly to GHC&#8217;s <code>DerivingFunctor</code> extension.</p>

<p>Now I&#8217;d like to show two examples of parallel scan composition in terms of binary trees, namely the top-down and bottom-up variants of perfect binary leaf trees used in previous posts. (In previous posts, I used the terms &quot;right-folded&quot; and &quot;left-folded&quot; instead of &quot;top-down&quot; and &quot;bottom-up&quot;.) The resulting two algorithms are expressed nearly identically, but have differ significantly in the work performed. The top-down version does <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mo stretchy="false">(</mo><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mspace width="0.167em"></mspace><mi>n</mi><mo stretchy="false">)</mo></mrow></math> work, while the bottom-up version does only <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow></math>, and thus the latter algorithm is work-efficient, while the former is not. Moreover, with a <em>very</em> simple optimization, the bottom-up tree algorithm corresponds closely to Guy Blelloch&#8217;s parallel prefix scan for arrays, given in <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.5739" title="Paper by Guy Blelloch"><em>Programming parallel algorithms</em></a>. I&#8217;m delighted with this result, as I had been wondering how to think about Guy&#8217;s algorithm.</p>

<p><strong>Edit:</strong></p>

<ul>
<li>2011-05-31: Added <code>Scan</code> and <code>Applicative</code> instances for <code>T2</code> and <code>T4</code>.</li>
</ul>

<p><span id="more-429"></span></p>

<h3 id="scanning-via-functor-combinators">Scanning via functor combinators</h3>

<p>In <a href="http://conal.net/blog/posts/composable-parallel-scanning/" title="blog post"><em>Composable parallel scanning</em></a>, we saw the <code>Scan</code> class:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">class</span> <span class="dt">Scan</span> f <span class="kw">where</span><br />  prefixScan, suffixScan <span class="ot">&#8759;</span> <span class="dt">Monoid</span> m <span class="ot">&#8658;</span> f m <span class="ot">&#8594;</span> (m, f m)</code></pre>

<p>Given a structure of values, the prefix and suffix scan methods generate the overall <code>fold</code> (of type <code>m</code>), plus a structure of the same type as the input. (In contrast, the usual Haskell <code>scanl</code> and <code>scanr</code> functions on lists yield a single list with one more element than the source list. I changed the interface for generality and composability.) The <a href="http://conal.net/blog/posts/composable-parallel-scanning/" title="blog post">post</a> gave instances for the basic set of five functor combinators.</p>

<p>Most functors are not defined via the basic combinators, but as mentioned above, we can scan by conversion to and from the basic set. For convenience, encapsulate this conversion in a type class:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">class</span> <span class="dt">EncodeF</span> f <span class="kw">where</span><br />  <span class="kw">type</span> <span class="dt">Enc</span> f <span class="ot">&#8759;</span> <span class="fu">*</span> <span class="ot">&#8594;</span> <span class="fu">*</span><br />  encode <span class="ot">&#8759;</span> f a <span class="ot">&#8594;</span> <span class="dt">Enc</span> f a<br />  decode <span class="ot">&#8759;</span> <span class="dt">Enc</span> f a <span class="ot">&#8594;</span> f a</code></pre>

<p>and define scan functions via <code>EncodeF</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">prefixScanEnc, suffixScanEnc <span class="ot">&#8759;</span><br />  (<span class="dt">EncodeF</span> f, <span class="dt">Scan</span> (<span class="dt">Enc</span> f), <span class="dt">Monoid</span> m) <span class="ot">&#8658;</span> f m <span class="ot">&#8594;</span> (m, f m)<br />prefixScanEnc <span class="fu">=</span> second decode &#8728; prefixScan &#8728; encode<br />suffixScanEnc <span class="fu">=</span> second decode &#8728; suffixScan &#8728; encode</code></pre>

<h4 id="lists">Lists</h4>

<p>As a first example, consider</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">EncodeF</span> [] <span class="kw">where</span><br />  <span class="kw">type</span> <span class="dt">Enc</span> [] <span class="fu">=</span> <span class="dt">Const</span> () <span class="fu">+</span> <span class="dt">Id</span> &#215; []<br />  encode [] <span class="fu">=</span> <span class="dt">InL</span> (<span class="dt">Const</span> ())<br />  encode (a <span class="fu">:</span> <span class="kw">as</span>) <span class="fu">=</span> <span class="dt">InR</span> (<span class="dt">Id</span> a &#215; <span class="kw">as</span>)<br />  decode (<span class="dt">InL</span> (<span class="dt">Const</span> ())) <span class="fu">=</span> []<br />  decode (<span class="dt">InR</span> (<span class="dt">Id</span> a &#215; <span class="kw">as</span>)) <span class="fu">=</span> a <span class="fu">:</span> <span class="kw">as</span></code></pre>

<p>And declare a boilerplate <code>Scan</code> instance via <code>EncodeF</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> [] <span class="kw">where</span><br />  prefixScan <span class="fu">=</span> prefixScanEnc<br />  suffixScan <span class="fu">=</span> suffixScanEnc</code></pre>

<p>I haven&#8217;t checked the details, but I think with this instance, suffix scanning has okay performance, while prefix scan does quadratic work. The reason is the in the <code>Scan</code> instance for products, the two components are scanned independently (in parallel), and then the whole second component is adjusted for <code>prefixScan</code>, while the whole first component is adjusted for <code>suffixScan</code>. In the case of lists, the first component is the list head, and second component is the list tail.</p>

<p>For your reading convenience, here&#8217;s that <code>Scan</code> instance again:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> (<span class="dt">Scan</span> f, <span class="dt">Scan</span> g, <span class="kw">Functor</span> f, <span class="kw">Functor</span> g) <span class="ot">&#8658;</span> <span class="dt">Scan</span> (f &#215; g) <span class="kw">where</span><br />  prefixScan (fa &#215; ga) <span class="fu">=</span> (af &#8853; ag, fa' &#215; ((af &#8853;) <span class="fu">&lt;$&gt;</span> ga'))<br />   <span class="kw">where</span> (af,fa') <span class="fu">=</span> prefixScan fa<br />         (ag,ga') <span class="fu">=</span> prefixScan ga<br /><br />  suffixScan (fa &#215; ga) <span class="fu">=</span> (af &#8853; ag, ((&#8853; ag) <span class="fu">&lt;$&gt;</span> fa') &#215; ga')<br />   <span class="kw">where</span> (af,fa') <span class="fu">=</span> suffixScan fa<br />         (ag,ga') <span class="fu">=</span> suffixScan ga</code></pre>

<p>The lop-sidedness of the list type thus interferes with parallelization, and makes the parallel scans perform much worse than cumulative sequential scans.</p>

<p>Let&#8217;s next look at a more balanced type.</p>

<h3 id="binary-trees">Binary Trees</h3>

<p>We&#8217;ll get better parallel performance by organizing our data so that we can cheaply partition it into roughly equal pieces. Tree types allows such partitioning.</p>

<h4 id="top-down-trees">Top-down trees</h4>

<p>We&#8217;ll try a few variations, starting with a simple binary tree.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">T1</span> a <span class="fu">=</span> <span class="dt">L1</span> a <span class="fu">|</span> <span class="dt">B1</span> (<span class="dt">T1</span> a) (<span class="dt">T1</span> a) <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>Encoding and decoding is straightforward:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">EncodeF</span> <span class="dt">T1</span> <span class="kw">where</span><br />  <span class="kw">type</span> <span class="dt">Enc</span> <span class="dt">T1</span> <span class="fu">=</span> <span class="dt">Id</span> <span class="fu">+</span> <span class="dt">T1</span> &#215; <span class="dt">T1</span><br />  encode (<span class="dt">L1</span> a)   <span class="fu">=</span> <span class="dt">InL</span> (<span class="dt">Id</span> a)<br />  encode (<span class="dt">B1</span> s t) <span class="fu">=</span> <span class="dt">InR</span> (s &#215; t)<br />  decode (<span class="dt">InL</span> (<span class="dt">Id</span> a))  <span class="fu">=</span> <span class="dt">L1</span> a<br />  decode (<span class="dt">InR</span> (s &#215; t)) <span class="fu">=</span> <span class="dt">B1</span> s t<br /><br /><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">T1</span> <span class="kw">where</span><br />  prefixScan <span class="fu">=</span> prefixScanEnc<br />  suffixScan <span class="fu">=</span> suffixScanEnc</code></pre>

<p>Note that these definitions could be generated automatically from the data type definition.</p>

<p>For <em>balanced trees</em>, prefix and suffix scan divide the problem in half at each step, solve each half, and do linear work to patch up one of the two halves. Letting <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math> be the number of elements, and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>W</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow></math> the work, we have the recurrence <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>W</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo>=</mo><mn>2</mn><mspace width="0.167em"></mspace><mi>W</mi><mo stretchy="false">(</mo><mi>n</mi><mo>/</mo><mn>2</mn><mo stretchy="false">)</mo><mo>+</mo><mi>c</mi><mspace width="0.167em"></mspace><mi>n</mi></mrow></math> for some constant factor <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>c</mi></mrow></math>. By the <a href="http://en.wikipedia.org/wiki/Master_theorem" title="Wikipedia entry">Master theorem</a>, therefore, the work done is <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mo stretchy="false">(</mo><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mspace width="0.167em"></mspace><mi>n</mi><mo stretchy="false">)</mo></mrow></math>. (Use case 2, with <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>a</mi><mo>=</mo><mi>b</mi><mo>=</mo><mn>2</mn></mrow></math>, <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>f</mi><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo><mo>=</mo><mi>c</mi><mspace width="0.167em"></mspace><mi>n</mi></mrow></math>, and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>k</mi><mo>=</mo><mn>0</mn></mrow></math>.)</p>

<p>Again assuming a <em>balanced</em> tree, the computation dependencies have logarithmic depth, so the ideal parallel running time (assuming sufficient processors) is <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mo stretchy="false">(</mo><mi>log</mi><mi>n</mi><mo stretchy="false">)</mo></mrow></math>. Thus we have an algorithm that is depth-efficient (modulo constant factors) but work-inefficient.</p>

<h4 id="composition">Composition</h4>

<p>A binary tree as defined above is either a leaf or a pair of binary trees. We can make this pair-ness more explicit with a reformulation:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">T2</span> a <span class="fu">=</span> <span class="dt">L2</span> a <span class="fu">|</span> <span class="dt">B2</span> (<span class="dt">Pair</span> (<span class="dt">T2</span> a)) <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>where <code>Pair</code>, as in <a href="http://conal.net/blog/posts/composable-parallel-scanning/" title="blog post"><em>Composable parallel scanning</em></a>, is defined as</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Pair</span> a <span class="fu">=</span> a <span class="fu">:#</span> a <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>or even</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">type</span> <span class="dt">Pair</span> <span class="fu">=</span> <span class="dt">Id</span> &#215; <span class="dt">Id</span></code></pre>

<p>For encoding and decoding, we could use the same representation as with <code>T1</code>, but let&#8217;s instead use a more natural one for the definition of <code>T2</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">EncodeF</span> <span class="dt">T2</span> <span class="kw">where</span><br />  <span class="kw">type</span> <span class="dt">Enc</span> <span class="dt">T2</span> <span class="fu">=</span> <span class="dt">Id</span> <span class="fu">+</span> <span class="dt">Pair</span> &#8728; <span class="dt">T2</span><br />  encode (<span class="dt">L2</span> a)  <span class="fu">=</span> <span class="dt">InL</span> (<span class="dt">Id</span> a)<br />  encode (<span class="dt">B2</span> st) <span class="fu">=</span> <span class="dt">InR</span> (<span class="dt">O</span> st)<br />  decode (<span class="dt">InL</span> (<span class="dt">Id</span> a)) <span class="fu">=</span> <span class="dt">L2</span> a<br />  decode (<span class="dt">InR</span> (<span class="dt">O</span> st)) <span class="fu">=</span> <span class="dt">B2</span> st</code></pre>

<p>Boilerplate scanning:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">T2</span> <span class="kw">where</span><br />  prefixScan <span class="fu">=</span> prefixScanEnc<br />  suffixScan <span class="fu">=</span> suffixScanEnc</code></pre>

<p>for which we&#8217;ll need an applicative instance:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">T2</span> <span class="kw">where</span><br />  pure <span class="fu">=</span> <span class="dt">L2</span><br />  <span class="dt">L2</span> f <span class="fu">&lt;*&gt;</span> <span class="dt">L2</span> x <span class="fu">=</span> <span class="dt">L2</span> (f x)<br />  <span class="dt">B2</span> (fs <span class="fu">:#</span> gs) <span class="fu">&lt;*&gt;</span> <span class="dt">B2</span> (xs <span class="fu">:#</span> ys) <span class="fu">=</span> <span class="dt">B2</span> ((fs <span class="fu">&lt;*&gt;</span> xs) <span class="fu">:#</span> (gs <span class="fu">&lt;*&gt;</span> ys))<br />  _ <span class="fu">&lt;*&gt;</span> _ <span class="fu">=</span> <span class="fu">error</span> <span class="st">&quot;T2 (&lt;*&gt;): structure mismatch&quot;</span></code></pre>

<p>The <code>O</code> constructor is for functor composition.</p>

<p>With a small change to the tree type, we can make the composition of <code>Pair</code> and <code>T</code> more explicit:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">T3</span> a <span class="fu">=</span> <span class="dt">L3</span> a <span class="fu">|</span> <span class="dt">B3</span> ((<span class="dt">Pair</span> &#8728; <span class="dt">T3</span>) a) <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>Then the conversion becomes even simpler, since there&#8217;s no need to add or remove <code>O</code> wrappers:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">EncodeF</span> <span class="dt">T3</span> <span class="kw">where</span><br />  <span class="kw">type</span> <span class="dt">Enc</span> <span class="dt">T3</span> <span class="fu">=</span> <span class="dt">Id</span> <span class="fu">+</span> <span class="dt">Pair</span> &#8728; <span class="dt">T3</span><br />  encode (<span class="dt">L3</span> a)  <span class="fu">=</span> <span class="dt">InL</span> (<span class="dt">Id</span> a)<br />  encode (<span class="dt">B3</span> st) <span class="fu">=</span> <span class="dt">InR</span> st<br />  decode (<span class="dt">InL</span> (<span class="dt">Id</span> a)) <span class="fu">=</span> <span class="dt">L3</span> a<br />  decode (<span class="dt">InR</span> st)     <span class="fu">=</span> <span class="dt">B3</span> st</code></pre>

<h4 id="bottom-up-trees">Bottom-up trees</h4>

<p>In the formulations above, a non-leaf tree consists of a pair of trees. I&#8217;ll call these trees &quot;top-down&quot;, since visible pair structure begins at the top.</p>

<p>With a very small change, we can instead use a tree of pairs:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">T4</span> a <span class="fu">=</span> <span class="dt">L4</span> a <span class="fu">|</span> <span class="dt">B4</span> (<span class="dt">T4</span> (<span class="dt">Pair</span> a)) <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>Again an applicative instance allows a standard <code>Scan</code> instance:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">T4</span> <span class="kw">where</span><br />  prefixScan <span class="fu">=</span> prefixScanEnc<br />  suffixScan <span class="fu">=</span> suffixScanEnc<br /><br /><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">T4</span> <span class="kw">where</span><br />  pure <span class="fu">=</span> <span class="dt">L4</span><br />  <span class="dt">L4</span> f   <span class="fu">&lt;*&gt;</span> <span class="dt">L4</span> x   <span class="fu">=</span> <span class="dt">L4</span> (f x)<br />  <span class="dt">B4</span> fgs <span class="fu">&lt;*&gt;</span> <span class="dt">B4</span> xys <span class="fu">=</span> <span class="dt">B4</span> (liftA2 h fgs xys)<br />   <span class="kw">where</span> h (f <span class="fu">:#</span> g) (x <span class="fu">:#</span> y) <span class="fu">=</span> f x <span class="fu">:#</span> g y<br />  _ <span class="fu">&lt;*&gt;</span> _ <span class="fu">=</span> <span class="fu">error</span> <span class="st">&quot;T4 (&lt;*&gt;): structure mismatch&quot;</span></code></pre>

<p>or a more explicitly composed form:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">T5</span> a <span class="fu">=</span> <span class="dt">L5</span> a <span class="fu">|</span> <span class="dt">B5</span> ((<span class="dt">T5</span> &#8728; <span class="dt">Pair</span>) a) <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>I&#8217;ll call these new variations &quot;bottom-up&quot; trees, since visible pair structure begins at the bottom. After stripping off the branch constructor, <code>B4</code>, we can get at the pair-valued leaves by means of <code>fmap</code>, <code>fold</code>, or <code>traverse</code> (or variations). For <code>B5</code>, we&#8217;d also have to strip off the <code>O</code> wrapper (functor composition).</p>

<p>Encoding is nearly the same as with top-down trees. For instance,</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">EncodeF</span> <span class="dt">T4</span> <span class="kw">where</span><br />  <span class="kw">type</span> <span class="dt">Enc</span> <span class="dt">T4</span> <span class="fu">=</span> <span class="dt">Id</span> <span class="fu">+</span> <span class="dt">T4</span> &#8728; <span class="dt">Pair</span><br />  encode (<span class="dt">L4</span> a) <span class="fu">=</span> <span class="dt">InL</span> (<span class="dt">Id</span> a)<br />  encode (<span class="dt">B4</span> t) <span class="fu">=</span> <span class="dt">InR</span> (<span class="dt">O</span> t)<br />  decode (<span class="dt">InL</span> (<span class="dt">Id</span> a)) <span class="fu">=</span> <span class="dt">L4</span> a<br />  decode (<span class="dt">InR</span> (<span class="dt">O</span> t))  <span class="fu">=</span> <span class="dt">B4</span> t</code></pre>

<h3 id="scanning-pairs">Scanning pairs</h3>

<p>We&#8217;ll need to scan on the <code>Pair</code> functor. If we use the definition of <code>Pair</code> above in terms of <code>Id</code> and <code>(×)</code>, then we&#8217;ll get scanning for free. For <em>using</em> <code>Pair</code>, I find the explicit data type definition above more convenient. We can then derive a <code>Scan</code> instance by conversion. Start with a standard specification:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Pair</span> a <span class="fu">=</span> a <span class="fu">:#</span> a <span class="kw">deriving</span> <span class="kw">Functor</span></code></pre>

<p>And encode &amp; decode explicitly:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">EncodeF</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  <span class="kw">type</span> <span class="dt">Enc</span> <span class="dt">Pair</span> <span class="fu">=</span> <span class="dt">Id</span> &#215; <span class="dt">Id</span><br />  encode (a <span class="fu">:#</span> b) <span class="fu">=</span> <span class="dt">Id</span> a &#215; <span class="dt">Id</span> b<br />  decode (<span class="dt">Id</span> a &#215; <span class="dt">Id</span> b) <span class="fu">=</span> a <span class="fu">:#</span> b</code></pre>

<p>Then use our boilerplate <code>Scan</code> instance for <code>EncodeF</code> instances:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  prefixScan <span class="fu">=</span> prefixScanEnc<br />  suffixScan <span class="fu">=</span> suffixScanEnc</code></pre>

<p>We&#8217;ve seen the <code>Scan</code> instance for <code>(×)</code> above. The instance for <code>Id</code> is very simple:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">Id</span> a <span class="fu">=</span> <span class="dt">Id</span> a<br /><br /><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">Id</span> <span class="kw">where</span><br />  prefixScan (<span class="dt">Id</span> m) <span class="fu">=</span> (m, <span class="dt">Id</span> &#8709;)<br />  suffixScan        <span class="fu">=</span> prefixScan</code></pre>

<p>Given these definitions, we can calculate a more streamlined <code>Scan</code> instance for <code>Pair</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (a <span class="fu">:#</span> b)<br />&#8801;  <span class="co">{- specification -}</span><br />  prefixScanEnc (a <span class="fu">:#</span> b)<br />&#8801;  <span class="co">{- prefixScanEnc definition -}</span><br />  (second decode &#8728; prefixScan &#8728; encode) (a <span class="fu">:#</span> b)<br />&#8801;  <span class="co">{- (&#8728;) -}</span><br />  second decode (prefixScan (encode (a <span class="fu">:#</span> b)))<br />&#8801;  <span class="co">{- encode definition for Pair -}</span><br />  second decode (prefixScan (<span class="dt">Id</span> a &#215; <span class="dt">Id</span> b))<br />&#8801;  <span class="co">{- prefixScan definition for f &#215; g -}</span><br />  second decode<br />    (af &#8853; ag, fa' &#215; ((af &#8853;) <span class="fu">&lt;$&gt;</span> ga'))<br />     <span class="kw">where</span> (af,fa') <span class="fu">=</span> prefixScan (<span class="dt">Id</span> a)<br />           (ag,ga') <span class="fu">=</span> prefixScan (<span class="dt">Id</span> b)<br />&#8801;  <span class="co">{- Definition of second on functions -}</span><br />  (af &#8853; ag, decode (fa' &#215; ((af &#8853;) <span class="fu">&lt;$&gt;</span> ga')))<br />   <span class="kw">where</span> (af,fa') <span class="fu">=</span> prefixScan (<span class="dt">Id</span> a)<br />         (ag,ga') <span class="fu">=</span> prefixScan (<span class="dt">Id</span> b)<br />&#8801;  <span class="co">{- prefixScan definition for Id -}</span><br />  (af &#8853; ag, decode (fa' &#215; ((af &#8853;) <span class="fu">&lt;$&gt;</span> ga')))<br />   <span class="kw">where</span> (af,fa') <span class="fu">=</span> (a, <span class="dt">Id</span> &#8709;)<br />         (ag,ga') <span class="fu">=</span> (b, <span class="dt">Id</span> &#8709;)<br />&#8801;  <span class="co">{- substitution -}</span><br />  (a &#8853; b, decode (<span class="dt">Id</span> &#8709; &#215; ((a &#8853;) <span class="fu">&lt;$&gt;</span> <span class="dt">Id</span> &#8709;)))<br />&#8801;  <span class="co">{- fmap/(&lt;$&gt;) for Id -}</span><br />  (a &#8853; b, decode (<span class="dt">Id</span> &#8709; &#215; <span class="dt">Id</span> (a &#8853; &#8709;)))<br />&#8801;  <span class="co">{- Monoid law -}</span><br />  (a &#8853; b, decode (<span class="dt">Id</span> &#8709; &#215; <span class="dt">Id</span> a))<br />&#8801;  <span class="co">{- decode definition on Pair -}</span><br />  (a &#8853; b, (&#8709; <span class="fu">:#</span> a))</code></pre>

<p>Whew! And similarly for <code>suffixScan</code>.</p>

<p>Now let&#8217;s recall the <code>Scan</code> instance for <code>Pair</code> given in <a href="http://conal.net/blog/posts/composable-parallel-scanning/" title="blog post"><em>Composable parallel scanning</em></a>:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  prefixScan (a <span class="fu">:#</span> b) <span class="fu">=</span> (a &#8853; b, (&#8709; <span class="fu">:#</span> a))<br />  suffixScan (a <span class="fu">:#</span> b) <span class="fu">=</span> (a &#8853; b, (b <span class="fu">:#</span> &#8709;))</code></pre>

<p>Hurray! The derivation led us to the same definition. A &quot;sufficiently smart&quot; compiler could do this derivation automatically.</p>

<p>With this warm-up derivation, let&#8217;s now turn to trees.</p>

<h3 id="scanning-trees">Scanning trees</h3>

<p>Given the tree encodings above, how does scan work? We&#8217;ll have to consult <code>Scan</code> instances for some of the functor combinators. The product instance is repeated above. We&#8217;ll also want the instances for sum and composition. Omitting the <code>suffixScan</code> definitions for brevity:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> (f <span class="fu">+</span> g) a <span class="fu">=</span> <span class="dt">InL</span> (f a) <span class="fu">|</span> <span class="dt">InR</span> (g a)<br /><br /><span class="kw">instance</span> (<span class="dt">Scan</span> f, <span class="dt">Scan</span> g) <span class="ot">&#8658;</span> <span class="dt">Scan</span> (f <span class="fu">+</span> g) <span class="kw">where</span><br />  prefixScan (<span class="dt">InL</span> fa) <span class="fu">=</span> second <span class="dt">InL</span> (prefixScan fa)<br />  prefixScan (<span class="dt">InR</span> ga) <span class="fu">=</span> second <span class="dt">InR</span> (prefixScan ga)<br /><br /><span class="kw">newtype</span> (g &#8728; f) a <span class="fu">=</span> <span class="dt">O</span> (g (f a))<br /><br /><span class="kw">instance</span> (<span class="dt">Scan</span> g, <span class="dt">Scan</span> f, <span class="kw">Functor</span> f, <span class="dt">Applicative</span> g) <span class="ot">&#8658;</span> <span class="dt">Scan</span> (g &#8728; f) <span class="kw">where</span><br />  prefixScan <span class="fu">=</span> second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>)<br />             &#8728; assocR<br />             &#8728; first prefixScan<br />             &#8728; <span class="fu">unzip</span><br />             &#8728; <span class="fu">fmap</span> prefixScan<br />             &#8728; unO</code></pre>

<p>This last definition uses a few utility functions:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">zip</span> <span class="ot">&#8759;</span> <span class="dt">Applicative</span> g <span class="ot">&#8658;</span> (g a, g b) <span class="ot">&#8594;</span> g (a,b)<br /><span class="fu">zip</span> <span class="fu">=</span> <span class="fu">uncurry</span> (liftA2 (,))<br /><br /><span class="fu">unzip</span> <span class="ot">&#8759;</span> <span class="kw">Functor</span> g <span class="ot">&#8658;</span> g (a,b) <span class="ot">&#8594;</span> (g a, g b)<br /><span class="fu">unzip</span> <span class="fu">=</span> <span class="fu">fmap</span> <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> <span class="fu">fmap</span> <span class="fu">snd</span><br /><br />assocR <span class="ot">&#8759;</span> ((a,b),c) <span class="ot">&#8594;</span> (a,(b,c))<br />assocR   ((a,b),c) <span class="fu">=</span>  (a,(b,c))<br /><br />adjustL <span class="ot">&#8759;</span> (<span class="kw">Functor</span> f, <span class="dt">Monoid</span> m) <span class="ot">&#8658;</span> (m, f m) <span class="ot">&#8594;</span> f m<br />adjustL (m, ms) <span class="fu">=</span> (m &#8853;) <span class="fu">&lt;$&gt;</span> ms</code></pre>

<p>Let&#8217;s consider how the <code>Scan (g ∘ f)</code> instance plays out for top-down vs bottom-up trees, given the functor-composition encodings above. The critical definitions:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">type</span> <span class="dt">Enc</span> <span class="dt">T2</span> <span class="fu">=</span> <span class="dt">Id</span> <span class="fu">+</span> <span class="dt">Pair</span> &#8728; <span class="dt">T2</span><br /><br /><span class="kw">type</span> <span class="dt">Enc</span> <span class="dt">T4</span> <span class="fu">=</span> <span class="dt">Id</span> <span class="fu">+</span> <span class="dt">T4</span> &#8728; <span class="dt">Pair</span></code></pre>

<p>Focusing on the branch case, we have <code>Pair ∘ T2</code> vs <code>T4 ∘ Pair</code>, so we&#8217;ll use the <code>Scan (g ∘ f)</code> instance either way. Let&#8217;s consider the work implied by that instance. There are two calls to <code>prefixScan</code>, plus a linear amount of other work. The meanings of those two calls differ, however:</p>

<ul>
<li>For top-down trees (<code>T2</code>), the recursive tree scans are in <code>fmap prefixScan</code>, mapping over the pair of trees. The <code>first prefixScan</code> is a pair scan and so does constant work. Since there are two recursive calls, each working on a tree of half size (assuming balance), plus linear other work, the total work <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mo stretchy="false">(</mo><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mspace width="0.167em"></mspace><mi>n</mi><mo stretchy="false">)</mo></mrow></math>, as explained above.</li>
<li>For bottom-up trees (<code>T4</code>), there is only one recursive recursive tree scan, which appears in <code>first prefixScan</code>. The <code>prefixScan</code> in <code>fmap prefixScan</code> is pair scan and so does constant work but is mapped over the half-sized tree (of pairs), and so does linear work altogether. Since there only one recursive tree scan, at half size, plus linear other work, the total work is then proportional to <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>+</mo><mi>n</mi><mo>/</mo><mn>2</mn><mo>+</mo><mi>n</mi><mo>/</mo><mn>4</mn><mo>+</mo><mo>&#8230;</mo><mo>&#8776;</mo><mn>2</mn><mspace width="0.167em"></mspace><mi>n</mi><mo>=</mo><mo>&#920;</mo><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow></math>. So we have a work-efficient algorithm!</li>
</ul>

<h3 id="looking-deeper">Looking deeper</h3>

<p>In addition to the simple analysis above of scanning over top-down and over bottom-up, let&#8217;s look in detail at what transpires and how each case can be optimized. This section may well have more detail than you&#8217;re interested in. If so, feel free to skip ahead.</p>

<h4 id="top-down">Top-down</h4>

<p>Beginning as with <code>Pair</code>,</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan t<br />&#8801;  <span class="co">{- specification -}</span><br />  prefixScanEnc t<br />&#8801;  <span class="co">{- prefixScanEnc definition -}</span><br />  (second decode &#8728; prefixScan &#8728; encode) t<br />&#8801;  <span class="co">{- (&#8728;) -}</span><br />  second decode (prefixScan (encode t))</code></pre>

<p>Take <code>T2</code>, with <code>T3</code> being quite similar. Now split into two cases for the two constructors of <code>T2</code>. First leaf:</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (<span class="dt">L2</span> m)<br />&#8801;  <span class="co">{- as above -}</span><br />  second decode (prefixScan (encode (<span class="dt">L2</span> m)))<br />&#8801;  <span class="co">{- encode for L2 -}</span><br />  second decode (prefixScan (<span class="dt">InL</span> (<span class="dt">Id</span> m)))<br />&#8801;  <span class="co">{- prefixScan for functor sum -}</span><br />  second decode (second <span class="dt">InL</span> (prefixScan (<span class="dt">Id</span> m)))<br />&#8801;  <span class="co">{- prefixScan for Id -}</span><br />  second decode (second <span class="dt">InL</span> (m, <span class="dt">Id</span> &#8709;))<br />&#8801;  <span class="co">{- second for functions -}</span><br />  second decode (m, <span class="dt">InL</span> (<span class="dt">Id</span> &#8709;))<br />&#8801;  <span class="co">{- second for functions -}</span><br />  (m, decode (<span class="dt">InL</span> (<span class="dt">Id</span> &#8709;)))<br />&#8801;  <span class="co">{- decode for L2 -}</span><br />  (m, <span class="dt">L2</span> &#8709;)</code></pre>

<p>Then branch:</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (<span class="dt">B2</span> (s <span class="fu">:#</span> t))<br />&#8801;  <span class="co">{- as above -}</span><br />  second decode (prefixScan (encode (<span class="dt">B2</span> (s <span class="fu">:#</span> t))))<br />&#8801;  <span class="co">{- encode for L2 -}</span><br />  second decode (prefixScan (<span class="dt">InR</span> (<span class="dt">O</span> (s <span class="fu">:#</span> t))))<br />&#8801;  <span class="co">{- prefixScan for (+) -}</span><br />  second decode (second <span class="dt">InR</span> (prefixScan (<span class="dt">O</span> (s <span class="fu">:#</span> t))))<br />&#8801;  <span class="co">{- property of second -}</span><br />  second (decode &#8728; <span class="dt">InR</span>) (prefixScan (<span class="dt">O</span> (s <span class="fu">:#</span> t)))</code></pre>

<p>Focus on the <code>prefixScan</code> application:</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (<span class="dt">O</span> (s <span class="fu">:#</span> t)) <span class="fu">=</span><br />&#8801;  <span class="co">{- prefixScan for (&#8728;) -}</span><br /> ( second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan<br /> &#8728; <span class="fu">unzip</span> &#8728; <span class="fu">fmap</span> prefixScan &#8728; unO ) (<span class="dt">O</span> (s <span class="fu">:#</span> t))<br />&#8801;  <span class="co">{- unO/O -}</span><br />  ( second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan<br />  &#8728; <span class="fu">unzip</span> &#8728; <span class="fu">fmap</span> prefixScan ) (s <span class="fu">:#</span> t)<br />&#8801;  <span class="co">{- fmap on Pair -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan &#8728; <span class="fu">unzip</span>)<br />    (prefixScan s <span class="fu">:#</span> prefixScan t)<br />&#8801;  <span class="co">{- expand prefixScan -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan &#8728; <span class="fu">unzip</span>)<br />    ((ms,s') <span class="fu">:#</span> (mt,t'))<br />      <span class="kw">where</span> (ms,s') <span class="fu">=</span> prefixScan s<br />            (mt,t') <span class="fu">=</span> prefixScan t<br />&#8801;  <span class="co">{- unzip -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan)<br />    ((ms <span class="fu">:#</span> mt), (s' <span class="fu">:#</span> t')) <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- first -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR)<br />    (prefixScan (ms <span class="fu">:#</span> mt), (s' <span class="fu">:#</span> t')) <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- prefixScan for Pair -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR)<br />    ((ms &#8853; mt, (&#8709; <span class="fu">:#</span> ms)), (s' <span class="fu">:#</span> t')) <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- assocR -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>))<br />    (ms &#8853; mt, ((&#8709; <span class="fu">:#</span> ms), (s' <span class="fu">:#</span> t'))) <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- second -}</span><br />  ( ms &#8853; mt<br />  , (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) ((&#8709; <span class="fu">:#</span> ms), (s' <span class="fu">:#</span> t')) ) <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- zip -}</span><br />  ( ms &#8853; mt<br />  , (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL) ((&#8709;,s') <span class="fu">:#</span> (ms,t')) )  <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- fmap for Pair -}</span><br />  ( ms &#8853; mt<br />  , <span class="dt">O</span> (adjustL (&#8709;,s') <span class="fu">:#</span> adjustL (ms,t')) )  <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- adjustL -}</span><br />  ( ms &#8853; mt<br />  , <span class="dt">O</span> (((&#8709; &#8853;) <span class="fu">&lt;$&gt;</span> s') <span class="fu">:#</span> ((ms &#8853;) <span class="fu">&lt;$&gt;</span> t')) )  <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- Monoid law (left identity) -}</span><br />  ( ms &#8853; mt<br />  , <span class="dt">O</span> ((<span class="fu">id</span> <span class="fu">&lt;$&gt;</span> s') <span class="fu">:#</span> ((ms &#8853;) <span class="fu">&lt;$&gt;</span> t')) )  <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- Functor law (fmap id) -}</span><br />  ( ms &#8853; mt<br />  , <span class="dt">O</span> (s' <span class="fu">:#</span> ((ms &#8853;) <span class="fu">&lt;$&gt;</span> t')) )<br />      <span class="kw">where</span> (ms,s') <span class="fu">=</span> prefixScan s<br />            (mt,t') <span class="fu">=</span> prefixScan t</code></pre>

<p>Continuing from above,</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (<span class="dt">B2</span> (s <span class="fu">:#</span> t))<br />&#8801;  <span class="co">{- see above -}</span><br />  second (decode &#8728; <span class="dt">InR</span>) (prefixScan (<span class="dt">O</span> (s <span class="fu">:#</span> t)))<br />&#8801;  <span class="co">{- prefixScan focus from above -}</span><br />  second (decode &#8728; <span class="dt">InR</span>)<br />    ( ms &#8853; mt<br />    , <span class="dt">O</span> (s' <span class="fu">:#</span> ((ms &#8853;) <span class="fu">&lt;$&gt;</span> t')) )<br />        <span class="kw">where</span> (ms,s') <span class="fu">=</span> prefixScan s<br />              (mt,t') <span class="fu">=</span> prefixScan t<br />&#8801;  <span class="co">{- definition of second on functions -}</span><br />    (ms &#8853; mt, (decode &#8728; <span class="dt">InR</span>) (<span class="dt">O</span> (s' <span class="fu">:#</span> ((ms &#8853;) <span class="fu">&lt;$&gt;</span> t')))) <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- (&#8728;) -}</span><br />    (ms &#8853; mt, decode (<span class="dt">InR</span> (<span class="dt">O</span> (s' <span class="fu">:#</span> ((ms &#8853;) <span class="fu">&lt;$&gt;</span> t'))))) <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- decode for B2 -}</span><br />    (ms &#8853; mt, <span class="dt">B2</span> (s' <span class="fu">:#</span> ((ms &#8853;) <span class="fu">&lt;$&gt;</span> t'))) <span class="kw">where</span> &#8943;</code></pre>

<p>This final form is as in <a href="http://conal.net/blog/posts/deriving-parallel-tree-scans/" title="blog post"><em>Deriving parallel tree scans</em></a>, changed for the new scan interface. The derivation saved some work in wrapping &amp; unwrapping and method invocation, plus one of the two adjustment passes over the sub-trees. As explained above, this algorithm performs <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mo stretchy="false">(</mo><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mspace width="0.167em"></mspace><mi>n</mi><mo stretchy="false">)</mo></mrow></math> work.</p>

<p>I&#8217;ll leave <code>suffixScan</code> for you to do yourself.</p>

<h4 id="bottom-up">Bottom-up</h4>

<p>What happens if we switch from top-down to bottom-up binary trees? I&#8217;ll use <code>T4</code> (though <code>T5</code> would work as well):</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">T4</span> a <span class="fu">=</span> <span class="dt">L4</span> a <span class="fu">|</span> <span class="dt">B4</span> (<span class="dt">T4</span> (<span class="dt">Pair</span> a))</code></pre>

<p>The leaf case is just as with <code>T2</code> above, so let&#8217;s get right to branches.</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (<span class="dt">B4</span> t)<br />&#8801;  <span class="co">{- as above -}</span><br />  second decode (prefixScan (encode (<span class="dt">B4</span> t)))<br />&#8801;  <span class="co">{- encode for L2 -}</span><br />  second decode (prefixScan (<span class="dt">InR</span> (<span class="dt">O</span> t)))<br />&#8801;  <span class="co">{- prefixScan for (+) -}</span><br />  second decode (second <span class="dt">InR</span> (prefixScan (<span class="dt">O</span> t)))<br />&#8801;  <span class="co">{- property of second -}</span><br />  second (decode &#8728; <span class="dt">InR</span>) (prefixScan (<span class="dt">O</span> t))</code></pre>

<p>As before, now focus on the <code>prefixScan</code> call.</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (<span class="dt">O</span> t) <span class="fu">=</span><br />&#8801;  <span class="co">{- prefixScan for (&#8728;) -}</span><br /> ( second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan<br /> &#8728; <span class="fu">unzip</span> &#8728; <span class="fu">fmap</span> prefixScan &#8728; unO ) (<span class="dt">O</span> t)<br />&#8801;  <span class="co">{- unO/O -}</span><br />  ( second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan<br />  &#8728; <span class="fu">unzip</span> &#8728; <span class="fu">fmap</span> prefixScan ) t<br />&#8801;  <span class="co">{- prefixScan on Pair (derived above) -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan &#8728; <span class="fu">unzip</span>)<br />    <span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (a &#8853; b, (&#8709; <span class="fu">:#</span> a))) t<br />&#8801;  <span class="co">{- unzip/fmap -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR &#8728; first prefixScan)<br />    ( <span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (a &#8853; b)) t<br />    , <span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (&#8709; <span class="fu">:#</span> a))   t )<br />&#8801;  <span class="co">{- first on functions -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR)<br />    ( prefixScan (<span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (a &#8853; b)) t)<br />    , <span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (&#8709; <span class="fu">:#</span> a))   t )<br />&#8801;  <span class="co">{- expand prefixScan -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) &#8728; assocR)<br />    ((mp,p'), <span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (&#8709; <span class="fu">:#</span> a)) t)<br />   <span class="kw">where</span> (mp,p') <span class="fu">=</span> prefixScan (<span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (a &#8853; b)) t)<br />&#8801;  <span class="co">{- assocR -}</span><br />  (second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>))<br />    (mp, (p', <span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (&#8709; <span class="fu">:#</span> a)) t))<br />   <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- second on functions -}</span><br />  (mp, (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>) (p', <span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (&#8709; <span class="fu">:#</span> a)) t))<br />    <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- fmap/zip/fmap -}</span><br />  (mp, <span class="dt">O</span> (liftA2 tweak p' t))<br />    <span class="kw">where</span> tweak s (a <span class="fu">:#</span> _) <span class="fu">=</span> adjustL (s, (&#8709; <span class="fu">:#</span> a))<br />          (mp,p') <span class="fu">=</span> prefixScan (<span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (a &#8853; b)) t)<br />&#8801;  <span class="co">{- adjustL, then simplify -}</span><br />  (mp, <span class="dt">O</span> (liftA2 tweak p' t))<br />    <span class="kw">where</span> tweak s (a <span class="fu">:#</span> _) <span class="fu">=</span> (s <span class="fu">:#</span> s &#8853; a)<br />          (mp,p') <span class="fu">=</span> prefixScan (<span class="fu">fmap</span> (&#955; (a <span class="fu">:#</span> b) <span class="ot">&#8594;</span> (a &#8853; b)) t)</code></pre>

<p>Now re-introduce the context of <code>prefixScan (O t)</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan (<span class="dt">B4</span> t)<br />&#8801;  <span class="co">{- see above -}</span><br />  second (decode &#8728; <span class="dt">InR</span>) (prefixScan (<span class="dt">O</span> t))<br />&#8801;  <span class="co">{- see above -}</span><br />  second (decode &#8728; <span class="dt">InR</span>)<br />    (mp, <span class="dt">O</span> (liftA2 tweak p' t))<br />      <span class="kw">where</span> &#8943;<br />&#8801;  <span class="co">{- decode for T4 -}</span><br />  (mp, <span class="dt">B4</span> (liftA2 tweak p' t))<br />    <span class="kw">where</span> p <span class="fu">=</span> <span class="fu">fmap</span> (&#955; (e <span class="fu">:#</span> o) <span class="ot">&#8594;</span> (e &#8853; o)) t<br />          (mp,p') <span class="fu">=</span> prefixScan p<br />          tweak s (e <span class="fu">:#</span> _) <span class="fu">=</span> (s <span class="fu">:#</span> s &#8853; e)</code></pre>

<p>Notice how much this bottom-up tree scan algorithm differs from the top-down algorithm derived above. In particular, there&#8217;s only one recursive tree scan (on a half-sized tree) instead of two, plus linear additional work, for a total of <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mo stretchy="false">(</mo><mi>n</mi><mo stretchy="false">)</mo></mrow></math> work.</p>

<h3 id="guy-blellochs-parallel-scan-algorithm">Guy Blelloch&#8217;s parallel scan algorithm</h3>

<p>In <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.53.5739" title="Paper by Guy Blelloch"><em>Programming parallel algorithms</em></a>, Guy Blelloch gives the following algorithm for parallel prefix scan, expressed in the parallel functional language NESL:</p>

<pre class="sourceCode"><code class="sourceCode haskell">function scan(a) <span class="fu">=</span><br /><span class="kw">if</span> <span class="fu">#</span>a &#8801; <span class="dv">1</span> <span class="kw">then</span> [<span class="dv">0</span>]<br /><span class="kw">else</span><br />  <span class="kw">let</span> es <span class="fu">=</span> even_elts(a);<br />      os <span class="fu">=</span> odd_elts(a);<br />      ss <span class="fu">=</span> scan({e<span class="fu">+</span>o<span class="fu">:</span> e <span class="kw">in</span> es; o <span class="kw">in</span> os})<br />  <span class="kw">in</span> interleave(ss,{s<span class="fu">+</span>e<span class="fu">:</span> s <span class="kw">in</span> ss; e <span class="kw">in</span> es})</code></pre>

<p>This algorithm is nearly identical to the <code>T4</code> scan algorithm above. I was very glad to find this route to Guy&#8217;s algorithm, which had been fairly mysterious to me. I mean, I could believe that the algorithm worked, but I had no idea how I might have discovered it myself. With the functor composition approach to scanning, I now see how Guy&#8217;s algorithm emerges as well as how it generalizes to other data structures.</p>

<h3 id="nested-data-types-and-parallelism">Nested data types and parallelism</h3>

<p>Most of the recursive algebraic data types that appear in Haskell programs are <em>regular</em>, meaning that the recursive instances are instantiated with the same type parameter as the containing type. For instance, a top-down tree of elements of type <code>a</code> is either a leaf or has two trees whose elements have that same type <code>a</code>. In contrast, in a bottom-up tree, the (single) recursively contained tree is over elements of type <code>(a,a)</code>. Such non-regular data types are called &quot;nested&quot;. The two tree scan algorithms above suggest to me that nested data types are particularly useful for efficient parallel algorithms.</p>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=429&amp;md5=a05805e935f7c2c3d368a59c3a7c2adb" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/a_XgXE8HynQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/parallel-tree-scanning-by-composition/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/parallel-tree-scanning-by-composition</feedburner:origLink></item>
		<item>
		<title>Composable parallel scanning</title>
		<link>http://feedproxy.google.com/~r/conal/~3/5XBzyl6RDOY/composable-parallel-scanning</link>
		<comments>http://conal.net/blog/posts/composable-parallel-scanning#comments</comments>
		<pubDate>Tue, 01 Mar 2011 22:33:36 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[scan]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=411</guid>
		<description><![CDATA[The post Deriving list scans gave a simple specification of the list-scanning functions scanl and scanr, and then transformed those specifications into the standard optimized implementations. Next, the post Deriving parallel tree scans adapted the specifications and derivations to a type of binary trees. The resulting implementations are parallel-friendly, but not work-efficient, in that ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p>The post <a href="http://conal.net/blog/posts/deriving-list-scans/" title="blog post"><em>Deriving list scans</em></a> gave a simple specification of the list-scanning functions <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:scanl"><code>scanl</code></a> and <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:scanr"><code>scanr</code></a>, and then transformed those specifications into the standard optimized implementations. Next, the post <a href="http://conal.net/blog/posts/deriving-parallel-tree-scans/" title="blog post"><em>Deriving parallel tree scans</em></a> adapted the specifications and derivations to a type of binary trees. The resulting implementations are parallel-friendly, but not work-efficient, in that they perform <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mspace width="0.167em"></mspace><mi>n</mi></mrow></math> work vs linear work as in the best-known sequential algorithm.</p>

<p>Besides the work-inefficiency, I don&#8217;t know how to extend the critical <code>initTs</code> and <code>tailTs</code> functions (analogs of <code>inits</code> and <code>tails</code> on lists) to depth-typed, perfectly balanced trees, of the sort I played with in <a href="http://conal.net/blog/posts/a-trie-for-length-typed-vectors/" title="blog post"><em>A trie for length-typed vectors</em></a> and <a href="http://conal.net/blog/posts/from-tries-to-trees/" title="blog post"><em>From tries to trees</em></a>. The difficulty I encounter is that the functions <code>initTs</code> and <code>tailTs</code> make unbalanced trees out of balanced ones, so I don&#8217;t know how to adapt the specifications when types prevent the existence of unbalanced trees.</p>

<p>This new post explores an approach to generalized scanning via type classes. After defining the classes and giving a simple example, I&#8217;ll give a simple &amp; general framework based on composing functor combinators.</p>

<p><strong>Edits:</strong></p>

<ul>
<li>2011-03-02: Fixed typo. &quot;constant functor is easiest&quot; (instead of &quot;identity functor&quot;). Thanks, frguybob.</li>
<li>2011-03-05: Removed final unfinished sentence.</li>
<li>2011-07-28: Replace &quot;<code>assocL</code>&quot; with &quot;<code>assocR</code>&quot; in <code>prefixScan</code> derivation for <code>g ∘ f</code>.</li>
</ul>

<p><span id="more-411"></span></p>

<h3 id="generalizing-list-scans">Generalizing list scans</h3>

<p>The left and right scan functions on lists have an awkward feature. The output list has one more element than the input list, corresponding to the fact that the number of prefixes (<a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:inits"><code>inits</code></a>) of a list is one more than the number of elements, and similarly for suffixes (<a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:tails"><code>tails</code></a>).</p>

<p>While it&#8217;s easy to extend a list by adding one more element, it&#8217;s not easy with other functors. In <a href="http://conal.net/blog/posts/deriving-parallel-tree-scans/" title="blog post"><em>Deriving parallel tree scans</em></a>, I simply removed the <code>∅</code> element from the scan. In this post, I&#8217;ll instead change the interface to produce an output of exactly the same shape, plus one extra element. The extra element will equal a <code>fold</code> over the complete input. If you recall, we had to search for that complete fold in an input subtree in order to adjust the other subtree. (See <code>headT</code> and <code>lastT</code> and their generalizations in <a href="http://conal.net/blog/posts/deriving-parallel-tree-scans/" title="blog post"><em>Deriving parallel tree scans</em></a>.) Separating out this value eliminates the search.</p>

<p>Define a class with methods for prefix and suffix scan:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">class</span> <span class="dt">Scan</span> f <span class="kw">where</span><br />  prefixScan, suffixScan <span class="ot">&#8759;</span> <span class="dt">Monoid</span> m <span class="ot">&#8658;</span> f m <span class="ot">&#8594;</span> (m, f m)</code></pre>

<p>Prefix scans (<code>prefixScan</code>) accumulate moving left-to-right, while suffix scans (<code>suffixScan</code>) accumulate moving right-to-left.</p>

<h4 id="a-simple-example-pairs">A simple example: pairs</h4>

<p>To get a first sense of generalized scans, let&#8217;s use see how to scan over a pair functor.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Pair</span> a <span class="fu">=</span> a <span class="fu">:#</span> a <span class="kw">deriving</span> (<span class="kw">Eq</span>,<span class="kw">Ord</span>,<span class="kw">Show</span>)</code></pre>

<p>With GHC&#8217;s <code>DeriveFunctor</code> option, we could also derive a <code>Functor</code> instance, but for clarity, define it explicitly:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="kw">Functor</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  <span class="fu">fmap</span> f (a <span class="fu">:#</span> b) <span class="fu">=</span> (f a <span class="fu">:#</span> f b)</code></pre>

<p>The scans:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  prefixScan (a <span class="fu">:#</span> b) <span class="fu">=</span> (a &#8853; b, (&#8709; <span class="fu">:#</span> a))<br />  suffixScan (a <span class="fu">:#</span> b) <span class="fu">=</span> (a &#8853; b, (b <span class="fu">:#</span> &#8709;))</code></pre>

<p>As you can see, if we eliminated the <code>∅</code> elements, we could shift to the left or right and forgo the extra result.</p>

<p>Naturally, there is also a <code>Fold</code> instance, and the scans produce the fold results as well sub-folds:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Foldable</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  fold (a <span class="fu">:#</span> b) <span class="fu">=</span> a &#8853; b</code></pre>

<p>The <code>Pair</code> functor also has unsurprising instances for <code>Applicative</code> and <code>Traversable</code>.</p>

<div class=toggle>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  pure a <span class="fu">=</span> a <span class="fu">:#</span> a<br />  (f <span class="fu">:#</span> g) <span class="fu">&lt;*&gt;</span> (x <span class="fu">:#</span> y) <span class="fu">=</span> (f x <span class="fu">:#</span> g y)<br /><br /><span class="kw">instance</span> <span class="dt">Traversable</span> <span class="dt">Pair</span> <span class="kw">where</span><br />  sequenceA (fa <span class="fu">:#</span> fb) <span class="fu">=</span> (<span class="fu">:#</span>) <span class="fu">&lt;$&gt;</span> fa <span class="fu">&lt;*&gt;</span> fb</code></pre>

</div>

<p>We don&#8217;t really have to figure out how to define scans for every functor separately. We can instead look at how functors are are composed out of their essential building blocks.</p>

<h3 id="scans-for-functor-combinators">Scans for functor combinators</h3>

<p>To see how to scan over a broad range of functors, let&#8217;s look at each of the functor combinators, e.g., as in <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post"><em>Elegant memoization with higher-order types</em></a>.</p>

<h4 id="constant">Constant</h4>

<p>The constant functor is easiest.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">Const</span> x a <span class="fu">=</span> <span class="dt">Const</span> x</code></pre>

<p>There are no values to accumulate, so the final result (fold) is <code>∅</code>.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> (<span class="dt">Const</span> x) <span class="kw">where</span><br />  prefixScan (<span class="dt">Const</span> x) <span class="fu">=</span> (&#8709;, <span class="dt">Const</span> x)<br />  suffixScan           <span class="fu">=</span> prefixScan</code></pre>

<h4 id="identity">Identity</h4>

<p>The identity functor is nearly as easy.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">Id</span> a <span class="fu">=</span> <span class="dt">Id</span> a</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Scan</span> <span class="dt">Id</span> <span class="kw">where</span><br />  prefixScan (<span class="dt">Id</span> m) <span class="fu">=</span> (m, <span class="dt">Id</span> &#8709;)<br />  suffixScan        <span class="fu">=</span> prefixScan</code></pre>

<h4 id="sum">Sum</h4>

<p>Scanning in a sum is just scanning in a summand:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> (f <span class="fu">+</span> g) a <span class="fu">=</span> <span class="dt">InL</span> (f a) <span class="fu">|</span> <span class="dt">InR</span> (g a)</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> (<span class="dt">Scan</span> f, <span class="dt">Scan</span> g) <span class="ot">&#8658;</span> <span class="dt">Scan</span> (f <span class="fu">+</span> g) <span class="kw">where</span><br />  prefixScan (<span class="dt">InL</span> fa) <span class="fu">=</span> second <span class="dt">InL</span> (prefixScan fa)<br />  prefixScan (<span class="dt">InR</span> ga) <span class="fu">=</span> second <span class="dt">InR</span> (prefixScan ga)<br /><br />  suffixScan (<span class="dt">InL</span> fa) <span class="fu">=</span> second <span class="dt">InL</span> (suffixScan fa)<br />  suffixScan (<span class="dt">InR</span> ga) <span class="fu">=</span> second <span class="dt">InR</span> (suffixScan ga)</code></pre>

<p>These definitions correspond to simple &quot;commutative diagram&quot; properties, e.g.,</p>

<pre class="sourceCode"><code class="sourceCode haskell">prefixScan &#8728; <span class="dt">InL</span> &#8801; second <span class="dt">InL</span> &#8728; prefixScan</code></pre>

<h4 id="product">Product</h4>

<p>Product scannning is a little trickier.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> (f &#215; g) a <span class="fu">=</span> f a &#215; g a</code></pre>

<p>Scan each of the two parts separately, and then combine the final (<code>fold</code>) part of one result with each of the non-final elements of the other.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> (<span class="dt">Scan</span> f, <span class="dt">Scan</span> g, <span class="kw">Functor</span> f, <span class="kw">Functor</span> g) <span class="ot">&#8658;</span> <span class="dt">Scan</span> (f &#215; g) <span class="kw">where</span><br />  prefixScan (fa &#215; ga) <span class="fu">=</span> (af &#8853; ag, fa' &#215; ((af &#8853;) <span class="fu">&lt;$&gt;</span> ga'))<br />   <span class="kw">where</span> (af,fa') <span class="fu">=</span> prefixScan fa<br />         (ag,ga') <span class="fu">=</span> prefixScan ga<br /><br />  suffixScan (fa &#215; ga) <span class="fu">=</span> (af &#8853; ag, ((&#8853; ag) <span class="fu">&lt;$&gt;</span> fa') &#215; ga')<br />   <span class="kw">where</span> (af,fa') <span class="fu">=</span> suffixScan fa<br />         (ag,ga') <span class="fu">=</span> suffixScan ga</code></pre>

<h4 id="composition">Composition</h4>

<p>Finally, composition is the trickiest.</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">newtype</span> (g &#8728; f) a <span class="fu">=</span> <span class="dt">O</span> (g (f a))</code></pre>

<p>The target signatures:</p>

<pre class="sourceCode"><code class="sourceCode haskell">  prefixScan, suffixScan <span class="ot">&#8759;</span> <span class="dt">Monoid</span> m <span class="ot">&#8658;</span> (g &#8728; f) m <span class="ot">&#8594;</span> (m, (g &#8728; f) m)</code></pre>

<p>To find the prefix and suffix scan definitions, fiddle with types beginning at the domain type for <code>prefixScan</code> or <code>suffixScan</code> and arriving at the range type.</p>

<p>Some helpers:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">zip</span> <span class="ot">&#8759;</span> <span class="dt">Applicative</span> g <span class="ot">&#8658;</span> (g a, g b) <span class="ot">&#8594;</span> g (a,b)<br /><span class="fu">zip</span> <span class="fu">=</span> <span class="fu">uncurry</span> (liftA2 (,))<br /><br /><span class="fu">unzip</span> <span class="ot">&#8759;</span> <span class="kw">Functor</span> g <span class="ot">&#8658;</span> g (a,b) <span class="ot">&#8594;</span> (g a, g b)<br /><span class="fu">unzip</span> <span class="fu">=</span> <span class="fu">fmap</span> <span class="fu">fst</span> <span class="fu">&amp;&amp;&amp;</span> <span class="fu">fmap</span> <span class="fu">snd</span></code></pre>

<pre class="sourceCode"><code class="sourceCode haskell">assocR <span class="ot">&#8759;</span> ((a,b),c) <span class="ot">&#8594;</span> (a,(b,c))<br />assocR   ((a,b),c) <span class="fu">=</span>  (a,(b,c))</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell">adjustL <span class="ot">&#8759;</span> (<span class="kw">Functor</span> f, <span class="dt">Monoid</span> m) <span class="ot">&#8658;</span> (m, f m) <span class="ot">&#8594;</span> f m<br />adjustL (m, ms) <span class="fu">=</span> (m &#8853;) <span class="fu">&lt;$&gt;</span> ms<br /><br />adjustR <span class="ot">&#8759;</span> (<span class="kw">Functor</span> f, <span class="dt">Monoid</span> m) <span class="ot">&#8658;</span> (m, f m) <span class="ot">&#8594;</span> f m<br />adjustR (m, ms) <span class="fu">=</span> (&#8853; m) <span class="fu">&lt;$&gt;</span> ms</code></pre>

<p>First <code>prefixScan</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">gofm                     <span class="ot">&#8759;</span> (g &#8728; f) m<br />unO                   <span class="ch">''</span> <span class="ot">&#8759;</span> g (f m)<br /><span class="fu">fmap</span> prefixScan       <span class="ch">''</span> <span class="ot">&#8759;</span> g (m, f m)<br /><span class="fu">unzip</span>                 <span class="ch">''</span> <span class="ot">&#8759;</span> (g m, g (f m))<br />first prefixScan      <span class="ch">''</span> <span class="ot">&#8759;</span> ((m, g m), g (f m))<br />assocR                <span class="ch">''</span> <span class="ot">&#8759;</span> (m, (g m, g (f m)))<br />second <span class="fu">zip</span>            <span class="ch">''</span> <span class="ot">&#8759;</span> (m, g (m, f m))<br />second (<span class="fu">fmap</span> adjustL) <span class="ch">''</span> <span class="ot">&#8759;</span> (m, g (f m))<br />second <span class="dt">O</span>              <span class="ch">''</span> <span class="ot">&#8759;</span> (m, (g &#8728; f) m)</code></pre>

<p>Then <code>suffixScan</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">gofm                     <span class="ot">&#8759;</span> (g &#8728; f) m<br />unO                   <span class="ch">''</span> <span class="ot">&#8759;</span> g (f m)<br /><span class="fu">fmap</span> suffixScan       <span class="ch">''</span> <span class="ot">&#8759;</span> g (m, f m)<br /><span class="fu">unzip</span>                 <span class="ch">''</span> <span class="ot">&#8759;</span> (g m, g (f m))<br />first suffixScan      <span class="ch">''</span> <span class="ot">&#8759;</span> ((m, g m), g (f m))<br />assocR                <span class="ch">''</span> <span class="ot">&#8759;</span> (m, (g m, g (f m)))<br />second <span class="fu">zip</span>            <span class="ch">''</span> <span class="ot">&#8759;</span> (m, (g (m, f m)))<br />second (<span class="fu">fmap</span> adjustR) <span class="ch">''</span> <span class="ot">&#8759;</span> (m, (g (f m)))<br />second <span class="dt">O</span>              <span class="ch">''</span> <span class="ot">&#8759;</span> (m, ((g &#8728; f) m))</code></pre>

<p>Putting together the pieces and simplifying just a bit leads to the method definitions:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> (<span class="dt">Scan</span> g, <span class="dt">Scan</span> f, <span class="kw">Functor</span> f, <span class="dt">Applicative</span> g) <span class="ot">&#8658;</span> <span class="dt">Scan</span> (g &#8728; f) <span class="kw">where</span><br />  prefixScan <span class="fu">=</span> second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustL &#8728; <span class="fu">zip</span>)<br />             &#8728; assocR<br />             &#8728; first prefixScan<br />             &#8728; <span class="fu">unzip</span><br />             &#8728; <span class="fu">fmap</span> prefixScan<br />             &#8728; unO<br /><br />  suffixScan <span class="fu">=</span> second (<span class="dt">O</span> &#8728; <span class="fu">fmap</span> adjustR &#8728; <span class="fu">zip</span>)<br />             &#8728; assocR<br />             &#8728; first suffixScan<br />             &#8728; <span class="fu">unzip</span><br />             &#8728; <span class="fu">fmap</span> suffixScan<br />             &#8728; unO</code></pre>

<h3 id="whats-coming-up">What&#8217;s coming up?</h3>

<ul>
<li>What might not easy to spot at this point is that the <code>prefixScan</code> and <code>suffixScan</code> methods given in this post do essentially the same job as in <a href="http://conal.net/blog/posts/deriving-parallel-tree-scans/" title="blog post"><em>Deriving parallel tree scans</em></a>, when the binary tree type is deconstructed into functor combinators. A future post will show this connection.</li>
<li>Switch from standard (right-folded) trees to left-folded trees (in the sense of <a href="http://conal.net/blog/posts/a-trie-for-length-typed-vectors/" title="blog post"><em>A trie for length-typed vectors</em></a> and <a href="http://conal.net/blog/posts/from-tries-to-trees/" title="blog post"><em>From tries to trees</em></a>), which reduces the running time from <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mspace width="0.167em"></mspace><mi>n</mi><mo stretchy="false">)</mo></mrow></math> to <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mo>&#920;</mo><mspace width="0.167em"></mspace><mi>n</mi></mrow></math>.</li>
<li>Scanning in place, i.e., destructively replacing the values in the input structure rather than allocating a new structure.</li>
</ul>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=411&amp;md5=9870e39e2e5552b7c42709138945e306" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/5XBzyl6RDOY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/composable-parallel-scanning/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/composable-parallel-scanning</feedburner:origLink></item>
		<item>
		<title>Deriving parallel tree scans</title>
		<link>http://feedproxy.google.com/~r/conal/~3/XXlDMF9aPLg/deriving-parallel-tree-scans</link>
		<comments>http://conal.net/blog/posts/deriving-parallel-tree-scans#comments</comments>
		<pubDate>Tue, 01 Mar 2011 20:41:09 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[program derivation]]></category>
		<category><![CDATA[scan]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=330</guid>
		<description><![CDATA[The post Deriving list scans explored folds and scans on lists and showed how the usual, efficient scan implementations can be derived from simpler specifications.
Let's see now how to apply the same techniques to scans over trees.
This new post is one of a series leading toward algorithms optimized for execution on massively parallel, consumer ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p>The post <a href="http://conal.net/blog/posts/deriving-list-scans/" title="blog post"><em>Deriving list scans</em></a> explored folds and scans on lists and showed how the usual, efficient scan implementations can be derived from simpler specifications.</p>

<p>Let&#8217;s see now how to apply the same techniques to scans over trees.</p>

<p>This new post is one of a series leading toward algorithms optimized for execution on massively parallel, consumer hardware, using CUDA or OpenCL.</p>

<p><strong>Edits:</strong></p>

<ul>
<li>2011-03-01: Added clarification about &quot;<code>∅</code>&quot; and &quot;<code>(⊕)</code>&quot;.</li>
<li>2011-03-23: corrected &quot;linear-time&quot; to &quot;linear-work&quot; in two places.</li>
</ul>

<p><span id="more-330"></span></p>

<h3 id="trees">Trees</h3>

<p>Our trees will be non-empty and binary:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">data</span> <span class="dt">T</span> a <span class="fu">=</span> <span class="dt">Leaf</span> a <span class="fu">|</span> <span class="dt">Branch</span> (<span class="dt">T</span> a) (<span class="dt">T</span> a)<br /><br /><span class="kw">instance</span> <span class="kw">Show</span> a <span class="ot">&#8658;</span> <span class="kw">Show</span> (<span class="dt">T</span> a) <span class="kw">where</span><br />  <span class="fu">show</span> (<span class="dt">Leaf</span> a)     <span class="fu">=</span> <span class="fu">show</span> a<br />  <span class="fu">show</span> (<span class="dt">Branch</span> s t) <span class="fu">=</span> <span class="st">&quot;(&quot;</span><span class="fu">++</span><span class="fu">show</span> s<span class="fu">++</span><span class="st">&quot;,&quot;</span><span class="fu">++</span><span class="fu">show</span> t<span class="fu">++</span><span class="st">&quot;)&quot;</span></code></pre>

<p>Nothing surprising in the instances:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="kw">Functor</span> <span class="dt">T</span> <span class="kw">where</span><br />  <span class="fu">fmap</span> f (<span class="dt">Leaf</span> a)     <span class="fu">=</span> <span class="dt">Leaf</span> (f a)<br />  <span class="fu">fmap</span> f (<span class="dt">Branch</span> s t) <span class="fu">=</span> <span class="dt">Branch</span> (<span class="fu">fmap</span> f s) (<span class="fu">fmap</span> f t)<br /><br /><span class="kw">instance</span> <span class="dt">Foldable</span> <span class="dt">T</span> <span class="kw">where</span><br />  fold (<span class="dt">Leaf</span> a)     <span class="fu">=</span> a<br />  fold (<span class="dt">Branch</span> s t) <span class="fu">=</span> fold s &#8853; fold t<br /><br /><span class="kw">instance</span> <span class="dt">Traversable</span> <span class="dt">T</span> <span class="kw">where</span><br />  sequenceA (<span class="dt">Leaf</span> a)     <span class="fu">=</span> <span class="fu">fmap</span> <span class="dt">Leaf</span> a<br />  sequenceA (<span class="dt">Branch</span> s t) <span class="fu">=</span><br />    liftA2 <span class="dt">Branch</span> (sequenceA s) (sequenceA t)</code></pre>

<p>BTW, <a href="https://github.com/conal/fix-symbols-gitit/">my type-setting software</a> uses &quot;<code>∅</code>&quot; and &quot;<code>(⊕)</code>&quot; for Haskell&#8217;s &quot;mempty&quot; and &quot;mappend&quot;.</p>

<p>Also handy will be extracting the first and last (i.e., leftmost and rightmost) leaves in a tree:</p>

<pre class="sourceCode"><code class="sourceCode haskell">headT <span class="ot">&#8759;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> a<br />headT (<span class="dt">Leaf</span> a)       <span class="fu">=</span> a<br />headT (s <span class="ot">`Branch`</span> _) <span class="fu">=</span> headT s<br /><br />lastT <span class="ot">&#8759;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> a<br />lastT (<span class="dt">Leaf</span> a)       <span class="fu">=</span> a<br />lastT (_ <span class="ot">`Branch`</span> t) <span class="fu">=</span> lastT t</code></pre>

<div class=exercise>
<p><em>Exercise:</em> Prove that</p>
<pre class="sourceCode"><code class="sourceCode haskell">headT &#8728; <span class="fu">fmap</span> f &#8801; f &#8728; headT<br />lastT &#8728; <span class="fu">fmap</span> f &#8801; f &#8728; lastT</code></pre>
<p>Answer:</p>

<div class=toggle>

<p>Consider the <code>Leaf</code> and <code>Branch</code> cases separately:</p>
<pre class="sourceCode"><code class="sourceCode haskell">  headT (<span class="fu">fmap</span> f (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- fmap on T -}</span><br />  headT (<span class="dt">Leaf</span> (f a))<br />&#8801;  <span class="co">{- headT def -}</span><br />  f a<br />&#8801;  <span class="co">{- headT def -}</span><br />  f (headT (<span class="dt">Leaf</span> a))</code></pre>
<pre class="sourceCode"><code class="sourceCode haskell">  headT (<span class="fu">fmap</span> f (<span class="dt">Branch</span> s t))<br />&#8801;  <span class="co">{- fmap on T -}</span><br />  headT (<span class="dt">Branch</span> (<span class="fu">fmap</span> f s) (<span class="fu">fmap</span> f t))<br />&#8801;  <span class="co">{- headT def -}</span><br />  headT (<span class="fu">fmap</span> f s)<br />&#8801;  <span class="co">{- induction -}</span><br />  f (headT s)<br />&#8801;  <span class="co">{- headT def -}</span><br />  f (headT (<span class="dt">Branch</span> s t))</code></pre>
<p>Similarly for <code>lastT</code>.</p>

</div>
 </div>

<h3 id="from-lists-to-trees-and-back">From lists to trees and back</h3>

<p>We can flatten trees into lists:</p>

<pre class="sourceCode"><code class="sourceCode haskell">flatten <span class="ot">&#8759;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> [a]<br />flatten <span class="fu">=</span> fold &#8728; <span class="fu">fmap</span> (<span class="fu">:</span>[])</code></pre>

<p>Equivalently, using <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Foldable.html#v:foldMap"><code>foldMap</code></a>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">flatten <span class="fu">=</span> foldMap (<span class="fu">:</span>[])</code></pre>

<p>Alternatively, we could define <code>fold</code> via <code>flatten</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Foldable</span> <span class="dt">T</span> <span class="kw">where</span> fold <span class="fu">=</span> fold &#8728; flatten</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell">flatten <span class="ot">&#8759;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> [a]<br />flatten (<span class="dt">Leaf</span> a)     <span class="fu">=</span> [a]<br />flatten (<span class="dt">Branch</span> s t) <span class="fu">=</span> flatten s <span class="fu">++</span> flatten t</code></pre>

<p>We can also &quot;unflatten&quot; lists into balanced trees:</p>

<pre class="sourceCode"><code class="sourceCode haskell">unflatten <span class="ot">&#8759;</span> [a] <span class="ot">&#8594;</span> <span class="dt">T</span> a<br />unflatten []  <span class="fu">=</span> <span class="fu">error</span> <span class="st">&quot;unflatten: Oops! Empty list&quot;</span><br />unflatten [a] <span class="fu">=</span> <span class="dt">Leaf</span> a<br />unflatten xs  <span class="fu">=</span> <span class="dt">Branch</span> (unflatten prefix) (unflatten suffix)<br /> <span class="kw">where</span><br />   (prefix,suffix) <span class="fu">=</span> <span class="fu">splitAt</span> (<span class="fu">length</span> xs <span class="ot">`div`</span> <span class="dv">2</span>) xs</code></pre>

<p>Both <code>flatten</code> and <code>unflatten</code> can be implemented more efficiently.</p>

<p>For instance,</p>

<pre class="sourceCode"><code class="sourceCode haskell">t1,t2 <span class="ot">&#8759;</span> <span class="dt">T</span> <span class="dt">Int</span><br />t1 <span class="fu">=</span> unflatten [<span class="dv">1</span><span class="fu">&#8229;</span><span class="dv">3</span>]<br />t2 <span class="fu">=</span> unflatten [<span class="dv">1</span><span class="fu">&#8229;</span><span class="dv">16</span>]</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> t1<br />(<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> t2<br />((((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">3</span>,<span class="dv">4</span>)),((<span class="dv">5</span>,<span class="dv">6</span>),(<span class="dv">7</span>,<span class="dv">8</span>))),(((<span class="dv">9</span>,<span class="dv">10</span>),(<span class="dv">11</span>,<span class="dv">12</span>)),((<span class="dv">13</span>,<span class="dv">14</span>),(<span class="dv">15</span>,<span class="dv">16</span>))))</code></pre>

<h3 id="specifying-tree-scans">Specifying tree scans</h3>

<h4 id="prefixes-and-suffixes">Prefixes and suffixes</h4>

<p>The post <a href="http://conal.net/blog/posts/deriving-list-scans/" title="blog post"><em>Deriving list scans</em></a> gave specifications for list scanning in terms of <code>inits</code> and <code>tails</code>. One consequence of this specification is that the output of scanning has one more element than the input. Alternatively, we could use non-empty variants of <code>inits</code> and <code>tails</code>, so that the input &amp; output are in one-to-one correspondence.</p>

<pre class="sourceCode"><code class="sourceCode haskell">inits' <span class="ot">&#8759;</span> [a] <span class="ot">&#8594;</span> [[a]]<br />inits' []     <span class="fu">=</span> []<br />inits' (x<span class="fu">:</span>xs) <span class="fu">=</span> <span class="fu">map</span> (x<span class="fu">:</span>) ([] <span class="fu">:</span> inits' xs)</code></pre>

<p>The cons case can also be written as</p>

<pre class="sourceCode"><code class="sourceCode haskell">inits' (x<span class="fu">:</span>xs) <span class="fu">=</span> [x] <span class="fu">:</span> <span class="fu">map</span> (x<span class="fu">:</span>) (inits' xs)</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell">tails' <span class="ot">&#8759;</span> [a] <span class="ot">&#8594;</span> [[a]]<br />tails' []         <span class="fu">=</span> []<br />tails' xs<span class="fu">@</span>(_<span class="fu">:</span>xs') <span class="fu">=</span> xs <span class="fu">:</span> tails' xs'</code></pre>

<p>For instance,</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> inits' <span class="st">&quot;abcd&quot;</span><br />[<span class="st">&quot;a&quot;</span>,<span class="st">&quot;ab&quot;</span>,<span class="st">&quot;abc&quot;</span>,<span class="st">&quot;abcd&quot;</span>]<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> tails' <span class="st">&quot;abcd&quot;</span><br />[<span class="st">&quot;abcd&quot;</span>,<span class="st">&quot;bcd&quot;</span>,<span class="st">&quot;cd&quot;</span>,<span class="st">&quot;d&quot;</span>]</code></pre>

<p>Our tree functor has a symmetric definition, so we get more symmetry in the counterparts to <code>inits'</code> and <code>tails'</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell">initTs <span class="ot">&#8759;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> <span class="dt">T</span> (<span class="dt">T</span> a)<br />initTs (<span class="dt">Leaf</span> a)       <span class="fu">=</span> <span class="dt">Leaf</span> (<span class="dt">Leaf</span> a)<br />initTs (s <span class="ot">`Branch`</span> t) <span class="fu">=</span><br />  <span class="dt">Branch</span> (initTs s) (<span class="fu">fmap</span> (s <span class="ot">`Branch`</span>) (initTs t))<br /><br />tailTs <span class="ot">&#8759;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> <span class="dt">T</span> (<span class="dt">T</span> a)<br />tailTs (<span class="dt">Leaf</span> a)       <span class="fu">=</span> <span class="dt">Leaf</span> (<span class="dt">Leaf</span> a)<br />tailTs (s <span class="ot">`Branch`</span> t) <span class="fu">=</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (<span class="ot">`Branch`</span> t) (tailTs s)) (tailTs t)</code></pre>

<p>Try it:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> t1<br />(<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> initTs t1<br />(<span class="dv">1</span>,((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>))))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> tailTs t1<br />((<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>)),((<span class="dv">2</span>,<span class="dv">3</span>),<span class="dv">3</span>))<br /><br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> unflatten [<span class="dv">1</span><span class="fu">&#8229;</span><span class="dv">5</span>]<br />((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">3</span>,(<span class="dv">4</span>,<span class="dv">5</span>)))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> initTs (unflatten [<span class="dv">1</span><span class="fu">&#8229;</span><span class="dv">5</span>])<br />((<span class="dv">1</span>,(<span class="dv">1</span>,<span class="dv">2</span>)),(((<span class="dv">1</span>,<span class="dv">2</span>),<span class="dv">3</span>),(((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">3</span>,<span class="dv">4</span>)),((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">3</span>,(<span class="dv">4</span>,<span class="dv">5</span>))))))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> tailTs (unflatten [<span class="dv">1</span><span class="fu">&#8229;</span><span class="dv">5</span>])<br />((((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">3</span>,(<span class="dv">4</span>,<span class="dv">5</span>))),(<span class="dv">2</span>,(<span class="dv">3</span>,(<span class="dv">4</span>,<span class="dv">5</span>)))),((<span class="dv">3</span>,(<span class="dv">4</span>,<span class="dv">5</span>)),((<span class="dv">4</span>,<span class="dv">5</span>),<span class="dv">5</span>)))</code></pre>

<div class=exercise>
<p><em>Exercise:</em> Prove that</p>
<pre class="sourceCode"><code class="sourceCode haskell">lastT &#8728; initTs &#8801; <span class="fu">id</span><br />headT &#8728; tailTs &#8801; <span class="fu">id</span></code></pre>
<p>Answer:</p>

<div class=toggle>

<pre class="sourceCode"><code class="sourceCode haskell">  lastT (initTs (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- initTs def -}</span><br />  lastT (<span class="dt">Leaf</span> (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- lastT def -}</span><br />  <span class="dt">Leaf</span> a<br /><br />  lastT (initTs (s <span class="ot">`Branch`</span> t))<br />&#8801;  <span class="co">{- initTs def -}</span><br />  lastT (<span class="dt">Branch</span> (&#8943;) (<span class="fu">fmap</span> (s <span class="ot">`Branch`</span>) (initTs t)))<br />&#8801;  <span class="co">{- lastT def -}</span><br />  lastT (<span class="fu">fmap</span> (s <span class="ot">`Branch`</span>) (initTs t))<br />&#8801;  <span class="co">{- lastT &#8728; fmap f -}</span><br />  (s <span class="ot">`Branch`</span>) (lastT (initTs t))<br />&#8801;  <span class="co">{- trivial -}</span><br />  s <span class="ot">`Branch`</span> lastT (initTs t)<br />&#8801;  <span class="co">{- induction -}</span><br />  s <span class="ot">`Branch`</span> t</code></pre>

</div>
 </div>

<h4 id="scan-specification">Scan specification</h4>

<p>Now we can specify prefix &amp; suffix scanning:</p>

<pre class="sourceCode"><code class="sourceCode haskell">scanlT, scanrT <span class="ot">&#8759;</span> <span class="dt">Monoid</span> a <span class="ot">&#8658;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> <span class="dt">T</span> a<br />scanlT <span class="fu">=</span> <span class="fu">fmap</span> fold &#8728; initTs<br />scanrT <span class="fu">=</span> <span class="fu">fmap</span> fold &#8728; tailTs</code></pre>

<p>Try it out:</p>

<pre class="sourceCode"><code class="sourceCode haskell">t3 <span class="ot">&#8759;</span> <span class="dt">T</span> <span class="dt">String</span><br />t3 <span class="fu">=</span> <span class="fu">fmap</span> (<span class="fu">:</span>[]) (unflatten <span class="st">&quot;abcde&quot;</span>)</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> t3<br />((<span class="st">&quot;a&quot;</span>,<span class="st">&quot;b&quot;</span>),(<span class="st">&quot;c&quot;</span>,(<span class="st">&quot;d&quot;</span>,<span class="st">&quot;e&quot;</span>)))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> scanlT t3<br />((<span class="st">&quot;a&quot;</span>,<span class="st">&quot;ab&quot;</span>),(<span class="st">&quot;abc&quot;</span>,(<span class="st">&quot;abcd&quot;</span>,<span class="st">&quot;abcde&quot;</span>)))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> scanrT t3<br />((<span class="st">&quot;abcde&quot;</span>,<span class="st">&quot;bcde&quot;</span>),(<span class="st">&quot;cde&quot;</span>,(<span class="st">&quot;de&quot;</span>,<span class="st">&quot;e&quot;</span>)))</code></pre>

<p>To test on numbers, I&#8217;ll use a <a href="http://matt.immute.net/content/pointless-fun" title="blog post by Matt Hellige">handy notation from Matt Hellige</a> to add pre- and post-processing:</p>

<pre class="sourceCode"><code class="sourceCode haskell">(&#8605;) <span class="ot">&#8759;</span> (a' <span class="ot">&#8594;</span> a) <span class="ot">&#8594;</span> (b <span class="ot">&#8594;</span> b') <span class="ot">&#8594;</span> ((a <span class="ot">&#8594;</span> b) <span class="ot">&#8594;</span> (a' <span class="ot">&#8594;</span> b'))<br />(f &#8605; h) g <span class="fu">=</span> h &#8728; g &#8728; f</code></pre>

<p>And a version specialized to functors:</p>

<pre class="sourceCode"><code class="sourceCode haskell">(&#8605;<span class="fu">*</span>) <span class="ot">&#8759;</span> <span class="kw">Functor</span> f <span class="ot">&#8658;</span> (a' <span class="ot">&#8594;</span> a) <span class="ot">&#8594;</span> (b <span class="ot">&#8594;</span> b')<br />     <span class="ot">&#8594;</span> (f a <span class="ot">&#8594;</span> f b) <span class="ot">&#8594;</span> (f a' <span class="ot">&#8594;</span> f b')<br />f &#8605;<span class="fu">*</span> g <span class="fu">=</span> <span class="fu">fmap</span> f &#8605; <span class="fu">fmap</span> g</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell">t4 <span class="ot">&#8759;</span> <span class="dt">T</span> <span class="dt">Integer</span><br />t4 <span class="fu">=</span> unflatten [<span class="dv">1</span><span class="fu">&#8229;</span><span class="dv">6</span>]<br /><br />t5 <span class="ot">&#8759;</span> <span class="dt">T</span> <span class="dt">Integer</span><br />t5 <span class="fu">=</span> (<span class="dt">Sum</span> &#8605;<span class="fu">*</span> getSum) scanlT t4</code></pre>

<p>Try it:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> t4<br />((<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>)),(<span class="dv">4</span>,(<span class="dv">5</span>,<span class="dv">6</span>)))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> initTs t4<br />((<span class="dv">1</span>,((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>)))),(((<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>)),<span class="dv">4</span>),(((<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>)),(<span class="dv">4</span>,<span class="dv">5</span>)),((<span class="dv">1</span>,(<span class="dv">2</span>,<span class="dv">3</span>)),(<span class="dv">4</span>,(<span class="dv">5</span>,<span class="dv">6</span>))))))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> t5<br />((<span class="dv">1</span>,(<span class="dv">3</span>,<span class="dv">6</span>)),(<span class="dv">10</span>,(<span class="dv">15</span>,<span class="dv">21</span>)))</code></pre>

<div class=exercise>
<p><em>Exercise</em>: Prove that we have properties similar to the ones relating <code>fold</code>, <code>scanlT</code>, and <code>scanrT</code> on list:</p>
<pre class="sourceCode"><code class="sourceCode haskell">fold &#8801; lastT &#8728; scanlT<br />fold &#8801; headT &#8728; scanrT</code></pre>
<p>Answer:</p>

<div class=toggle>

<pre class="sourceCode"><code class="sourceCode haskell">  lastT &#8728; scanlT<br />&#8801;  <span class="co">{- scanlT spec -}</span><br />  lastT &#8728; <span class="fu">fmap</span> fold &#8728; initTs<br />&#8801;  <span class="co">{- lastT &#8728; fmap f -}</span><br />  fold &#8728; lastT &#8728; initTs<br />&#8801;  <span class="co">{- lastT &#8728; initTs -}</span><br />  fold<br /><br />  headT &#8728; scanrT <br />&#8801;  <span class="co">{- scanrT def -}</span><br />  headT &#8728; <span class="fu">fmap</span> fold &#8728; tailTs<br />&#8801;  <span class="co">{- headT &#8728; fmap f -}</span><br />  fold &#8728; headT &#8728; tailTs<br />&#8801;  <span class="co">{- headT &#8728; tailTs -}</span><br />  fold</code></pre>

</div>

<p>For instance,</p>
<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> fold t3<br /><span class="st">&quot;abcde&quot;</span><br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> (lastT &#8728; scanlT) t3<br /><span class="st">&quot;abcde&quot;</span><br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> (headT &#8728; scanrT) t3<br /><span class="st">&quot;abcde&quot;</span></code></pre>

</div>

<h3 id="deriving-faster-scans">Deriving faster scans</h3>

<p>Recall the specifications:</p>

<pre class="sourceCode"><code class="sourceCode haskell">scanlT <span class="fu">=</span> <span class="fu">fmap</span> fold &#8728; initTs<br />scanrT <span class="fu">=</span> <span class="fu">fmap</span> fold &#8728; tailTs</code></pre>

<p>To derive more efficient implementations, proceed as in <a href="http://conal.net/blog/posts/deriving-list-scans/" title="blog post"><em>Deriving list scans</em></a>. Start with prefix scan (<code>scanlT</code>), and consider the <code>Leaf</code> and <code>Branch</code> cases separately.</p>

<pre class="sourceCode"><code class="sourceCode haskell">  scanlT (<span class="dt">Leaf</span> a)<br />&#8801;  <span class="co">{- scanlT spec -}</span><br />  <span class="fu">fmap</span> fold (initTs (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- initTs def -}</span><br />  <span class="fu">fmap</span> fold (<span class="dt">Leaf</span> (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- fmap def -}</span><br />  <span class="dt">Leaf</span> (fold (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- fold def -}</span><br />  <span class="dt">Leaf</span> a<br /><br />  scanlT (s <span class="ot">`Branch`</span> t)<br />&#8801;  <span class="co">{- scanlT spec -}</span><br />  <span class="fu">fmap</span> fold (initTs (s <span class="ot">`Branch`</span> t))<br />&#8801;  <span class="co">{- initTs def -}</span><br />  <span class="fu">fmap</span> fold (<span class="dt">Branch</span> (initTs s) (<span class="fu">fmap</span> (s <span class="ot">`Branch`</span>) (initTs t)))<br />&#8801;  <span class="co">{- fmap def -}</span><br />   <span class="dt">Branch</span> (<span class="fu">fmap</span> fold (initTs s)) (<span class="fu">fmap</span> fold (<span class="fu">fmap</span> (s <span class="ot">`Branch`</span>) (initTs t)))<br />&#8801;  <span class="co">{- scanlT spec -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> fold (<span class="fu">fmap</span> (s <span class="ot">`Branch`</span>) (initTs t)))<br />&#8801;  <span class="co">{- functor law -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> (fold &#8728; (s <span class="ot">`Branch`</span>)) (initTs t))<br />&#8801;  <span class="co">{- rework as &#955; -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> (&#955; t' <span class="ot">&#8594;</span> fold (s <span class="ot">`Branch`</span> t')) (initTs t))<br />&#8801;  <span class="co">{- fold def -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> (&#955; t' <span class="ot">&#8594;</span> fold s &#8853; fold t')) (initTs t))<br />&#8801;  <span class="co">{- rework &#955; -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> ((fold s &#8853;) &#8728; fold) (initTs t))<br />&#8801;  <span class="co">{- functor law -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> (fold s &#8853;) (<span class="fu">fmap</span> fold (initTs t)))<br />&#8801;  <span class="co">{- scanlT spec -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> (fold s &#8853;) (scanlT t))<br />&#8801;  <span class="co">{- lastT &#8728; scanlT &#8801; fold -}</span><br />  <span class="dt">Branch</span> (scanlT s) (<span class="fu">fmap</span> (lastT (scanlT s) &#8853;) (scanlT t))<br />&#8801;  <span class="co">{- factor out defs -}</span><br />  <span class="dt">Branch</span> s' (<span class="fu">fmap</span> (lastT s' &#8853;) t')<br />     <span class="kw">where</span> s' <span class="fu">=</span> scanlT s<br />           t' <span class="fu">=</span> scanlT t</code></pre>

<p>Suffix scan has a similar derivation.</p>

<div class=toggle>

<pre class="sourceCode"><code class="sourceCode haskell">  scanrT (<span class="dt">Leaf</span> a)<br />&#8801;  <span class="co">{- scanrT def -}</span><br />  <span class="fu">fmap</span> fold (tailTs (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- tailTs def -}</span><br />  <span class="fu">fmap</span> fold (<span class="dt">Leaf</span> (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- fmap on T -}</span><br />  <span class="dt">Leaf</span> (fold (<span class="dt">Leaf</span> a))<br />&#8801;  <span class="co">{- fold def -}</span><br />  <span class="dt">Leaf</span> a<br /><br />  scanrT (s <span class="ot">`Branch`</span> t)<br />&#8801;  <span class="co">{- scanrT spec -}</span><br />  <span class="fu">fmap</span> fold (tailTs (s <span class="ot">`Branch`</span> t))<br />&#8801;  <span class="co">{- tailTs def -}</span><br />  <span class="fu">fmap</span> fold (<span class="dt">Branch</span> (<span class="fu">fmap</span> (<span class="ot">`Branch`</span> t) (tailTs s)) (tailTs t))<br />&#8801;  <span class="co">{- fmap def -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> fold (<span class="fu">fmap</span> (<span class="ot">`Branch`</span> t) (tailTs s))) (<span class="fu">fmap</span> fold (tailTs t))<br />&#8801;  <span class="co">{- scanrT spec -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> fold (<span class="fu">fmap</span> (<span class="ot">`Branch`</span> t) (tailTs s))) (scanrT t)<br />&#8801;  <span class="co">{- functor law -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (fold &#8728; (<span class="ot">`Branch`</span> t)) (tailTs s)) (scanrT t)<br />&#8801;  <span class="co">{- rework as &#955; -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (&#955; s' <span class="ot">&#8594;</span> fold (s' <span class="ot">`Branch`</span> t)) (tailTs s)) (scanrT t)<br />&#8801;  <span class="co">{- functor law -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (&#955; s' <span class="ot">&#8594;</span> fold s' &#8853; fold t) (tailTs s)) (scanrT t)<br />&#8801;  <span class="co">{- rework &#955; -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> ((&#8853; fold t) &#8728; fold) (tailTs s)) (scanrT t)<br />&#8801;  <span class="co">{- scanrT spec -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (&#8853; fold t) (scanrT s)) (scanrT t)<br />&#8801;  <span class="co">{- headT &#8728; scanrT -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (&#8853; headT (scanrT t)) (scanrT s)) (scanrT t)<br />&#8801;  <span class="co">{- factor out defs -}</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (&#8853; headT t') s') t'<br />    <span class="kw">where</span> s' <span class="fu">=</span> scanrT s<br />          t' <span class="fu">=</span> scanrT t</code></pre>

</div>

<p>Extract code from these derivations:</p>

<pre class="sourceCode"><code class="sourceCode haskell">scanlT' <span class="ot">&#8759;</span> <span class="dt">Monoid</span> a <span class="ot">&#8658;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> <span class="dt">T</span> a<br />scanlT' (<span class="dt">Leaf</span> a)       <span class="fu">=</span> <span class="dt">Leaf</span> a<br />scanlT' (s <span class="ot">`Branch`</span> t) <span class="fu">=</span><br />  <span class="dt">Branch</span> s' (<span class="fu">fmap</span> (lastT s' &#8853;) t')<br />     <span class="kw">where</span> s' <span class="fu">=</span> scanlT' s<br />           t' <span class="fu">=</span> scanlT' t<br /><br />scanrT' <span class="ot">&#8759;</span> <span class="dt">Monoid</span> a <span class="ot">&#8658;</span> <span class="dt">T</span> a <span class="ot">&#8594;</span> <span class="dt">T</span> a<br />scanrT' (<span class="dt">Leaf</span> a)       <span class="fu">=</span> <span class="dt">Leaf</span> a<br />scanrT' (s <span class="ot">`Branch`</span> t) <span class="fu">=</span><br />  <span class="dt">Branch</span> (<span class="fu">fmap</span> (&#8853; headT t') s') t'<br />    <span class="kw">where</span> s' <span class="fu">=</span> scanrT' s<br />          t' <span class="fu">=</span> scanrT' t</code></pre>

<p>Try it:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> t3<br />((<span class="st">&quot;a&quot;</span>,<span class="st">&quot;b&quot;</span>),(<span class="st">&quot;c&quot;</span>,(<span class="st">&quot;d&quot;</span>,<span class="st">&quot;e&quot;</span>)))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> scanlT' t3<br />((<span class="st">&quot;a&quot;</span>,<span class="st">&quot;ab&quot;</span>),(<span class="st">&quot;abc&quot;</span>,(<span class="st">&quot;abcd&quot;</span>,<span class="st">&quot;abcde&quot;</span>)))<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> scanrT' t3<br />((<span class="st">&quot;abcde&quot;</span>,<span class="st">&quot;bcde&quot;</span>),(<span class="st">&quot;cde&quot;</span>,(<span class="st">&quot;de&quot;</span>,<span class="st">&quot;e&quot;</span>)))</code></pre>

<h3 id="efficiency">Efficiency</h3>

<p>Although I was just following my nose, without trying to get anywhere in particular, this result is exactly the algorithm I first thought of when considering how to parallelize tree scanning.</p>

<p>Let&#8217;s now consider the running time of this algorithm. Assume that the tree is <em>balanced</em>, to maximize parallelism. (I think balancing is optimal for parallelism here, but I&#8217;m not certain.)</p>

<p>For a tree with <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi></mrow></math> leaves, the work <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>W</mi><mspace width="0.167em"></mspace><mi>n</mi></mrow></math> will be constant when <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>=</mo><mn>1</mn></mrow></math> and <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mn>2</mn><mo>&#8901;</mo><mi>W</mi><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>n</mi><mo>/</mo><mn>2</mn><mo stretchy="false">)</mo><mo>+</mo><mi>n</mi></mrow></math> when <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mo>&gt;</mo><mn>1</mn></mrow></math>. Using <a href="http://en.wikipedia.org/wiki/Master_theorem#Case_2">the <em>Master Theorem</em></a> (explained more <a href="http://www.math.dartmouth.edu/archive/m19w03/public_html/Section5-2.pdf">here</a>), <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>W</mi><mspace width="0.167em"></mspace><mi>n</mi><mo>=</mo><mo>&#920;</mo><mspace width="0.167em"></mspace><mo stretchy="false">(</mo><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mi>n</mi><mo stretchy="false">)</mo></mrow></math>.</p>

<p>This result is disappointing, since scanning can be done with linear work by threading a single accumulator while traversing the input tree and building up the output tree.</p>

<p>I&#8217;m using the term &quot;work&quot; instead of &quot;time&quot; here, since I&#8217;m not assuming sequential execution.</p>

<p>We have a parallel algorithm that performs <math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>n</mi><mspace width="0.167em"></mspace><mi>log</mi><mspace width="0.167em"></mspace><mi>n</mi></mrow></math> work, and a sequential program that performs linear work. Can we construct a linear-parallel algorithm?</p>

<p>Yes. Guy Blelloch came up with a clever linear-work parallel algorithm, which I&#8217;ll derive in another post.</p>

<h3 id="generalizing-head-and-last">Generalizing <code>head</code> and <code>last</code></h3>

<p>Can we replace the ad hoc (tree-specific) <code>headT</code> and <code>lastT</code> functions with general versions that work on all foldables? I&#8217;d want the generalization to also generalize the list functions <code>head</code> and <code>last</code> or, rather, to <em>total</em> variants (ones that cannot error due to empty list). For totality, provide a default value for when there are no elements.</p>

<pre class="sourceCode"><code class="sourceCode haskell">headF, lastF <span class="ot">&#8759;</span> <span class="dt">Foldable</span> f <span class="ot">&#8658;</span> a <span class="ot">&#8594;</span> f a <span class="ot">&#8594;</span> a</code></pre>

<p>I also want these functions to be as efficient on lists as <code>head</code> and <code>last</code> and as efficient on trees as <code>headT</code> and <code>lastT</code>.</p>

<p>The <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Monoid.html#v:First"><code>First</code></a> and <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Monoid.html#v:Last"><code>Last</code></a> monoids provide left-biased and right-biased choice. They&#8217;re implemented as <code>newtype</code> wrappers around <code>Maybe</code>:</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">First</span> a <span class="fu">=</span> <span class="dt">First</span> { getFirst <span class="ot">&#8759;</span> <span class="dt">Maybe</span> a }<br /><br /><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">First</span> a) <span class="kw">where</span><br />  &#8709; <span class="fu">=</span> <span class="dt">First</span> <span class="kw">Nothing</span><br />  r<span class="fu">@</span>(<span class="dt">First</span> (<span class="kw">Just</span> _)) &#8853; _ <span class="fu">=</span> r<br />  <span class="dt">First</span> <span class="kw">Nothing</span>      &#8853; r <span class="fu">=</span> r</code></pre>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="kw">newtype</span> <span class="dt">Last</span> a <span class="fu">=</span> <span class="dt">Last</span> { getLast <span class="ot">&#8759;</span> <span class="dt">Maybe</span> a }<br /><br /><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">Last</span> a) <span class="kw">where</span><br />  &#8709; <span class="fu">=</span> <span class="dt">Last</span> <span class="kw">Nothing</span><br />  _ &#8853; r<span class="fu">@</span>(<span class="dt">Last</span> (<span class="kw">Just</span> _)) <span class="fu">=</span> r<br />  r &#8853; <span class="dt">Last</span> <span class="kw">Nothing</span>      <span class="fu">=</span> r</code></pre>

<p>For <code>headF</code>, embed all of the elements into the <code>First</code> monoid (via <code>First ∘ Just</code>), fold over the result, and extract the result, using the provided default value in case there are no elements. Similarly for <code>lastF</code>.</p>

<pre class="sourceCode"><code class="sourceCode haskell">headF dflt <span class="fu">=</span> fromMaybe dflt &#8728; getFirst &#8728; foldMap (<span class="dt">First</span> &#8728; <span class="kw">Just</span>)<br />lastF dflt <span class="fu">=</span> fromMaybe dflt &#8728; getLast  &#8728; foldMap (<span class="dt">Last</span>  &#8728; <span class="kw">Just</span>)</code></pre>

<p>For instance,</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> headF <span class="dv">3</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">4</span>,<span class="dv">8</span>]<br /><span class="dv">1</span><br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> headF <span class="dv">3</span> []<br /><span class="dv">3</span></code></pre>

<p>When our elements belong to a monoid, we can use <code>∅</code> as the default:</p>

<pre class="sourceCode"><code class="sourceCode haskell">headFM <span class="ot">&#8759;</span> (<span class="dt">Foldable</span> f, <span class="dt">Monoid</span> m) <span class="ot">&#8658;</span> f m <span class="ot">&#8594;</span> m<br />headFM <span class="fu">=</span> headF &#8709;<br /><br />lastFM <span class="ot">&#8759;</span> (<span class="dt">Foldable</span> f, <span class="dt">Monoid</span> m) <span class="ot">&#8658;</span> f m <span class="ot">&#8594;</span> m<br />lastFM <span class="fu">=</span> headF &#8709;</code></pre>

<p>For instance,</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> lastFM ([] <span class="ot">&#8759;</span> [<span class="dt">String</span>])<br /><span class="st">&quot;&quot;</span></code></pre>

<p>Using <code>headFM</code> and <code>lastFM</code> in place of <code>headT</code> and <code>lastT</code>, we can easily handle addition of an <code>Empty</code> case to our tree functor in this post. The key choice is that <code>fold Empty ≡ ∅</code> and <code>fmap _ Empty ≡ Empty</code>. Then <code>headFM</code> will choose the first <em>leaf</em>, and <code>lastT</code></p>

<p>What about efficiency? Because <code>headF</code> and <code>lastF</code> are defined via <code>foldMap</code>, which is a composition of <code>fold</code> and <code>fmap</code>, one might think that we have to traverse the entire structure when used with functors like <code>[]</code> or <code>T</code>.</p>

<p>Laziness saves us, however, and we can even extract the head of an infinite list or a partially defined one. For instance,</p>

<pre class="sourceCode"><code class="sourceCode haskell">  foldMap (<span class="dt">First</span> &#8728; <span class="kw">Just</span>) [<span class="dv">5</span> <span class="fu">&#8229;</span>]<br />&#8801; foldMap (<span class="dt">First</span> &#8728; <span class="kw">Just</span>) (<span class="dv">5</span> <span class="fu">:</span> [<span class="dv">6</span> <span class="fu">&#8229;</span>])<br />&#8801; <span class="dt">First</span> (<span class="kw">Just</span> <span class="dv">5</span>) &#8853; foldMap (<span class="dt">First</span> &#8728; <span class="kw">Just</span>) [<span class="dv">6</span> <span class="fu">&#8229;</span>]<br />&#8801; <span class="dt">First</span> (<span class="kw">Just</span> <span class="dv">5</span>)</code></pre>

<p>So</p>

<pre class="sourceCode"><code class="sourceCode haskell">  headF d [<span class="dv">5</span> <span class="fu">&#8229;</span>]<br />&#8801; fromMaybe d (getFirst (foldMap (<span class="dt">First</span> &#8728; <span class="kw">Just</span>) [<span class="dv">5</span> <span class="fu">&#8229;</span>]))<br />&#8801; fromMaybe d (getFirst (<span class="dt">First</span> (<span class="kw">Just</span> <span class="dv">5</span>)))<br />&#8801; fromMaybe d (<span class="kw">Just</span> <span class="dv">5</span>)<br />&#8801; <span class="dv">5</span></code></pre>

<p>And, sure enough,</p>

<pre class="sourceCode"><code class="sourceCode haskell"><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> foldMap (<span class="dt">First</span> &#8728; <span class="kw">Just</span>) [<span class="dv">5</span> <span class="fu">&#8229;</span>]<br /><span class="dt">First</span> {getFirst <span class="fu">=</span> <span class="kw">Just</span> <span class="dv">5</span>}<br /><span class="fu">*</span><span class="dt">T</span><span class="fu">&gt;</span> headF &#8869; [<span class="dv">5</span> <span class="fu">&#8229;</span>]<br /><span class="dv">5</span></code></pre>

<h3 id="where-to-go-from-here">Where to go from here?</h3>

<ul>
<li>As mentioned above, the derived scanning implementations perform asymtotically more work than necessary. Future posts explore how to derive parallel-friendly, linear-work algorithms. Then we&#8217;ll see how to transform the parallel-friendly algorithms so that they work <em>destructively</em>, overwriting their input as they go, and hence suitably for execution entirely in CUDA or OpenCL.</li>
<li>The functions <code>initTs</code> and <code>tailTs</code> are still tree-specific. To generalize the specification and derivation of list and tree scanning, find a way to generalize these two functions. The types of <code>initTs</code> and <code>tailTs</code> fit with the <a href="http://hackage.haskell.org/packages/archive/comonad/1.0.1/doc/html/Data-Functor-Extend.html#v:duplicate"><code>duplicate</code></a> method on comonads. Moreover, <code>tails</code> is the usual definition of <code>duplicate</code> on lists, and I think <code>inits</code> would be <code>extend</code> for &quot;snoc lists&quot;. For trees, however, I don&#8217;t think the correspondence holds. Am I missing something?</li>
<li>In particular, I want to extend the derivation to depth-typed, perfectly balanced trees, of the sort I played with in <a href="http://conal.net/blog/posts/a-trie-for-length-typed-vectors/" title="blog post"><em>A trie for length-typed vectors</em></a> and <a href="http://conal.net/blog/posts/from-tries-to-trees/" title="blog post"><em>From tries to trees</em></a>. The functions <code>initTs</code> and <code>tailTs</code> make unbalanced trees out of balanced ones, so I don&#8217;t know how to adapt the specifications given here to the setting of depth-typed balanced trees. Maybe I could just fill up the to-be-ignored elements with <code>∅</code>.</li>
</ul>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=330&amp;md5=0fc7825e5d47f397d7ee6f3f19c7c416" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/XXlDMF9aPLg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/deriving-parallel-tree-scans/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/deriving-parallel-tree-scans</feedburner:origLink></item>
		<item>
		<title>Deriving list scans</title>
		<link>http://feedproxy.google.com/~r/conal/~3/2xgwjTM77JU/deriving-list-scans</link>
		<comments>http://conal.net/blog/posts/deriving-list-scans#comments</comments>
		<pubDate>Tue, 22 Feb 2011 20:42:40 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[fold]]></category>
		<category><![CDATA[program derivation]]></category>
		<category><![CDATA[scan]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=341</guid>
		<description><![CDATA[I've been playing with deriving efficient parallel, imperative implementations of &#34;prefix sum&#34; or more generally &#34;left scan&#34;. Following posts will explore the parallel &#38; imperative derivations, but as a warm-up, I'll tackle the functional &#38; sequential case here.FoldsYou're probably familiar with the higher-order functions for left and right &#34;fold&#34;. The current documentation says:
foldl, applied ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p
>I&#8217;ve been playing with deriving efficient parallel, imperative implementations of &quot;prefix sum&quot; or more generally &quot;left scan&quot;. Following posts will explore the parallel &amp; imperative derivations, but as a warm-up, I&#8217;ll tackle the functional &amp; sequential case here.</p
>

<div id="folds"
><h3
  >Folds</h3
  ><p
  >You&#8217;re probably familiar with the higher-order functions for left and right &quot;fold&quot;. The current documentation says:</p
  ><blockquote>
<p
  ><a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:foldl"
    ><code
      >foldl</code
      ></a
    >, applied to a binary operator, a starting value (typically the left-identity of the operator), and a list, reduces the list using the binary operator, from left to right:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >foldl</span
      > f z [x1, x2, &#8943;, xn] &#8801; (&#8943;((z <span class="ot"
      >`f`</span
      > x1) <span class="ot"
      >`f`</span
      > x2) <span class="ot"
      >`f`</span
      >&#8943;) <span class="ot"
      >`f`</span
      > xn<br
       /></code
    ></pre
  ><p
  >The list must be finite.</p
  ><p
  ><a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:foldr"
    ><code
      >foldr</code
      ></a
    >, applied to a binary operator, a starting value (typically the right-identity of the operator), and a list, reduces the list using the binary operator, from right to left:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >foldr</span
      > f z [x1, x2, &#8943;, xn] &#8801; x1 <span class="ot"
      >`f`</span
      > (x2 <span class="ot"
      >`f`</span
      > &#8943; (xn <span class="ot"
      >`f`</span
      > z)&#8943;)<br
       /></code
    ></pre
  ></blockquote>
<p
  >And here are typical definitions:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >foldl</span
      > <span class="dv"
      >&#8759;</span
      > (b &#8594; a &#8594; b) &#8594; b &#8594; [a] &#8594; b<br
       /><span class="fu"
      >foldl</span
      > f z []     <span class="fu"
      >=</span
      > z<br
       /><span class="fu"
      >foldl</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > <span class="fu"
      >foldl</span
      > f (z <span class="ot"
      >`f`</span
      > x) xs<br
       /><br
       /><span class="fu"
      >foldr</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; b) &#8594; b &#8594; [a] &#8594; b<br
       /><span class="fu"
      >foldr</span
      > f z []     <span class="fu"
      >=</span
      > z<br
       /><span class="fu"
      >foldr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > x <span class="ot"
      >`f`</span
      > <span class="fu"
      >foldr</span
      > f z xs<br
       /></code
    ></pre
  ><p
  >Notice that <code
    >foldl</code
    > builds up its result one step at a time and reveals it all at once, in the end. The whole result value is locked up until the entire input list has been traversed. In contrast, <code
    >foldr</code
    > starts revealing information right away, and so works well with infinite lists. Like <code
    >foldl</code
    >, <code
    >foldr</code
    > also yields only a final value.</p
  ><p
  >Sometimes it's handy to also get to all of the intermediate steps. Doing so takes us beyond the land of folds to the kingdom of scans.</p
  ></div
>

<div id="scans"
><h3
  >Scans</h3
  ><p
  >The <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:scanl"
    ><code
      >scanl</code
      ></a
    > and <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:scanr"
    ><code
      >scanr</code
      ></a
    > functions correspond to <code
    >foldl</code
    > and <code
    >foldr</code
    > but produce <em
    >all</em
    > intermediate accumulations, not just the final one.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > <span class="dv"
      >&#8759;</span
      > (b &#8594; a &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><br
       /><span class="fu"
      >scanl</span
      > f z [x1, x2,  &#8943; ] &#8801; [z, z <span class="ot"
      >`f`</span
      > x1, (z <span class="ot"
      >`f`</span
      > x1) <span class="ot"
      >`f`</span
      > x2, &#8943;]<br
       /><br
       /><span class="fu"
      >scanr</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><br
       /><span class="fu"
      >scanr</span
      > f z [&#8943;, xn_1, xn] &#8801; [&#8943;, xn_1 <span class="ot"
      >`f`</span
      > (xn <span class="ot"
      >`f`</span
      > z), xn <span class="ot"
      >`f`</span
      > z, z]<br
       /></code
    ></pre
  ><p
  >As you might expect, the last value is the complete left fold, and the <em
    >first</em
    > value in the scan is the complete <em
    >right</em
    > fold:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >last</span
      > (<span class="fu"
      >scanl</span
      > f z xs) &#8801; <span class="fu"
      >foldl</span
      > f z xs<br
       /><span class="fu"
      >head</span
      > (<span class="fu"
      >scanr</span
      > f z xs) &#8801; <span class="fu"
      >foldr</span
      > f z xs<br
       /></code
    ></pre
  ><p
  >which is to say</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >last</span
      > &#8728; <span class="fu"
      >scanl</span
      > f z &#8801; <span class="fu"
      >foldl</span
      > f z<br
       /><span class="fu"
      >head</span
      > &#8728; <span class="fu"
      >scanr</span
      > f z &#8801; <span class="fu"
      >foldr</span
      > f z<br
       /></code
    ></pre
  ><p
  >The standard scan definitions are trickier than the fold definitions:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > <span class="dv"
      >&#8759;</span
      > (b &#8594; a &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><span class="fu"
      >scanl</span
      > f z ls <span class="fu"
      >=</span
      > z <span class="fu"
      >:</span
      > (<span class="kw"
      >case</span
      > ls <span class="kw"
      >of</span
      ><br
       />                     []   &#8594; []<br
       />                     x<span class="fu"
      >:</span
      >xs &#8594; <span class="fu"
      >scanl</span
      > f (z <span class="ot"
      >`f`</span
      > x) xs)<br
       /><br
       /><span class="fu"
      >scanr</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; b) &#8594; b &#8594; [a] &#8594; [b]<br
       /><span class="fu"
      >scanr</span
      > _ z []     <span class="fu"
      >=</span
      > [z]<br
       /><span class="fu"
      >scanr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > (x <span class="ot"
      >`f`</span
      > q) <span class="fu"
      >:</span
      > qs<br
       />                   <span class="kw"
      >where</span
      > qs<span class="fu"
      >@</span
      >(q<span class="fu"
      >:</span
      >_) <span class="fu"
      >=</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       /></code
    ></pre
  ><p
  >Every time I encounter these definitions, I have to walk through it again to see what's going on. I finally sat down to figure out how these tricky definitions might <em
    >emerge</em
    > from simpler specifications. In other words, how to <em
    >derive</em
    > these definitions systematically from simpler but less efficient definitions.</p
  ><p
  >Most likely, these derivations have been done before, but I learned something from the effort, and I hope you do, too.</p
  ><span id="more-341"></span></div
>

<div id="specifying-scans"
><h3
  >Specifying scans</h3
  ><p
  >As I pointed out above, the last element of a left scan is the left fold over the whole list. In fact, <em
    >all</em
    > of the elements are left folds, but over <em
    >prefixes</em
    > of the list. Similarly, all of the elements of a right-scan are right folds, but over <em
    >suffixes</em
    > of the list. These observations give rise to very simple specifications for <code
    >scanl</code
    > and <code
    >scanr</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > f z xs <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (inits xs)<br
       /><span class="fu"
      >scanr</span
      > f z xs <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails xs)<br
       /></code
    ></pre
  ><p
  >Equivalently,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >scanl</span
      > f z <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) &#8728; inits<br
       /><span class="fu"
      >scanr</span
      > f z <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) &#8728; tails<br
       /></code
    ></pre
  ><p
  >Here I'm using the standard <code
    >inits</code
    > and <code
    >tails</code
    > functions from <code
    >Data.List</code
    >, documented as follows:</p
  ><blockquote>
<p
  >The <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:inits"
    ><code
      >inits</code
      ></a
    > function returns all initial segments of the argument, shortest first. For example,</p
  ><pre class="sourceCode haskell"
  ><code
    >inits <span class="st"
      >&quot;abc&quot;</span
      > &#8801; [<span class="st"
      >&quot;&quot;</span
      >,<span class="st"
      >&quot;a&quot;</span
      >,<span class="st"
      >&quot;ab&quot;</span
      >,<span class="st"
      >&quot;abc&quot;</span
      >]<br
       /></code
    ></pre
  ><p
  >The <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html#v:tails"
    ><code
      >tails</code
      ></a
    > function returns all final segments of the argument, longest first. For example,</p
  ><pre class="sourceCode haskell"
  ><code
    >tails <span class="st"
      >&quot;abc&quot;</span
      > &#8801; [<span class="st"
      >&quot;abc&quot;</span
      >, <span class="st"
      >&quot;bc&quot;</span
      >, <span class="st"
      >&quot;c&quot;</span
      >,<span class="st"
      >&quot;&quot;</span
      >]<br
       /></code
    ></pre
  ></blockquote>
<p
  ><a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#inits"
    >The</a
    > <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/Data-List.html#tails"
    >definitions</a
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    >inits <span class="dv"
      >&#8759;</span
      > [a] &#8594; [[a]]<br
       />inits []     <span class="fu"
      >=</span
      > [[]]<br
       />inits (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >=</span
      > [[]] <span class="fu"
      >++</span
      > <span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs)<br
       /><br
       />tails <span class="dv"
      >&#8759;</span
      > [a] &#8594; [[a]]<br
       />tails []         <span class="fu"
      >=</span
      > [[]]<br
       />tails xs<span class="fu"
      >@</span
      >(_<span class="fu"
      >:</span
      >xs') <span class="fu"
      >=</span
      > xs <span class="fu"
      >:</span
      > tails xs'<br
       /></code
    ></pre
  ><p
  >This definition of <code
    >inits</code
    > is stricter than necessary, as it examines its argument before emitting anything but ends up emitting an initial empty list whether the argument is nil or a cons. Here's a lazier definition:</p
  ><pre class="sourceCode haskell"
  ><code
    >inits xs <span class="fu"
      >=</span
      > [] <span class="fu"
      >:</span
      > <span class="kw"
      >case</span
      > xs <span class="kw"
      >of</span
      ><br
       />                  []     &#8594; []<br
       />                  (x<span class="fu"
      >:</span
      >xs) &#8594; <span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs)<br
       /></code
    ></pre
  ><p
  >This second version produces the initial <code
    >[]</code
    > before examining its argument, which helps to avoid deadlock in some recursive contexts.</p
  ><p
  >These specifications of <code
    >scanl</code
    > and <code
    >scanr</code
    > make it very easy to prove the properties given above that</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >last</span
      > &#8728; <span class="fu"
      >scanl</span
      > f z &#8801; <span class="fu"
      >foldl</span
      > f z<br
       /><span class="fu"
      >head</span
      > &#8728; <span class="fu"
      >scanr</span
      > f z &#8801; <span class="fu"
      >foldr</span
      > f z<br
       /></code
    ></pre
  ><p
  >(Hint: use the fact that <code
    >last &#8728; inits &#8801; id</code
    >, and <code
    >head &#8728; tails &#8801; id</code
    >.)</p
  ><p
  >Although these specifications of <code
    >scanl</code
    > (via <code
    >map</code
    >, <code
    >foldl</code
    >/<code
    >foldr</code
    >, and <code
    >inits</code
    >/<code
    >tails</code
    >) state succinctly and simply <em
    >what</em
    > <code
    >scanl</code
    > and <code
    >scanr</code
    > compute, they are terrible recipes for <em
    >how</em
    >, because they perform quadratic work instead of linear.</p
  ><p
  >But that's okay, because now we're going to see how to turn these inefficient &amp; clear specifications into efficient &amp; less clear implementations.</p
  ></div
>

<div id="deriving-efficient-scans"
><h3
  >Deriving efficient scans</h3
  ><p
  >To derive efficient scans, use the specifications and perform some simplifications.</p
  ><p
  >Divide <code
    >scanl</code
    > into empty lists and nonempty lists, starting with empty:</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanl</span
      > f z []<br
       />&#8801; <span class="co"
      >{- scanl spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (inits [])<br
       />&#8801; <span class="co"
      >{- inits def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) [[]]<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  [<span class="fu"
      >foldl</span
      > f z []]<br
       />&#8801; <span class="co"
      >{- foldl def -}</span
      ><br
       />  [z]<br
       /></code
    ></pre
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanl</span
      > f z (x<span class="fu"
      >:</span
      >xs)<br
       />&#8801; <span class="co"
      >{- scanl spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (inits (x<span class="fu"
      >:</span
      >xs))<br
       />&#8801; <span class="co"
      >{- inits def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) ([] <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs))<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  <span class="fu"
      >foldl</span
      > f z [] <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (<span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs))<br
       />&#8801; <span class="co"
      >{- foldl def -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z) (<span class="fu"
      >map</span
      > (x<span class="fu"
      >:</span
      >) (inits xs))<br
       />&#8801; <span class="co"
      >{- map g &#8728; map f &#8801; map (g &#8728; f) -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f z &#8728; (x<span class="fu"
      >:</span
      >)) (inits xs)<br
       />&#8801; <span class="co"
      >{- (&#8728;) def -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (&#955; ys &#8594; <span class="fu"
      >foldl</span
      > f z (x<span class="fu"
      >:</span
      >ys)) (inits xs)<br
       />&#8801; <span class="co"
      >{- foldl def -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (&#955; ys &#8594; <span class="fu"
      >foldl</span
      > f (z <span class="ot"
      >`f`</span
      > x) ys)) (inits xs)<br
       />&#8801; <span class="co"
      >{- &#951; reduction -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldl</span
      > f (z <span class="ot"
      >`f`</span
      > x))) (inits xs)<br
       />&#8801; <span class="co"
      >{- scanl spec -}</span
      ><br
       />  z <span class="fu"
      >:</span
      > <span class="fu"
      >scanl</span
      > f (z <span class="ot"
      >`f`</span
      > x) xs<br
       /></code
    ></pre
  ><p
  >Combine these conclusions and factor out the common <code
    >(z : )</code
    > to yield the standard &quot;optimized&quot; definition.</p
  ><p
  >Does <code
    >scanr</code
    > work out similarly? Let's find out, replacing <code
    >scanl</code
    > with <code
    >scanr</code
    >, <code
    >foldl</code
    > with <code
    >foldr</code
    >, and <code
    >inits</code
    > with <code
    >tails</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanr</span
      > f z []<br
       />&#8801; <span class="co"
      >{- scanr spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails [])<br
       />&#8801; <span class="co"
      >{- tails def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) ([[]])<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  [<span class="fu"
      >foldr</span
      > f z []]<br
       />&#8801; <span class="co"
      >{- foldr def -}</span
      ><br
       />  [z]<br
       /></code
    ></pre
  ><p
  >The derivation for nonempty lists deviates from <code
    >scanl</code
    >, due to differences between <code
    >inits</code
    > and <code
    >tails</code
    >, but it all works out nicely.</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="fu"
      >scanr</span
      > f z (x<span class="fu"
      >:</span
      >xs)<br
       />&#8801; <span class="co"
      >{- scanr spec -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails (x<span class="fu"
      >:</span
      >xs))<br
       />&#8801; <span class="co"
      >{- tails def -}</span
      ><br
       />  <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) ((x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >:</span
      > tails xs)<br
       />&#8801; <span class="co"
      >{- map def -}</span
      ><br
       />  <span class="fu"
      >foldr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >:</span
      > <span class="fu"
      >map</span
      > (<span class="fu"
      >foldr</span
      > f z) (tails xs)<br
       />&#8801; <span class="co"
      >{- scanr spec -}</span
      ><br
       />  <span class="fu"
      >foldr</span
      > f z (x<span class="fu"
      >:</span
      >xs) <span class="fu"
      >:</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- foldr def -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > <span class="fu"
      >foldr</span
      > f z xs) <span class="fu"
      >:</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- head/scanr property -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > <span class="fu"
      >head</span
      > (<span class="fu"
      >scanr</span
      > f z xs)) <span class="fu"
      >:</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- factor out shared expression -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > <span class="fu"
      >head</span
      > qs) <span class="fu"
      >:</span
      > qs <span class="kw"
      >where</span
      > qs <span class="fu"
      >=</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       />&#8801; <span class="co"
      >{- stylistic variation -}</span
      ><br
       />  (x <span class="ot"
      >`f`</span
      > q) <span class="fu"
      >:</span
      > qs <span class="kw"
      >where</span
      > qs<span class="fu"
      >@</span
      >(q<span class="fu"
      >:</span
      >_) <span class="fu"
      >=</span
      > <span class="fu"
      >scanr</span
      > f z xs<br
       /></code
    ></pre
  ></div
>

<div id="coming-attractions"
><h3
  >Coming attractions</h3
  ><p
  >The scan implementations above are thoroughly sequential, in that they thread a single linear chain of data dependencies throughout the computation. Upcoming posts will look at more parallel-friendly variations.</p
  ></div
>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=341&amp;md5=1d0b111320d43a274e7ac15b91118e5d" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/2xgwjTM77JU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/deriving-list-scans/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/deriving-list-scans</feedburner:origLink></item>
		<item>
		<title>From tries to trees</title>
		<link>http://feedproxy.google.com/~r/conal/~3/yRldV_aXS1A/from-tries-to-trees</link>
		<comments>http://conal.net/blog/posts/from-tries-to-trees#comments</comments>
		<pubDate>Tue, 01 Feb 2011 18:36:32 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[tree]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=314</guid>
		<description><![CDATA[This post is the last of a series of six relating numbers, vectors, and trees, revolving around the themes of static size-typing and memo tries. We've seen that length-typed vectors form a trie for bounded numbers, and can handily represent numbers as well. We've also seen that n-dimensional vectors themselves have an elegant trie, ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p
>This post is the last of a series of six relating numbers, vectors, and trees, revolving around the themes of static size-typing and <a href="http://conal.net/blog/tag/memoization/" title="Posts on memoization"
  >memo</a
  > <a href="http://conal.net/blog/tag/trie/" title="Posts on tries"
  >tries</a
  >. We&#8217;ve seen that length-typed vectors form a trie for bounded numbers, and can handily represent numbers as well. We&#8217;ve also seen that <span class="math"
  ><em
    >n</em
    ></span
  >-dimensional vectors themselves have an elegant trie, which is the <span class="math"
  ><em
    >n</em
    ></span
  >-ary composition of the element type&#8217;s trie functor:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >type</span
    > <span class="dt"
    >VTrie</span
    > n a <span class="fu"
    >=</span
    > <span class="dt"
    >Trie</span
    > a <span class="fu"
    >:^</span
    > n <br
     /></code
  ></pre
>

<p
>where for any functor <code
  >f</code
  > and natural number type <code
  >n</code
  >,</p
>

<pre class="sourceCode haskell"
><code
  >f <span class="fu"
    >:^</span
    > n <span class="dt"
    >&#8773;</span
    > f &#8728; &#8943; &#8728; f  <span class="co"
    >-- (n times)</span
    ><br
     /></code
  ></pre
>

<p
>This final post in the series places this elegant mechanism of <span class="math"
  ><em
    >n</em
    ></span
  >-ary functor composition into a familiar &amp; useful context, namely trees. Again, type-encoded Peano numbers are central. Just as <code
  >BNat</code
  > uses these number types to (statically) bound natural numbers (e.g., for a vector index or a numerical digit), and <code
  >Vec</code
  > uses number types to capture vector <em
  >length</em
  >, we'll next use number types to capture tree <em
  >depth</em
  >.</p
>

<p
><strong
  >Edits:</strong
  ></p
>

<ul
><li
  >2011-02-02: Changes thanks to comments from Sebastian Fischer<ul
    ><li
      >Added note about number representations and leading zeros (without size-typing).</li
      ><li
      >Added pointer to <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization/" title="blog post"
    ><em
      >Memoizing polymorphic functions via unmemoization</em
      ></a
    > for derivation of <code
    >Tree d a &#8773; [d] &#8594; a</code
    >.</li
      ><li
      >Fixed signatures for some <code
    >Branch</code
    > variants, bringing type parameter <code
    >a</code
    > into parens.</li
      ><li
      >Clarification about number of <code
    >VecTree</code
    > vs pairing constructors in remarks on left- vs right-folded trees.</li
      ></ul
    ></li
  ><li
  >2011-02-06: Fixed link to <a href="http://www.eecs.usma.edu/webs/people/okasaki/pubs.html#icfp99" title="Paper by Chris Okasaki"
    ><em
      >From Fast Exponentiation to Square Matrices</em
      ></a
    >.</li
  ></ul
>

<p><span id="more-314"></span></p>

<div id="infinite-trees"
><h3
  >Infinite trees</h3
  ><p
  >In the post <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization/" title="blog post"
    ><em
      >Memoizing polymorphic functions via unmemoization</em
      ></a
    >, I played with a number of container types, looking at which ones are tries over what domain types. I referred to these domain types as &quot;index types&quot; for the container type. One such container was a type of infinite binary trees with values at every node:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > a <span class="fu"
      >=</span
      > <span class="dt"
      >BinTree</span
      > a (<span class="dt"
      >BinTree</span
      > a) (<span class="dt"
      >BinTree</span
      > a)<br
       /></code
    ></pre
  ><p
  >By the usual exponent laws, this <code
    >BinTree</code
    > functor is (isomorphic to) the functor of tries over a type of binary natural numbers formulated as follows:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinNat</span
      > <span class="fu"
      >=</span
      > <span class="dt"
      >Zero</span
      > <span class="fu"
      >|</span
      > <span class="dt"
      >Even</span
      > <span class="dt"
      >BinNat</span
      > <span class="fu"
      >|</span
      > <span class="dt"
      >Odd</span
      > <span class="dt"
      >BinNat</span
      ><br
       /></code
    ></pre
  ><p
  >As a variation on this <code
    >BinTree</code
    >, we can replace the two subtrees with a <em
    >pair</em
    > of subtrees:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > a <span class="fu"
      >=</span
      > <span class="dt"
      >BinTree</span
      > a (<span class="dt"
      >Pair</span
      > (<span class="dt"
      >BinTree</span
      > a))<br
       /></code
    ></pre
  ><p
  >Where <code
    >Pair</code
    > could be defined as</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >Pair</span
      > a <span class="fu"
      >=</span
      > <span class="dt"
      >Pair</span
      > a a<br
       /></code
    ></pre
  ><p
  >or, using <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post"
    >functor combinators</a
    >,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Pair</span
      > <span class="fu"
      >=</span
      > <span class="dt"
      >Id</span
      > &#215; <span class="dt"
      >Id</span
      ><br
       /></code
    ></pre
  ><p
  >The reformulation of <code
    >BinTree</code
    > leads to a slightly different representation for our index type, a little-endian list of bits:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinNat</span
      > <span class="fu"
      >=</span
      > <span class="dt"
      >Zero</span
      > <span class="fu"
      >|</span
      > <span class="dt"
      >NonZero</span
      > <span class="dt"
      >Bool</span
      > <span class="dt"
      >BinNat</span
      ><br
       /></code
    ></pre
  ><p
  >or simply</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >BinNat</span
      > <span class="fu"
      >=</span
      > [<span class="dt"
      >Bool</span
      >]<br
       /></code
    ></pre
  ><p
  >Note that <code
    >Bool</code
    > is the index type for <code
    >Pair</code
    > (and conversely, <code
    >Pair</code
    > is the trie for <code
    >Bool</code
    >), which suggests that we play this same trick for <em
    >all</em
    > index types and their corresponding trie functors. Generalizing,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >Tree</span
      > d a <span class="fu"
      >=</span
      > <span class="dt"
      >Tree</span
      > a (d &#8603; <span class="dt"
      >Tree</span
      > d a)<br
       /></code
    ></pre
  ><p
  >where <code
    >k &#8603; v</code
    > is short for <code
    >Trie k v</code
    >, and <code
    >Trie k</code
    > is the trie functor associated with the type <code
    >k</code
    >. See <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post"
    ><em
      >Elegant memoization with higher-order types</em
      ></a
    >.</p
  ><p
  >These generalized trees are indexed by little-endian natural numbers over a &quot;digit&quot; type <code
    >d</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="dt"
      >Tree</span
      > d a <span class="dt"
      >&#8773;</span
      > [d] &#8594; a<br
       /></code
    ></pre
  ><p
  >which is to say that <code
    >Tree d</code
    > is a trie for <code
    >[d]</code
    >. See <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization/" title="blog post"
    ><em
      >Memoizing polymorphic functions via unmemoization</em
      ></a
    > for a derivation.</p
  ><p
  >Note that all of these number representations have a serious problem, which is that they distinguish between number representations that differ only by leading zeros. The size-typed versions do not have this problem.</p
  ></div
>

<div id="finite-trees"
><h3
  >Finite trees</h3
  ><p
  >The reason I chose infinite trees was that the finite tree types I knew of have choice-points/alternatives, and so are isomorphic to sums. I don't know of trie-construction techniques that synthesize sums.</p
  ><p
  >Can we design a tree type that is both finite and choice-free? We've already tackled a similar challenge above with lists earlier in previous posts.</p
  ><p
  >In <a href="http://conal.net/blog/posts/fixing-lists/" title="blog post"
    ><em
      >Fixing lists</em
      ></a
    >, I wanted to &quot;fix&quot; lists, in the sense of eliminating the choice points in the standard type <code
    >[a]</code
    > so that the result could be a trie. Doing so led to the type <code
    >Vec n a</code
    >, which appears to have choice points, due to the two constructors <code
    >ZVec</code
    > and <code
    >(:&lt;)</code
    >, but for any given <code
    >n</code
    >, at most one constructor is applicable. (For this reason, regular algebraic data types are inadequate.) For handy review,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >Vec</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >ZVec</span
      > <span class="dv"
      >&#8759;</span
      >                <span class="dt"
      >Vec</span
      > <span class="dt"
      >Z</span
      >     a<br
       />  (<span class="fu"
      >:&lt;</span
      >) <span class="dv"
      >&#8759;</span
      > a &#8594; <span class="dt"
      >Vec</span
      > n a &#8594; <span class="dt"
      >Vec</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Let's try the same trick with trees, fixing depth instead length, to get depth-typed binary trees:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      > a                         &#8594; <span class="dt"
      >BinTree</span
      > <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >BinTree</span
      > n a &#8594; <span class="dt"
      >BinTree</span
      > n a &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Again, we can replace the two subtrees with a single pair of subtrees in the <code
    >Branch</code
    > constructor::</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Pair</span
      > (<span class="dt"
      >BinTree</span
      > n) a &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Or, recalling that <code
    >Bool</code
    > is the index type for <code
    >Pair</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      >                    a &#8594; <span class="dt"
      >BinTree</span
      > <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > (<span class="dt"
      >Bool</span
      > &#8603; <span class="dt"
      >BinTree</span
      > n a) &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >The use of <code
    >Bool</code
    > is rather ad hoc. Its useful property is isomorphism with <code
    >1 + 1</code
    >, whose corresponding trie functor is <code
    >Id + Id</code
    >, i.e., <code
    >Pair</code
    >. In the post <a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
    ><em
      >Type-bounded numbers</em
      ></a
    >, we saw another, more systematic, type isomorphic to <code
    >1 + 1</code
    >, which is <code
    >BNat TwoT</code
    > (i.e., <code
    >BNat (S (S Z))</code
    >), which is the type of natural numbers less than two.</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > (<span class="dt"
      >BNat</span
      > <span class="dt"
      >TwoT</span
      > &#8603; <span class="dt"
      >BinTree</span
      > n a) &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >This replacement suggests a generalization from binary trees to <span class="math"
    ><em
      >b</em
      ></span
    >-ary trees (i.e., having branch factor <span class="math"
    ><em
      >b</em
      ></span
    >).</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >VecTree</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      >                        a &#8594; <span class="dt"
      >VecTree</span
      > b <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > (<span class="dt"
      >BNat</span
      > b &#8603; <span class="dt"
      >VecTree</span
      > b n a) &#8594; <span class="dt"
      >VecTree</span
      > b (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Recall that the motivation for <code
    >BNat b</code
    > was as an index type for <code
    >Vec b</code
    >, which is to say that <code
    >Vec b</code
    > turned out to be the trie functor for the type <code
    >BNat b</code
    >. With this relationship in mind, the <code
    >Branch</code
    > type is equivalent to</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > b (<span class="dt"
      >VecTree</span
      > b n a) &#8594; <span class="dt"
      >VecTree</span
      > b (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Unsurprisingly then, a <span class="math"
    ><em
      >b</em
      ></span
    >-ary tree is either a single leaf value or a branch node containing <span class="math"
    ><em
      >b</em
      ></span
    > subtrees. Also, the depth of a leaf is zero, and the depth of a branch node containing <span class="math"
    ><em
      >b</em
      ></span
    > subtrees each of of depth <span class="math"
    ><em
      >n</em
      ></span
    > is <span class="math"
    ><em
      >n</em
      > + 1</span
    >.</p
  ><p
  >We can also generalize this <code
    >VecTree</code
    > type by replacing <code
    >Vec b</code
    > with an arbitrary functor <code
    >f</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >FTree</span
      > <span class="dv"
      >&#8759;</span
      > (<span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      >) &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      >               a &#8594; <span class="dt"
      >FTree</span
      > f <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > f (<span class="dt"
      >FTree</span
      > f n) a &#8594; <span class="dt"
      >FTree</span
      > f (<span class="dt"
      >S</span
      > n) a<br
       /><br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >VecTree</span
      > b <span class="fu"
      >=</span
      > <span class="dt"
      >FTree</span
      > (<span class="dt"
      >Vec</span
      > b)<br
       /></code
    ></pre
  ><p
  >Better yet, introduce an intermediate generalization, using the property that <code
    >Vec b &#8801; Trie (BNat b)</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >TrieTree</span
      > i <span class="fu"
      >=</span
      > <span class="dt"
      >FTree</span
      > (<span class="dt"
      >Trie</span
      > i)<br
       /><br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >VecTree</span
      > b <span class="fu"
      >=</span
      > <span class="dt"
      >TrieTree</span
      > (<span class="dt"
      >BNat</span
      > b)<br
       /></code
    ></pre
  ><p
  >With the exception of the most general form (<code
    >FTree</code
    >), these trees are also tries.</p
  ></div
>

<div id="generalizing-and-inverting-our-trees"
><h3
  >Generalizing and inverting our trees</h3
  ><p
  >The <code
    >FTree</code
    > type looks very like another data type that came up above, namely right-folded <span class="math"
    ><em
      >b</em
      ></span
    >-ary functor composition:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > (<span class="fu"
      >:^</span
      >) <span class="dv"
      >&#8759;</span
      > (<span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      >) &#8594; <span class="fu"
      >*</span
      > &#8594; (<span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      >) <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >ZeroC</span
      > <span class="dv"
      >&#8759;</span
      >             a  &#8594; (f <span class="fu"
      >:^</span
      > <span class="dt"
      >Z</span
      >    ) a<br
       />  <span class="dt"
      >SuccC</span
      > <span class="dv"
      >&#8759;</span
      > f ((f <span class="fu"
      >:^</span
      > n) a) &#8594; (f <span class="fu"
      >:^</span
      > (<span class="dt"
      >S</span
      > n)) a<br
       /></code
    ></pre
  ><p
  >These two types are not just similar; they're identical (different only in naming, i.e., <span class="math"
    >α</span
    >-equivalent), so we can use <code
    >f :^ n</code
    > in place of <code
    >FTree f n</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >TrieTree</span
      > i <span class="fu"
      >=</span
      > (<span class="fu"
      >:^</span
      >) (<span class="dt"
      >Trie</span
      > i)<br
       /></code
    ></pre
  ><p
  >Instead of <em
    >right-folded</em
    > functor composition, we could go with left-folded. What difference would it make to our notions of <span class="math"
    ><em
      >b</em
      ></span
    >-ary or binary trees?</p
  ><p
  >First look at (right-folded) <code
    >BinTree</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      >                  a &#8594; <span class="dt"
      >BinTree</span
      > <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Pair</span
      > (<span class="dt"
      >BinTree</span
      > n) a &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Equivalently,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      >                         a &#8594; <span class="dt"
      >BinTree</span
      > <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > (<span class="dt"
      >BNat</span
      > <span class="dt"
      >TwoT</span
      > &#8603; <span class="dt"
      >BinTree</span
      > n a) &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >With left-folding, the <code
    >Branch</code
    > constructors would be</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >BinTree</span
      > n (<span class="dt"
      >Pair</span
      > a) &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >or</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >BinTree</span
      > n (<span class="dt"
      >BNat</span
      > <span class="dt"
      >TwoT</span
      > &#8603; a) &#8594; <span class="dt"
      >BinTree</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Then (right-folded) <code
    >VecTree</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >VecTree</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      >                        a &#8594; <span class="dt"
      >VecTree</span
      > b <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > (<span class="dt"
      >BNat</span
      > b &#8603; <span class="dt"
      >VecTree</span
      > b n a) &#8594; <span class="dt"
      >VecTree</span
      > b (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Equivalently,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >VecTree</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Leaf</span
      >   <span class="dv"
      >&#8759;</span
      >                    a  &#8594; <span class="dt"
      >VecTree</span
      > b <span class="dt"
      >Z</span
      >     a<br
       />  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > b (<span class="dt"
      >VecTree</span
      > b n a) &#8594; <span class="dt"
      >VecTree</span
      > b (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >With left-folding:</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >VecTree</span
      > b n (<span class="dt"
      >BNat</span
      > b &#8603; a) &#8594; <span class="dt"
      >VecTree</span
      > b (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >or</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >Branch</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >VecTree</span
      > b n (<span class="dt"
      >Vec</span
      > b a) &#8594; <span class="dt"
      >VecTree</span
      > b (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >In shifting from right- to left-folding, our tree structuring becomes inverted. Now a &quot;<span class="math"
    ><em
      >b</em
      ></span
    >-ary&quot; tree really has only <em
    >one</em
    > subtree per branch node, not <span class="math"
    ><em
      >b</em
      ></span
    > subtrees.</p
  ><p
  >For instance, right-folded a binary tree of depth two might look like</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="dt"
      >Branch</span
      > (<span class="dt"
      >Branch</span
      > (<span class="dt"
      >Leaf</span
      > <span class="dv"
      >0</span
      >, <span class="dt"
      >Leaf</span
      > <span class="dv"
      >1</span
      >), <span class="dt"
      >Branch</span
      > (<span class="dt"
      >Leaf</span
      > <span class="dv"
      >2</span
      >, <span class="dt"
      >Leaf</span
      > <span class="dv"
      >3</span
      >))<br
       /></code
    ></pre
  ><p
  >For readability, I'm using normal pairs instead of 2-vectors or <code
    >Pair</code
    > pairs here. In contrast, the corresponding left-folded a binary tree would look like</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="dt"
      >Branch</span
      > (<span class="dt"
      >Branch</span
      > (<span class="dt"
      >Leaf</span
      > ((<span class="dv"
      >0</span
      >,<span class="dv"
      >1</span
      >),(<span class="dv"
      >2</span
      >,<span class="dv"
      >3</span
      >))))<br
       /></code
    ></pre
  ><p
  >Note that the <code
    >VecTree</code
    > constructors are in a linear chain, forming an outer shell, and the number of such constructors is the one more than the depth, and hence logarithmic in the number of leaves. The right-folded form has <code
    >VecTree</code
    > constructors scattered throughout the tree, and the number of such constructors is exponential in the depth, and hence linear in the number of leaves. (As Sebastian Fischer pointed out, however, the number of <em
    >pairing</em
    > constructors is not reduced in the left-folded form.)</p
  ><p
  >For more examples of this sort of inversion, see Chris Okasaki's gem of a paper <a href="http://www.eecs.usma.edu/webs/people/okasaki/pubs.html#icfp99" title="Paper by Chris Okasaki"
    ><em
      >From Fast Exponentiation to Square Matrices</em
      ></a
    >.</p
  ></div
>

<div id="what-sort-of-trees-do-we-have"
><h3
  >What sort of trees do we have?</h3
  ><p
  >I pulled a bit of a bait-and-switch above in reformulating trees. The initial infinite tree type had values <em
    >and</em
    > branching at every node:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > a <span class="fu"
      >=</span
      > <span class="dt"
      >BinTree</span
      > a (<span class="dt"
      >BinTree</span
      > a) (<span class="dt"
      >BinTree</span
      > a)<br
       /></code
    ></pre
  ><p
  >In contrast, the depth-typed trees (whether binary, <span class="math"
    ><em
      >b</em
      ></span
    >-ary, trie-ary, or functor-ary) all have strict separation of leaf nodes from branching nodes.</p
  ><p
  >A conventional, finite binary tree data type might look like</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > a <span class="fu"
      >=</span
      > <span class="dt"
      >Leaf</span
      > a <span class="fu"
      >|</span
      > <span class="dt"
      >Branch</span
      > (<span class="dt"
      >Pair</span
      > (<span class="dt"
      >BinTree</span
      > a))<br
       /></code
    ></pre
  ><p
  >Its inverted (left-folded) form:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BinTree</span
      > a <span class="fu"
      >=</span
      > <span class="dt"
      >Leaf</span
      > a <span class="fu"
      >|</span
      > <span class="dt"
      >Branch</span
      > (<span class="dt"
      >BinTree</span
      > (<span class="dt"
      >Pair</span
      > a))<br
       /></code
    ></pre
  ><p
  >When we had depth typing, the right- and left-folded forms were equally expressive. They both described &quot;perfect&quot; trees, with each depth consisting entirely of branching or (for the deepest level) entirely of values. (I'm speaking figuratively for the left-folded case, since literally there is no branching.)</p
  ><p
  >Without depth typing, the expressiveness differs significantly. Right-folded trees can be ragged, with leaves occurring at various depths in the same tree. Left-folded binary trees of depth <span class="math"
    ><em
      >n</em
      ></span
    > can only be perfect, even though the depth is determined dynamically, not statically (i.e., not from type).</p
  ><p
  >Dynamically-depthed binary trees generalize to <span class="math"
    ><em
      >b</em
      ></span
    >-ary, trie-ary, and functor-ary versions. In each case, the left-folded versions are much more statically constrained than their right-folded counterparts.</p
  ></div
>

<div id="from-here"
><h3
  >From here</h3
  ><p
  >This post is the last of a six-part series on tries and static size-typing in the context of numbers, vectors, and trees. Maybe you're curious where these ideas came from and where they might be going.</p
  ><p
  >I got interested in these relationships while noodling over some imperative, data-parallel programs. I asked one one of my standard questions: What elegant beauty is hiding deep beneath these low-level implementation details. In this case, prominent details include array indices, bit fiddling, and power-of-two restrictions, which led me to play with binary numbers. Moreover, parallel algorithms often use a divide-and-conquer strategy. That strategy hints at balanced binary trees, which then can be indexed by binary numbers (bit sequences). Indexing brought memo tries to mind.</p
  ><p
  >I expect to write soon about some ideas &amp; techniques for deriving low-level, side-effecting, parallel algorithms from semantically simple and elegant specifications.</p
  ></div
>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=314&amp;md5=209bdcd3e572f837b906074e674313d9" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/yRldV_aXS1A" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/from-tries-to-trees/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/from-tries-to-trees</feedburner:origLink></item>
		<item>
		<title>A trie for length-typed vectors</title>
		<link>http://feedproxy.google.com/~r/conal/~3/kiieMvb8qFI/a-trie-for-length-typed-vectors</link>
		<comments>http://conal.net/blog/posts/a-trie-for-length-typed-vectors#comments</comments>
		<pubDate>Mon, 31 Jan 2011 23:03:48 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=308</guid>
		<description><![CDATA[As you might have noticed, I've been thinking and writing about memo tries lately. I don't mean to; they just keep coming up.Memoization is the conversion of functions to data structures. A simple, elegant, and purely functional form of memoization comes from applying three common type isomorphisms, which also correspond to three laws of ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p
>As you might have noticed, I&#8217;ve been thinking and writing about <a href="http://conal.net/blog/tag/memoization/" title="Posts on memoization"
  >memo</a
  > <a href="http://conal.net/blog/tag/trie/" title="Posts on tries"
  >tries</a
  > lately. I don&#8217;t mean to; they just keep coming up.</p
>

<p
>Memoization is the conversion of functions to data structures. A simple, elegant, and purely functional form of memoization comes from applying three common type isomorphisms, which also correspond to three laws of exponents, familiar from high school math, as noted by Ralf Hinze in his paper <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.8.4069" title="Paper by Ralf Hinze"
  ><em
    >Generalizing Generalized Tries</em
    ></a
  >.</p
>

<p
>In Haskell, one can neatly formulate memo tries via an associated functor, <code
  >Trie</code
  >, with a convenient synonym &quot;<code
  >k &#8603; v</code
  >&quot; for <code
  >Trie k v</code
  >, as in <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post"
  ><em
    >Elegant memoization with higher-order types</em
    ></a
  >. (Note that I've changed my pretty-printing from &quot;<code
  >k :&#8594;: v</code
  >&quot; to &quot;<code
  >k &#8603; v</code
  >&quot;.) The key property is that the data structure encodes (is isomorphic to) a function, i.e.,</p
>

<pre class="sourceCode haskell"
><code
  >k &#8603; a <span class="dt"
    >&#8773;</span
    > k &#8594; a<br
     /></code
  ></pre
>

<p
>In most cases, we ignore non-strictness, though there is <a href="http://conal.net/blog/posts/nonstrict-memoization/" title="blog post"
  >a delightful solution</a
  > for memoizing non-strict functions correctly.</p
>

<p
><a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
  >My</a
  > <a href="http://conal.net/blog/posts/fixing-lists/" title="blog post"
  >previous</a
  > <a href="http://conal.net/blog/posts/doing-more-with-length-typed-vectors/" title="blog post"
  >four</a
  > <a href="http://conal.net/blog/posts/reverse-engineering-length-typed-vectors/" title="blog post"
  >posts</a
  > explored use of types to statically bound numbers and to determine lengths of vectors.</p
>

<p
>Just as (infinite-only) streams are the natural trie for unary natural numbers, we saw in <a href="http://conal.net/blog/posts/reverse-engineering-length-typed-vectors/" title="blog post"
  ><em
    >Reverse-engineering length-typed vectors</em
    ></a
  > that length-typed vectors (one-dimensional arrays) are the natural trie for statically <em
  >bounded</em
  > natural numbers.</p
>

<pre class="sourceCode haskell"
><code
  ><span class="dt"
    >BNat</span
    > n &#8603; a &#8801; <span class="dt"
    >Vec</span
    > n a<br
     /></code
  ></pre
>

<p
>and so</p
>

<pre class="sourceCode haskell"
><code
  ><span class="dt"
    >BNat</span
    > n &#8594; a <span class="dt"
    >&#8773;</span
    > <span class="dt"
    >Vec</span
    > n a<br
     /></code
  ></pre
>

<p
>In retrospect, this relationship is completely unsurprising, since a vector of length <span class="math"
  ><em
    >n</em
    ></span
  > is a collection of values, indexed by <span class="math"
  >0, . . . , <em
    >n</em
    > - 1</span
  >.</p
>

<p
>In that <a href="http://conal.net/blog/posts/reverse-engineering-length-typed-vectors/" title="blog post"
  >same post</a
  >, I noted that vectors are not only a trie for bounded numbers, but when the elements are also bounded numbers, the vectors can also be thought of <em
  >as numbers</em
  >. Both the number of digits and the number base are captured statically, in types:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >type</span
    > <span class="dt"
    >Digits</span
    > n b <span class="fu"
    >=</span
    > <span class="dt"
    >Vec</span
    > n (<span class="dt"
    >BNat</span
    > b)<br
     /></code
  ></pre
>

<p
>The type parameters <code
  >n</code
  > and <code
  >b</code
  > here are type-encodigs of unary numbers, i.e., built up from zero and successor (<code
  >Z</code
  > and <code
  >S</code
  >). For instance, when <code
  >b &#8801; S (S Z)</code
  >, we have <span class="math"
  ><em
    >n</em
    ></span
  >-bit binary numbers.</p
>

<p
>In this new post, I look at another question of tries and vectors. Given that <code
  >Vec n</code
  > is the trie for <code
  >BNat n</code
  >, is there also a trie for <code
  >Vec n</code
  >?</p
>

<p
><strong
  >Edits:</strong
  ></p
>

<ul
><li
  >2011-01-31: Switched trie notation to &quot;<code
    >k &#8603; v</code
    >&quot; to avoid missing character on iPad.</li
  ></ul
>

<p><span id="more-308"></span></p>

<div id="a-trie-for-length-typed-vectors"
><h3
  >A trie for length-typed vectors</h3
  ><p
  >A vector is a trie over bounded numbers. What is a trie over vectors? As always, isomorphisms show us the way.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="dt"
      >Vec</span
      > n a &#8594; b <span class="dt"
      >&#8773;</span
      > (a &#215; &#8943; &#215; a) &#8594; b<br
       />             <span class="dt"
      >&#8773;</span
      > a &#8594; &#8943; &#8594; a &#8594; b<br
       />             <span class="dt"
      >&#8773;</span
      > a &#8603; &#8943; &#8603; a &#8603; b<br
       />             &#8801; <span class="dt"
      >Trie</span
      > a (&#8943; (<span class="dt"
      >Trie</span
      > a b)&#8943;)<br
       />             <span class="dt"
      >&#8773;</span
      > (<span class="dt"
      >Trie</span
      > a &#8728; &#8943; &#8728; <span class="dt"
      >Trie</span
      > a) b<br
       /></code
    ></pre
  ><p
  >So the trie (functor) for <code
    >Vec n a</code
    > is the <span class="math"
    ><em
      >n</em
      ></span
    >-ary composition of tries for <code
    >a</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >VTrie</span
      > n a <span class="fu"
      >=</span
      > <span class="dt"
      >Trie</span
      > a <span class="fu"
      >:^</span
      > n <br
       /></code
    ></pre
  ><p
  >where for any functor <code
    >f</code
    > and natural number type <code
    >n</code
    >,</p
  ><pre class="sourceCode haskell"
  ><code
    >f <span class="fu"
      >:^</span
      > n <span class="dt"
      >&#8773;</span
      > f &#8728; &#8943; &#8728; f  <span class="co"
      >-- (n times)</span
      ><br
       /></code
    ></pre
  ></div
>

<div id="n-ary-functor-composition"
><h3
  >N-ary functor composition</h3
  ><p
  >Since composition is associative, a recursive formulation might naturally fold from the left or from right. (Or perhaps in a balanced tree, to facilitate parallel execution.)</p
  ><div id="right-folded-composition"
  ><h4
    >Right-folded composition</h4
    ><p
    >Let's look at each fold direction, starting with the right, i.e.,</p
    ><pre class="sourceCode haskell"
    ><code
      >f <span class="fu"
    >:^</span
    > <span class="dt"
    >Z</span
    >   <span class="dt"
    >&#8773;</span
    > <span class="dt"
    >Id</span
    ><br
     />f <span class="fu"
    >:^</span
    > <span class="dt"
    >S</span
    > n <span class="dt"
    >&#8773;</span
    > f &#8728; (f <span class="fu"
    >:^</span
    > n)<br
     /></code
      ></pre
    ><p
    >Writing as a GADT:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >data</span
    > (<span class="fu"
    >:^</span
    >) <span class="dv"
    >&#8759;</span
    > (<span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    >) &#8594; <span class="fu"
    >*</span
    > &#8594; (<span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    >) <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >ZeroC</span
    > <span class="dv"
    >&#8759;</span
    >                        a  &#8594; (f <span class="fu"
    >:^</span
    > <span class="dt"
    >Z</span
    >) a<br
     />  <span class="dt"
    >SuccC</span
    > <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >IsNat</span
    > n &#8658; f ((f <span class="fu"
    >:^</span
    > n) a) &#8594; (f <span class="fu"
    >:^</span
    > (<span class="dt"
    >S</span
    > n)) a<br
     /></code
      ></pre
    ><p
    >Functors compose into functors and applicatives into applicatives. (See <a href="http://www.soi.city.ac.uk/~ross/papers/Applicative.html" title="Paper by Conor McBride and Ross Paterson"
      ><em
    >Applicative Programming with Effects</em
    ></a
      > (section 5) and the instance definitions in <a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post"
      ><em
    >Semantic editor combinators</em
    ></a
      >.) The following definitions arise from the standard instances for binary functor composition.</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >instance</span
    > <span class="kw"
    >Functor</span
    > f &#8658; <span class="kw"
    >Functor</span
    > (f <span class="fu"
    >:^</span
    > n) <span class="kw"
    >where</span
    ><br
     />  <span class="fu"
    >fmap</span
    > h (<span class="dt"
    >ZeroC</span
    > a)  <span class="fu"
    >=</span
    > <span class="dt"
    >ZeroC</span
    > (h a)<br
     />  <span class="fu"
    >fmap</span
    > h (<span class="dt"
    >SuccC</span
    > fs) <span class="fu"
    >=</span
    > <span class="dt"
    >SuccC</span
    > ((fmap&#8728;fmap) h fs)<br
     /></code
      ></pre
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >instance</span
    > (<span class="dt"
    >IsNat</span
    > n, <span class="dt"
    >Applicative</span
    > f) &#8658; <span class="dt"
    >Applicative</span
    > (f <span class="fu"
    >:^</span
    > n) <span class="kw"
    >where</span
    ><br
     />  pure <span class="fu"
    >=</span
    > pureN nat<br
     />  <span class="dt"
    >ZeroC</span
    > f  &#8859; <span class="dt"
    >ZeroC</span
    > x  <span class="fu"
    >=</span
    > <span class="dt"
    >ZeroC</span
    > (f x)<br
     />  <span class="dt"
    >SuccC</span
    > fs &#8859; <span class="dt"
    >SuccC</span
    > xs <span class="fu"
    >=</span
    > <span class="dt"
    >SuccC</span
    > (liftA2 (&#8859;) fs xs)<br
     /></code
      ></pre
    ><!--

>   _ <*> _ = error "ComposeFunctor.<*>: can't happen" {- why needed? -}

 --><pre class="sourceCode haskell"
    ><code
      >pureN <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >Applicative</span
    > f &#8658; <span class="dt"
    >Nat</span
    > n &#8594; a &#8594; (f <span class="fu"
    >:^</span
    > n) a<br
     />pureN <span class="dt"
    >Zero</span
    >     a <span class="fu"
    >=</span
    > <span class="dt"
    >ZeroC</span
    > a<br
     />pureN (<span class="dt"
    >Succ</span
    > _) a <span class="fu"
    >=</span
    > <span class="dt"
    >SuccC</span
    > ((pure &#8728; pure) a)<br
     /></code
      ></pre
    ><p
    >More explicitly, the second <code
      >pure</code
      > could instead use <code
      >pureN</code
      >:</p
    ><pre class="sourceCode haskell"
    ><code
      >pureN (<span class="dt"
    >Succ</span
    > n) a <span class="fu"
    >=</span
    > <span class="dt"
    >SuccC</span
    > ((pure &#8728; pureN n) a)<br
     /></code
      ></pre
    ><div id="some-tidier-definitions"
    ><h5
      >Some tidier definitions</h5
      ><p
      >Using <code
    >(&#8852;)</code
    >, there are tidier definitions of <code
    >fmap</code
    > and <code
    >(&#8859;)</code
    >:</p
      ><pre class="sourceCode haskell"
      ><code
    >  <span class="fu"
      >fmap</span
      > <span class="fu"
      >=</span
      > inZeroC  (<span class="fu"
      >$</span
      >) &#8852; inSuccC  (fmap&#8728;fmap)<br
       /><br
       />  (&#8859;)  <span class="fu"
      >=</span
      > inZeroC2 (<span class="fu"
      >$</span
      >) &#8852; inSuccC2 (liftA2 (&#8859;))<br
       /></code
    ></pre
      ><p
      >where the new combinators are <em
    >partial</em
    > functions that work inside of <code
    >ZeroC</code
    > and <code
    >SuccC</code
    >.</p
      ><pre class="sourceCode haskell"
      ><code
    >inZeroC  h (<span class="dt"
      >ZeroC</span
      > a ) <span class="fu"
      >=</span
      > <span class="dt"
      >ZeroC</span
      > (h a )<br
       /><br
       />inSuccC  h (<span class="dt"
      >SuccC</span
      > as) <span class="fu"
      >=</span
      > <span class="dt"
      >SuccC</span
      > (h as)<br
       /></code
    ></pre
      ><pre class="sourceCode haskell"
      ><code
    >inZeroC2 h (<span class="dt"
      >ZeroC</span
      > a ) (<span class="dt"
      >ZeroC</span
      > b ) <span class="fu"
      >=</span
      > <span class="dt"
      >ZeroC</span
      > (h a  b )<br
       /><br
       />inSuccC2 h (<span class="dt"
      >SuccC</span
      > as) (<span class="dt"
      >SuccC</span
      > bs) <span class="fu"
      >=</span
      > <span class="dt"
      >SuccC</span
      > (h as bs)<br
       /></code
    ></pre
      ><p
      >This example demonstrates another notational benefit of <code
    >(&#8852;)</code
    >, extending the techniques in the post <a href="http://conal.net/blog/posts/lazier-function-definitions-by-merging-partial-values/" title="blog post"
    ><em
      >Lazier function definitions by merging partial values</em
      ></a
    >.</p
      ></div
    ></div
  ><div id="left-folded-composition"
  ><h4
    >Left-folded composition</h4
    ><p
    >For left-folded composition, a tiny change suffices in the <code
      >S</code
      > case:</p
    ><pre class="sourceCode haskell"
    ><code
      >f <span class="fu"
    >:^</span
    > <span class="dt"
    >Z</span
    >   <span class="dt"
    >&#8773;</span
    > <span class="dt"
    >Id</span
    ><br
     />f <span class="fu"
    >:^</span
    > <span class="dt"
    >S</span
    > n <span class="dt"
    >&#8773;</span
    > (f <span class="fu"
    >:^</span
    > n) &#8728; f<br
     /></code
      ></pre
    ><p
    >which translates to a correspondingly tiny change in the <code
      >SuccC</code
      > constructor.</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >data</span
    > (<span class="fu"
    >:^</span
    >) <span class="dv"
    >&#8759;</span
    > (<span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    >) &#8594; <span class="fu"
    >*</span
    > &#8594; (<span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    >) <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >ZeroC</span
    > <span class="dv"
    >&#8759;</span
    >                        a  &#8594; (f <span class="fu"
    >:^</span
    > <span class="dt"
    >Z</span
    >) a<br
     />  <span class="dt"
    >SuccC</span
    > <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >IsNat</span
    > n &#8658; (f <span class="fu"
    >:^</span
    > n) (f a) &#8594; (f <span class="fu"
    >:^</span
    > (<span class="dt"
    >S</span
    > n)) a<br
     /></code
      ></pre
    ><p
    >The <code
      >Functor</code
      > and <code
      >Applicative</code
      > instances are completely unchanged.</p
    ></div
  ></div
>

<div id="vector-tries-continued"
><h3
  >Vector tries (continued)</h3
  ><p
  >Using the analysis above, we can easily define tries over vectors as <span class="math"
    ><em
      >n</em
      ></span
    >-ary composition of tries over the vector element type. Again, there is a right-folded and a left-folded version.</p
  ><div id="right-folded-vector-tries"
  ><h4
    >Right-folded vector tries</h4
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >instance</span
    > (<span class="dt"
    >IsNat</span
    > n, <span class="dt"
    >HasTrie</span
    > a) &#8658; <span class="dt"
    >HasTrie</span
    > (<span class="dt"
    >Vec</span
    > n a) <span class="kw"
    >where</span
    ><br
     />  <span class="kw"
    >type</span
    > <span class="dt"
    >Trie</span
    > (<span class="dt"
    >Vec</span
    > n a) <span class="fu"
    >=</span
    > <span class="dt"
    >Trie</span
    > a <span class="fu"
    >:^</span
    > n<br
     /></code
      ></pre
    ><p
    >Conversion from trie to function is, as always, a trie look-up. Its definition closely follows the definition of <code
      >f :^ n</code
      >:</p
    ><pre class="sourceCode haskell"
    ><code
      >  <span class="dt"
    >ZeroC</span
    > v <span class="ot"
    >`untrie`</span
    > <span class="dt"
    >ZVec</span
    >      <span class="fu"
    >=</span
    > v<br
     />  <span class="dt"
    >SuccC</span
    > t <span class="ot"
    >`untrie`</span
    > (a <span class="fu"
    >:&lt;</span
    > as) <span class="fu"
    >=</span
    > (t <span class="ot"
    >`untrie`</span
    > a) <span class="ot"
    >`untrie`</span
    > as<br
     /></code
      ></pre
    ><!--

<   _ `untrie` _ = error "untrie on Vec n a: Can't happen" {- why nec? -}

<   enumerate = error "enumerate: not yet defined on Vec n a"

 --><p
    >For <code
      >untrie</code
      >, we were able to follow the zero/successor structure of the trie. For <code
      >trie</code
      >, we don't have such a structure to follow, but we can play the same trick as for defining <code
      >units</code
      > above. Use the <code
      >nat</code
      > method of the <code
      >IsNat</code
      > class to synthesize a number of type <code
      >Nat n</code
      >, and then follow the structure of that number in a new recursive function definition.</p
    ><pre class="sourceCode haskell"
    ><code
      >  trie <span class="fu"
    >=</span
    > trieN nat<br
     /></code
      ></pre
    ><p
    >where</p
    ><pre class="sourceCode haskell"
    ><code
      >trieN <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >HasTrie</span
    > a &#8658; <span class="dt"
    >Nat</span
    > n &#8594; (<span class="dt"
    >Vec</span
    > n a &#8594; b) &#8594; (<span class="dt"
    >Trie</span
    > a <span class="fu"
    >:^</span
    > n) b<br
     />trieN <span class="dt"
    >Zero</span
    >     f <span class="fu"
    >=</span
    > <span class="dt"
    >ZeroC</span
    > (f <span class="dt"
    >ZVec</span
    >)<br
     />trieN (<span class="dt"
    >Succ</span
    > _) f <span class="fu"
    >=</span
    > <span class="dt"
    >SuccC</span
    > (trie (&#955; a &#8594; trie (f &#8728; (a <span class="fu"
    >:&lt;</span
    >))))<br
     /></code
      ></pre
    ></div
  ><div id="left-folded-vector-tries"
  ><h4
    >Left-folded vector tries</h4
    ><p
    >The change from right-folding to left-folding is minuscule.</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >instance</span
    > (<span class="dt"
    >IsNat</span
    > n, <span class="dt"
    >HasTrie</span
    > a) &#8658; <span class="dt"
    >HasTrie</span
    > (<span class="dt"
    >Vec</span
    > n a) <span class="kw"
    >where</span
    ><br
     />  <span class="kw"
    >type</span
    > <span class="dt"
    >Trie</span
    > (<span class="dt"
    >Vec</span
    > n a) <span class="fu"
    >=</span
    > <span class="dt"
    >Trie</span
    > a <span class="fu"
    >:^</span
    > n<br
     /><br
     />  <span class="dt"
    >ZeroC</span
    > b <span class="ot"
    >`untrie`</span
    > <span class="dt"
    >ZVec</span
    >      <span class="fu"
    >=</span
    > b<br
     />  <span class="dt"
    >SuccC</span
    > t <span class="ot"
    >`untrie`</span
    > (a <span class="fu"
    >:&lt;</span
    > as) <span class="fu"
    >=</span
    > (t <span class="ot"
    >`untrie`</span
    > as) <span class="ot"
    >`untrie`</span
    > a<br
     />  <br
     />  trie <span class="fu"
    >=</span
    > trieN nat<br
     /></code
      ></pre
    ><pre class="sourceCode haskell"
    ><code
      >trieN <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >HasTrie</span
    > a &#8658; <span class="dt"
    >Nat</span
    > n &#8594; (<span class="dt"
    >Vec</span
    > n a &#8594; b) &#8594; (<span class="dt"
    >Trie</span
    > a <span class="fu"
    >:^</span
    > n) b<br
     />trieN <span class="dt"
    >Zero</span
    >     f <span class="fu"
    >=</span
    > <span class="dt"
    >ZeroC</span
    > (f <span class="dt"
    >ZVec</span
    >)<br
     />trieN (<span class="dt"
    >Succ</span
    > _) f <span class="fu"
    >=</span
    > <span class="dt"
    >SuccC</span
    > (trie (&#955; as &#8594; trie (f &#8728; (<span class="fu"
    >:&lt;</span
    > as))))<br
     /></code
      ></pre
    ></div
  ><div id="right-vs-left"
  ><h4
    >Right vs Left?</h4
    ><p
    >There are two tries for <code
      >Vec n a</code
      >, but with Haskell we have to choose one as <em
      >the</em
      > <code
      >HasTrie</code
      > instance. How can we make our choice?</p
    ><p
    >The same sort of question arises earlier. The post <a href="http://conal.net/blog/posts/reverse-engineering-length-typed-vectors/" title="blog post"
      ><em
    >Reverse-engineering length-typed vectors</em
    ></a
      > showed how to discover <code
      >Vec n</code
      > by looking for the trie functor for the <code
      >BNat n</code
      >. The derivation was</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="dt"
    >Vec</span
    > n a <span class="dt"
    >&#8773;</span
    > a &#215; &#8943; &#215; a<br
     />        <span class="dt"
    >&#8773;</span
    > (<span class="dv"
    >1</span
    > &#8594; a) &#215; &#8943; &#215; (<span class="dv"
    >1</span
    > &#8594; a)<br
     />        <span class="dt"
    >&#8773;</span
    > (<span class="dv"
    >1</span
    > <span class="fu"
    >+</span
    > &#8943; <span class="fu"
    >+</span
    > <span class="dv"
    >1</span
    >) &#8594; a<br
     /></code
      ></pre
    ><p
    >The question of associativity arises here as well, for both product and sum. The <code
      >BNat n a</code
      > and <code
      >Vec n</code
      > types both choose right-associativity:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >data</span
    > <span class="dt"
    >BNat</span
    > <span class="dv"
    >&#8759;</span
    > <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >BZero</span
    > <span class="dv"
    >&#8759;</span
    >          <span class="dt"
    >BNat</span
    > (<span class="dt"
    >S</span
    > n)<br
     />  <span class="dt"
    >BSucc</span
    > <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >BNat</span
    > n &#8594; <span class="dt"
    >BNat</span
    > (<span class="dt"
    >S</span
    > n)<br
     /><br
     /><span class="kw"
    >data</span
    > <span class="dt"
    >Vec</span
    > <span class="dv"
    >&#8759;</span
    > <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >ZVec</span
    > <span class="dv"
    >&#8759;</span
    >                <span class="dt"
    >Vec</span
    > <span class="dt"
    >Z</span
    >     a<br
     />  (<span class="fu"
    >:&lt;</span
    >) <span class="dv"
    >&#8759;</span
    > a &#8594; <span class="dt"
    >Vec</span
    > n a &#8594; <span class="dt"
    >Vec</span
    > (<span class="dt"
    >S</span
    > n) a<br
     /></code
      ></pre
    ><p
    >Since trie construction is type-driven, I see the vector trie based on <em
      >right-folded</em
      > composition as in line with these definitions. Left-folding would come from a small initial change, swapping the constructors in the <code
      >BNat</code
      > definition:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >data</span
    > <span class="dt"
    >BNat</span
    > <span class="dv"
    >&#8759;</span
    > <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >BSucc</span
    > <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >BNat</span
    > n &#8594; <span class="dt"
    >BNat</span
    > (<span class="dt"
    >S</span
    > n)<br
     />  <span class="dt"
    >BZero</span
    > <span class="dv"
    >&#8759;</span
    >          <span class="dt"
    >BNat</span
    > (<span class="dt"
    >S</span
    > n)<br
     /></code
      ></pre
    ><p
    >From this tweaked beginning, a <code
      >BNat</code
      > trie construction would lead to a left-associated <code
      >Vec</code
      > type:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >data</span
    > <span class="dt"
    >Vec</span
    > <span class="dv"
    >&#8759;</span
    > <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > <span class="kw"
    >where</span
    ><br
     />  (<span class="fu"
    >:&lt;</span
    >) <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >Vec</span
    > n a &#8594; a &#8594; <span class="dt"
    >Vec</span
    > (<span class="dt"
    >S</span
    > n) a<br
     />  <span class="dt"
    >ZVec</span
    > <span class="dv"
    >&#8759;</span
    >                <span class="dt"
    >Vec</span
    > <span class="dt"
    >Z</span
    >     a<br
     /></code
      ></pre
    ><p
    >And then left-folded composition for the <code
      >Vec</code
      > trie.</p
    ></div
  ></div
>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=308&amp;md5=c22f70ca5eb996033fdb76a4a76593ff" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/kiieMvb8qFI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/a-trie-for-length-typed-vectors/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/a-trie-for-length-typed-vectors</feedburner:origLink></item>
		<item>
		<title>Reverse-engineering length-typed vectors</title>
		<link>http://feedproxy.google.com/~r/conal/~3/zTa4gJm6jj4/reverse-engineering-length-typed-vectors</link>
		<comments>http://conal.net/blog/posts/reverse-engineering-length-typed-vectors#comments</comments>
		<pubDate>Mon, 31 Jan 2011 17:52:56 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=305</guid>
		<description><![CDATA[The last few posts posts followed a winding path toward a formulation of a type for length-typed vectors. In Fixing lists, I mused how something like lists could be a trie type. The Stream functor (necessarily infinite lists) is the natural trie for Peano numbers. The standard list functor  (possibly finite lists) doesn't ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p
>The <a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
  >last</a
  > <a href="http://conal.net/blog/posts/fixing-lists/" title="blog post"
  >few</a
  > <a href="http://conal.net/blog/posts/doing-more-with-length-typed-vectors/" title="blog post"
  >posts</a
  > posts followed a winding path toward a formulation of a type for length-typed vectors. In <a href="http://conal.net/blog/posts/fixing-lists/" title="blog post"
  ><em
    >Fixing lists</em
    ></a
  >, I mused how something like lists could be a trie type. The <code
  >Stream</code
  > functor (necessarily infinite lists) is the natural trie for Peano numbers. The standard list functor <code
  >[]</code
  > (possibly finite lists) doesn't seem to be a trie, since it's built from sums. However, the functor <code
  >Vec n</code
  > of vectors (&quot;fixed lists&quot;) of length <code
  >n</code
  > is built from (isomorphic to) products only (for any given <code
  >n</code
  >), and so might well be a trie.</p
>

<p
>Of what type is <code
  >Vec n</code
  > the corresponding trie? In other words, for what type <code
  >q</code
  > is <code
  >Vec n a</code
  > isomorphic to <code
  >q &#8594; a</code
  > (for all <code
  >a</code
  >).</p
>

<p
>Turning this question on its head, what simpler type gives rise to length-typed vectors in a standard fashion?</p
>

<p
><strong
  >Edits:</strong
  ></p
>

<ul
><li
  >2011-02-01: Define <code
    >Digits n b</code
    > as <code
    >BNat n &#8603; BNat b</code
    >.</li
  ></ul
>

<p><span id="more-305"></span></p>

<div id="deriving-vectors"
><h3
  >Deriving vectors</h3
  ><p
  >Recalling that <code
    >Vec n a</code
    > is an <code
    >n</code
    >-ary product of the type <code
    >a</code
    >, and forming the sort of derivation I used in <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization/" title="blog post"
    ><em
      >Memoizing polymorphic functions via unmemoization</em
      ></a
    >,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="dt"
      >Vec</span
      > n a <span class="dt"
      >&#8773;</span
      > a &#215; &#8943; &#215; a<br
       />        <span class="dt"
      >&#8773;</span
      > (<span class="dv"
      >1</span
      > &#8594; a) &#215; &#8943; &#215; (<span class="dv"
      >1</span
      > &#8594; a)<br
       />        <span class="dt"
      >&#8773;</span
      > (<span class="dv"
      >1</span
      > <span class="fu"
      >+</span
      > &#8943; <span class="fu"
      >+</span
      > <span class="dv"
      >1</span
      >) &#8594; a<br
       /></code
    ></pre
  ><p
  >where the type <code
    >1</code
    > is what we call &quot;unit&quot; or &quot;<code
    >()</code
    >&quot; in Haskell, having exactly one (non-bottom) value. I used the isomorphism <span class="math"
    >(<em
      >a</em
      > + <em
      >b</em
      >) → <em
      >c</em
      > ≅ (<em
      >a</em
      > → <em
      >c</em
      >) × (<em
      >b</em
      > → <em
      >c</em
      >)</span
    >, which corresponds to a familiar law of exponents: <span class="math"
    ><em
      >c</em
      ><sup
      ><em
    >a</em
    > + <em
    >b</em
    ></sup
      > = <em
      >c</em
      ><sup
      ><em
    >a</em
    ></sup
      > × <em
      >c</em
      ><sup
      ><em
    >b</em
    ></sup
      ></span
    >.</p
  ><p
  >So the sought domain type <code
    >q</code
    > is any type isomorphic to <code
    >1 + &#8943; + 1</code
    >, which is to say a type consisting of exactly <span class="math"
    ><em
      >n</em
      ></span
    > choices.</p
  ><p
  >We have already seen a candidate for the index type <code
    >q</code
    >, of which <code
    >Vec n</code
    > is the natural trie functor. The post <a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
    ><em
      >Type-bounded numbers</em
      ></a
    > defines a type <code
    >BNat n</code
    > corresponding to natural numbers less than <code
    >n</code
    >, where <code
    >n</code
    > is a type-encoded natural number.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BNat</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >BZero</span
      > <span class="dv"
      >&#8759;</span
      >          <span class="dt"
      >BNat</span
      > (<span class="dt"
      >S</span
      > n)<br
       />  <span class="dt"
      >BSucc</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >BNat</span
      > n &#8594; <span class="dt"
      >BNat</span
      > (<span class="dt"
      >S</span
      > n)<br
       /></code
    ></pre
  ><p
  >These two constructors correspond to two axioms about inequality: <span class="math"
    >0 &lt; <em
      >n</em
      > + 1</span
    > and <span class="math"
    ><em
      >m</em
      > &lt; <em
      >n</em
      > ⇒ <em
      >m</em
      > + 1 &lt; <em
      >n</em
      > + 1</span
    >. The type <code
    >BNat n</code
    > then corresponds to canonoical proofs that <span class="math"
    ><em
      >m</em
      > &lt; <em
      >n</em
      ></span
    > for various values of <span class="math"
    ><em
      >m</em
      ></span
    >, where the proofs are built out of the two axioms and the law of <em
    >modus ponens</em
    > (which corresponds to function application).</p
  ><p
  >Assuming a type <code
    >n</code
    > is built up solely from <code
    >Z</code
    > and <code
    >S</code
    >, a simple inductive argument shows that the number of fully-defined elements (not containing <code
    >&#8869;</code
    >) of <code
    >BNat n</code
    > is the natural number corresponding to <code
    >n</code
    > (i.e., <code
    >nat &#8759; Nat n</code
    >, where <code
    >nat</code
    > is as in the post <a href="http://conal.net/blog/posts/doing-more-with-length-typed-vectors/" title="blog post"
    ><em
      >Doing more with length-typed vectors</em
      ></a
    >).</p
  ></div
>

<div id="vectors-as-numbers"
><h3
  >Vectors as numbers</h3
  ><p
  >We've seen that <code
    >Vec</code
    > is a trie for bounded unary numbers, i.e., <code
    >BNat n &#8603; a &#8801; Vec n a</code
    >, using the notation from <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post"
    ><em
      >Elegant memoization with higher-order types</em
      ></a
    >. (Note that I've changed my pretty-printing from &quot;<code
    >k :&#8594;: v</code
    >&quot; to &quot;<code
    >k &#8603; v</code
    >&quot;.)</p
  ><p
  >It's also the case that a vector of digits can be used to <em
    >represent</em
    > numbers:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Digits</span
      > n b <span class="fu"
      >=</span
      > <span class="dt"
      >Vec</span
      > n (<span class="dt"
      >BNat</span
      > b)  <span class="co"
      >-- n-digit number in base b</span
      ><br
       /></code
    ></pre
  ><p
  >Or, more pleasing to my eye,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Digits</span
      > n b <span class="fu"
      >=</span
      > <span class="dt"
      >BNat</span
      > n &#8603; <span class="dt"
      >BNat</span
      > b<br
       /></code
    ></pre
  ><p
  >These representations can be given a little-endian or big-endian interpretation:</p
  ><pre class="sourceCode haskell"
  ><code
    >littleEndianToZ, bigEndianToZ <span class="dv"
      >&#8759;</span
      > &#8704; n b<span class="fu"
      >.</span
      > <span class="dt"
      >IsNat</span
      > b &#8658; <span class="dt"
      >Digits</span
      > n b &#8594; <span class="dt"
      >Integer</span
      ><br
       /></code
    ></pre
  ><pre class="sourceCode haskell"
  ><code
    >littleEndianToZ <span class="fu"
      >=</span
      > foldr' (&#955; x s &#8594; fromBNat x <span class="fu"
      >+</span
      > b <span class="fu"
      >*</span
      > s) <span class="dv"
      >0</span
      ><br
       /> <span class="kw"
      >where</span
      > b <span class="fu"
      >=</span
      > natToZ (nat <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Nat</span
      > b)<br
       /></code
    ></pre
  ><pre class="sourceCode haskell"
  ><code
    >bigEndianToZ    <span class="fu"
      >=</span
      > foldl' (&#955; s x &#8594; fromBNat x <span class="fu"
      >+</span
      > b <span class="fu"
      >*</span
      > s) <span class="dv"
      >0</span
      ><br
       /> <span class="kw"
      >where</span
      > b <span class="fu"
      >=</span
      > natToZ (nat <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Nat</span
      > b)<br
       /></code
    ></pre
  ><p
  >The <code
    >foldl'</code
    > and <code
    >foldr'</code
    > are from <a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Foldable.html#v:foldl-39-"
    ><code
      >Data.Foldable</code
      ></a
    >.</p
  ><p
  >Give it a try:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >Vec</span
      ><span class="fu"
      >&gt;</span
      > <span class="kw"
      >let</span
      > ds <span class="fu"
      >=</span
      > <span class="fu"
      >map</span
      > toBNat [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >] <span class="dv"
      >&#8759;</span
      > [<span class="dt"
      >BNat</span
      > <span class="dt"
      >TenT</span
      >]<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >Vec</span
      ><span class="fu"
      >&gt;</span
      > <span class="kw"
      >let</span
      > v3 <span class="fu"
      >=</span
      > fromList ds <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > <span class="dt"
      >ThreeT</span
      > (<span class="dt"
      >BNat</span
      > <span class="dt"
      >TenT</span
      >)<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >Vec</span
      ><span class="fu"
      >&gt;</span
      > v3<br
       />fromList [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >]<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >Vec</span
      ><span class="fu"
      >&gt;</span
      > littleEndianToZ v3<br
       /><span class="dv"
      >753</span
      ><br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >Vec</span
      ><span class="fu"
      >&gt;</span
      > bigEndianToZ v3<br
       /><span class="dv"
      >357</span
      ><br
       /></code
    ></pre
  ><p
  >It's a shame here to map to the unconstrained <code
    >Integer</code
    > type, since (a) the result must be a natural number, and (b) the result is statically bounded by <span class="math"
    ><em
      >b</em
      ><sup
      ><em
    >n</em
    ></sup
      ></span
    >.</p
  ></div
>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=305&amp;md5=149f3f6ab1983a1194b76aa15ee55562" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/zTa4gJm6jj4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/reverse-engineering-length-typed-vectors/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/reverse-engineering-length-typed-vectors</feedburner:origLink></item>
		<item>
		<title>Doing more with length-typed vectors</title>
		<link>http://feedproxy.google.com/~r/conal/~3/v9drsriDmv4/doing-more-with-length-typed-vectors</link>
		<comments>http://conal.net/blog/posts/doing-more-with-length-typed-vectors#comments</comments>
		<pubDate>Mon, 31 Jan 2011 01:16:09 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[applicative functor]]></category>
		<category><![CDATA[monad]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=293</guid>
		<description><![CDATA[The post Fixing lists defined a (commonly used) type of vectors, whose lengths are determined statically, by type. In Vec n a, the length is n, and the elements have type a, where n is a type-encoded unary number, built up from zero and successor (Z and S).infixr 5 :&#60;data Vec &#8759; * &#8594; ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p
>The post <a href="http://conal.net/blog/posts/fixing-lists/" title="blog post"
  ><em
    >Fixing lists</em
    ></a
  > defined a (commonly used) type of vectors, whose lengths are determined statically, by type. In <code
  >Vec n a</code
  >, the length is <code
  >n</code
  >, and the elements have type <code
  >a</code
  >, where <code
  >n</code
  > is a type-encoded unary number, built up from zero and successor (<code
  >Z</code
  > and <code
  >S</code
  >).</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >infixr</span
    > <span class="dv"
    >5</span
    > <span class="fu"
    >:&lt;</span
    ><br
     /><br
     /><span class="kw"
    >data</span
    > <span class="dt"
    >Vec</span
    > <span class="dv"
    >&#8759;</span
    > <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > &#8594; <span class="fu"
    >*</span
    > <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >ZVec</span
    > <span class="dv"
    >&#8759;</span
    >                <span class="dt"
    >Vec</span
    > <span class="dt"
    >Z</span
    >     a<br
     />  (<span class="fu"
    >:&lt;</span
    >) <span class="dv"
    >&#8759;</span
    > a &#8594; <span class="dt"
    >Vec</span
    > n a &#8594; <span class="dt"
    >Vec</span
    > (<span class="dt"
    >S</span
    > n) a<br
     /></code
  ></pre
>

<p
>It was fairly easy to define <code
  >foldr</code
  > for a <code
  >Foldable</code
  > instance, <code
  >fmap</code
  > for <code
  >Functor</code
  >, and <code
  >(&#8859;)</code
  > for <code
  >Applicative</code
  >. Completing the <code
  >Applicative</code
  > instance is tricky, however. Unlike <code
  >foldr</code
  >, <code
  >fmap</code
  >, and <code
  >(&#8859;)</code
  >, <code
  >pure</code
  > doesn't have a vector structure to crawl over. It must create just the right structure anyway. I left this challenge as a question to amuse readers. In this post, I give a few solutions, including my current favorite.</p
>

<p
>You can find the code for this post and the two <a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
  >previous</a
  > <a href="http://conal.net/blog/posts/fixing-lists/" title="blog post"
  >ones</a
  > in a <a href="https://github.com/conal/numbers-vectors-trees/" title="github repository"
  >code repository</a
  >.</p
>

<p><span id="more-293"></span></p>

<div id="an-applicative-instance"
><h3
  >An Applicative instance</h3
  ><p
  >As a review, here is our <code
    >Functor</code
    > instance:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="kw"
      >Functor</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  <span class="fu"
      >fmap</span
      > _ <span class="dt"
      >ZVec</span
      >     <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       />  <span class="fu"
      >fmap</span
      > f (a <span class="fu"
      >:&lt;</span
      > u) <span class="fu"
      >=</span
      > f a <span class="fu"
      >:&lt;</span
      > <span class="fu"
      >fmap</span
      > f u<br
       /></code
    ></pre
  ><p
  >And part of an <code
    >Applicative</code
    > instance:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="dt"
      >Applicative</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  pure a <span class="fu"
      >=</span
      > <span class="fu"
      >??</span
      ><br
       />  <span class="dt"
      >ZVec</span
      >      &#8859; <span class="dt"
      >ZVec</span
      >      <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       />  (f <span class="fu"
      >:&lt;</span
      > fs) &#8859; (x <span class="fu"
      >:&lt;</span
      > xs) <span class="fu"
      >=</span
      > f x <span class="fu"
      >:&lt;</span
      > (fs &#8859; xs)<br
       /></code
    ></pre
  ><p
  >For <code
    >pure</code
    >, recall the troublesome goal signature:</p
  ><pre class="sourceCode haskell"
  ><code
    >  pure <span class="dv"
      >&#8759;</span
      > a &#8594; <span class="dt"
      >Vec</span
      > n a<br
       /></code
    ></pre
  ><p
  >There's at least one very good reason this type is problematic. The type <code
    >n</code
    > is <em
    >completely</em
    > unrestricted. There is nothing to require <code
    >n</code
    > to be a natural number type, rather than <code
    >Bool</code
    >, <code
    >String</code
    >, <code
    >String &#8594; Bool</code
    >, etc.</p
  ><p
  >In contrast to this difficulty with <code
    >pure</code
    >, consider what if <code
    >n &#8801; String</code
    > in the type of <code
    >fmap</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >fmap</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b) &#8594; <span class="dt"
      >Vec</span
      > n a &#8594; <span class="dt"
      >Vec</span
      > n b<br
       /></code
    ></pre
  ><p
  >The definition of <code
    >Vec</code
    > guarantees that that there are no values of type <code
    >Vec String a</code
    >. So it's vacuously easy to cover that case (with an empty function). Similarly for <code
    >(&#8859;)</code
    >.</p
  ><p
  >If we were to somehow define <code
    >pure</code
    > with the type given above, then <code
    >pure ()</code
    > would have type <code
    >Vec String ()</code
    > (among many other types). However, there are no values of that type. Hence, <code
    >pure</code
    > cannot be defined without restricting <code
    >n</code
    >.</p
  ><p
  >Since the essential difficulty here is the unrestricted nature of <code
    >n</code
    >, let's look at restricting it. We'll want to include exactly the types that can arise in constructing <code
    >Vec</code
    > values, namely <code
    >Z</code
    >, <code
    >S Z</code
    >, <code
    >S (S Z)</code
    >, <code
    >S (S (S Z))</code
    >, etc.</p
  ><p
  >As a first try, define a class with two instances:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >class</span
      > <span class="dt"
      >IsNat</span
      > n<br
       /><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > <span class="dt"
      >Z</span
      ><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >IsNat</span
      > (<span class="dt"
      >S</span
      > n)<br
       /></code
    ></pre
  ><p
  >Then change the <code
    >Applicative</code
    > instance to require <code
    >IsNat n</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >Applicative</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  &#8943;<br
       /></code
    ></pre
  ><p
  >The definition of <code
    >(&#8859;)</code
    > given above still type-checks. Well, not quite. Really, the recursive call to <code
    >(&#8859;)</code
    > fails to type-check, because the <code
    >IsNat</code
    > constraint cannot be proved. One solution is to add that constraint to the vector type:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >Vec</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >ZVec</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > <span class="dt"
      >Z</span
      > a<br
       />  (<span class="fu"
      >:&lt;</span
      >) <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; a &#8594; <span class="dt"
      >Vec</span
      > n a &#8594; <span class="dt"
      >Vec</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >Another is to break the definition <code
    >(&#8859;)</code
    > out into a separate recursion that omits the <code
    >IsNat</code
    > constraint:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >Applicative</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  pure <span class="fu"
      >=</span
      > <span class="fu"
      >???</span
      ><br
       />  (&#8859;)  <span class="fu"
      >=</span
      > applyV<br
       /><br
       />applyV <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > n (a &#8594; b) &#8594; <span class="dt"
      >Vec</span
      > n a &#8594; <span class="dt"
      >Vec</span
      > n b<br
       /><span class="dt"
      >ZVec</span
      >      <span class="ot"
      >`applyV`</span
      > <span class="dt"
      >ZVec</span
      >      <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       />(f <span class="fu"
      >:&lt;</span
      > fs) <span class="ot"
      >`applyV`</span
      > (x <span class="fu"
      >:&lt;</span
      > xs) <span class="fu"
      >=</span
      > f x <span class="fu"
      >:&lt;</span
      > (fs <span class="ot"
      >`applyV`</span
      > xs)<br
       /></code
    ></pre
  ><p
  >Now, how can we define <code
    >pure</code
    >? We still don't have enough structure. To get that structure, add a method to <code
    >IsNat</code
    >. That method could simply be the definition of <code
    >pure</code
    > that we need.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >class</span
      > <span class="dt"
      >IsNat</span
      > n <span class="kw"
      >where</span
      > pureN <span class="dv"
      >&#8759;</span
      > a &#8594; <span class="dt"
      >Vec</span
      > n a<br
       /><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > <span class="dt"
      >Z</span
      >                <span class="kw"
      >where</span
      > pureN a <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >IsNat</span
      > (<span class="dt"
      >S</span
      > n) <span class="kw"
      >where</span
      > pureN a <span class="fu"
      >=</span
      > a <span class="fu"
      >:&lt;</span
      > pureN a<br
       /></code
    ></pre
  ><p
  >To get this second instance to type-check, we'll have to add the constraint <code
    >IsNat n</code
    > to the <code
    >(:&lt;)</code
    > constructor in <code
    >Vec</code
    >. Then define <code
    >pure = pureN</code
    > for <code
    >Vec</code
    >.</p
  ><p
  >I prefer a variation on this solution. Instead of <code
    >pureN</code
    >, use a method that can only make vectors of <code
    >()</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >class</span
      > <span class="dt"
      >IsNat</span
      > n <span class="kw"
      >where</span
      > units <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > n ()<br
       /><br
       /><span class="kw"
      >instance</span
      >            <span class="dt"
      >IsNat</span
      > <span class="dt"
      >Z</span
      >     <span class="kw"
      >where</span
      > units <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >IsNat</span
      > (<span class="dt"
      >S</span
      > n) <span class="kw"
      >where</span
      > units <span class="fu"
      >=</span
      > () <span class="fu"
      >:&lt;</span
      > units<br
       /></code
    ></pre
  ><p
  >Then define</p
  ><pre class="sourceCode haskell"
  ><code
    >  pure a <span class="fu"
      >=</span
      > <span class="fu"
      >fmap</span
      > (<span class="fu"
      >const</span
      > a) units<br
       /></code
    ></pre
  ><p
  >Neat trick, huh? I got it from <a href="http://www.soi.city.ac.uk/~ross/papers/Applicative.html" title="Paper by Conor McBride and Ross Paterson"
    ><em
      >Applicative Programming with Effects</em
      ></a
    > (section 7).</p
  ></div
>

<div id="value-typed-natural-numbers"
><h3
  >Value-typed natural numbers</h3
  ><p
  >There's still another way to define <code
    >IsNat</code
    >, and it's the one I actually use.</p
  ><p
  >Define a type of natural number with matching value &amp; type:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >Nat</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >Zero</span
      > <span class="dv"
      >&#8759;</span
      >                    <span class="dt"
      >Nat</span
      > <span class="dt"
      >Z</span
      ><br
       />  <span class="dt"
      >Succ</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >Nat</span
      > n &#8594; <span class="dt"
      >Nat</span
      > (<span class="dt"
      >S</span
      > n)<br
       /></code
    ></pre
  ><p
  >Interpret a <code
    >Nat</code
    > as an <code
    >Integer</code
    ></p
  ><pre class="sourceCode haskell"
  ><code
    >natToZ <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Nat</span
      > n &#8594; <span class="dt"
      >Integer</span
      ><br
       />natToZ <span class="dt"
      >Zero</span
      >     <span class="fu"
      >=</span
      > <span class="dv"
      >0</span
      ><br
       />natToZ (<span class="dt"
      >Succ</span
      > n) <span class="fu"
      >=</span
      > (<span class="fu"
      >succ</span
      > &#8728; natToZ) n<br
       /></code
    ></pre
  ><p
  >I wrote the second clause strangely to emphasize the following lovely property, which corresponds to a simple commutative diagram:</p
  ><pre class="sourceCode haskell"
  ><code
    >natToZ &#8728; <span class="dt"
      >Succ</span
      > <span class="fu"
      >=</span
      > <span class="fu"
      >succ</span
      > &#8728; natToZ<br
       /></code
    ></pre
  ><p
  >This <code
    >natToZ</code
    > function is handy for showing natural numbers:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="kw"
      >Show</span
      > (<span class="dt"
      >Nat</span
      > n) <span class="kw"
      >where</span
      > <span class="fu"
      >show</span
      > <span class="fu"
      >=</span
      > <span class="fu"
      >show</span
      > &#8728; natToZ<br
       /></code
    ></pre
  ><p
  >A fun &amp; strange thing about <code
    >Nat n</code
    > is that it can have at most one inhabitant for any type <code
    >n</code
    >. We can synthesize that inhabitant via an alternative definition of the <code
    >IsNat</code
    > class defined (twice) above:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >class</span
      > <span class="dt"
      >IsNat</span
      > n <span class="kw"
      >where</span
      > nat <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Nat</span
      > n<br
       /><br
       /><span class="kw"
      >instance</span
      >            <span class="dt"
      >IsNat</span
      > <span class="dt"
      >Z</span
      >     <span class="kw"
      >where</span
      > nat <span class="fu"
      >=</span
      > <span class="dt"
      >Zero</span
      ><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >IsNat</span
      > (<span class="dt"
      >S</span
      > n) <span class="kw"
      >where</span
      > nat <span class="fu"
      >=</span
      > <span class="dt"
      >Succ</span
      > nat<br
       /></code
    ></pre
  ><p
  >Using this latest version of <code
    >IsNat</code
    >, we can easily define <code
    >units</code
    > (and hence <code
    >pure</code
    > on <code
    >Vec n</code
    > for <code
    >IsNat n</code
    >):</p
  ><pre class="sourceCode haskell"
  ><code
    >units <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >Vec</span
      > n ()<br
       />units <span class="fu"
      >=</span
      > unitsN nat<br
       /><br
       />unitsN <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Nat</span
      > n &#8594; <span class="dt"
      >Vec</span
      > n ()<br
       />unitsN <span class="dt"
      >Zero</span
      >     <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       />unitsN (<span class="dt"
      >Succ</span
      > n) <span class="fu"
      >=</span
      > () <span class="fu"
      >:&lt;</span
      > unitsN n<br
       /></code
    ></pre
  ><p
  >I prefer this latest <code
    >IsNat</code
    > definition over the previous two, because it relies only on <code
    >Nat</code
    >, which is simpler and more broadly useful than <code
    >Vec</code
    >. Examples abound, including improving an recent post, as we'll see now.</p
  ></div
>

<div id="revisiting-type-bounded-numbers"
><h3
  >Revisiting type-bounded numbers</h3
  ><p
  >The post <a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
    ><em
      >Type-bounded numbers</em
      ></a
    > defined a type <code
    >BNat n</code
    > of natural numbers less than <code
    >n</code
    >, which can be used, for instance, as numerical digits in base <code
    >n</code
    >.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BNat</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >BZero</span
      > <span class="dv"
      >&#8759;</span
      >          <span class="dt"
      >BNat</span
      > (<span class="dt"
      >S</span
      > n)<br
       />  <span class="dt"
      >BSucc</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >BNat</span
      > n &#8594; <span class="dt"
      >BNat</span
      > (<span class="dt"
      >S</span
      > n)<br
       /></code
    ></pre
  ><p
  >One useful operation is conversion from integer to <code
    >BNat n</code
    >. This operation had the awkward task of coming up with <code
    >BNat</code
    > structure. The solution given was to introduce a type class, with instances for <code
    >Z</code
    > and <code
    >S</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >class</span
      > <span class="dt"
      >HasBNat</span
      > n <span class="kw"
      >where</span
      > toBNat <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Integer</span
      > &#8594; <span class="dt"
      >Maybe</span
      > (<span class="dt"
      >BNat</span
      > n)<br
       /><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >HasBNat</span
      > <span class="dt"
      >Z</span
      > <span class="kw"
      >where</span
      > toBNat _ <span class="fu"
      >=</span
      > <span class="kw"
      >Nothing</span
      ><br
       /><br
       /><span class="kw"
      >instance</span
      > <span class="dt"
      >HasBNat</span
      > n &#8658; <span class="dt"
      >HasBNat</span
      > (<span class="dt"
      >S</span
      > n) <span class="kw"
      >where</span
      ><br
       />  toBNat m <span class="fu"
      >|</span
      > m <span class="fu"
      >&lt;</span
      > <span class="dv"
      >1</span
      >     <span class="fu"
      >=</span
      > <span class="kw"
      >Just</span
      > <span class="dt"
      >BZero</span
      ><br
       />           <span class="fu"
      >|</span
      > <span class="fu"
      >otherwise</span
      > <span class="fu"
      >=</span
      > <span class="fu"
      >fmap</span
      > <span class="dt"
      >BSucc</span
      > (toBNat (<span class="fu"
      >pred</span
      > m))<br
       /></code
    ></pre
  ><p
  >We can instead eliminate the <code
    >HasBNat</code
    > class and reuse the <code
    >IsNat</code
    > class, as in the last technique above for defining <code
    >units</code
    > or <code
    >pure</code
    >.</p
  ><pre class="sourceCode haskell"
  ><code
    >toBNat <span class="dv"
      >&#8759;</span
      > &#8704; n<span class="fu"
      >.</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="dt"
      >Integer</span
      > &#8594; <span class="dt"
      >Maybe</span
      > (<span class="dt"
      >BNat</span
      > n)<br
       />toBNat <span class="fu"
      >=</span
      > loop n <span class="kw"
      >where</span
      ><br
       />  n <span class="fu"
      >=</span
      > nat <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Nat</span
      > n<br
       />  loop <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Nat</span
      > n' &#8594; <span class="dt"
      >Integer</span
      > &#8594; <span class="dt"
      >Maybe</span
      > (<span class="dt"
      >BNat</span
      > n')<br
       />  loop <span class="dt"
      >Zero</span
      >      _ <span class="fu"
      >=</span
      > <span class="kw"
      >Nothing</span
      ><br
       />  loop (<span class="dt"
      >Succ</span
      > _)  <span class="dv"
      >0</span
      > <span class="fu"
      >=</span
      > <span class="kw"
      >Just</span
      > <span class="dt"
      >BZero</span
      ><br
       />  loop (<span class="dt"
      >Succ</span
      > n') m <span class="fu"
      >=</span
      > <span class="fu"
      >fmap</span
      > <span class="dt"
      >BSucc</span
      > (loop n' (<span class="fu"
      >pred</span
      > m))<br
       /></code
    ></pre
  ></div
>

<div id="a-monad-instance"
><h3
  >A Monad instance</h3
  ><p
  >First the easy parts: standard definitions in terms of <code
    >pure</code
    > and <code
    >join</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="dt"
      >IsNat</span
      > n &#8658; <span class="kw"
      >Monad</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  <span class="fu"
      >return</span
      >  <span class="fu"
      >=</span
      > pure<br
       />  v <span class="fu"
      >&gt;&gt;=</span
      > f <span class="fu"
      >=</span
      > join (<span class="fu"
      >fmap</span
      > f v)<br
       /></code
    ></pre
  ><p
  >The <code
    >join</code
    > function on <code
    >Vec n</code
    > is just like <code
    >join</code
    > for functions and for streams. (Rightly so, considering the principle of <a href="http://conal.net/blog/tag/type-class-morphism/" title="Posts on type class morphisms"
    >type class morphism</a
    >s.) It uses diagonalization, and one way to think of vector <code
    >join</code
    > is that it extracts the diagonal of a square matrix.</p
  ><pre class="sourceCode haskell"
  ><code
    >join <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > n (<span class="dt"
      >Vec</span
      > n a) &#8594; <span class="dt"
      >Vec</span
      > n a<br
       />join <span class="dt"
      >ZVec</span
      >      <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       />join (v <span class="fu"
      >:&lt;</span
      > vs) <span class="fu"
      >=</span
      > headV v <span class="fu"
      >:&lt;</span
      > join (<span class="fu"
      >fmap</span
      > tailV vs)<br
       /></code
    ></pre
  ><p
  >The <code
    >headV</code
    > and <code
    >tailV</code
    > functions are like <code
    >head</code
    > and <code
    >tail</code
    > but understand lengths:</p
  ><pre class="sourceCode haskell"
  ><code
    >headV <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > (<span class="dt"
      >S</span
      > n) a &#8594; a<br
       />headV (a <span class="fu"
      >:&lt;</span
      > _) <span class="fu"
      >=</span
      > a<br
       /></code
    ></pre
  ><pre class="sourceCode haskell"
  ><code
    >tailV <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > (<span class="dt"
      >S</span
      > n) a &#8594; <span class="dt"
      >Vec</span
      > n a<br
       />tailV (_ <span class="fu"
      >:&lt;</span
      > as) <span class="fu"
      >=</span
      > as<br
       /></code
    ></pre
  ><p
  >Unlike their list counterparts, <code
    >headV</code
    > and <code
    >tailV</code
    > are <em
    >safe</em
    >, in that the precondition of non-emptiness is verified statically.</p
  ></div
>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=293&amp;md5=0fd4950067e60840fabf4f89a33ab982" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/v9drsriDmv4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/doing-more-with-length-typed-vectors/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/doing-more-with-length-typed-vectors</feedburner:origLink></item>
		<item>
		<title>Fixing lists</title>
		<link>http://feedproxy.google.com/~r/conal/~3/NOZPBCJwsPA/fixing-lists</link>
		<comments>http://conal.net/blog/posts/fixing-lists#comments</comments>
		<pubDate>Sun, 30 Jan 2011 18:14:30 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[applicative functor]]></category>
		<category><![CDATA[functor]]></category>
		<category><![CDATA[number]]></category>
		<category><![CDATA[trie]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=284</guid>
		<description><![CDATA[In the post Memoizing polymorphic functions via unmemoization, I toyed with the idea of lists as tries. I don't think  is a trie, simply because  is a sum type (being either nil or a cons), while tries are built out of the identity, product, and composition functors. In contrast, Stream is a ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p
>In the post <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization/" title="blog post"
  ><em
    >Memoizing polymorphic functions via unmemoization</em
    ></a
  >, I toyed with the idea of lists as tries. I don&#8217;t think <code
  >[a]</code
  > is a trie, simply because <code
  >[a]</code
  > is a <em
  >sum</em
  > type (being either nil or a cons), while tries are built out of the identity, product, and composition functors. In contrast, <code
  >Stream</code
  > <em
  >is</em
  > a trie, being built solely with the identity and product functors. Moreover, <code
  >Stream</code
  > is not just any old trie, it is the trie that corresponds to Peano (unary natural) numbers, i.e., <code
  >Stream a &#8773; N &#8594; a</code
  >, where</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >data</span
    > <span class="dt"
    >N</span
    > <span class="fu"
    >=</span
    > <span class="dt"
    >Zero</span
    > <span class="fu"
    >|</span
    > <span class="dt"
    >Succ</span
    > <span class="dt"
    >N</span
    ><br
     /><br
     /><span class="kw"
    >data</span
    > <span class="dt"
    >Stream</span
    > a <span class="fu"
    >=</span
    > <span class="dt"
    >Cons</span
    > a (<span class="dt"
    >Stream</span
    > a)<br
     /></code
  ></pre
>

<p
>If we didn't already know the <code
  >Stream</code
  > type, we would derive it systematically from <code
  >N</code
  >, using standard isomorphisms.</p
>

<p
><code
  >Stream</code
  > is a trie (over unary numbers), thanks to it having no choice points, i.e., no sums in its construction. However, streams are infinite-only, which is not always what we want. In contrast, lists can be finite, but are not a trie in any sense I understand. In this post, I look at how to <em
  >fix</em
  > lists, so they can be finite and yet be a trie, thanks to having no choice points (sums)?</p
>

<p
>You can find the code for this post and the <a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
  >previous one</a
  > in a <a href="https://github.com/conal/numbers-vectors-trees/" title="github repository"
  >code repository</a
  >.</p
>

<p
><strong
  >Edits</strong
  >:</p
>

<ul
><li
  >2011-01-30: Added spoilers warning.</li
  ><li
  >2011-01-30: Pointer to <a href="https://github.com/conal/numbers-vectors-trees/" title="github repository"
    >code repository</a
    >.</li
  ></ul
>

<p><span id="more-284"></span></p>

<div id="fixing-lists"
><h3
  >Fixing lists</h3
  ><p
  >Is there a type of finite lists without choice points (sums)? Yes. There are lots of them. One for each length. Instead of having a single type of lists, have an infinite family of types of <span class="math"
    ><em
      >n</em
      ></span
    >-element lists, one type for each <span class="math"
    ><em
      >n</em
      ></span
    >.</p
  ><p
  >In other words, to fix the problem with lists (trie-unfriendliness), split up the usual list type into subtypes (so to speak), each of which has a fixed length.</p
  ><p
  >I realize I'm changing the question to a simpler one. I hope you'll forgive me and hang in to see where this ride goes.</p
  ><p
  >As a first try, we might use tuples as our fixed-length lists:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >L0</span
      > a <span class="fu"
      >=</span
      > ()<br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >L1</span
      > a <span class="fu"
      >=</span
      > (a)<br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >L2</span
      > a <span class="fu"
      >=</span
      > (a,a)<br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >L3</span
      > a <span class="fu"
      >=</span
      > (a,a,a)<br
       />&#8943;<br
       /></code
    ></pre
  ><p
  >However, we can only write down finitely many such types, and I don't know how we could write any definitions that are polymorphic over <em
    >length</em
    >.</p
  ><p
  >What can &quot;polymorphic over length&quot; mean in a setting like Haskell, where polymorphism is over <em
    >types</em
    > rather than <em
    >values</em
    >. Can we express numbers (for lengths, etc) as types? Yes, as in the previous post, <a href="http://conal.net/blog/posts/type-bounded-numbers/" title="blog post"
    ><em
      >Type-bounded numbers</em
      ></a
    >, using a common encoding:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >Z</span
      >    <span class="co"
      >-- zero</span
      ><br
       /><span class="kw"
      >data</span
      > <span class="dt"
      >S</span
      > n  <span class="co"
      >-- successor</span
      ><br
       /></code
    ></pre
  ><p
  >Given these type-level numbers, we can define a data type <code
    >Vec n a</code
    >, containing only vectors (fixed lists) of length <code
    >n</code
    > and elements of type <code
    >a</code
    >. Such vectors can be built up as either the zero-length vector, or by adding an element to an vector of length <span class="math"
    ><em
      >n</em
      ></span
    > to get a vector of length <span class="math"
    ><em
      >n</em
      > + 1</span
    >. I don't know how to define this type as a regular algebraic data type, but it's easy as a <em
    >generalized</em
    > algebraic data type (<a href="http://en.wikibooks.org/wiki/Haskell/GADT" title="Haskell Wikibook page"
    >GADT</a
    >):</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >infixr</span
      > <span class="dv"
      >5</span
      > <span class="fu"
      >:&lt;</span
      ><br
       /><br
       /><span class="kw"
      >data</span
      > <span class="dt"
      >Vec</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >ZVec</span
      > <span class="dv"
      >&#8759;</span
      >                <span class="dt"
      >Vec</span
      > <span class="dt"
      >Z</span
      >     a<br
       />  (<span class="fu"
      >:&lt;</span
      >) <span class="dv"
      >&#8759;</span
      > a &#8594; <span class="dt"
      >Vec</span
      > n a &#8594; <span class="dt"
      >Vec</span
      > (<span class="dt"
      >S</span
      > n) a<br
       /></code
    ></pre
  ><p
  >For example,</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >Vec</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >:</span
      >ty <span class="ch"
      >'z'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="ch"
      >'o'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="ch"
      >'m'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="ch"
      >'g'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="dt"
      >ZVec</span
      ><br
       /><span class="ch"
      >'z'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="ch"
      >'o'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="ch"
      >'m'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="ch"
      >'g'</span
      > <span class="fu"
      >:&lt;</span
      > <span class="dt"
      >ZVec</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > (<span class="dt"
      >S</span
      > (<span class="dt"
      >S</span
      > (<span class="dt"
      >S</span
      > (<span class="dt"
      >S</span
      > <span class="dt"
      >Z</span
      >)))) <span class="dt"
      >Char</span
      ><br
       /></code
    ></pre
  ><p
  >As desired, <code
    >Vec</code
    > is length-typed, covers all (finite) lengths, and allows definition of length-polymorphic functions. For instance, it's easy to map functions over vectors:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="kw"
      >Functor</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  <span class="fu"
      >fmap</span
      > _ <span class="dt"
      >ZVec</span
      >     <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       />  <span class="fu"
      >fmap</span
      > f (a <span class="fu"
      >:&lt;</span
      > u) <span class="fu"
      >=</span
      > f a <span class="fu"
      >:&lt;</span
      > <span class="fu"
      >fmap</span
      > f u<br
       /></code
    ></pre
  ><p
  >The type of <code
    >fmap</code
    > here is <code
    >(a &#8594; b) &#8594; Vec n a &#8594; Vec n b</code
    >.</p
  ><p
  >Folding over vectors is also straightforward:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="dt"
      >Foldable</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  <span class="fu"
      >foldr</span
      > _ b <span class="dt"
      >ZVec</span
      >      <span class="fu"
      >=</span
      > b<br
       />  <span class="fu"
      >foldr</span
      > h b (a <span class="fu"
      >:&lt;</span
      > as) <span class="fu"
      >=</span
      > a <span class="ot"
      >`h`</span
      > <span class="fu"
      >foldr</span
      > h b as<br
       /></code
    ></pre
  ><p
  >Is <code
    >Vec n</code
    > an applicative functor as well?</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="dt"
      >Applicative</span
      > (<span class="dt"
      >Vec</span
      > n) <span class="kw"
      >where</span
      ><br
       />  &#8943;<br
       /></code
    ></pre
  ><p
  >We would need</p
  ><pre class="sourceCode haskell"
  ><code
    >pure <span class="dv"
      >&#8759;</span
      > a &#8594; <span class="dt"
      >Vec</span
      > n a<br
       />(&#8859;)  <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Vec</span
      > n (a &#8594; b) &#8594; <span class="dt"
      >Vec</span
      > n a &#8594; <span class="dt"
      >Vec</span
      > n b<br
       /></code
    ></pre
  ><p
  >The <code
    >(&#8859;)</code
    > method can be defined similarly to <code
    >fmap</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    >  <span class="dt"
      >ZVec</span
      >      &#8859; <span class="dt"
      >ZVec</span
      >      <span class="fu"
      >=</span
      > <span class="dt"
      >ZVec</span
      ><br
       />  (f <span class="fu"
      >:&lt;</span
      > fs) &#8859; (x <span class="fu"
      >:&lt;</span
      > xs) <span class="fu"
      >=</span
      > f x <span class="fu"
      >:&lt;</span
      > (fs &#8859; xs)<br
       /></code
    ></pre
  ><p
  >Unlike <code
    >fmap</code
    > and <code
    >(&#8859;)</code
    >, <code
    >pure</code
    > doesn't have a vector structure to crawl over. It must create just the right structure anyway. You might enjoy thinking about how to solve this puzzle, which I'll tackle in my next post. (Warning: spoilers in the comments below.)</p
  ></div
>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=284&amp;md5=8a876a1ca74b5e365684d743df52c81c" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/NOZPBCJwsPA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/fixing-lists/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/fixing-lists</feedburner:origLink></item>
		<item>
		<title>Type-bounded numbers</title>
		<link>http://feedproxy.google.com/~r/conal/~3/Sclnv8JRFeA/type-bounded-numbers</link>
		<comments>http://conal.net/blog/posts/type-bounded-numbers#comments</comments>
		<pubDate>Sat, 29 Jan 2011 17:53:57 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[number]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=271</guid>
		<description><![CDATA[I've been thinking a lot lately about how to derive low-level massively parallel programs from high-level specifications. One of the recurrent tools is folds (reductions) with an associative operator. Associativity allows a linear chain of computations to be restructured into a tree, exposing parallelism. I'll write up some of my thoughts on deriving parallel ...]]></description>
			<content:encoded><![CDATA[<!-- teaser -->

<p
>I&#8217;ve been thinking a lot lately about how to derive low-level massively parallel programs from high-level specifications. One of the recurrent tools is folds (reductions) with an associative operator. Associativity allows a linear <em
  >chain</em
  > of computations to be restructured into a <em
  >tree</em
  >, exposing parallelism. I&#8217;ll write up some of my thoughts on deriving parallel programs, but first I&#8217;d like to share a few fun ideas I&#8217;ve encountered, relating natural numbers (represented in various bases), vectors (one-dimensional arrays), and trees. This material got rather long for a single blog post, so I&#8217;ve broken it up into six. A theme throughout will be using types to capture the <em
  >sizes</em
  > of the numbers, vectors, and trees.</p
>

<p
>In writing this series, I wanted to explore an idea for how binary numbers can <em
  >emerge</em
  > from simpler and/or more universal notions. And how trees can likewise emerge from binary numbers.</p
>

<p
>Let&#8217;s start with unary (Peano) natural numbers:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >data</span
    > <span class="dt"
    >Unary</span
    > <span class="fu"
    >=</span
    > <span class="dt"
    >Zero</span
    > <span class="fu"
    >|</span
    > <span class="dt"
    >Succ</span
    > <span class="dt"
    >Unary</span
    ><br
     /></code
  ></pre
>

<p
>You might notice a similarity with the list type, which could be written as follows:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >data</span
    > <span class="dt"
    >List</span
    > a <span class="fu"
    >=</span
    > <span class="dt"
    >Nil</span
    > <span class="fu"
    >|</span
    > <span class="dt"
    >Cons</span
    > a (<span class="dt"
    >List</span
    > a)<br
     /></code
  ></pre
>

<p
>or with a bit of renaming:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >data</span
    > [a] <span class="fu"
    >=</span
    > [] <span class="fu"
    >|</span
    > a <span class="fu"
    >:</span
    > [a]<br
     /></code
  ></pre
>

<p
>Specializing <code
  >a</code
  > to <code
  >()</code
  >, we could just as well have define <code
  >Unary</code
  > as a list of unit values:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >type</span
    > <span class="dt"
    >Unary</span
    > <span class="fu"
    >=</span
    > [()]<br
     /></code
  ></pre
>

<p
>Though only if we're willing to ignore bottom elements (i.e., <code
  >&#8869; &#8759; ()</code
  >).</p
>

<p
>Suppose, however, that we don't want to use unary. We could define and use a type for binary natural numbers. A binary number is either zero, or a zero bit followed by a binary number, or a one bit followed by a binary number:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >data</span
    > <span class="dt"
    >Binary</span
    > <span class="fu"
    >=</span
    > <span class="dt"
    >Zero</span
    > <span class="fu"
    >|</span
    > <span class="dt"
    >ZeroAnd</span
    > <span class="dt"
    >Binary</span
    > <span class="fu"
    >|</span
    > <span class="dt"
    >OneAnd</span
    > <span class="dt"
    >Binary</span
    ><br
     /></code
  ></pre
>

<p
>Alternatively, combine the latter two cases into one, making the bit type explicit:</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >data</span
    > <span class="dt"
    >Binary</span
    > <span class="fu"
    >=</span
    > <span class="dt"
    >Zero</span
    > <span class="fu"
    >|</span
    > <span class="dt"
    >NonZero</span
    > <span class="dt"
    >Bit</span
    > <span class="dt"
    >Binary</span
    ><br
     /></code
  ></pre
>

<p
>Equivalently,</p
>

<pre class="sourceCode haskell"
><code
  ><span class="kw"
    >type</span
    > <span class="dt"
    >Binary</span
    > <span class="fu"
    >=</span
    > [<span class="dt"
    >Bit</span
    >]<br
     /></code
  ></pre
>

<p
>We could define the <code
  >Bit</code
  > type as a synonym for <code
  >Bool</code
  > or as its own distinct, two-valued data type.</p
>

<p
>Next, how about ternary numbers, decimal numbers, etc? Rather than defining an ad hoc collection of data types, how might we define a single general type of <span class="math"
  ><em
    >n</em
    ></span
  >-ary numbers?</p
>

<p
>You can find the code for this post in a <a href="https://github.com/conal/numbers-vectors-trees/" title="github repository"
  >code repository</a
  >.</p
>

<p
><strong
  >Edits</strong
  >:</p
>

<ul
><li
  >2011-01-30: Example of finding the natural numbers greater than a given one</li
  ><li
  >2011-01-30: Equality and comparison</li
  ><li
  >2011-01-30: More section headings</li
  ><li
  >2011-01-30: Mention of correspondence to commutative diagram</li
  ><li
  >2011-01-30: Pointer to <a href="https://github.com/conal/numbers-vectors-trees/" title="github repository"
    >code repository</a
    >.</li
  ></ul
>

<p><span id="more-271"></span></p>

<div id="first-try"
><h3
  >First try</h3
  ><p
  >As a first crack, we might replace the <code
    >()</code
    > and <code
    >Bit</code
    > types above with a general <code
    >Digit</code
    > type, defined as an integer:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Digit</span
      > <span class="fu"
      >=</span
      > <span class="dt"
      >Integer</span
      ><br
       /><br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >Nary</span
      > <span class="fu"
      >=</span
      > [<span class="dt"
      >Digit</span
      >]<br
       /></code
    ></pre
  ><p
  >We could then define operations to convert between <code
    >Integer</code
    > and <code
    >Nary</code
    >, and to perform arithmetic operation on <code
    >Nary</code
    >.</p
  ><p
  >This first approach has some drawbacks:</p
  ><ul
  ><li
    >In each case, one parameter would have to be the number base.</li
    ><li
    >One can accidentally produce a number as if in one base and then consume as if in another.</li
    ><li
    >One can accidentally add numbers in different bases.</li
    ><li
    >For base <span class="math"
      ><em
    >n</em
    ></span
      >, every digit is required to be in the range <span class="math"
      >0</span
      >, ..., <span class="math"
      ><em
    >n</em
    > - 1</span
      >. This constraint is not enforced statically, and so would either have to be checked dynamically (costing time and code) or could be accidentally broken.</li
    ></ul
  ><p
  >I'd rather have the number bases be statically apparent and statically checked.</p
  ><p
  >What I'm looking for is a type of <em
    >bounded</em
    > natural numbers, where <em
    >BNat n</em
    > consists of values that correspond to <span class="math"
    >0</span
    >, ..., <span class="math"
    ><em
      >n</em
      > - 1</span
    >. Then</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Nary</span
      > n <span class="fu"
      >=</span
      > [<span class="dt"
      >BNat</span
      > n]<br
       /></code
    ></pre
  ><p
  >Since the base is now part of the static type, it does not have to be passed in explicitly (and perhaps incorrectly), and it cannot be used inconsistently.</p
  ><p
  >But wait a minute! We don't have dependent types (i.e., types that depend on values) in Haskell, so what could I mean by &quot;<code
    >n</code
    >&quot; in &quot;<code
    >BNat n</code
    >&quot;?</p
  ></div
>

<div id="type-level-natural-numbers"
><h3
  >Type-level natural numbers</h3
  ><p
  >A by-now-common trick is to build type-level unary natural numbers out of two data types.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >Z</span
      >    <span class="co"
      >-- zero</span
      ><br
       /><span class="kw"
      >data</span
      > <span class="dt"
      >S</span
      > n  <span class="co"
      >-- successor</span
      ><br
       /></code
    ></pre
  ><p
  >We won't use values of these types, so there are no corresponding value constructors.</p
  ><p
  >Some handy aliases:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >ZeroT</span
      > <span class="fu"
      >=</span
      > <span class="dt"
      >Z</span
      ><br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >OneT</span
      >  <span class="fu"
      >=</span
      > <span class="dt"
      >S</span
      > <span class="dt"
      >ZeroT</span
      ><br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >TwoT</span
      >  <span class="fu"
      >=</span
      > <span class="dt"
      >S</span
      > <span class="dt"
      >OneT</span
      ><br
       />&#8943;<br
       /><span class="kw"
      >type</span
      > <span class="dt"
      >TenT</span
      >  <span class="fu"
      >=</span
      > <span class="dt"
      >S</span
      > <span class="dt"
      >NineT</span
      ><br
       /></code
    ></pre
  ><p
  >For instance, <code
    >FourT</code
    > is the type <code
    >S (S (S (S Z)))</code
    >.</p
  ></div
>

<div id="type-bounded-unary-numbers"
><h3
  >Type-bounded unary numbers</h3
  ><p
  >We want our type <code
    >BNat n</code
    > to consist of (values corresponding to) <span class="math"
    >0, . . . , <em
      >n</em
      > - 1</span
    >. To get an inductive perspective, note that (a) <code
    >BNat Z</code
    > is empty; and (b) an element of <code
    >BNat (S n)</code
    > is either <span class="math"
    >0</span
    >, or it is one more than a number in the range <span class="math"
    >0, . . . , <em
      >n</em
      > - 1</span
    >, i.e., an element of <code
    >BNat n</code
    >. These two possibilities lead directly to a representation for <code
    >BNat</code
    >, as a <a href="http://en.wikibooks.org/wiki/Haskell/GADT" title="Haskell Wikibook page"
    >GADT</a
    > (generalized algebraic data type):</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >data</span
      > <span class="dt"
      >BNat</span
      > <span class="dv"
      >&#8759;</span
      > <span class="fu"
      >*</span
      > &#8594; <span class="fu"
      >*</span
      > <span class="kw"
      >where</span
      ><br
       />  <span class="dt"
      >BZero</span
      > <span class="dv"
      >&#8759;</span
      >          <span class="dt"
      >BNat</span
      > (<span class="dt"
      >S</span
      > n)<br
       />  <span class="dt"
      >BSucc</span
      > <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >BNat</span
      > n &#8594; <span class="dt"
      >BNat</span
      > (<span class="dt"
      >S</span
      > n)<br
       /></code
    ></pre
  ><div id="conversion-to-and-from-integers"
  ><h4
    >Conversion to and from integers</h4
    ><p
    >These two constructors correspond to two facts about inequality: <span class="math"
      >0 &lt; <em
    >n</em
    > + 1</span
      >, and <span class="math"
      ><em
    >m</em
    > &lt; <em
    >n</em
    > ⇒ <em
    >m</em
    > + 1 &lt; <em
    >n</em
    > + 1</span
      >. Elements of the type <code
      >BNat n</code
      > then correspond to canonoical proofs that <span class="math"
      ><em
    >m</em
    > &lt; <em
    >n</em
    ></span
      > for various values of <span class="math"
      ><em
    >m</em
    ></span
      >, where the proofs are built out of the two facts and <em
      >modus ponens</em
      > (i.e., <span class="math"
      >((<em
    >P</em
    > ⇒ <em
    >Q</em
    >) ∧ <em
    >P</em
    >) ⇒ <em
    >Q</em
    ></span
      >, which corresponds to function application).</p
    ><p
    >We can extract the <span class="math"
      ><em
    >m</em
    ></span
      > of these proofs:</p
    ><pre class="sourceCode haskell"
    ><code
      >fromBNat <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >BNat</span
    > n &#8594; <span class="dt"
    >Integer</span
    ><br
     />fromBNat <span class="dt"
    >BZero</span
    >     <span class="fu"
    >=</span
    > <span class="dv"
    >0</span
    ><br
     />fromBNat (<span class="dt"
    >BSucc</span
    > n) <span class="fu"
    >=</span
    > (<span class="fu"
    >succ</span
    > &#8728; fromBNat) n<br
     /></code
      ></pre
    ><p
    >I wrote the second clause strangely to emphasize the following lovely property, corresponding to a commutative diagram:</p
    ><pre class="sourceCode haskell"
    ><code
      >fromBNat &#8728; <span class="dt"
    >BSucc</span
    > <span class="fu"
    >=</span
    > <span class="fu"
    >succ</span
    > &#8728; fromBNat<br
     /></code
      ></pre
    ><p
    >Note that the type of <code
      >fromBNat</code
      > may be generalized:</p
    ><pre class="sourceCode haskell"
    ><code
      >fromBNat <span class="dv"
    >&#8759;</span
    > (<span class="kw"
    >Enum</span
    > a, <span class="kw"
    >Num</span
    > a) &#8658; <span class="dt"
    >BNat</span
    > n &#8594; a<br
     /></code
      ></pre
    ><p
    >To present <code
      >BNat</code
      > values, convert them to integers:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >instance</span
    > <span class="kw"
    >Show</span
    > (<span class="dt"
    >BNat</span
    > n) <span class="kw"
    >where</span
    > <span class="fu"
    >show</span
    > <span class="fu"
    >=</span
    > <span class="fu"
    >show</span
    > &#8728; fromBNat<br
     /></code
      ></pre
    ><p
    >The reverse mapping is handy also, i.e., for a number type <span class="math"
      ><em
    >n</em
    ></span
      >, given an integer <span class="math"
      ><em
    >m</em
    ></span
      >, generate a proof that <span class="math"
      ><em
    >m</em
    > &lt; <em
    >n</em
    ></span
      >, or fail if <span class="math"
      ><em
    >m</em
    > ≥ <em
    >n</em
    ></span
      >.</p
    ><pre class="sourceCode haskell"
    ><code
      >toBNat <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >Integer</span
    > &#8594; <span class="dt"
    >Maybe</span
    > (<span class="dt"
    >BNat</span
    > n)<br
     /></code
      ></pre
    ><p
    >Unlike <code
      >fromBNat</code
      >, <code
      >toBNat</code
      > doesn't have a structure to crawl over. It must create just the right structure anyway. What can we do?</p
    ><p
    >One solution is to use a type class: with instances for <code
      >Z</code
      > and <code
      >S</code
      >:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >class</span
    > <span class="dt"
    >HasBNat</span
    > n <span class="kw"
    >where</span
    > toBNat <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >Integer</span
    > &#8594; <span class="dt"
    >Maybe</span
    > (<span class="dt"
    >BNat</span
    > n)<br
     /><br
     /><span class="kw"
    >instance</span
    > <span class="dt"
    >HasBNat</span
    > <span class="dt"
    >Z</span
    > <span class="kw"
    >where</span
    > toBNat _ <span class="fu"
    >=</span
    > <span class="kw"
    >Nothing</span
    ><br
     /><br
     /><span class="kw"
    >instance</span
    > <span class="dt"
    >HasBNat</span
    > n &#8658; <span class="dt"
    >HasBNat</span
    > (<span class="dt"
    >S</span
    > n) <span class="kw"
    >where</span
    ><br
     />  toBNat m <span class="fu"
    >|</span
    > m <span class="fu"
    >&lt;</span
    > <span class="dv"
    >1</span
    >     <span class="fu"
    >=</span
    > <span class="kw"
    >Just</span
    > <span class="dt"
    >BZero</span
    ><br
     />           <span class="fu"
    >|</span
    > <span class="fu"
    >otherwise</span
    > <span class="fu"
    >=</span
    > <span class="fu"
    >fmap</span
    > <span class="dt"
    >BSucc</span
    > (toBNat (<span class="fu"
    >pred</span
    > m))<br
     /></code
      ></pre
    ><pre class="sourceCode haskell"
    ><code
      ><span class="fu"
    >*</span
    ><span class="dt"
    >BNat</span
    ><span class="fu"
    >&gt;</span
    > toBNat  <span class="dv"
    >3</span
    > <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >Maybe</span
    > (<span class="dt"
    >BNat</span
    > <span class="dt"
    >EightT</span
    >)<br
     /><span class="kw"
    >Just</span
    > <span class="dv"
    >3</span
    ><br
     /><span class="fu"
    >*</span
    ><span class="dt"
    >BNat</span
    ><span class="fu"
    >&gt;</span
    > toBNat <span class="dv"
    >10</span
    > <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >Maybe</span
    > (<span class="dt"
    >BNat</span
    > <span class="dt"
    >EightT</span
    >)<br
     /><span class="kw"
    >Nothing</span
    ><br
     /></code
      ></pre
    ><p
    >Later blog posts will include another solution for <code
      >toBNat</code
      > as well as some applications of <code
      >BNat</code
      >.</p
    ><p
    >We can also get a description of all natural numbers <em
      >greater than</em
      > a given one:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="fu"
    >*</span
    ><span class="dt"
    >BNat</span
    ><span class="fu"
    >&gt;</span
    > <span class="fu"
    >:</span
    >ty <span class="dt"
    >BSucc</span
    > (<span class="dt"
    >BSucc</span
    > <span class="dt"
    >BZero</span
    >)<br
     /><span class="dt"
    >BSucc</span
    > (<span class="dt"
    >BSucc</span
    > <span class="dt"
    >BZero</span
    >) <span class="dv"
    >&#8759;</span
    > <span class="dt"
    >BNat</span
    > (<span class="dt"
    >S</span
    > (<span class="dt"
    >S</span
    > (<span class="dt"
    >S</span
    > n)))<br
     /></code
      ></pre
    ><p
    >In words, the natural numbers greater than two are exactly those of the form <span class="math"
      >3 + <em
    >n</em
    ></span
      >, for natural numbers <span class="math"
      ><em
    >n</em
    ></span
      >.</p
    ></div
  ><div id="equality-and-comparison"
  ><h4
    >Equality and comparison</h4
    ><p
    >Equality and ordering are easily defined, all based on simple properties of numbers:</p
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >instance</span
    > <span class="kw"
    >Eq</span
    > (<span class="dt"
    >BNat</span
    > n) <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >BZero</span
    >   &#8801; <span class="dt"
    >BZero</span
    >    <span class="fu"
    >=</span
    > <span class="kw"
    >True</span
    ><br
     />  <span class="dt"
    >BSucc</span
    > m &#8801; <span class="dt"
    >BSucc</span
    > m' <span class="fu"
    >=</span
    > m &#8801; m'<br
     />  _       &#8801; _        <span class="fu"
    >=</span
    > <span class="kw"
    >False</span
    ><br
     /></code
      ></pre
    ><pre class="sourceCode haskell"
    ><code
      ><span class="kw"
    >instance</span
    > <span class="kw"
    >Ord</span
    > (<span class="dt"
    >BNat</span
    > n) <span class="kw"
    >where</span
    ><br
     />  <span class="dt"
    >BZero</span
    >   <span class="ot"
    >`compare`</span
    > <span class="dt"
    >BZero</span
    >    <span class="fu"
    >=</span
    > <span class="kw"
    >EQ</span
    ><br
     />  <span class="dt"
    >BSucc</span
    > m <span class="ot"
    >`compare`</span
    > <span class="dt"
    >BSucc</span
    > m' <span class="fu"
    >=</span
    > m <span class="ot"
    >`compare`</span
    > m'<br
     />  <span class="dt"
    >BZero</span
    >   <span class="ot"
    >`compare`</span
    > <span class="dt"
    >BSucc</span
    > _  <span class="fu"
    >=</span
    > <span class="kw"
    >LT</span
    ><br
     />  <span class="dt"
    >BSucc</span
    > _ <span class="ot"
    >`compare`</span
    > <span class="dt"
    >BZero</span
    >    <span class="fu"
    >=</span
    > <span class="kw"
    >GT</span
    ><br
     /></code
      ></pre
    ></div
  ></div
>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=271&amp;md5=6dd4edce892a0769eabb89e5e20b2c9e" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/Sclnv8JRFeA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/type-bounded-numbers/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/type-bounded-numbers</feedburner:origLink></item>
		<item>
		<title>Adding numbers</title>
		<link>http://feedproxy.google.com/~r/conal/~3/AdSKJ8XxV5Y/adding-numbers</link>
		<comments>http://conal.net/blog/posts/adding-numbers#comments</comments>
		<pubDate>Mon, 25 Oct 2010 20:57:41 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[number]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=240</guid>
		<description><![CDATA[IntroductionI’m starting to think about exact numeric computation. As a first step in getting into issues, I’ve been playing with addition on number representations, particularly carry look-ahead adders.This post plays with adding numbers and explores a few variations, beginning with the standard algorithm I learned as a child, namely working from right to left ...]]></description>
			<content:encoded><![CDATA[<div id="post-from-gitit">
<div>
<!-- references -->
















<!-- teaser -->
<!--
**Edits**:

* 2010-02-09: just fiddling around
 -->
<div id="introduction"
><h3
  ><a href="#TOC"
    >Introduction</a
    ></h3
  ><p
  >I’m starting to think about exact numeric computation. As a first step in getting into issues, I’ve been playing with addition on number representations, particularly <a href="http://en.wikipedia.org/wiki/Carry_look-ahead_adder"
    >carry look-ahead adders</a
    >.</p
  ><p
  >This post plays with adding numbers and explores a few variations, beginning with the standard algorithm I learned as a child, namely working from right to left (least to most significant), propagating carries. For fun &amp; curiosity, I also try out a pseudo-parallel version using circular programming, as well as a state-monad formulation. Each of these variations has its own elegance.</p
  ><p
  >While familiar and simple, right-to-left algorithms have a fundamental limitation. Since they begin with the least significant digit, they cannot be applied numbers that have infinitely many decreasingly significant digits. To add exact real numbers, we’ll need a different algorithm.</p
  ><p
  >Given clear formulations of right-to-left addition, and with exact real addition in mind, I was curious about left-to-right addition. The circular formulation adapts straightforwardly. Delightfully, the monadic version adapts even more easily, by replacing the usual state monad with the <em
    >backward</em
    > state monad.</p
  ><p
  >To exploit the right-to-left algorithms in exact real addition, I had to tweak the single-digit addition step to be a bit laxer (less strict). With this change, infinite-digit addition works just fine.</p
  ><span id="more-240"></span>
</div
><div id="full-adders"
><h3
  ><a href="#TOC"
    >Full adders</a
    ></h3
  ><p
  >In <a href="/blog/src/adding-numbers/AddingMachines.hs"
    ><code
      >AddingMachines.hs</code
      ></a
    >, define a <em
    >full adder</em
    >, which takes two values to add and a carry flag, and produces a sum with a carry flag:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Adder</span
      > a <span class="fu"
      >=</span
      > a &#8594; a &#8594; <span class="dt"
      >Bool</span
      > &#8594; (a, <span class="dt"
      >Bool</span
      >)<br
       /></code
    ></pre
  ><p
  >Define a single-digit full adder, for a given base:</p
  ><pre class="sourceCode haskell"
  ><code
    >addBase <span class="dv"
      >&#8759;</span
      > (<span class="kw"
      >Num</span
      > a, <span class="kw"
      >Ord</span
      > a) =&gt; a &#8594; <span class="dt"
      >Adder</span
      > a<br
       />addBase base a b carry <span class="fu"
      >|</span
      > sum' <span class="fu"
      >&lt;</span
      > base <span class="fu"
      >=</span
      > (sum', <span class="kw"
      >False</span
      >)<br
       />                       <span class="fu"
      >|</span
      > <span class="fu"
      >otherwise</span
      >   <span class="fu"
      >=</span
      > (sum'<span class="fu"
      >-</span
      >base, <span class="kw"
      >True</span
      >)<br
       />  <span class="kw"
      >where</span
      ><br
       />    sum' <span class="fu"
      >=</span
      > a <span class="fu"
      >+</span
      > b <span class="fu"
      >+</span
      > <span class="kw"
      >if</span
      > carry <span class="kw"
      >then</span
      > <span class="dv"
      >1</span
      > <span class="kw"
      >else</span
      > <span class="dv"
      >0</span
      ><br
       /></code
    ></pre
  ><p
  >For the examples below, I’ll specialize to base 10:</p
  ><pre class="sourceCode haskell"
  ><code
    >add10 <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Adder</span
      > <span class="dt"
      >Int</span
      ><br
       />add10 <span class="fu"
      >=</span
      > addBase <span class="dv"
      >10</span
      ><br
       /></code
    ></pre
  ><p
  >Then string together (full) adders to make multi-digit adders:</p
  ><pre class="sourceCode haskell"
  ><code
    >adds <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Adder</span
      > a &#8594; <span class="dt"
      >Adder</span
      > [a]<br
       /></code
    ></pre
  ><p
  >The digits are in little-endian order, i.e., least to most significant, which is the order in which I was taught to add.</p
  ></div
><div id="explicit-carry-threading"
><h3
  ><a href="#TOC"
    >Explicit carry threading</a
    ></h3
  ><p
  >How to string together the carries? For simplicity, require that the two digit lists have the same length. As a first implementation, let’s thread the carries through manually:</p
  ><pre class="sourceCode haskell"
  ><code
    >adds <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Adder</span
      > a &#8594; <span class="dt"
      >Adder</span
      > [a]<br
       />adds _ [] [] i <span class="fu"
      >=</span
      > ([],i)<br
       />adds add (a<span class="fu"
      >:</span
      >as) (b<span class="fu"
      >:</span
      >bs) i <span class="fu"
      >=</span
      > (c<span class="fu"
      >:</span
      >cs,o')<br
       />  <span class="kw"
      >where</span
      ><br
       />    (c ,o ) <span class="fu"
      >=</span
      > add a b i<br
       />    (cs,o') <span class="fu"
      >=</span
      > adds add as bs o<br
       />adds _ _ _ _ <span class="fu"
      >=</span
      > <span class="fu"
      >error</span
      > <span class="st"
      >&quot;adds: differing number of digits&quot;</span
      ><br
       /></code
    ></pre
  ><p
  >In this definition and throughout this post, I’ll use the names “<code
    >i</code
    >” and “<code
    >o</code
    >” for incoming and outgoing carry flags, respectively.</p
  ><p
  >Try it:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > adds add10 [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >] <span class="kw"
      >False</span
      ><br
       />([<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >0</span
      >],<span class="kw"
      >True</span
      >)<br
       /></code
    ></pre
  ></div
><div id="pseudo-parallel-carries"
><h3
  ><a href="#TOC"
    >Pseudo-parallel carries</a
    ></h3
  ><p
  >Here’s an idea for a more elegant approach: do all of the additions in parallel, with the list of carries coming in. The input carries come from the outputs of the additions, shifted by one position, resulting in a <em
    >circular program</em
    >.</p
  ><pre class="sourceCode haskell"
  ><code
    >addsP add as bs i <span class="fu"
      >=</span
      > (cs,<span class="fu"
      >last</span
      > is)<br
       /> <span class="kw"
      >where</span
      ><br
       />   (cs,os) <span class="fu"
      >=</span
      > <span class="fu"
      >unzip</span
      > (<span class="fu"
      >zipWith3</span
      > add as bs is)<br
       />   is <span class="fu"
      >=</span
      > i <span class="fu"
      >:</span
      > os<br
       /></code
    ></pre
  ><p
  >Note the mutual recursion in the two local definitions. I’m relying on the last element of <code
    >is</code
    > being dropped by <code
    >zipWith3</code
    >. I could instead pass in <code
    >init is</code
    >, but when I do so, no digits get out. I think the reason has to do with a subtlety in the definition of <code
    >init</code
    >.</p
  ><p
  >Try it:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > addsP add10 [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >] <span class="kw"
      >False</span
      ><br
       />([<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >0</span
      >],<span class="kw"
      >True</span
      >)<br
       /></code
    ></pre
  ><p
  >What makes <code
    >addsP</code
    > <em
    >productive</em
    >, i.e., what allows us to get information out of this circular definition? I think the key to productivity in <code
    >addsP</code
    > is that the first element of <code
    >is</code
    > is available before anything at all is known about <code
    >os</code
    >, and then the second element of <code
    >is</code
    > is ready when only the first element of <code
    >os</code
    > is knowable, etc.</p
  ></div
><div id="state-monad"
><h3
  ><a href="#TOC"
    >State monad</a
    ></h3
  ><p
  >The explicit threading done in the first <code
    >adds</code
    > definition above is just the sort of thing that the <code
    >State</code
    > monad takes care of. In <a href="/blog/src/adding-numbers/StateAdd.hs"
    ><code
      >StateAdd.hs</code
      ></a
    >, define a <em
    >carrier</em
    > monad to be <code
    >State</code
    > with a boolean carry flag as state:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Carrier</span
      > <span class="fu"
      >=</span
      > <span class="dt"
      >State</span
      > <span class="dt"
      >Bool</span
      ><br
       /></code
    ></pre
  ><p
  >Then tweak the <code
    >Adder</code
    > type:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Adder</span
      > a <span class="fu"
      >=</span
      > a &#8594; a &#8594; <span class="dt"
      >Carrier</span
      > a<br
       /></code
    ></pre
  ><p
  >For single-digit addition, just wrap the previous version (imported qualified as <code
    >AM</code
    >):</p
  ><pre class="sourceCode haskell"
  ><code
    >addBase <span class="dv"
      >&#8759;</span
      > (<span class="kw"
      >Ord</span
      > a, <span class="kw"
      >Num</span
      > a) =&gt; a &#8594; <span class="dt"
      >Adder</span
      > a<br
       />addBase base a b <span class="fu"
      >=</span
      > <span class="dt"
      >State</span
      > (AM.addBase base a b)<br
       /></code
    ></pre
  ><p
  >Or, using <a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post"
    >semantic editor combinators</a
    >,</p
  ><pre class="sourceCode haskell"
  ><code
    >addBase <span class="fu"
      >=</span
      > (result<span class="fu"
      >.</span
      >result<span class="fu"
      >.</span
      >result) <span class="dt"
      >State</span
      > AM.addBase<br
       /></code
    ></pre
  ><p
  >A big win with the <code
    >Carrier</code
    > monad is that <code
    >zipWithM</code
    > handles carry-propagation exactly as needed for multi-digit addition:</p
  ><pre class="sourceCode haskell"
  ><code
    >adds <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Adder</span
      > a &#8594; <span class="dt"
      >Adder</span
      > [a]<br
       />adds <span class="fu"
      >=</span
      > zipWithM<br
       /></code
    ></pre
  ><p
  >Try it:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >StateAdd</span
      ><span class="fu"
      >&gt;</span
      > runState (adds add10 [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >]) <span class="kw"
      >False</span
      ><br
       />([<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >0</span
      >],<span class="kw"
      >True</span
      >)<br
       /></code
    ></pre
  ></div
><div id="addition-in-reverse"
><h3
  ><a href="#TOC"
    >Addition in reverse</a
    ></h3
  ><p
  >So far, we’re adding digits in the standard direction: from least to most significant. This order makes it easy to propagate carries in the explicit-threading and the state monad formulations of multi-digit addition. However, it also has a potentially serious drawback. Suppose a computation depends on an <em
    >approximation</em
    > to the sum of two numbers, e.g., the only the first most significant digits. Then the unnecessary less-significant digits will all have to be computed anyway.</p
  ><p
  >One extreme and important example of this drawback is when there are <em
    >infinitely many</em
    > digits of diminishing significance, which is the case with exact reals, when our digits are past the radix point. The algorithms above cannot even represent such numbers, since the digit lists are from least to most significant.</p
  ><p
  >Let’s reverse the order of digits in our number representations, so they run from most to least significant. With this reversal, we can easily represent numbers with infinitely many decreasingly significant digits. Carrying, however, becomes trickier. As a first try, here’s an explicitly threaded multi-digit adder:</p
  ><pre class="sourceCode haskell"
  ><code
    >addsR <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Adder</span
      > a &#8594; <span class="dt"
      >Adder</span
      > [a]<br
       />addsR _ [] [] i <span class="fu"
      >=</span
      > ([],i)<br
       />addsR add (a<span class="fu"
      >:</span
      >as) (b<span class="fu"
      >:</span
      >bs) i <span class="fu"
      >=</span
      > (c<span class="fu"
      >:</span
      >cs,o')<br
       />  <span class="kw"
      >where</span
      ><br
       />    (c,o') <span class="fu"
      >=</span
      > add a b o<br
       />    (cs,o) <span class="fu"
      >=</span
      > addsR add as bs i<br
       />addsR _ _ _ _ <span class="fu"
      >=</span
      > <span class="fu"
      >error</span
      > <span class="st"
      >&quot;adds: differing number of digits&quot;</span
      ><br
       /></code
    ></pre
  ><p
  >The only difference from the forward-cary <code
    >adds</code
    > is in the local definitions, which propagate the carry. From the original version:</p
  ><pre class="sourceCode haskell"
  ><code
    >    (c ,o ) <span class="fu"
      >=</span
      > add a b i<br
       />    (cs,o') <span class="fu"
      >=</span
      > adds add as bs o<br
       /></code
    ></pre
  ><p
  >With this change, carries now propagate in the reverse order. To remind us of the changed direction, I’ll swap the digits &amp; carry flag in testing.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsR add10 [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >] <span class="kw"
      >False</span
      ><br
       />(<span class="kw"
      >False</span
      >,[<span class="dv"
      >5</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >9</span
      >])<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsR add10 [<span class="dv"
      >8</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >3</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >1</span
      >] <span class="kw"
      >False</span
      ><br
       />(<span class="kw"
      >True</span
      >,[<span class="dv"
      >0</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >4</span
      >])<br
       /></code
    ></pre
  ><p
  >where</p
  ><pre class="sourceCode haskell"
  ><code
    >swap <span class="dv"
      >&#8759;</span
      > (a,b) &#8594; (b,a)<br
       />swap (a,b) <span class="fu"
      >=</span
      > (b,a)<br
       /></code
    ></pre
  ></div
><div id="lax-addition"
><h3
  ><a href="#TOC"
    >Lax addition</a
    ></h3
  ><p
  >Let’s now see how lax our definitions are. (Reminder: <em
    >laxness</em
    > is the opposite of strictness and is sometimes confused with the operational notion of laziness.)</p
  ><p
  >Back to our original example, using forward carrying (from least to most significant):</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > adds add10 [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >] <span class="kw"
      >False</span
      ><br
       />([<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >0</span
      >],<span class="kw"
      >True</span
      >)<br
       /></code
    ></pre
  ><p
  >Now replace the third digit of one number with <code
    >&#8869;</code
    >. There is still enough information to compute the two least significant digits:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > adds add10 [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,&#8869;,<span class="dv"
      >8</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >] <span class="kw"
      >False</span
      ><br
       />([<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >,<span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /></code
    ></pre
  ><p
  >If we reverse the digits and try again, we run into trouble at the outset, with both the carry and the digits.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="kw"
      >let</span
      > q <span class="fu"
      >=</span
      > swap <span class="fu"
      >$</span
      > addsR add10 [<span class="dv"
      >8</span
      >,&#8869;,<span class="dv"
      >5</span
      >,<span class="dv"
      >3</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >1</span
      >] <span class="kw"
      >False</span
      ><br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > first q<br
       /><span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >snd</span
      > q<br
       />[<span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /></code
    ></pre
  ><p
  >Closer examination shows that the two least significant digits are still computed (as before):</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >snd</span
      > q <span class="fu"
      >!!</span
      > <span class="dv"
      >0</span
      ><br
       /><span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >snd</span
      > q <span class="fu"
      >!!</span
      > <span class="dv"
      >1</span
      ><br
       /><span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >snd</span
      > q <span class="fu"
      >!!</span
      > <span class="dv"
      >2</span
      ><br
       /><span class="dv"
      >1</span
      ><br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >snd</span
      > q <span class="fu"
      >!!</span
      > <span class="dv"
      >3</span
      ><br
       /><span class="dv"
      >4</span
      ><br
       /></code
    ></pre
  ><p
  >In this example, neither of the most significant two digits can be known. The sum might start with a 9 with carry <code
    >False</code
    >, or it could start with a 0 with carry <code
    >True</code
    >, depending on whether there is a carry coming out of adding the second digit.</p
  ><p
  >Now consider the sum <code
    >74&#8869;&#8869; + 13&#8869;&#8869;</code
    >.</p
  ><p
  >Just from looking at the first digits, we can deduce that the overall carry is <code
    >False</code
    > Similarly, looking at the second digits, we know their carry is also <code
    >False</code
    >, which means we also know that the first sum is <code
    >7 + 1 + 0 == 8</code
    >. Let’s see how <code
    >addsR</code
    > does with this example:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsR add10 [<span class="dv"
      >7</span
      >,<span class="dv"
      >4</span
      >,&#8869;,&#8869;] [<span class="dv"
      >1</span
      >,<span class="dv"
      >3</span
      >,&#8869;,&#8869;] <span class="kw"
      >False</span
      ><br
       />(<span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /></code
    ></pre
  ><p
  >To get more information out, rewrite <code
    >addBase</code
    > to be laxer in the carry argument. Where possible, compute the carry-out based solely on the digits being added, without considering the carry-in. The carry-out must be false if those digits sum to less than <code
    >base-1</code
    >, and must be true if the digits sum to more than <code
    >base-1</code
    >. Only when the sum is exactly equal to <code
    >base-1</code
    > must the carry-in be examined.</p
  ><pre class="sourceCode haskell"
  ><code
    >addBase <span class="dv"
      >&#8759;</span
      > (<span class="kw"
      >Num</span
      > a, <span class="kw"
      >Ord</span
      > a) =&gt; a &#8594; <span class="dt"
      >Adder</span
      > a<br
       />addBase base a b carry <span class="fu"
      >=</span
      ><br
       />  <span class="kw"
      >case</span
      > ab <span class="ot"
      >`compare`</span
      > (base <span class="fu"
      >-</span
      > <span class="dv"
      >1</span
      >) <span class="kw"
      >of</span
      ><br
       />    <span class="kw"
      >LT</span
      > &#8594; uncarried<br
       />    <span class="kw"
      >GT</span
      > &#8594; carried<br
       />    <span class="kw"
      >EQ</span
      > &#8594; <span class="kw"
      >if</span
      > sum' <span class="fu"
      >&lt;</span
      > base <span class="kw"
      >then</span
      > uncarried <span class="kw"
      >else</span
      > carried<br
       />  <span class="kw"
      >where</span
      ><br
       />    ab <span class="fu"
      >=</span
      > a <span class="fu"
      >+</span
      > b<br
       />    sum' <span class="fu"
      >=</span
      > ab <span class="fu"
      >+</span
      > <span class="kw"
      >if</span
      > carry <span class="kw"
      >then</span
      > <span class="dv"
      >1</span
      > <span class="kw"
      >else</span
      > <span class="dv"
      >0</span
      ><br
       />    uncarried <span class="fu"
      >=</span
      > (sum',<span class="kw"
      >False</span
      >)<br
       />    carried <span class="fu"
      >=</span
      > (sum'<span class="fu"
      >-</span
      >base,<span class="kw"
      >True</span
      >)<br
       /></code
    ></pre
  ><p
  >Sure enough, we can now extract the overall carry and the most significant digit of the sum:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsR add10 [<span class="dv"
      >7</span
      >,<span class="dv"
      >4</span
      >,&#8869;,&#8869;] <span class="fu"
      >&gt;</span
      > [<span class="dv"
      >1</span
      >,<span class="dv"
      >3</span
      >,&#8869;,&#8869;] <span class="kw"
      >False</span
      ><br
       />(<span class="kw"
      >False</span
      >,[<span class="dv"
      >8</span
      >,<span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /></code
    ></pre
  ><p
  >We can also handle an unknown or infinite number of digits:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsR add10 (<span class="dv"
      >7</span
      ><span class="fu"
      >:</span
      ><span class="dv"
      >4</span
      ><span class="fu"
      >:</span
      >&#8869;) (<span class="dv"
      >1</span
      ><span class="fu"
      >:</span
      ><span class="dv"
      >3</span
      ><span class="fu"
      >:</span
      >&#8869;) &#8869;<br
       />(<span class="kw"
      >False</span
      >,[<span class="dv"
      >8</span
      >,<span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /></code
    ></pre
  ><p
  >Note that even the carry-in flag is undefined, as it wouldn’t be used until the least-significant digit. If we know we’ll have infinitely many digits, then we can discard the carry-in bit altogether for <code
    >addsR</code
    >.</p
  ></div
><div id="pseudo-parallel-reverse-carry"
><h3
  ><a href="#TOC"
    >Pseudo-parallel, reverse carry</a
    ></h3
  ><p
  >Recall pseudo-parallel forward-carrying addition from above:</p
  ><pre class="sourceCode haskell"
  ><code
    >addsP add as bs i <span class="fu"
      >=</span
      > (cs,<span class="fu"
      >last</span
      > is)<br
       /> <span class="kw"
      >where</span
      ><br
       />   (cs,os) <span class="fu"
      >=</span
      > <span class="fu"
      >unzip</span
      > (<span class="fu"
      >zipWith3</span
      > add as bs is)<br
       />   is <span class="fu"
      >=</span
      > i <span class="fu"
      >:</span
      > os<br
       /></code
    ></pre
  ><p
  >Reversing the digits requires shifting the carries in the other direction. Instead of rotating the external carry into the start of the carry list and removing the last element, we’ll rotate the external carry into the end of the carry list and remove the first element.</p
  ><pre class="sourceCode haskell"
  ><code
    >addsPR <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Adder</span
      > a &#8594; <span class="dt"
      >Adder</span
      > [a]<br
       />addsPR add as bs i <span class="fu"
      >=</span
      > (cs,<span class="fu"
      >head</span
      > is)<br
       /> <span class="kw"
      >where</span
      ><br
       />   (cs,os) <span class="fu"
      >=</span
      > <span class="fu"
      >unzip</span
      > (<span class="fu"
      >zipWith3</span
      > add as bs (<span class="fu"
      >tail</span
      > is))<br
       />   is <span class="fu"
      >=</span
      > os <span class="fu"
      >++</span
      > [i]<br
       /></code
    ></pre
  ><p
  >Testing this definition, even on fully defined input, shows that neither the carry nor the digits produce any information.</p
  ><p
  >After some head-scratching, it occurred to me that <code
    >zipWith3</code
    > is overly strict in its last for our purposes. The definition:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >zipWith3</span
      > <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; c &#8594; d) &#8594; [a] &#8594; [b] &#8594; [c] &#8594; [d]<br
       /><span class="fu"
      >zipWith3</span
      > f (a<span class="fu"
      >:</span
      >as) (b<span class="fu"
      >:</span
      >bs) (c<span class="fu"
      >:</span
      >cs) <span class="fu"
      >=</span
      > f a b c <span class="fu"
      >:</span
      > <span class="fu"
      >zipWith3</span
      > f as bs cs<br
       /><span class="fu"
      >zipWith3</span
      > _ _ _ _ <span class="fu"
      >=</span
      > []<br
       /></code
    ></pre
  ><p
  >With this definition, <code
    >zipWith3</code
    > cannot produce any information until it knows whether its last argument is empty or non-empty. With some thought, we can see that in our use, the last list has the same length as the shorter of the other two lists, but the compiler doesn’t know, so it uses an unnecessary run-time check (that cannot complete). We can avoid this problem by using a lazier version of <code
    >zipWith3</code
    >. The only difference is the use of a lazy pattern for the last argument.</p
  ><pre class="sourceCode haskell"
  ><code
    >zipWith3' <span class="dv"
      >&#8759;</span
      > (a &#8594; b &#8594; c &#8594; d) &#8594; [a] &#8594; [b] &#8594; [c] &#8594; [d]<br
       />zipWith3' f (a<span class="fu"
      >:</span
      >as) (b<span class="fu"
      >:</span
      >bs) <span class="fu"
      >~</span
      >(c<span class="fu"
      >:</span
      >cs) <span class="fu"
      >=</span
      > f a b c <span class="fu"
      >:</span
      > zipWith3' f as bs cs<br
       />zipWith3' _ _ _ _ <span class="fu"
      >=</span
      > []<br
       /></code
    ></pre
  ><p
  >Then amend the definition of <code
    >addsPR</code
    > to use <code
    >zipWith3'</code
    >, and away we go:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > addsPS add10 (<span class="dv"
      >7</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >4</span
      ><span class="fu"
      >&lt;:&gt;</span
      >&#8869;) (<span class="dv"
      >1</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >3</span
      ><span class="fu"
      >&lt;:&gt;</span
      >&#8869;)<br
       />(<span class="kw"
      >False</span
      >,<span class="dv"
      >8</span
      > <span class="fu"
      >&lt;:&gt;</span
      > <span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /></code
    ></pre
  ><p
  >Recall that in the original definition of <code
    >addsP</code
    >, the last argument to <code
    >zipWith3</code
    > was <code
    >is</code
    > instead of the more fitting <code
    >init is</code
    >. When I tried <code
    >init is</code
    >, evaluation gets stuck at the beginning. Switching from <code
    >zipWith3</code
    > to <code
    >zipWith3'</code
    > gets the first three digits out but not the last one. I suspect the reason has to do with the definition of <code
    >init</code
    >, which has to know when the list has only one element, rather than being almost empty.</p
  ><p
  >Now let’s look a a really infinite examples</p
  ><pre
  ><code
    >  .357835783578...
+ .726726726726...
------------------
 1.08456251030?...
</code
    ></pre
  ><p
  >The “?” is for a digit that can be either 4 or 5, depending on carry. The incoming carry never gets used, so let’s make it <code
    >&#8869;</code
    >.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsPR add10 (<span class="fu"
      >cycle</span
      > [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >]) (<span class="fu"
      >cycle</span
      > [<span class="dv"
      >7</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >6</span
      >]) &#8869;<br
       />(<span class="kw"
      >True</span
      >,[<span class="dv"
      >0</span
      >,<span class="dv"
      >8</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >5</span
      >,<br
       /></code
    ></pre
  ><p
  >The computation got stuck after after <code
    >1.0845625</code
    >.</p
  ><p
  >It took me a fair bit of poking around to find the problem. A clue along the way was this surprise:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >length</span
      > <span class="fu"
      >$</span
      > <span class="fu"
      >fst</span
      > <span class="fu"
      >$</span
      > <span class="fu"
      >unzip</span
      > [&#8869;]<br
       /><span class="fu"
      >***</span
      > <span class="dt"
      >Exception</span
      ><span class="fu"
      >:</span
      > <span class="dt"
      >Prelude</span
      ><span class="fu"
      >.</span
      >&#8869;<br
       /></code
    ></pre
  ><p
  >The culprit turns out to be an unfortunate interaction between the definitions of <a href="http://haskell.org/ghc/docs/6.12.1/html/libraries/base/src/GHC-List.html#unzip"
    ><code
      >unzip</code
      ></a
    > and <code
    >addBase</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >unzip</span
      > <span class="dv"
      >&#8759;</span
      > [(a,b)] &#8594; ([a],[b])<br
       /><span class="fu"
      >unzip</span
      > <span class="fu"
      >=</span
      >  <span class="fu"
      >foldr</span
      > (&#955;(a,b) <span class="fu"
      >~</span
      >(as,bs) &#8594; (a<span class="fu"
      >:</span
      >as,b<span class="fu"
      >:</span
      >bs)) ([],[])<br
       /></code
    ></pre
  ><p
  >Look carefully at the function passed to <code
    >foldr</code
    >. It’s lazy in its second argument and strict in its first. The laziness here allows the input list to be demanded incrementally as the output list is demanded. Without that laziness, <code
    >unzip</code
    > couldn’t handle infinite lists. The strict pattern in the first position means that each incoming value must be evaluated enough to see the outer pair structure. Thus, e.g., <code
    >unzip [&#8869;]</code
    > is <code
    >&#8869;</code
    >, not <code
    >(&#8869;,&#8869;)</code
    >.</p
  ><p
  >Here’s a lazier version that works for <code
    >addsPR</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    >unzip' <span class="fu"
      >=</span
      > <span class="fu"
      >foldr</span
      > (&#955; <span class="fu"
      >~</span
      >(a,b) <span class="fu"
      >~</span
      >(as,bs) &#8594; (a<span class="fu"
      >:</span
      >as,b<span class="fu"
      >:</span
      >bs)) ([],[])<br
       /></code
    ></pre
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > <span class="fu"
      >length</span
      > <span class="fu"
      >$</span
      > <span class="fu"
      >fst</span
      > <span class="fu"
      >$</span
      > unzip' [&#8869;]<br
       /><span class="dv"
      >1</span
      ><br
       /></code
    ></pre
  ><p
  >Now look our (second) definition of <code
    >addBase</code
    > from above:</p
  ><pre class="sourceCode haskell"
  ><code
    >addBase <span class="dv"
      >&#8759;</span
      > (<span class="kw"
      >Num</span
      > a, <span class="kw"
      >Ord</span
      > a) =&gt; a &#8594; <span class="dt"
      >Adder</span
      > a<br
       />addBase base a b carry <span class="fu"
      >=</span
      ><br
       />  <span class="kw"
      >case</span
      > ab <span class="ot"
      >`compare`</span
      > (base <span class="fu"
      >-</span
      > <span class="dv"
      >1</span
      >) <span class="kw"
      >of</span
      ><br
       />    <span class="kw"
      >LT</span
      > &#8594; uncarried<br
       />    <span class="kw"
      >GT</span
      > &#8594; carried<br
       />    <span class="kw"
      >EQ</span
      > &#8594; <span class="kw"
      >if</span
      > sum' <span class="fu"
      >&lt;</span
      > base <span class="kw"
      >then</span
      > uncarried <span class="kw"
      >else</span
      > carried<br
       />  <span class="kw"
      >where</span
      ><br
       />    ab <span class="fu"
      >=</span
      > a <span class="fu"
      >+</span
      > b<br
       />    sum' <span class="fu"
      >=</span
      > ab <span class="fu"
      >+</span
      > <span class="kw"
      >if</span
      > carry <span class="kw"
      >then</span
      > <span class="dv"
      >1</span
      > <span class="kw"
      >else</span
      > <span class="dv"
      >0</span
      ><br
       />    uncarried <span class="fu"
      >=</span
      > (sum',<span class="kw"
      >False</span
      >)<br
       />    carried <span class="fu"
      >=</span
      > (sum'<span class="fu"
      >-</span
      >base,<span class="kw"
      >True</span
      >)<br
       /></code
    ></pre
  ><p
  >Consider the <code
    >EQ</code
    > case, i.e., <code
    >a+b == base-1</code
    >. Evaluating the conditional produces either <code
    >uncarried</code
    > or <code
    >carried</code
    >, each of which is manifestly a pair. However, no outer pair structure can be seen <em
    >until</em
    > the boolean resolves to either <code
    >True</code
    > or <code
    >False</code
    >. In this case, the boolean depends on <code
    >sum'</code
    >, which depends on <code
    >carry</code
    >. Thus pairness cannot be seen until <code
    >carry</code
    > is evaluated.</p
  ><p
  >Using <code
    >unzip'</code
    > instead of <code
    >unzip</code
    > in <code
    >addsPR</code
    > gets us unstuck:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsPR add10 (<span class="fu"
      >cycle</span
      > [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >]) (<span class="fu"
      >cycle</span
      > [<span class="dv"
      >7</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >6</span
      >]) &#8869;<br
       />(<span class="kw"
      >True</span
      >,[<span class="dv"
      >0</span
      >,<span class="dv"
      >8</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >3</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >8</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >3</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >8</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >2</span
      >,<span class="fu"
      >&#8229;.</span
      >])<br
       /></code
    ></pre
  ><p
  >(I filled in the “<code
    >&#8229;.</code
    >” here.)</p
  ></div
><div id="some-other-lax-solutions"
><h3
  ><a href="#TOC"
    >Some other lax solutions</a
    ></h3
  ><p
  >Rather than making <code
    >unzip</code
    > <em
    >demand less</em
    > information, we can instead make <code
    >addBase</code
    > <em
    >provide more</em
    > information.</p
  ><div id="hack-away"
  ><h4
    ><a href="#TOC"
      >Hack away</a
      ></h4
    ><p
    >One way to make <code
      >addBase</code
      > more defined is to dig into the definition of <code
      >addBase</code
      >, changing the <code
      >EQ</code
      > case to generate a pair immediately. For instance,</p
    ><pre class="sourceCode haskell"
    ><code
      >    <span class="kw"
    >EQ</span
    > &#8594; (<span class="kw"
    >if</span
    > sum' <span class="fu"
    >&lt;</span
    > base <span class="kw"
    >then</span
    > sum' <span class="kw"
    >else</span
    > sum'<span class="fu"
    >-</span
    >base, sum' <span class="fu"
    >&lt;</span
    > base)<br
     /></code
      ></pre
    ><p
    >This version has a lot of repetition, adding more awkwardness to an already awkward definition of <code
      >addBase</code
      >.</p
    ></div
  ><div id="laxer-if-then-else"
  ><h4
    ><a href="#TOC"
      >Laxer if-then-else</a
      ></h4
    ><p
    >I recently wrote two posts on “lazier functional programming”. <a href="http://conal.net/blog/posts/lazier-functional-programming-part-1/" title="blog post"
      >Part one</a
      > offered the puzzle of how to make <code
      >if-then-else</code
      > and <code
      >either</code
      > laxer (less strict). <a href="http://conal.net/blog/posts/lazier-functional-programming-part-2/" title="blog post"
      >Part two</a
      > revealed elegant solutions in terms of the least-upper-bound and greatest-lower-bound operators (<code
      >(&#8852;)</code
      > and <code
      >(&#8851;)</code
      >) from domain theory.</p
    ><p
    >The laxer if-then-else from part two gives us a drop-in replacement for the standard, overly strict conditional used in <code
      >addBase</code
      >:</p
    ><pre class="sourceCode haskell"
    ><code
      >    <span class="kw"
    >EQ</span
    > &#8594; laxIf (sum' <span class="fu"
    >&lt;</span
    > base) uncarried carried<br
     /></code
      ></pre
    ><p
    >where</p
    ><pre class="sourceCode haskell"
    ><code
      >laxIf <span class="dv"
    >&#8759;</span
    > a &#8594; a &#8594; <span class="dt"
    >Bool</span
    > &#8594; a<br
     />laxIf c a b <span class="fu"
    >=</span
    > cond a b c<br
     /></code
      ></pre
    ><pre class="sourceCode haskell"
    ><code
      >cond <span class="dv"
    >&#8759;</span
    > a &#8594; a &#8594; <span class="dt"
    >Bool</span
    > &#8594; a<br
     />cond a b <span class="fu"
    >=</span
    > <span class="fu"
    >const</span
    > (a &#8851; b) &#8852; (&#955; c &#8594; <span class="kw"
    >if</span
    > c <span class="kw"
    >then</span
    > a <span class="kw"
    >else</span
    > b)<br
     /></code
      ></pre
    ><p
    >The key to fixing <code
      >addBase</code
      > is that <code
      >uncarried &#8851; carried == (&#8869;,&#8869;)</code
      >.</p
    ></div
  ><div id="lax-pairs"
  ><h4
    ><a href="#TOC"
      >Lax pairs</a
      ></h4
    ><p
    >A more specialized solution is to use the standard if-then-else and draw out the pair structure of the result without looking at it.</p
    ><pre class="sourceCode haskell"
    ><code
      >laxPair <span class="dv"
    >&#8759;</span
    > (a,b) &#8594; (a,b)<br
     />laxPair  <span class="fu"
    >~</span
    >(a,b) <span class="fu"
    >=</span
    > (a,b)<br
     /></code
      ></pre
    ><p
    >We can apply <code
      >laxPair</code
      > directly to the conditional:</p
    ><pre class="sourceCode haskell"
    ><code
      >    <span class="kw"
    >EQ</span
    > &#8594; laxPair <span class="fu"
    >$</span
    > <span class="kw"
    >if</span
    > sum' <span class="fu"
    >&lt;</span
    > base <span class="kw"
    >then</span
    > uncarried <span class="kw"
    >else</span
    > carried<br
     /></code
      ></pre
    ><p
    >or to the body of <code
      >addBase</code
      > as a whole:</p
    ><pre class="sourceCode haskell"
    ><code
      >addBase <span class="dv"
    >&#8759;</span
    > (<span class="kw"
    >Num</span
    > a, <span class="kw"
    >Ord</span
    > a) =&gt; a &#8594; <span class="dt"
    >Adder</span
    > a<br
     />addBase base a b carry <span class="fu"
    >=</span
    > laxPair <span class="fu"
    >$</span
    > <span class="fu"
    >&#8229;.</span
    ><br
     /></code
      ></pre
    ><p
    >or even from the outside:</p
    ><pre class="sourceCode haskell"
    ><code
      >addBase' <span class="dv"
    >&#8759;</span
    > (<span class="kw"
    >Num</span
    > a, <span class="kw"
    >Ord</span
    > a) =&gt; a &#8594; <span class="dt"
    >Adder</span
    > a<br
     />addBase' base a b carry <span class="fu"
    >=</span
    > laxPair <span class="fu"
    >$</span
    > addBase base a b carry<br
     /></code
      ></pre
    ><p
    >In this last case, <a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post"
      >semantic editor combinators</a
      > allow for a more elegant formulation:</p
    ><pre class="sourceCode haskell"
    ><code
      >addBase' <span class="fu"
    >=</span
    > (result<span class="fu"
    >.</span
    >result<span class="fu"
    >.</span
    >result<span class="fu"
    >.</span
    >result) laxPair addBase<br
     /></code
      ></pre
    ></div
  ><div id="starting-over"
  ><h4
    ><a href="#TOC"
      >Starting over</a
      ></h4
    ><p
    >I’m not happy with any of the <code
      >addBase</code
      > definitions above after the first one, which was much too strict. The others get the job done, but heavy handedly, lacking in grace and elegance.</p
    ><p
    >Here is a definition that is more graceful and is lax enough for our purposes:</p
    ><pre class="sourceCode haskell"
    ><code
      >addBase <span class="dv"
    >&#8759;</span
    > (<span class="kw"
    >Num</span
    > a, <span class="kw"
    >Ord</span
    > a) =&gt; a &#8594; <span class="dt"
    >Adder</span
    > a<br
     />addBase base a b i <span class="fu"
    >=</span
    > (ab', o)<br
     /> <span class="kw"
    >where</span
    ><br
     />   ab  <span class="fu"
    >=</span
    > a <span class="fu"
    >+</span
    > b<br
     />   ab' <span class="fu"
    >=</span
    > ab <span class="fu"
    >+</span
    > (<span class="kw"
    >if</span
    > i <span class="kw"
    >then</span
    > <span class="dv"
    >1</span
    > <span class="kw"
    >else</span
    > <span class="dv"
    >0</span
    >) <span class="fu"
    >-</span
    > (<span class="kw"
    >if</span
    > o <span class="kw"
    >then</span
    > base <span class="kw"
    >else</span
    > <span class="dv"
    >0</span
    >)<br
     />   o   <span class="fu"
    >=</span
    > <span class="kw"
    >case</span
    > ab <span class="ot"
    >`compare`</span
    > (base<span class="fu"
    >-</span
    ><span class="dv"
    >1</span
    >) <span class="kw"
    >of</span
    ><br
     />           <span class="kw"
    >LT</span
    > &#8594; <span class="kw"
    >False</span
    ><br
     />           <span class="kw"
    >GT</span
    > &#8594; <span class="kw"
    >True</span
    ><br
     />           <span class="kw"
    >EQ</span
    > &#8594; i<br
     /></code
      ></pre
    ><p
    >Written more compactly, and exploiting the short-circuiting nature of <code
      >(&amp;&amp;)</code
      > and <code
      >(||)</code
      > (each non-strict in its second argument):</p
    ><pre class="sourceCode haskell"
    ><code
      >   o   <span class="fu"
    >=</span
    > ab <span class="fu"
    >&gt;=</span
    > base<span class="fu"
    >-</span
    ><span class="dv"
    >1</span
    > <span class="fu"
    >&amp;&amp;</span
    > (ab <span class="fu"
    >&gt;=</span
    > base <span class="fu"
    >||</span
    > i)<br
     /></code
      ></pre
    ></div
  ></div
><div id="infinite-digit-streams"
><h3
  ><a href="#TOC"
    >Infinite digit streams</a
    ></h3
  ><p
  >Some of the previous cases were tricky due to testing for empty lists. To eliminate these details, we can switch from (possibly-finite) lists to (necessary-infinite) streams. I’ll use Wouter Swierstra’s <a href="http://hackage.haskell.org/package/Stream" title="Haskell library on Hackage"
    >Stream library</a
    >.</p
  ><p
  >With infinite digit streams, we have no use for a carry in, so I’ll switch from a full adder to a half adder.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >HalfAdder</span
      > a <span class="fu"
      >=</span
      > a &#8594; a &#8594; (a,<span class="dt"
      >Bool</span
      >)<br
       /></code
    ></pre
  ><p
  >The Stream library doesn’t define a <code
    >zipWith3</code
    >, but the general <code
    >liftA3</code
    > function on applicative functors fills the same role. Eliminating the carry-in allows the definition to become more tightly circular:</p
  ><pre class="sourceCode haskell"
  ><code
    >addsPS <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >Adder</span
      > a &#8594; <span class="dt"
      >HalfAdder</span
      > (<span class="dt"
      >Stream</span
      > a)<br
       />addsPS add as bs <span class="fu"
      >=</span
      > (cs, S.head is)<br
       /> <span class="kw"
      >where</span
      ><br
       />   (cs,is) <span class="fu"
      >=</span
      > S.unzip (liftA3 add as bs (S.tail is))<br
       /></code
    ></pre
  ><p
  >I’m using qualified names for <code
    >head</code
    >, <code
    >tail</code
    >, and <code
    >unzip</code
    > on streams to avoid clashes with the versions on lists.</p
  ><p
  >Giving this stream adder a spin, we get the same infinite sum as with lists above:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >AddingMachines</span
      ><span class="fu"
      >&gt;</span
      > swap <span class="fu"
      >$</span
      > addsPS add10 (S.fromList <span class="fu"
      >$</span
      > <span class="fu"
      >cycle</span
      > [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >])<br
       />                                     (S.fromList <span class="fu"
      >$</span
      > <span class="fu"
      >&gt;</span
      > <span class="fu"
      >cycle</span
      > [<span class="dv"
      >7</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >6</span
      >])<br
       />(<span class="kw"
      >True</span
      >,<span class="dv"
      >0</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >8</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >4</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >5</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >6</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >2</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >5</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >1</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >0</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >3</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >0</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >5</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >0</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >8</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >4</span
      ><span class="fu"
      >&lt;:&gt;</span
      ><span class="dv"
      >5</span
      > <span class="fu"
      >&#8229;.</span
      >)<br
       /></code
    ></pre
  ></div
><div id="reverse-state-monad"
><h3
  ><a href="#TOC"
    >Reverse state monad</a
    ></h3
  ><p
  >Can we combine reverse-carrying with a state monad formulation? Yes, using the “backwards state” monad mentioned in <em
    ><a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.38.9516" title="Paper by Philip Wadler"
      >The essence of functional programming</a
      ></em
    >, Section 2.8.</p
  ><p
  >In <a href="/blog/src/adding-numbers/ReverseStateAdd.hs"
    ><code
      >ReverseStateAdd.hs</code
      ></a
    >, define</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >type</span
      > <span class="dt"
      >Carrier</span
      > <span class="fu"
      >=</span
      > <span class="dt"
      >StateR</span
      > <span class="dt"
      >Bool</span
      ><br
       /></code
    ></pre
  ><p
  >Given the reverse state monad, the single-digit addition is as easy to define as with (forward) <code
    >State</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    >addBase <span class="dv"
      >&#8759;</span
      > (<span class="kw"
      >Ord</span
      > a, <span class="kw"
      >Num</span
      > a) =&gt; a &#8594; <span class="dt"
      >Adder</span
      > a<br
       />addBase <span class="fu"
      >=</span
      > (result<span class="fu"
      >.</span
      >result<span class="fu"
      >.</span
      >result) <span class="dt"
      >StateR</span
      > AM.addBase<br
       /></code
    ></pre
  ><p
  >For convenience, swap the carry &amp; digits while testing.</p
  ><pre class="sourceCode haskell"
  ><code
    >runStateR' <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >StateR</span
      > s a &#8594; s &#8594; (s,a)<br
       />runStateR' <span class="fu"
      >=</span
      > (result<span class="fu"
      >.</span
      >result) swap runStateR<br
       /></code
    ></pre
  ><p
  >Try with finitely many digits:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >ReverseStateAdd</span
      ><span class="fu"
      >&gt;</span
      > runStateR' (adds add10 [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >1</span
      >]) <span class="kw"
      >False</span
      ><br
       />(<span class="kw"
      >False</span
      >,[<span class="dv"
      >5</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >9</span
      >])<br
       /><span class="fu"
      >*</span
      ><span class="dt"
      >ReverseStateAdd</span
      ><span class="fu"
      >&gt;</span
      > runStateR' (adds add10 [<span class="dv"
      >8</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >3</span
      >] [<span class="dv"
      >1</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >1</span
      >]) <span class="kw"
      >False</span
      ><br
       />(<span class="kw"
      >True</span
      >,[<span class="dv"
      >0</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >4</span
      >])<br
       /></code
    ></pre
  ><p
  >And infinitely many digits:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="fu"
      >*</span
      ><span class="dt"
      >ReverseStateAdd</span
      ><span class="fu"
      >&gt;</span
      > runStateR' (adds add10 (<span class="fu"
      >cycle</span
      > [<span class="dv"
      >3</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >7</span
      >,<span class="dv"
      >8</span
      >]) (<span class="fu"
      >cycle</span
      > [<span class="dv"
      >7</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >6</span
      >])) &#8869;<br
       />(<span class="kw"
      >True</span
      >,[<span class="dv"
      >0</span
      >,<span class="dv"
      >8</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >3</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >8</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >1</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >3</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >0</span
      >,<span class="dv"
      >8</span
      >,<span class="dv"
      >4</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >6</span
      >,<span class="dv"
      >2</span
      >,<span class="dv"
      >5</span
      >,<span class="dv"
      >1</span
      > <span class="fu"
      >&#8229;.</span
      >])<br
       /></code
    ></pre
  ></div
><div id="implementing-the-reverse-state-monad"
><h3
  ><a href="#TOC"
    >Implementing the reverse state monad</a
    ></h3
  ><p
  >The reverse (backward) state is defined just as <code
    >State</code
    > (forward state):</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >newtype</span
      > <span class="dt"
      >StateR</span
      > s a <span class="fu"
      >=</span
      > <span class="dt"
      >StateR</span
      > { runStateR <span class="dv"
      >&#8759;</span
      > s &#8594; (a,s) }<br
       /></code
    ></pre
  ><pre class="sourceCode haskell"
  ><code
    >runStateR' <span class="dv"
      >&#8759;</span
      > <span class="dt"
      >StateR</span
      > s a &#8594; s &#8594; (s,a)<br
       />runStateR' <span class="fu"
      >=</span
      > (result<span class="fu"
      >.</span
      >result) swap runStateR<br
       /></code
    ></pre
  ><p
  >The <code
    >Functor</code
    > instance is also defined as with <code
    >State</code
    >:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="kw"
      >Functor</span
      > (<span class="dt"
      >StateR</span
      > s) <span class="kw"
      >where</span
      ><br
       />  <span class="fu"
      >fmap</span
      > f (<span class="dt"
      >StateR</span
      > h) <span class="fu"
      >=</span
      > <span class="dt"
      >StateR</span
      > (&#955; s &#8594; <span class="kw"
      >let</span
      > (a,s') <span class="fu"
      >=</span
      > h s <span class="kw"
      >in</span
      > (f a, s'))<br
       /></code
    ></pre
  ><p
  >Using the ideas from <em
    ><a href="http://conal.net/blog/posts/prettier-functions-for-wrapping-and-wrapping/" title="blog post"
      >Prettier functions for wrapping and wrapping</a
      ></em
    > and the notational improvement from Matt Hellige’s <em
    ><a href="http://matt.immute.net/content/pointless-fun" title="blog post by Matt Hellige"
      >Pointless fun</a
      ></em
    >, we can get a much more elegant definition:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="kw"
      >Functor</span
      > (<span class="dt"
      >StateR</span
      > s) <span class="kw"
      >where</span
      ><br
       />  <span class="fu"
      >fmap</span
      > <span class="fu"
      >=</span
      > inStateR <span class="fu"
      >.</span
      > result <span class="fu"
      >.</span
      > first<br
       /></code
    ></pre
  ><p
  >where</p
  ><pre class="sourceCode haskell"
  ><code
    >inStateR <span class="dv"
      >&#8759;</span
      > ((s &#8594; (a,s)) &#8594; (t &#8594; (b,t)))<br
       />         &#8594; (<span class="dt"
      >StateR</span
      > s a  &#8594; <span class="dt"
      >StateR</span
      > t b)<br
       />inStateR <span class="fu"
      >=</span
      > runStateR <span class="fu"
      >~&gt;</span
      > <span class="dt"
      >StateR</span
      ><br
       /></code
    ></pre
  ><p
  >The <code
    >Monad</code
    > instance shows how the flow of state is reversed. The incoming state flows into the second action, which produces a state for the first action.</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="kw"
      >Monad</span
      > (<span class="dt"
      >StateR</span
      > s) <span class="kw"
      >where</span
      ><br
       />  <span class="fu"
      >return</span
      > a <span class="fu"
      >=</span
      > <span class="dt"
      >StateR</span
      > <span class="fu"
      >$</span
      > &#955; s &#8594; (a,s)<br
       />  m <span class="fu"
      >&gt;&gt;=</span
      > k  <span class="fu"
      >=</span
      > <span class="dt"
      >StateR</span
      > <span class="fu"
      >$</span
      > &#955; u &#8594; <span class="kw"
      >let</span
      > (a,s) <span class="fu"
      >=</span
      > runStateR m t<br
       />                                 (b,t) <span class="fu"
      >=</span
      > runStateR (k a) u<br
       />                             <span class="kw"
      >in</span
      ><br
       />                               (b,s)<br
       /></code
    ></pre
  ><p
  >Although <code
    >zipWithM</code
    > is defined for monads, it can be defined more generally, for arbitrary applicative functors, so we really only required that <code
    >StateR</code
    > be an applicative functor. I wonder whether there are example uses of the backward state monad that need the full expressive power of the <code
    >Monad</code
    > interface, as opposed to the simpler &amp; more general <code
    >Applicative</code
    > interface. The <code
    >Applicative</code
    > instance of <code
    >StateR</code
    > is more straightforward, as there is no longer information flowing in opposite directions:</p
  ><pre class="sourceCode haskell"
  ><code
    ><span class="kw"
      >instance</span
      > <span class="dt"
      >Applicative</span
      > (<span class="dt"
      >StateR</span
      > s) <span class="kw"
      >where</span
      ><br
       />  pure a <span class="fu"
      >=</span
      > <span class="dt"
      >StateR</span
      > <span class="fu"
      >$</span
      > &#955; s &#8594; (a,s)<br
       />  <span class="dt"
      >StateR</span
      > hf <span class="fu"
      >&lt;*&gt;</span
      > <span class="dt"
      >StateR</span
      > hx <span class="fu"
      >=</span
      > <span class="dt"
      >StateR</span
      > <span class="fu"
      >$</span
      > &#955; u &#8594;<br
       />    <span class="kw"
      >let</span
      > (x,t) <span class="fu"
      >=</span
      > hx u<br
       />        (f,s) <span class="fu"
      >=</span
      > hf t<br
       />    <span class="kw"
      >in</span
      ><br
       />      (f x,s)<br
       /></code
    ></pre
  ></div
><div id="closing-thoughts"
><h3
  ><a href="#TOC"
    >Closing thoughts</a
    ></h3
  ><p
  >Adding digits in right-to-left (most to least significant) order saves effort when decisions can be based on approximations rather than exact values. To see how very common this situation is, consider the popularity of finite-precision floating point representations like <code
    >Float</code
    > and <code
    >Double</code
    >. <em
    >Whenever</em
    > we use these representations, we’re computing with only most significant digits. Although efficient, thanks to hardware support, these common types lack the sort of modularity that characterizes pure, lazy functional programming. Commitment to a particular finite precision up front computes too little information, leading to incorrect results, or too much information, leading to wasted time and power.</p
  ><p
  >The requirement of choosing precision up front breaks modularity, because the best choice depends on how intermediate computed values are <em
    >consumed</em
    >. Modularity insists that values be specified independently from their uses. Exactly this issue motivates laziness, as explained and illustrated in <em
    ><a href="http://www.cs.chalmers.se/~rjmh/Papers/whyfp.html" title="Paper by John Hughes"
      >Why Functional Programming Matters</a
      ></em
    >. Requiring ourselves to program with types like <code
    >Float</code
    > and <code
    >Double</code
    > is thus like having to choose between fixed-length list types, with elements getting lost off the end when the preselected length is exceeded.</p
  ><p
  >Of course the representations in this post are nowhere near suited to replace hardware-supported, inexact numerics. Still, they’re fun to play with, and they illustrate some functional programming techniques, while restoring compositionality/modularity and simple, precise semantics.</p
  ></div
></div
>
</div>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=240&amp;md5=5be70e58b5a95fc3ce9ea7fc839a42b0" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/AdSKJ8XxV5Y" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/adding-numbers/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/adding-numbers</feedburner:origLink></item>
		<item>
		<title>Memoizing polymorphic functions via unmemoization</title>
		<link>http://feedproxy.google.com/~r/conal/~3/w98M_vFBWKc/memoizing-polymorphic-functions-via-unmemoization</link>
		<comments>http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization#comments</comments>
		<pubDate>Mon, 27 Sep 2010 22:38:46 +0000</pubDate>
		<dc:creator>conal</dc:creator>
				<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[memoization]]></category>

		<guid isPermaLink="false">http://conal.net/blog/?p=203</guid>
		<description><![CDATA[<dl>
: http://www.haskell.org/haskellwiki/DeepArrow "Haskell wiki entry"
<dd>
http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/ "blog post"
</dd>

<dd>
http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/ "blog post"
</dd>

<dd>
http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/ "blog post"
</dd>

<dd>
http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/ "blog post"
</dd>

<dd>
http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html "blog post by Dan Piponi"
</dd>

<dd>
http://conal.net/blog/tag/memoization/ "Posts ...
</dd>
</dl>]]></description>
			<content:encoded><![CDATA[<!-- 

Title: Memoizing polymorphic functions via unmemoization

Tags: memoization

URL: http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization/

-->

<!-- references -->

<!-- teaser -->

<p>Last year I wrote two posts on memoizing polymorphic functions.
The <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-part-one/" title="blog post">first post</a> gave a solution of sorts that uses a combination of patricia trees (for integer-keyed maps), stable names, and type equality proofs.
The <a href="http://conal.net/blog/posts/memoizing-polymorphic-functions-part-two/" title="blog post">second post</a> showed how to transform some functions that do not quite fit the required form so that they do fit.</p>

<p>Dan Piponi wrote a follow-up post <em><a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Memoizing Polymorphic Functions with High School Algebra and Quantifiers</a></em> showing a different approach that was more in the spirit of type-directed functional memoization, as it follows purely from mathematical properties, free of the deeply operational magic of stable names.
Recently, I finally studied and worked with Dan&#8217;s post enough to understand what he did.
It&#8217;s <em>very</em> clever and beautiful!</p>

<p>This post re-presents Dan&#8217;s elegant insight as I understand it, via some examples that helped it come together for me.</p>

<!--
**Edits**:

* 2010-02-09: just fiddling around
-->

<!-- without a comment or something here, the last item above becomes a paragraph -->

<p><span id="more-203"></span></p>

<h3>Playing with quantifiers</h3>

<p>Consider the type of <code>fmap</code>:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #cccc00; font-weight: bold;">Functor</span></a> f ⇒ <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → f a → f b</pre>
</div></p>

<p>and make the type quantification explicit</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: #339933; font-weight: bold;">::</span> ∀ f a b<span style="color: #339933; font-weight: bold;">.</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #cccc00; font-weight: bold;">Functor</span></a> f ⇒ <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → f a → f b</pre>
</div></p>

<p>Since the <code>Functor</code> constraint depends only on <code>f</code>, restrict the scope of the other quantifiers:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: #339933; font-weight: bold;">::</span> ∀ f<span style="color: #339933; font-weight: bold;">.</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #cccc00; font-weight: bold;">Functor</span></a> f ⇒ ∀ a b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → f a → f b</pre>
</div></p>

<p>We cannot further restrict the scope of <code>a</code> or <code>b</code>, because the first argument of the function involves both <code>a</code> and <code>b</code>.
The <em>second</em> argument, however, ignores <code>b</code>, so let&#8217;s next <code>flip</code> the arguments.</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:flip"><span style="font-weight: bold;">flip</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: #339933; font-weight: bold;">::</span> ∀ f<span style="color: #339933; font-weight: bold;">.</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #cccc00; font-weight: bold;">Functor</span></a> f ⇒ ∀ a b<span style="color: #339933; font-weight: bold;">.</span> f a → <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → f b</pre>
</div></p>

<p>and restrict the scope of <code>b</code>:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:flip"><span style="font-weight: bold;">flip</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <span style="color: #339933; font-weight: bold;">::</span> ∀ f<span style="color: #339933; font-weight: bold;">.</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #cccc00; font-weight: bold;">Functor</span></a> f ⇒ ∀ a<span style="color: #339933; font-weight: bold;">.</span> f a → ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → f b</pre>
</div></p>

<p>Next introduce names:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> Yo f a <span style="color: #339933; font-weight: bold;">=</span> ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → f b
&nbsp;
toYo <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Functor"><span style="color: #cccc00; font-weight: bold;">Functor</span></a> f ⇒ ∀ a<span style="color: #339933; font-weight: bold;">.</span> f a → Yo f a
toYo <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:flip"><span style="font-weight: bold;">flip</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a></pre>
</div></p>

<p>So <code>flip fmap</code> is a way to map <code>f a</code> to <code>Yo f a</code>.
The reverse is easier:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">fromYo <span style="color: #339933; font-weight: bold;">::</span> ∀ a<span style="color: #339933; font-weight: bold;">.</span> Yo f a → f a
fromYo f <span style="color: #339933; font-weight: bold;">=</span> f <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a></pre>
</div></p>

<p>GHC&#8217;s type-checker won&#8217;t really let this <code>toYo</code> definition fly, because of persnickety details about universal quantification.
Instead, inline <code>flip</code> and simplify:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">toYo x p <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> p x</pre>
</div></p>

<h3>The Yoneda lemma</h3>

<p>Are the functions <code>fromYo</code> and <code>toYo</code> inverses of each other?
The <a href="http://en.wikipedia.org/wiki/Yoneda_lemma">Yoneda lemma</a> from category theory says yes.
The following proof is taken from <a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Dan&#8217;s post</a>:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  fromYo <span style="color: green;">&#40;</span>toYo x<span style="color: green;">&#41;</span>
≡ fromYo <span style="color: green;">&#40;</span>λ p → <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> p x<span style="color: green;">&#41;</span>
≡ <span style="color: green;">&#40;</span>λ p → <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> p x<span style="color: green;">&#41;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a>
≡ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a> x
≡ x                    <span style="color: #5d478b; font-style: italic;">-- a functor law</span>
&nbsp;
  toYo <span style="color: green;">&#40;</span>fromYo f<span style="color: green;">&#41;</span>
≡ toYo <span style="color: green;">&#40;</span>f <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a><span style="color: green;">&#41;</span>
≡ λ p → <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> p <span style="color: green;">&#40;</span>f <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a><span style="color: green;">&#41;</span>
≡ λ p → f <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> p <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a><span style="color: green;">&#41;</span>  <span style="color: #5d478b; font-style: italic;">-- f is polymorphic/natural</span>
≡ λ p → f <span style="color: green;">&#40;</span>p ∘ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:id"><span style="font-weight: bold;">id</span></a><span style="color: green;">&#41;</span>     <span style="color: #5d478b; font-style: italic;">-- fmap on functions is (∘)</span>
≡ λ p → f p
≡ f</pre>
</div></p>

<p>Note the critical role of <em>naturality</em>, which holds of parametrically polymorphic functions in Haskell.
To say that a function <code>f</code> is <em>natural</em> means that it commutes with <code>fmap p</code>, for all functions <code>p</code>, i.e.,</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> p ∘ f  ≡  f ∘ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:fmap"><span style="font-weight: bold;">fmap</span></a> p</pre>
</div></p>

<h2>Playing with the Yoneda lemma</h2>

<p>With a little type massaging, the Yoneda lemma can be applied more broadly than its literal form.
For instance, consider the type <code>(∀ b. f b)</code> for a functor <code>f.</code>
Does it have a simpler isomorphic form?</p>

<p>The Yoneda lemma applies to types of the form <code>∀ b. (a → b) → f b</code> for some type <code>a</code>.
We don&#8217;t have a function to <code>f b</code>, but we could fake one by introducing a unit argument:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ b<span style="color: #339933; font-weight: bold;">.</span> f b
≅ ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: red;">1</span> → f b</pre>
</div></p>

<p>Warning: this step is only correct for strict functions, so I&#8217;m fudging here.</p>

<p>I&#8217;m using &#8220;<code>1</code>&#8221; for the Haskell type <code>()</code>.
I&#8217;ll also use &#8220;×&#8221; and &#8220;+&#8221; for product and sum types in these examples, in place of the Haskell names &#8220;<code>(,)</code>&#8221; and &#8220;<code>Either</code>&#8220;.
For parsing the examples, × binds more tightly than than +, which binds more tightly than →.</p>

<p>We haven&#8217;t gotten to the required form yet, because we have <code>1</code> where we need <code>a → b</code> for some <code>a</code>.
Hm.
For what type <code>a</code> is there only one function from <code>a</code> to <code>b</code>, where <code>b</code> is <em>arbitrary</em> type?
By choosing <code>b</code> to have at least two elements, we can make different functions of type <code>a → b</code> by mapping some element of <code>a</code> to different elements of <code>b</code>.
Unless <code>a</code> has no elements at all!</p>

<p>Let <code>0</code> be the type with no elements:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> <span style="color: red;">0</span></pre>
</div></p>

<p>This type is usually named &#8220;<code>Void</code>&#8221; in Haskell.</p>

<p>Since there are no values of type <code>0</code>, there is exactly one function from <code>0</code> to any other type <code>b</code>, i.e., <code>1 ≅ 0 → b</code>.
(This type isomorphism corresponds to a familiar equality on numbers.)
Thus continuing our definition from above</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">⋯ ≅ ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: red;">0</span> → b<span style="color: green;">&#41;</span> → f b</pre>
</div></p>

<p>Now we have the form covered directly by the Yoneda lemma</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">⋯ ≅ f <span style="color: red;">0</span></pre>
</div></p>

<p>Oh dear, I keep lying to you.
The step from <code>1</code> to <code>0 → b</code> is also valid only for strict functions, or for a <code>0</code> without ⊥.</p>

<p>Replaying this derivation,</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ b<span style="color: #339933; font-weight: bold;">.</span> f b
≅ ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: red;">1</span> → f b
≅ ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: red;">0</span> → b<span style="color: green;">&#41;</span> → f b
≅ f <span style="color: red;">0</span></pre>
</div></p>

<p>Next try a simpler example: <code>∀ a. a</code>.
This time, temporarily introduce the identity functor <code>Id</code>:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ a<span style="color: #339933; font-weight: bold;">.</span> a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> Id a
≅ Id <span style="color: red;">0</span>
≅ <span style="color: red;">0</span></pre>
</div></p>

<p>which is correct, as there is no non-⊥ value of type <code>∀ a. a</code>.</p>

<p>Next try <code>∀ a. a → a</code>:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ a<span style="color: #339933; font-weight: bold;">.</span> a → a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> → Id a
≅ Id <span style="color: red;">1</span>
≅ <span style="color: red;">1</span></pre>
</div></p>

<p>And indeed, there is only one (non-⊥) function of type <code>∀ a. a → a</code>.</p>

<p>Here&#8217;s a simple specialization of the Yoneda lemma (also mentioned in <a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Dan&#8217;s post</a>):</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → b
≅ ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → Id b
≅ Id a
≅ a</pre>
</div></p>

<p>These examples prove the existence of bijection, but we can also synthesize the bijections, as <a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Dan Piponi demonstrates</a>.
The bijections then let us memoize.</p>

<h3>Memoizing polymorphic functions via <em>unmemoization</em></h3>

<p>Let&#8217;s look at the Yoneda lemma again.
Recall</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> Yo f a <span style="color: #339933; font-weight: bold;">=</span> ∀ b<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>a → b<span style="color: green;">&#41;</span> → f b</pre>
</div></p>

<p>For all natural transformations <code>f</code> (in Haskell polymorphic functions  <a href="http://blog.sigfpe.com/2006/11/yoneda-lemma.html" title="blog post by Dan Piponi">&#8220;with no funny stuff&#8221;</a>), the Yoneda lemma says that</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">Yo f a ≅ f a</pre>
</div></p>

<p>where the conversions between <code>Yo f a</code> and <code>f a</code> are very simple: <code>($ id)</code> and <code>flip fmap</code>.</p>

<p>Now suppose we want to memoize a polymorphic function <code>∀ a. T a → f a</code>.
The Yoneda lemma suggests that we find some <code>Q</code> such that <code>T a ≅ Q → a</code>, in which case</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ a<span style="color: #339933; font-weight: bold;">.</span> T a → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>Q → a<span style="color: green;">&#41;</span> → f a
≅ f Q</pre>
</div></p>

<p>How do <code>Q</code> and <code>T</code> relate?
<code>T</code> is a memo table for <code>Q</code>.
In other words, <code>Q</code> is the type of <em>indices</em> into <code>T</code>.
In still other words, <code>Q</code> is an <em>unmemoization</em> of <code>T</code>.</p>

<p>This trick is from Dan Piponi&#8217;s post <em><a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Memoizing Polymorphic Functions with High School Algebra and Quantifiers</a></em>.
We started with a polymorphic function, and we ended up with a data structure, i.e., we have <em>memoized</em>.
But the critical step one the route to memoization was <em>unmemoization</em> (of <code>T</code>).
Delightful!</p>

<p>We saw some very simple examples in the previous section.
Let&#8217;s next look at some more examples.</p>

<h4>Pairs</h4>

<p>How can we memoize polymorphic functions on pairs, i.e., functions of type <code>∀ a. a × a → f a</code>?</p>

<p>We can work out an answer by appealing to the same laws of exponents used in <a href="http://conal.net/blog/posts/elegant-memoization-with-functional-memo-tries/" title="blog post">memoization</a>, but now applied in reverse (to create function types instead of eliminate them).</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  a × a
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span> → a
≅ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a> → a</pre>
</div></p>

<p>Again, I&#8217;m handling only <em>strict</em> functions here.</p>

<p>Therefore,</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> a × a → f a<span style="color: green;">&#41;</span>  ≅  f <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a></pre>
</div></p>

<p>Spelling out this conclusion (once more for practice),</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ a<span style="color: #339933; font-weight: bold;">.</span> a × a      → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a> → a<span style="color: green;">&#41;</span> → f a
≅ f <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a></pre>
</div></p>

<p>A variation on this derivation is to make the pairing functor explicit as</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> P a <span style="color: #339933; font-weight: bold;">=</span> P a a</pre>
</div></p>

<p>or, using <a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">functor combinators</a>,</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> P <span style="color: #339933; font-weight: bold;">=</span> Id :<span style="color: #339933; font-weight: bold;">*</span>: Id</pre>
</div></p>

<p>Now imagine we have a type family <code>UnTrie</code> that acts as an inverse to <code>Trie</code></p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> UnTrie P <span style="color: #339933; font-weight: bold;">=</span> UnTrie <span style="color: green;">&#40;</span>Id :<span style="color: #339933; font-weight: bold;">*</span>: Id<span style="color: green;">&#41;</span>
              <span style="color: #339933; font-weight: bold;">=</span> UnTrie Id <span style="color: #339933; font-weight: bold;">+</span> UnTrie Id
              <span style="color: #339933; font-weight: bold;">=</span> <span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span>
              ≅ <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a></pre>
</div></p>

<h4>Streams</h4>

<p>A type of streams (infinite-only lazy lists) is like the type of lists but without a nil case:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> Stream a <span style="color: #339933; font-weight: bold;">=</span> Cons a <span style="color: green;">&#40;</span>Stream a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>How can we memoize <code>∀ a. Stream a → f a</code>?
We simply ask: for what type is <code>Stream</code> a memo table?
Or: what type naturally indexes a stream?
An answer is natural numbers in Peano form:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> Nat <span style="color: #339933; font-weight: bold;">=</span> Zero <span style="color: #339933; font-weight: bold;">|</span> Succ Nat</pre>
</div></p>

<p>Memoizing <code>Nat → a</code> as in <em><a href="http://conal.net/blog/posts/elegant-memoization-with-higher-order-types/" title="blog post">Elegant memoization with higher-order types</a></em> leads to <code>Stream a</code>.</p>

<p>Therefore,</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">∀ a<span style="color: #339933; font-weight: bold;">.</span> Stream a → f a  ≅  f Nat</pre>
</div></p>

<p>In case we didn&#8217;t think of <code>Nat</code> right off, we can derive it systematically.
We&#8217;ll appeal to the same three laws of exponents used in memoization, but now applied in reverse (to create function types instead of eliminate them).</p>

<p>Look for a type <code>N</code> such that <code>N → a ≅ Stream a</code>.</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  N → a
≅ Stream a
≅ a × Stream a
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>N → a<span style="color: green;">&#41;</span>   <span style="color: #5d478b; font-style: italic;">--  coinductively</span>
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> N<span style="color: green;">&#41;</span> → a</pre>
</div></p>

<p>A sufficient condition then is that <code>N ≅ 1 + N</code>, which condition then translates to a recursive data type definition:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> N <span style="color: #339933; font-weight: bold;">=</span> Z <span style="color: #339933; font-weight: bold;">|</span> S N</pre>
</div></p>

<p>or</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> Nat <span style="color: #339933; font-weight: bold;">=</span> Zero <span style="color: #339933; font-weight: bold;">|</span> Succ Nat</pre>
</div></p>

<h4>Infinite binary trees</h4>

<p>Next let&#8217;s look at one form of binary trees, having values at each node and only infinite paths.</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> BTree a <span style="color: #339933; font-weight: bold;">=</span> BTree a <span style="color: green;">&#40;</span>BTree a<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>BTree a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>and let <code>B</code> be an unmemoized form of <code>BTree</code>, or type of indices of <code>BTree</code>, i.e., <code>B → a ≅ BTree a</code>.</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  B → a
≅ BTree a
≅ a × BTree a × BTree a
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>B → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>B → a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> B <span style="color: #339933; font-weight: bold;">+</span> B<span style="color: green;">&#41;</span> → a</pre>
</div></p>

<p>A sufficient definition for <code>B</code> is then <code>B = 1 + B + B</code>.
Or in legal Haskell form (no recursive type synonyms):</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> B <span style="color: #339933; font-weight: bold;">=</span> Z <span style="color: #339933; font-weight: bold;">|</span> E B <span style="color: #339933; font-weight: bold;">|</span> O B</pre>
</div></p>

<p>We can think of this data type as representing natural numbers in <a href="http://en.wikipedia.org/wiki/Endianness">little endian</a> binary.
Expanding the type and constructor names:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> BinNat <span style="color: #339933; font-weight: bold;">=</span> Zero <span style="color: #339933; font-weight: bold;">|</span> Even BinNat <span style="color: #339933; font-weight: bold;">|</span> Odd BinNat</pre>
</div></p>

<h4>A variation on infinite binary trees</h4>

<p>We might have written our tree type differently:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> BTree a <span style="color: #339933; font-weight: bold;">=</span> BTree a <span style="color: green;">&#40;</span>P <span style="color: green;">&#40;</span>BTree a<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>where <code>P</code> is the pairing functor.
Again, let <code>B</code> be the sought index type for (unmemoization of) <code>BTree</code></p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  B → a
≅ BTree a
≅ a × P <span style="color: green;">&#40;</span>BTree a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a> → BTree a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a> → B → a<span style="color: green;">&#41;</span>     ­<span style="color: #339933; font-weight: bold;">-</span> coinductively
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a> × B → a<span style="color: green;">&#41;</span>
≅ <span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a> × B → a</pre>
</div></p>

<p>which then leads to a slightly different representation for our index type:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> BinNat <span style="color: #339933; font-weight: bold;">=</span> Zero <span style="color: #339933; font-weight: bold;">|</span> NonZero <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a> BinNat</pre>
</div></p>

<p>We&#8217;ve made the <em>bit</em> type explicit.
In this form, <code>BinNat</code> is a little-endian list of bits, so we can redefine it as such:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> BinNat <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#91;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a><span style="color: green;">&#93;</span></pre>
</div></p>

<p>and the desired isomorphism</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> BTree a → f a<span style="color: green;">&#41;</span>  ≅  f <span style="color: green;">&#91;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a><span style="color: green;">&#93;</span></pre>
</div></p>

<h4>Generalized infinite trees</h4>

<p>The functor <code>P</code> and the type <code>Bool</code> have an important relationship to each other in the previous derivation, namely <code>Bool</code> is the index type for <code>P</code>.
We can play this same trick for <em>all</em> index types and their corresponding trie (memoization) functors.
Generalize from binary trees:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> Tree d a <span style="color: #339933; font-weight: bold;">=</span> Tree a <span style="color: green;">&#40;</span>d :→: Tree d a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>where &#8220;<code>k :→: v</code>&#8221; is the type of memo tries over domain type <code>k</code>, with range <code>v</code>.
(The trie structure is driven entirely by <code>k</code>.)
See other <a href="http://conal.net/blog/tag/memoization/" title="Posts on memoization">posts on memoization</a>.</p>

<p>These generalized trees are indexed by little-endian natural numbers over a &#8220;digit&#8221; type <code>d</code>.
Generalizing the proof for binary trees we get</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">Tree d a ≅ <span style="color: green;">&#91;</span>d<span style="color: green;">&#93;</span> → a</pre>
</div></p>

<p>Details:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  Tree d a
≅ a × <span style="color: green;">&#40;</span>d :→: Tree d a<span style="color: green;">&#41;</span>
≅ a × <span style="color: green;">&#40;</span>d → Tree d a<span style="color: green;">&#41;</span>
≅ a × <span style="color: green;">&#40;</span>d → <span style="color: green;">&#91;</span>d<span style="color: green;">&#93;</span> → a<span style="color: green;">&#41;</span>   ­<span style="color: #339933; font-weight: bold;">-</span> coinductively
≅ a × <span style="color: green;">&#40;</span>d × <span style="color: green;">&#91;</span>d<span style="color: green;">&#93;</span> → a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>d × <span style="color: green;">&#91;</span>d<span style="color: green;">&#93;</span> → a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span><span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> d × <span style="color: green;">&#91;</span>d<span style="color: green;">&#93;</span> → a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#91;</span>d<span style="color: green;">&#93;</span> → a</pre>
</div></p>

<p>So the Yoneda lemma tells us that</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> Tree d a → f a<span style="color: green;">&#41;</span> ≅ f <span style="color: green;">&#91;</span>d<span style="color: green;">&#93;</span></pre>
</div></p>

<p>Specializing, we get binary trees indexed by binary numbers, and streams (&#8220;unary trees&#8221;) indexed by unary numbers:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> BTree <span style="color: #339933; font-weight: bold;">=</span> Tree <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Bool"><span style="color: #cccc00; font-weight: bold;">Bool</span></a>
<span style="color: #06c; font-weight: bold;">type</span> Stream <span style="color: #339933; font-weight: bold;">=</span> Tree <span style="color: red;">1</span></pre>
</div></p>

<p>For rose trees we would need an index type <code>d</code> whose memo tries are lists, i.e., <code>d :→: v ≅ [v]</code> for all types <code>v</code>.
I don&#8217;t think there is such a type <code>d</code>, since <code>[v]</code> is isomorphic to a <code>sum</code> type, and memoization&#8211;like exponentiation­-doesn&#8217;t produce sums.
I&#8217;ll return to this question below.</p>

<h4><code>Maybe</code></h4>

<p>Let&#8217;s try something a bit simpler: memoizing <code>∀ a. Maybe a → f a</code>.
Of what domain type is <code>Maybe a</code> a memo table?</p>

<p>Oops.
None of the memoizing transformations generates a sum type such as <code>Maybe</code>.
So we&#8217;ll have to try something else.
First split the domain sum, yielding a product, and then proceed with the summands.</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ a<span style="color: #339933; font-weight: bold;">.</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Maybe"><span style="color: #cccc00; font-weight: bold;">Maybe</span></a> a → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> a<span style="color: green;">&#41;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: red;">1</span> → f a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>a → f a<span style="color: green;">&#41;</span>
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> f a × <span style="color: green;">&#40;</span>a → f a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> f a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> a → f a<span style="color: green;">&#41;</span>
≅ f <span style="color: red;">0</span> × f <span style="color: red;">1</span></pre>
</div></p>

<h4>Lists</h4>

<p>(Even more than the previous sections, this one is a regurgitation of material from <a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Dan&#8217;s post</a>.)</p>

<p>We&#8217;ve covered <code>Maybe</code> and <code>Stream</code> above, so lists might work out with a combination of techniques.</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: red;">1</span> → f a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span>
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> f a × <span style="color: green;">&#40;</span>a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> f a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span>
≅ f <span style="color: red;">0</span> × <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span></pre>
</div></p>

<p>How to continue from here?
The remaining polymorphic function doesn&#8217;t look quite like what we started with.
Dan&#8217;s trick was to generalize (as <a href="http://en.wikipedia.org/wiki/How_to_Solve_It">Pólya recommended</a>), replacing <code>[a]</code> with <code>a^n × [a]</code>, starting the process with <code>n ≡ 0</code>.
Dan generalized even more, where <code>n</code> is an arbitrary <em>type</em>, to <code>(n → a) × [a]</code>, starting with <code>n ≡ 0</code> (zero).</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> T f n <span style="color: #339933; font-weight: bold;">=</span> ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a</pre>
</div></p>

<p>Then</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">  T f n
≡ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span><span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> × <span style="color: red;">1</span> <span style="color: #339933; font-weight: bold;">+</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> × a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> × a × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span><span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">+</span> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a
≅ ∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> → f a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span><span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span>
≅ <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n → a<span style="color: green;">&#41;</span> → f a<span style="color: green;">&#41;</span> × <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span>
≅ f n × <span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span> → a<span style="color: green;">&#41;</span> × <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span>
≡ f n × T f <span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>Inductively, this isomorphism gives rise to an function-free type:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">type</span> Q f n <span style="color: #339933; font-weight: bold;">=</span> f n × Q f <span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>for which</p>

<p><div>
<pre class="haskell" style="font-family:monospace;">Q f n ≅ T f n</pre>
</div></p>

<p>Since Haskell doesn&#8217;t handle recursive type synonyms, instead define a new <code>data</code> type, as in <a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Dan&#8217;s post</a>:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> Q f n <span style="color: #339933; font-weight: bold;">=</span> Q <span style="color: green;">&#40;</span>f n<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Q f <span style="color: green;">&#40;</span>n <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>Since <code>n + 1 ≅ Maybe n</code>, we could instead define</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> Q f n <span style="color: #339933; font-weight: bold;">=</span> Q <span style="color: green;">&#40;</span>f n<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Q f <span style="color: green;">&#40;</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Maybe"><span style="color: #cccc00; font-weight: bold;">Maybe</span></a> n<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre>
</div></p>

<p>As Dan described, the trick in this derivation is to rework the type <code>[a]</code> in polynomial form <code>[a] ≅ 1 + a + a^2 + a^3 + ⋯</code>.
Then memoization works out fairly easily:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span> ≅ f <span style="color: red;">0</span> × f <span style="color: red;">1</span> × f <span style="color: red;">2</span> × <span style="color: #339933; font-weight: bold;">...</span></pre>
</div></p>

<p>Where the types <code>0</code>, <code>1</code>, <code>2</code>, … have 0, 1, 2, … elements, respectively.
We can choose <code>2 = Maybe 1</code>, <code>3 = Maybe 2</code>, … or <code>2 = 1 + 1</code>, <code>3 = 2 + 1</code>, ….</p>

<h3>Where to go from here?</h3>

<h4>Algebraic types</h4>

<p>I&#8217;m not entirely satisfied with this solution to memoizing polymorphic functions over lists (and other algebraic types).
I want to find another angle that doesn&#8217;t require this conversion to polynomial form.
Partly because I don&#8217;t think it handles infinite lists (as Dan mentioned).
I suppose one could just add the infinite case:</p>

<p><div>
<pre class="haskell" style="font-family:monospace;"><span style="color: green;">&#40;</span>∀ a<span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> → f a<span style="color: green;">&#41;</span> ≅ <span style="color: green;">&#40;</span>f <span style="color: red;">0</span> × f <span style="color: red;">1</span> × f <span style="color: red;">2</span> × <span style="color: #339933; font-weight: bold;">...</span><span style="color: green;">&#41;</span> × f Nat ≅ Q f n × f Nat</pre>
</div></p>

<p>How to justify/derive this isomorphism?
And how to get non-strict memoization, including sharing of work for computations that use bounded input?</p>

<p>I also want a representation that&#8217;s friendly to non-strict memoization, sharing work on common prefixes.</p>

<h4>Constructing isomorphisms</h4>

<p>As always, type isomorphism is at the core of functional memoization.
However, it&#8217;s not enough to show that isomorphisms exist.
We have to <em>construct</em> the isomorphisms in order to implement a harder memoization problem via an easier one.</p>

<p><a href="http://blog.sigfpe.com/2009/11/memoizing-polymorphic-functions-with.html" title="blog post by Dan Piponi">Dan&#8217;s post</a> builds up some isomorphisms.
The process is rather tedious, and I&#8217;d like to make it much easier.
I&#8217;ve tinkered with making this process much more elegant by applying <em><a href="http://conal.net/blog/posts/semantic-editor-combinators/" title="blog post">Semantic editor combinators</a></em> in their generalized form (as in the paper <em><a href="http://conal.net/papers/Eros/" title="Paper">Tangible Functional Programming</a></em>), using bijections as the <a href="DeepArrow">deep arrow</a>.
So far, however, I&#8217;m struggling unsuccessfully against awkwardness in the handling of explicit polymorphism (higher-rank types).</p>

<h4>Automation</h4>

<p>In my other <a href="http://conal.net/blog/tag/memoization/" title="Posts on memoization">posts on memoization</a>, functions are memoized in a fully automatic, type-driven way.
Can the same be done somehow with polymorphic functions?</p>

<h4>Non-strictness</h4>

<p>I fudged treatment of non-strictness above.
Can non-strict polymorphic functions be handled correctly and elegantly, perhaps with a simple combination of previous techniques or perhaps with new ones?</p>

<h4>Other memoization tools?</h4>

<p>Dan&#8217;s use of the Yoneda lemma to memoize polymorphic functions (via <em>unmemoization</em>) came as a surprise to me.
Are there other deep properties of typed, pure functional programming that give rise to additional tools for memoization?
One place to start looking is additional free theorems.</p>

<h4>Relationship to numeric representations</h4>

<p>In <em><a href="http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504" title="book by Chris Okasaki">Purely Functional Data Structures</a></em>, Chris Okasaki points out a correspondence between number representation schemes and collection data structures.
How does this correspondence relate to memoization?</p>
<p class="wp-flattr-button"></p> <p><a href="http://conal.net/blog/?flattrss_redirect&amp;id=203&amp;md5=3c1df60132147b7dfd9e3c1eeead2a76" title="Flattr" target="_blank"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/></a></p><img src="http://feeds.feedburner.com/~r/conal/~4/w98M_vFBWKc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization/feed</wfw:commentRss>
		<slash:comments>12</slash:comments>
		<feedburner:origLink>http://conal.net/blog/posts/memoizing-polymorphic-functions-via-unmemoization</feedburner:origLink></item>
	</channel>
</rss>
