<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Conal Elliott &#187; vector</title>
	<atom:link href="http://conal.net/blog/tag/vector/feed" rel="self" type="application/rss+xml" />
	<link>http://conal.net/blog</link>
	<description>Inspirations &#38; experiments, mainly about denotative/functional programming in Haskell</description>
	<lastBuildDate>Thu, 25 Jul 2019 18:15:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.1.17</generator>
	<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2F&amp;language=en_US&amp;category=text&amp;title=Conal+Elliott&amp;description=Inspirations+%26amp%3B+experiments%2C+mainly+about+denotative%2Ffunctional+programming+in+Haskell&amp;tags=blog" type="text/html" />
	<item>
		<title>From tries to trees</title>
		<link>http://conal.net/blog/posts/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><![CDATA[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&#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 n-dimensional vectors themselves have an elegant trie, which [&#8230;]]]></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><a href="http://conal.net/blog/?flattrss_redirect&amp;id=314&amp;md5=209bdcd3e572f837b906074e674313d9"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/from-tries-to-trees/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ffrom-tries-to-trees&amp;language=en_GB&amp;category=text&amp;title=From+tries+to+trees&amp;description=This+post+is+the+last+of+a+series+of+six+relating+numbers%2C+vectors%2C+and+trees%2C+revolving+around+the+themes+of+static+size-typing+and+memo+tries.+We%26%238217%3Bve+seen+that+length-typed+vectors...&amp;tags=number%2Ctree%2Ctrie%2Cvector%2Cblog" type="text/html" />
	</item>
		<item>
		<title>A trie for length-typed vectors</title>
		<link>http://conal.net/blog/posts/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><![CDATA[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&#8217;ve been thinking and writing about memo tries lately. I don&#8217;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 [&#8230;]]]></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&#8217;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><a href="http://conal.net/blog/?flattrss_redirect&amp;id=308&amp;md5=c22f70ca5eb996033fdb76a4a76593ff"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/a-trie-for-length-typed-vectors/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fa-trie-for-length-typed-vectors&amp;language=en_GB&amp;category=text&amp;title=A+trie+for+length-typed+vectors&amp;description=As+you+might+have+noticed%2C+I%26%238217%3Bve+been+thinking+and+writing+about+memo+tries+lately.+I+don%26%238217%3Bt+mean+to%3B+they+just+keep+coming+up.+Memoization+is+the+conversion+of+functions+to...&amp;tags=number%2Ctrie%2Cvector%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Reverse-engineering length-typed vectors</title>
		<link>http://conal.net/blog/posts/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><![CDATA[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&#8217;t seem [&#8230;]]]></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&#8217;t seem to be a trie, since it&#8217;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><a href="http://conal.net/blog/?flattrss_redirect&amp;id=305&amp;md5=149f3f6ab1983a1194b76aa15ee55562"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/reverse-engineering-length-typed-vectors/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Freverse-engineering-length-typed-vectors&amp;language=en_GB&amp;category=text&amp;title=Reverse-engineering+length-typed+vectors&amp;description=The+last+few+posts+posts+followed+a+winding+path+toward+a+formulation+of+a+type+for+length-typed+vectors.+In+Fixing+lists%2C+I+mused+how+something+like+lists+could+be+a...&amp;tags=number%2Cvector%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Doing more with length-typed vectors</title>
		<link>http://conal.net/blog/posts/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><![CDATA[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; [&#8230;]]]></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><a href="http://conal.net/blog/?flattrss_redirect&amp;id=293&amp;md5=0fd4950067e60840fabf4f89a33ab982"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/doing-more-with-length-typed-vectors/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Fdoing-more-with-length-typed-vectors&amp;language=en_GB&amp;category=text&amp;title=Doing+more+with+length-typed+vectors&amp;description=The+post+Fixing+lists+defined+a+%28commonly+used%29+type+of+vectors%2C+whose+lengths+are+determined+statically%2C+by+type.+In+Vec+n+a%2C+the+length+is+n%2C+and+the+elements+have...&amp;tags=applicative+functor%2Cmonad%2Cnumber%2Cvector%2Cblog" type="text/html" />
	</item>
		<item>
		<title>Fixing lists</title>
		<link>http://conal.net/blog/posts/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><![CDATA[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&#8217;t think [a] is a trie, simply because [a] 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 trie, [&#8230;]]]></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><a href="http://conal.net/blog/?flattrss_redirect&amp;id=284&amp;md5=8a876a1ca74b5e365684d743df52c81c"><img src="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png" srcset="http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@2x.png 2xhttp://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white.png, http://conal.net/blog/wp-content/plugins/flattr/img/flattr-badge-white@3x.png 3x" alt="Flattr this!"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://conal.net/blog/posts/fixing-lists/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		<atom:link rel="payment" title="Flattr this!" href="https://flattr.com/submit/auto?user_id=conal&amp;popout=1&amp;url=http%3A%2F%2Fconal.net%2Fblog%2Fposts%2Ffixing-lists&amp;language=en_GB&amp;category=text&amp;title=Fixing+lists&amp;description=In+the+post+Memoizing+polymorphic+functions+via+unmemoization%2C+I+toyed+with+the+idea+of+lists+as+tries.+I+don%26%238217%3Bt+think+%5Ba%5D+is+a+trie%2C+simply+because+%5Ba%5D+is+a+sum...&amp;tags=applicative+functor%2Cfunctor%2Cnumber%2Ctrie%2Cvector%2Cblog" type="text/html" />
	</item>
	</channel>
</rss>
