<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"
    xmlns:dc="http://purl.org/dc/elements/1.1/">
    <channel>
        <title>Donnacha Oisín Kidney's Blog</title>
        <link>https://doisinkidney.com</link>
        <description><![CDATA[Mainly writing about programming]]></description>
        <atom:link href="https://doisinkidney.com/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Tue, 03 Mar 2026 00:00:00 UT</lastBuildDate>
        <item>
    <title>Monuses and Heaps</title>
    <link>https://doisinkidney.com/posts/2026-03-03-monus-heaps.html</link>
    <description><![CDATA[<div class="info">
    Posted on March  3, 2026
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>This post is about a simple algebraic structure that I have found
useful for algorithms that involve searching or sorting based on some
ordered weight. I used it a bit in a pair of papers on graph search
<span class="citation"
data-cites="kidney_algebras_2021 kidney_formalising_2025">(<a
href="#ref-kidney_algebras_2021" role="doc-biblioref">2021</a>; <a
href="#ref-kidney_formalising_2025"
role="doc-biblioref">2025</a>)</span>, and more recently I used it to
implement a version of the <code
class="sourceCode haskell"><span class="dt">Phases</span></code> type
<span class="citation" data-cites="easterly_functions_2019">(<a
href="#ref-easterly_functions_2019" role="doc-biblioref">Easterly
2019</a>)</span> that supported arbitrary keys, inspired by some work by
Blöndal <span class="citation"
data-cites="blondal_generalized_2025 blondal_phases_2025">(<a
href="#ref-blondal_generalized_2025" role="doc-biblioref">2025a</a>; <a
href="#ref-blondal_phases_2025" role="doc-biblioref">2025b</a>)</span>
and <span class="citation" data-cites="visscher_phases_2025">Visscher
(<a href="#ref-visscher_phases_2025"
role="doc-biblioref">2025</a>)</span>.</p>
<p>The algebraic structure in question is a <em>monus</em>, which is a
kind of monoid that supports a partial subtraction operation (that
subtraction operation, denoted by the symbol ∸, is itself often called a
“monus”). However, before giving the full definition of the structure,
let me first try to motivate its use. The context here is heap-based
algorithms. For the purposes of this post, a heap is a tree that obeys
the “heap property”; i.e. every node in the tree has some “weight”
attached to it, and every parent node has a weight less than or equal to
the weight of each of its children. So, for a tree like the
following:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>   ┌d</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a> ┌b┤</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>a┤ └e</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a> └c</span></code></pre></div>
<p>The heap property is satisfied when
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>≤</mo><mi>b</mi></mrow><annotation encoding="application/x-tex">a \leq b</annotation></semantics></math>,
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo>≤</mo><mi>c</mi></mrow><annotation encoding="application/x-tex">a \leq c</annotation></semantics></math>,
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo>≤</mo><mi>d</mi></mrow><annotation encoding="application/x-tex">b \leq d</annotation></semantics></math>,
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>b</mi><mo>≤</mo><mi>e</mi></mrow><annotation encoding="application/x-tex">b \leq e</annotation></semantics></math>.</p>
<p>Usually, we also want our heap structure to have an operation like
<code
class="sourceCode haskell"><span class="ot">popMin ::</span> <span class="dt">Heap</span> k v <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (v, <span class="dt">Heap</span> k v)</code>
that returns the least-weight value in the heap paired with the rest of
the heap. If this operation is efficient, we can use the heap to
efficiently implement sorting algorithms, graph search, etc. In fact,
let me give the whole basic interface for a heap here:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">popMin ::</span> <span class="dt">Heap</span> k v <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (v, <span class="dt">Heap</span> k v)</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> k <span class="ot">-&gt;</span> v <span class="ot">-&gt;</span> <span class="dt">Heap</span> k v <span class="ot">-&gt;</span> <span class="dt">Heap</span> k v</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ot">empty  ::</span> <span class="dt">Heap</span> k v</span></code></pre></div>
<p>Using these functions it’s not hard to see how we can implement a
sorting algorithm:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">sortOn ::</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>sortOn k <span class="ot">=</span> unfoldr popMin <span class="op">.</span> <span class="fu">foldr</span> (\x <span class="ot">-&gt;</span> insert (k x) x) empty</span></code></pre></div>
<p>The monus becomes relevant when the weight involved is some kind of
<em>monoid</em>. This is quite a common situation: if we were using the
heap for graph search (least-cost paths or something), we would expect
the weight to correspond to path costs, and we would expect that we can
add the costs of paths in a kind of monoidal way. Furthermore, we would
probably expect the monoidal operations to relate to the order in some
coherent way. A monus <span class="citation"
data-cites="amer_equationally_1984">(<a
href="#ref-amer_equationally_1984" role="doc-biblioref">Amer
1984</a>)</span> is an ordered monoid where the order itself can be
defined <em>in terms</em> of the monoidal operations<a href="#fn1"
class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a>:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>≤</mo><mi>y</mi><mo>⇔</mo><mo>∃</mo><mi>z</mi><mi>.</mi><mspace width="0.278em"></mspace><mi>y</mi><mo>=</mo><mi>x</mi><mo>•</mo><mi>z</mi></mrow><annotation encoding="application/x-tex"> x \leq y \iff \exists z. \; y = x \bullet z </annotation></semantics></math></p>
<p>I read this definition as saying
“<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>
is less than
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>y</mi><annotation encoding="application/x-tex">y</annotation></semantics></math>
iff there is some
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>z</mi><annotation encoding="application/x-tex">z</annotation></semantics></math>
that <em>fits between</em>
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>y</mi><annotation encoding="application/x-tex">y</annotation></semantics></math>”.
In other words, the <em>gap</em> between
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>y</mi><annotation encoding="application/x-tex">y</annotation></semantics></math>
has to exist, and it is equal to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>z</mi><annotation encoding="application/x-tex">z</annotation></semantics></math>.</p>
<p>Notice that this order definition won’t work for groups like
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>ℤ</mi><mo>,</mo><mi>+</mi><mo>,</mo><mn>0</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(\mathbb{Z},+,0)</annotation></semantics></math>.
For a group, we can <em>always</em> find some
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>z</mi><annotation encoding="application/x-tex">z</annotation></semantics></math>
that will fit the existential (specifically,
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>z</mi><mo>=</mo><mo stretchy="false" form="prefix">(</mo><mi>−</mi><mi>x</mi><mo stretchy="false" form="postfix">)</mo><mo>•</mo><mi>y</mi></mrow><annotation encoding="application/x-tex">z = (- x) \bullet y</annotation></semantics></math>).
Monuses, then, tend to be positive monoids: in fact, many monuses are
the positive cones of some group
(<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>ℕ</mi><mo>,</mo><mi>+</mi><mo>,</mo><mn>0</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(\mathbb{N},+,0)</annotation></semantics></math>
is the positive cone of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>ℤ</mi><mo>,</mo><mi>+</mi><mo>,</mo><mn>0</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(\mathbb{Z},+,0)</annotation></semantics></math>).</p>
<p>We can derive a lot of useful properties from this basic structure.
For example, if the order above is total, then we can derive the binary
subtraction operator mentioned above:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>∸</mo><mi>y</mi><mo>=</mo><mrow><mo stretchy="true" form="prefix">{</mo><mtable><mtr><mtd columnalign="left" style="text-align: left"><mi>z</mi><mo>,</mo></mtd><mtd columnalign="left" style="text-align: left"><mrow><mtext mathvariant="normal">if </mtext><mspace width="0.333em"></mspace></mrow><mi>y</mi><mo>≤</mo><mi>x</mi><mrow><mspace width="0.333em"></mspace><mtext mathvariant="normal"> and </mtext><mspace width="0.333em"></mspace></mrow><mi>x</mi><mo>=</mo><mi>y</mi><mo>•</mo><mi>z</mi></mtd></mtr><mtr><mtd columnalign="left" style="text-align: left"><mn>0</mn><mo>,</mo></mtd><mtd columnalign="left" style="text-align: left"><mtext mathvariant="normal">otherwise.</mtext></mtd></mtr></mtable></mrow></mrow><annotation encoding="application/x-tex"> x ∸ y =
\begin{cases}
z, &amp; \text{if } y \leq x \text{ and } x = y \bullet z  \\
0, &amp; \text{otherwise.}
\end{cases}
</annotation></semantics></math></p>
<p>If we require the underlying monoid to be commutative, and we further
require the derived order to be total and antisymmetric, we get the
particular flavour of monus I worked with in a pair of papers on graph
search <span class="citation"
data-cites="kidney_algebras_2021 kidney_formalising_2025">(<a
href="#ref-kidney_algebras_2021" role="doc-biblioref">2021</a>; <a
href="#ref-kidney_formalising_2025"
role="doc-biblioref">2025</a>)</span>. In this post I will actually be
working with a weakened form of the algebra that I will define
shortly.</p>
<p>Getting back to our heap from above, with this new order defined, we
can see that the heap property actually tells us something about the
makeup of the weights in the tree. Instead of every child just having a
weight equal to some arbitrary quantity, the heap property tells us that
each child weight has to be made up of the combination of its parent’s
weight and some difference.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>   ┌d              ┌b•(d∸b)</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a> ┌b┤       ┌a•(b∸a)┤</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>a┤ └e  <span class="ot">=</span>  a┤       └b•(e∸b)</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a> └c        └a•(c∸a)</span></code></pre></div>
<p>This observation gives us an opportunity for a different
representation: instead of storing the full weight at each node, we
could instead just store the difference.</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>     ┌d∸b</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a> ┌b∸a┤</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>a┤   └e∸b</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> └c∸a</span></code></pre></div>
<p>Just in terms of data structure design, I prefer this version: if we
wanted to write down a type of heaps using the previous design, we would
first define the type of trees, and then separately write a predicate
corresponding to the heap property. With this design, it is impossible
to write down a tree that <em>doesn’t</em> satisfy the heap
property.</p>
<p>More practically, though, using this algebraic structure when working
with heaps enables some optimisations that might be difficult to
implement otherwise. The strength of this representation is that it
allows for efficient relative and global computation: now, if we wanted
to add some quantity to every weight in the tree, we can do it just by
adding the weight to the root node.</p>
<h1 id="monuses-in-haskell">Monuses in Haskell</h1>
<p>To see some examples of how to use this pattern, let’s first write a
class for Haskell monuses:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (<span class="dt">Semigroup</span> a, <span class="dt">Ord</span> a) <span class="ot">=&gt;</span> <span class="dt">Monus</span> a <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  (∸)<span class="ot"> ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>You’ll notice that we’re requiring semigroup here, not monoid. That’s
because one of the nice uses of this pattern actually works with a
weakening of the usual monus algebra; this weakening only requires
semigroup, and the following two laws.</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>≤</mo><mi>y</mi><mo>⟹</mo><mi>x</mi><mo>•</mo><mo stretchy="false" form="prefix">(</mo><mi>y</mi><mo>∸</mo><mi>x</mi><mo stretchy="false" form="postfix">)</mo><mo>=</mo><mi>y</mi><mspace width="1.0em"></mspace><mspace width="1.0em"></mspace><mspace width="1.0em"></mspace><mspace width="1.0em"></mspace><mspace width="1.0em"></mspace><mi>x</mi><mo>≤</mo><mi>y</mi><mo>⟹</mo><mi>z</mi><mo>•</mo><mi>x</mi><mo>≤</mo><mi>z</mi><mo>•</mo><mi>y</mi></mrow><annotation encoding="application/x-tex"> x \leq y \implies x \bullet (y ∸ x) = y
\quad \quad \quad \quad \quad
x \leq y \implies z \bullet x \leq z \bullet y </annotation></semantics></math></p>
<p>A straightforward monus instance is the following:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Num</span> a, <span class="dt">Ord</span> a) <span class="ot">=&gt;</span> <span class="dt">Monus</span> (<span class="dt">Sum</span> a) <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  (∸) <span class="ot">=</span> (<span class="op">-</span>)</span></code></pre></div>
<h1 id="pairing-heaps-in-haskell">Pairing Heaps in Haskell</h1>
<p>Next, let’s look at a simple heap implementation. I will always go
for pairing heaps <span class="citation"
data-cites="fredman_pairing_1986">(<a href="#ref-fredman_pairing_1986"
role="doc-biblioref">Fredman et al. 1986</a>)</span> in Haskell; they
are extremely simple to implement, and (as long as you don’t have
significant persistence requirements) their performance seems to be the
best of the available pointer-based heaps <span class="citation"
data-cites="larkin_backtobasics_2013">(<a
href="#ref-larkin_backtobasics_2013" role="doc-biblioref">Larkin, Sen,
and Tarjan 2013</a>)</span>. Here is the type definition:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Root</span> k v <span class="ot">=</span> <span class="dt">Root</span> <span class="op">!</span>k v [<span class="dt">Root</span> k v]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Heap</span> k v <span class="ot">=</span> <span class="dt">Maybe</span> (<span class="dt">Root</span> k v)</span></code></pre></div>
<p>A <code
class="sourceCode haskell"><span class="dt">Root</span></code> is a
non-empty pairing heap; the <code
class="sourceCode haskell"><span class="dt">Heap</span></code> type
represents possibly-empty heaps. The key function to implement is the
merging of two heaps; we can accomplish this as an implementation of the
semigroup <code
class="sourceCode haskell"><span class="op">&lt;&gt;</span></code>.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> <span class="dt">Semigroup</span> (<span class="dt">Root</span> k v) <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Root</span> xk xv xs <span class="op">&lt;&gt;</span> <span class="dt">Root</span> yk yv ys</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> xk <span class="op">&lt;=</span> yk  <span class="ot">=</span> <span class="dt">Root</span> xk xv (<span class="dt">Root</span> (yk ∸ xk) yv ys <span class="op">:</span> xs)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Root</span> yk yv (<span class="dt">Root</span> (xk ∸ yk) xv xs <span class="op">:</span> ys)</span></code></pre></div>
<p>The only difference between this and a normal pairing heap merge is
the use of <code class="sourceCode haskell">∸</code> in the key of the
child node (<code class="sourceCode haskell">yk ∸ xk</code> and <code
class="sourceCode haskell">xk ∸ yk</code>). This difference ensures that
each child only holds the difference of the weight between itself and
its parent.</p>
<p>It’s worth working out why the weakened monus laws above are all we
need in order to maintain the heap property on this structure.</p>
<p>The rest of the methods are implemented the same as their
implementations on a normal pairing heap. First, we have the pairing
merge of a list of heaps, here given as an implementation of the
semigroup method <code class="sourceCode haskell">sconcat</code>:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>  sconcat (x1 <span class="op">:|</span> []) <span class="ot">=</span> x1</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  sconcat (x1 <span class="op">:|</span> [x2]) <span class="ot">=</span> x1 <span class="op">&lt;&gt;</span> x2</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  sconcat (x1 <span class="op">:|</span> x2 <span class="op">:</span> x3 <span class="op">:</span> xs) <span class="ot">=</span> (x1 <span class="op">&lt;&gt;</span> x2) <span class="op">&lt;&gt;</span> sconcat (x3 <span class="op">:|</span> xs)</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="ot">merges ::</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> [<span class="dt">Root</span> k v] <span class="ot">-&gt;</span> <span class="dt">Heap</span> k v</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>merges <span class="ot">=</span> <span class="fu">fmap</span> sconcat <span class="op">.</span> nonEmpty</span></code></pre></div>
<p>The pattern of this two-level merge is what gives the pairing heap
its excellent performance.</p>
<p>The <code
class="sourceCode haskell"><span class="dt">Heap</span></code> type
derives its monoid instance from the monoid instance on <code
class="sourceCode haskell"><span class="dt">Maybe</span></code> (<code
class="sourceCode haskell"><span class="kw">instance</span> <span class="dt">Semigroup</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Maybe</span> a)</code>),
so we can implement <code class="sourceCode haskell">insert</code> like
so:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> k <span class="ot">-&gt;</span> v <span class="ot">-&gt;</span> <span class="dt">Heap</span> k v <span class="ot">-&gt;</span> <span class="dt">Heap</span> k v</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>insert k v hp <span class="ot">=</span> <span class="dt">Just</span> (<span class="dt">Root</span> k v []) <span class="op">&lt;&gt;</span> hp</span></code></pre></div>
<p>And <code class="sourceCode haskell">popMin</code> is also relatively
simple:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">delay ::</span> <span class="dt">Semigroup</span> k <span class="ot">=&gt;</span> k <span class="ot">-&gt;</span> <span class="dt">Heap</span> k v <span class="ot">-&gt;</span> <span class="dt">Heap</span> k v</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>delay by <span class="ot">=</span> <span class="fu">fmap</span> (\(<span class="dt">Root</span> k v xs) <span class="ot">-&gt;</span> <span class="dt">Root</span> (by <span class="op">&lt;&gt;</span> k) v xs)</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ot">popMin ::</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> <span class="dt">Heap</span> k v <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (v,<span class="dt">Heap</span> k v)</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>popMin <span class="ot">=</span> <span class="fu">fmap</span> (\(<span class="dt">Root</span> k v xs) <span class="ot">-&gt;</span> (v, k <span class="ot">`delay`</span> merges xs))</span></code></pre></div>
<p>Notice that we <code class="sourceCode haskell">delay</code> the rest
of the heap, because all of its entries need to be offset by the weight
of the previous root node. Thankfully, because we’re only storing the
differences, we can “modify” every weight by just increasing the weight
of the root, making this an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
operation.</p>
<p>Finally, we can implement heap sort like so:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">sortOn ::</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>sortOn k <span class="ot">=</span> unfoldr popMin <span class="op">.</span> foldl&#39; (\xs x <span class="ot">-&gt;</span> insert (k x) x xs) <span class="dt">Nothing</span></span></code></pre></div>
<p>And it does indeed work:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> sortOn <span class="dt">Sum</span> [<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">2</span>,<span class="dv">5</span>,<span class="dv">1</span>]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>]</span></code></pre></div>
<p>Here is a trace of the output:</p>
<details>
<summary>
Trace
</summary>
<pre class="text"><code>Input           Heap:
list:

[3,4,2,5,1]


[4,2,5,1]       3


[2,5,1]         3─1


[5,1]           2─1─1


[1]              ┌3
                2┤
                 └1─1


[]                 ┌3
                1─1┤
                   └1─1


Output          Heap:
list:

[]                 ┌3
                1─1┤
                   └1─1


[1]              ┌3
                2┤
                 └1─1


[1,2]            ┌2
                3┤
                 └1


[1,2,3]         4─1


[1,2,3,4]       5


[1,2,3,4,5]</code></pre>
</details>
<p>While the heap implementation presented here is pretty efficient,
note that we could significantly improve its performance with a few
optimisations: first, we could unpack all of the constructors, using a
custom list definition in <code
class="sourceCode haskell"><span class="dt">Root</span></code> instead
of Haskell’s built-in lists; second, in <code
class="sourceCode haskell">foldl&#39;</code> we could avoid the <code
class="sourceCode haskell"><span class="dt">Maybe</span></code> wrapper
by building a non-empty heap. There are probably more small
optimisations available as well.</p>
<h1 id="retrieving-a-normal-heap">Retrieving a Normal Heap</h1>
<p>A problem with the definition of <code
class="sourceCode haskell">sortOn</code> above is that it requires a
<code class="sourceCode haskell"><span class="dt">Monus</span></code>
instance on the keys, but it only really needs <code
class="sourceCode haskell"><span class="dt">Ord</span></code>. It seems
that by switching to the <code
class="sourceCode haskell"><span class="dt">Monus</span></code>-powered
heap we have lost some generality.</p>
<p>Luckily, there are two monuses we can use to solve this problem:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Monus</span> (<span class="dt">Max</span> a) <span class="kw">where</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  x ∸ y <span class="ot">=</span> x</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Monus</span> (<span class="dt">Last</span> a) <span class="kw">where</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>  x ∸ y <span class="ot">=</span> x</span></code></pre></div>
<p>The <code
class="sourceCode haskell"><span class="dt">Max</span></code> semigroup
uses the <code
class="sourceCode haskell"><span class="fu">max</span></code> operation,
and the <code
class="sourceCode haskell"><span class="dt">Last</span></code> semigroup
returns its second operand.</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Semigroup</span> (<span class="dt">Max</span> a) <span class="kw">where</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Max</span> x <span class="op">&lt;&gt;</span> <span class="dt">Max</span> y <span class="ot">=</span> <span class="dt">Max</span> (<span class="fu">max</span> x y)</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semigroup</span> (<span class="dt">Last</span> a) <span class="kw">where</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&lt;&gt;</span> y <span class="ot">=</span> y</span></code></pre></div>
<p>While the <code
class="sourceCode haskell"><span class="dt">Monus</span></code>
instances here might seem degenerate, they do actually satisfy the <code
class="sourceCode haskell"><span class="dt">Monus</span></code> laws as
given above.</p>
<details>
<summary>
<code class="sourceCode haskell"><span class="dt">Max</span></code> and
<code class="sourceCode haskell"><span class="dt">Last</span></code>
Monus laws
</summary>
<p>Max:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;=</span> y <span class="op">==&gt;</span> x <span class="op">&lt;&gt;</span> (y ∸ x) <span class="ot">=</span> y</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Max</span> x <span class="op">&lt;=</span> <span class="dt">Max</span> y <span class="op">==&gt;</span> <span class="dt">Max</span> x <span class="op">&lt;&gt;</span> (<span class="dt">Max</span> y ∸ <span class="dt">Max</span> x) <span class="ot">=</span> <span class="dt">Max</span> y</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Max</span> x <span class="op">&lt;=</span> <span class="dt">Max</span> y <span class="op">==&gt;</span> <span class="dt">Max</span> x <span class="op">&lt;&gt;</span> <span class="dt">Max</span> y <span class="ot">=</span> <span class="dt">Max</span> y</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="dt">Max</span> x <span class="op">&lt;=</span> <span class="dt">Max</span> y <span class="op">==&gt;</span> <span class="dt">Max</span> (<span class="fu">max</span> x y) <span class="ot">=</span> <span class="dt">Max</span> y</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;=</span> y <span class="op">==&gt;</span> <span class="fu">max</span> x y <span class="ot">=</span> y</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;=</span> y <span class="op">==&gt;</span> z <span class="op">&lt;&gt;</span> x <span class="op">&lt;=</span> z <span class="op">&lt;&gt;</span> y</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Max</span> x <span class="op">&lt;=</span> <span class="dt">Max</span> y <span class="op">==&gt;</span> <span class="dt">Max</span> z <span class="op">&lt;&gt;</span> <span class="dt">Max</span> x <span class="op">&lt;=</span> <span class="dt">Max</span> z <span class="op">&lt;&gt;</span> <span class="dt">Max</span> y</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a><span class="dt">Max</span> x <span class="op">&lt;=</span> <span class="dt">Max</span> y <span class="op">==&gt;</span> <span class="dt">Max</span> (<span class="fu">max</span> z x) <span class="op">&lt;=</span> <span class="dt">Max</span> (<span class="fu">max</span> z y)</span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;=</span> y <span class="op">==&gt;</span> <span class="fu">max</span> z x <span class="op">&lt;=</span> <span class="fu">max</span> z y</span></code></pre></div>
<p>Last:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;=</span> y <span class="op">==&gt;</span> x <span class="op">&lt;&gt;</span> (y ∸ x) <span class="ot">=</span> y</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Last</span> x <span class="op">&lt;=</span> <span class="dt">Last</span> y <span class="op">==&gt;</span> <span class="dt">Last</span> x <span class="op">&lt;&gt;</span> (<span class="dt">Last</span> y ∸ <span class="dt">Last</span> x) <span class="ot">=</span> <span class="dt">Last</span> y</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Last</span> x <span class="op">&lt;=</span> <span class="dt">Last</span> y <span class="op">==&gt;</span> <span class="dt">Last</span> x <span class="op">&lt;&gt;</span> <span class="dt">Last</span> y <span class="ot">=</span> <span class="dt">Last</span> y</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="dt">Last</span> x <span class="op">&lt;=</span> <span class="dt">Last</span> y <span class="op">==&gt;</span> <span class="dt">Last</span> y <span class="ot">=</span> <span class="dt">Last</span> y</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;=</span> y <span class="op">==&gt;</span> z <span class="op">&lt;&gt;</span> x <span class="op">&lt;=</span> z <span class="op">&lt;&gt;</span> y</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a><span class="dt">Last</span> x <span class="op">&lt;=</span> <span class="dt">Last</span> y <span class="op">==&gt;</span> <span class="dt">Last</span> z <span class="op">&lt;&gt;</span> <span class="dt">Last</span> x <span class="op">&lt;=</span> <span class="dt">Last</span> z <span class="op">&lt;&gt;</span> <span class="dt">Last</span> y</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Last</span> x <span class="op">&lt;=</span> <span class="dt">Last</span> y <span class="op">==&gt;</span> <span class="dt">Last</span> x <span class="op">&lt;=</span> <span class="dt">Last</span> y</span></code></pre></div>
</details>
<p>Either <code
class="sourceCode haskell"><span class="dt">Max</span></code> or <code
class="sourceCode haskell"><span class="dt">Last</span></code> will
work; semantically, there’s no real difference. <code
class="sourceCode haskell"><span class="dt">Last</span></code> avoids
some comparisons, so we can use that:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">sortOn&#39; ::</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>sortOn&#39; k <span class="ot">=</span> sortOn (<span class="dt">Last</span> <span class="op">.</span> k)</span></code></pre></div>
<h1 id="phases-as-a-pairing-heap">Phases as a Pairing Heap</h1>
<p>The <code
class="sourceCode haskell"><span class="dt">Phases</span></code>
applicative <span class="citation"
data-cites="easterly_functions_2019">(<a
href="#ref-easterly_functions_2019" role="doc-biblioref">Easterly
2019</a>)</span> is an <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
transformer that allows reordering of <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
effects in an easy-to-use, high-level way. The interface looks like
this:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">phase     ::</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="ot">runPhases ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Phases</span> f)</span></code></pre></div>
<p>And we can use it like this:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">phased ::</span> <span class="dt">IO</span> <span class="dt">String</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>phased <span class="ot">=</span> runPhases <span class="op">$</span> <span class="fu">sequenceA</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  [ phase <span class="dv">3</span> <span class="op">$</span> emit <span class="ch">&#39;a&#39;</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>  , phase <span class="dv">2</span> <span class="op">$</span> emit <span class="ch">&#39;b&#39;</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>  , phase <span class="dv">1</span> <span class="op">$</span> emit <span class="ch">&#39;c&#39;</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>  , phase <span class="dv">2</span> <span class="op">$</span> emit <span class="ch">&#39;d&#39;</span></span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>  , phase <span class="dv">3</span> <span class="op">$</span> emit <span class="ch">&#39;e&#39;</span> ]</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span> emit c <span class="ot">=</span> <span class="fu">putChar</span> c <span class="op">&gt;&gt;</span> <span class="fu">return</span> c</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> phased</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>cbdae</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;abcde&quot;</span></span></code></pre></div>
<p>The above computation performs the <em>effects</em> in the order
dictated by their phases (this is why the characters are printed out in
the order <code class="sourceCode haskell">cbdae</code>), but the pure
value (the returned string) has its order unaffected.</p>
<p>I have written about this type <a
href="2019-05-28-linear-phases.html">before</a>, and in a handful of
papers <span class="citation"
data-cites="kidney_algebras_2021 gibbons_breadthfirst_2022 gibbons_phases_2023">(<a
href="#ref-kidney_algebras_2021" role="doc-biblioref">2021</a>; <a
href="#ref-gibbons_breadthfirst_2022" role="doc-biblioref">Gibbons et
al. 2022</a>; <a href="#ref-gibbons_phases_2023"
role="doc-biblioref">Gibbons et al. 2023</a>)</span>, but more recently
<span class="citation" data-cites="blondal_generalized_2025">Blöndal (<a
href="#ref-blondal_generalized_2025"
role="doc-biblioref">2025a</a>)</span> started looking into trying to
use the <code
class="sourceCode haskell"><span class="dt">Phases</span></code> pattern
with arbitrary ordered keys <span class="citation"
data-cites="visscher_phases_2025 blondal_phases_2025">(<a
href="#ref-visscher_phases_2025" role="doc-biblioref">Visscher 2025</a>;
<a href="#ref-blondal_phases_2025" role="doc-biblioref">Blöndal
2025b</a>)</span>. There are a lot of different directions you can go
from the <code
class="sourceCode haskell"><span class="dt">Phases</span></code> type;
what interested me most immediately was the idea of implementing the
type efficiently using standard data-structure representations. If our
core goal here is to order some values according to a key, then that is
clearly a problem that a heap should solve: enter the free applicative
pairing heap.</p>
<p>Here is the type’s definition:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heap</span> k f a <span class="kw">where</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Heap</span> k f a</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Root</span><span class="ot"> ::</span> <span class="op">!</span>k <span class="ot">-&gt;</span> (x <span class="ot">-&gt;</span> y <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> f x <span class="ot">-&gt;</span> <span class="dt">Heaps</span> k f y <span class="ot">-&gt;</span> <span class="dt">Heap</span> k f a</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heaps</span> k f a <span class="kw">where</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span><span class="ot"> ::</span> <span class="dt">Heaps</span> k f ()</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">App</span><span class="ot"> ::</span> <span class="op">!</span>k <span class="ot">-&gt;</span> f x <span class="ot">-&gt;</span> <span class="dt">Heaps</span> k f y <span class="ot">-&gt;</span> <span class="dt">Heaps</span> k f z <span class="ot">-&gt;</span> <span class="dt">Heaps</span> k f (x,y,z)</span></code></pre></div>
<p>We have had to change a few aspects of the original pairing heap, but
the overall structure remains. The entries in this heap are now
effectful computations: the <code class="sourceCode haskell">f</code>s.
The data structure also contains some scaffolding to reconstruct the
pure values “inside” each effect when we actually run the heap.</p>
<p>The root-level structure is the <code
class="sourceCode haskell"><span class="dt">Heap</span></code>: this can
either be <code
class="sourceCode haskell"><span class="dt">Pure</span></code>
(corresponding to an empty heap: notice that, though this constructor
has some contents (the <code class="sourceCode haskell">a</code>), it is
still regarded as “empty” because it contains no effects (<code
class="sourceCode haskell">f</code>)); or a <code
class="sourceCode haskell"><span class="dt">Root</span></code>, which is
a singleton value, paired with the list of sub-heaps represented by the
<code class="sourceCode haskell"><span class="dt">Heaps</span></code>
type. We’re using the usual Yoneda-ish trick here to allow the top-level
data type to be parametric and a <code
class="sourceCode haskell"><span class="dt">Functor</span></code>, by
storing the function <code
class="sourceCode haskell">x <span class="ot">-&gt;</span> y <span class="ot">-&gt;</span> a</code>.</p>
<p>The <code
class="sourceCode haskell"><span class="dt">Heaps</span></code> type
then plays the role of <code
class="sourceCode haskell">[<span class="dt">Root</span> k v]</code> in
the previous pairing heap implementation; here, we have inlined all of
the constructors so that we can get all of the types to line up.
Remember, this is a heap of <em>effects</em>, not of pure values: the
pure values need to be able to be reconstructed to one single top-level
<code class="sourceCode haskell">a</code> when we run the heap at the
end.</p>
<p>Merging two heaps happens in the <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
instance itself:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">Heap</span> k f) <span class="kw">where</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Pure</span> x) <span class="ot">=</span> <span class="dt">Pure</span> (f x)</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Root</span> k c x xs) <span class="ot">=</span> <span class="dt">Root</span> k (\a b <span class="ot">-&gt;</span> f (c a b)) x xs</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Heap</span> k f) <span class="kw">where</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Pure</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span> f <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> <span class="fu">fmap</span> f xs</span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">&lt;*&gt;</span> <span class="dt">Pure</span> f <span class="ot">=</span> <span class="fu">fmap</span> (<span class="op">$</span> f) xs</span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Root</span> xk xc xs xss <span class="op">&lt;*&gt;</span> <span class="dt">Root</span> yk yc ys yss</span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> xk <span class="op">&lt;=</span> yk  <span class="ot">=</span> <span class="dt">Root</span> xk (\a (b,c,d) <span class="ot">-&gt;</span> xc a d (yc b c)) xs (<span class="dt">App</span> (yk ∸ xk) ys yss xss)</span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Root</span> yk (\a (b,c,d) <span class="ot">-&gt;</span> xc b c (yc a d)) ys (<span class="dt">App</span> (xk ∸ yk) xs xss yss)</span></code></pre></div>
<p>To actually run the heap we will use the following two functions:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">merges ::</span> (<span class="dt">Monus</span> k, <span class="dt">Applicative</span> f) <span class="ot">=&gt;</span> <span class="dt">Heaps</span> k f a <span class="ot">-&gt;</span> <span class="dt">Heap</span> k f a</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>merges <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Pure</span> ()</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>merges (<span class="dt">App</span> k1 e1 t1 <span class="dt">Nil</span>) <span class="ot">=</span> <span class="dt">Root</span> k1 (,,()) e1 t1</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>merges (<span class="dt">App</span> k1 e1 t1 (<span class="dt">App</span> k2 e2 t2 xs)) <span class="ot">=</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>   (<span class="dt">Root</span> k1 (\a b cd es <span class="ot">-&gt;</span> (a,b, cd es)) e1 t1 <span class="op">&lt;*&gt;</span> <span class="dt">Root</span> k2 (,,) e2 t2) <span class="op">&lt;*&gt;</span> merges xs</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a><span class="ot">runHeap ::</span> (<span class="dt">Monus</span> k, <span class="dt">Applicative</span> f) <span class="ot">=&gt;</span> <span class="dt">Heap</span> k f a <span class="ot">-&gt;</span> f a</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>runHeap (<span class="dt">Pure</span> x) <span class="ot">=</span> <span class="fu">pure</span> x</span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>runHeap (<span class="dt">Root</span> _ c x xs) <span class="ot">=</span> liftA2 c x (runHeap (merges xs))</span></code></pre></div>
<p>And we can lift a computation into <code
class="sourceCode haskell"><span class="dt">Phases</span></code> like
so:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="ot">phase ::</span> k <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Heap</span> k f a</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>phase k xs <span class="ot">=</span> <span class="dt">Root</span> k <span class="fu">const</span> xs <span class="dt">Nil</span></span></code></pre></div>
<h1 id="stabilising-phases">Stabilising Phases</h1>
<p>There’s a problem. A heap sort based on a pairing heap isn’t
<em>stable</em>. That means that the order of effects here can vary for
two effects in the same phase. If we look back to the example with the
strings we saw above, that means that outputs like <code
class="sourceCode haskell">cdbea</code> would be possible (in actual
fact, we don’t get any reordering in this particular example, but that’s
just an accident of the way the applicative operators are associated
under the hood).</p>
<p>This is problematic because we would expect effects in the same phase
to behave as if they were normal applicative effects, sequenced
according to their syntactic order. It also means that the applicative
transformer breaks the applicative laws, because effects might be
reordered according to the association of the applicative operators,
which should lawfully be associative.</p>
<p>To make the sort stable, we could layer the heap effect with some
state effect that would tag each effect with its order. However, that
would hurt efficiency and composability: it would force us to linearise
the whole heap sort procedure, where currently different branches of the
tree can compute completely independently of each other. The solution
comes in the form of another monus: the key monus.</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Key</span> k <span class="ot">=</span> <span class="op">!</span>k <span class="op">:*</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Int</span> <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>)</span></code></pre></div>
<p>A <code
class="sourceCode haskell"><span class="dt">Key</span> k</code> is some
ordered key <code class="sourceCode haskell">k</code> coupled with an
<code class="sourceCode haskell"><span class="dt">Int</span></code> that
represents the offset between the original position and the current
position of the key. In this way, when two keys compare as equal, we can
cascade on to compare their original positions, thereby maintaining
their original order when there is ambiguity caused by a key collision.
However, in contrast to the approach of walking over the data once and
tagging it all with positions, this approach keeps the location
information completely local: we never need to know that some key is in
the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>th
position in the original sequence, only that it has moved
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
steps from its original position.</p>
<p>The instances are as follows:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semigroup</span> (<span class="dt">Key</span> k) <span class="kw">where</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>  (xk <span class="op">:*</span> xi) <span class="op">&lt;&gt;</span> (yk <span class="op">:*</span> yi) <span class="ot">=</span> yk <span class="op">:*</span> (xi <span class="op">+</span> yi)</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> <span class="dt">Monus</span> (<span class="dt">Key</span> k) <span class="kw">where</span></span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>  (xk <span class="op">:*</span> xi) ∸ (yk <span class="op">:*</span> yi) <span class="ot">=</span> xk <span class="op">:*</span> (xi <span class="op">-</span> yi)</span></code></pre></div>
<p>This instance is basically a combination of the <code
class="sourceCode haskell"><span class="dt">Last</span></code> semigroup
and the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>ℤ</mi><mo>,</mo><mi>+</mi><mo>,</mo><mn>0</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(\mathbb{Z}, +, 0)</annotation></semantics></math>
group. We could make a slightly more generalised version of <code
class="sourceCode haskell"><span class="dt">Key</span></code> that is
the combination of any monus and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>ℤ</mi><annotation encoding="application/x-tex">\mathbb{Z}</annotation></semantics></math>,
but since I’m only going to be using this type for simple sorting-like
algorithms I will leave that generalisation for another time.</p>
<p>The stable heap type is as follows:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Stable</span> k f a</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Stable</span> {<span class="ot"> size ::</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Int</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>           ,<span class="ot"> heap ::</span> <span class="op">!</span>(<span class="dt">Heap</span> (<span class="dt">Key</span> k) f a) }</span></code></pre></div>
<p>We need to track the size of the heap so that we can supply the
right-hand operand with their offsets. Because we’re storing
differences, we can add an offset to every entry in a heap in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
time by simply adding to the root:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">delayKey ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dt">Key</span> k) f a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dt">Key</span> k) f a</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>delayKey _ hp<span class="op">@</span>(<span class="dt">Pure</span> _) <span class="ot">=</span> hp</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>delayKey n (<span class="dt">Root</span> (k <span class="op">:*</span> m) c x xs) <span class="ot">=</span> <span class="dt">Root</span> (k <span class="op">:*</span> (n <span class="op">+</span> m)) c x xs</span></code></pre></div>
<p>Finally, using this we can implement the <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
instance and the rest of the interface:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Stable</span> k f) <span class="kw">where</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Stable</span> <span class="dv">0</span> <span class="op">.</span> <span class="fu">pure</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Stable</span> n xs <span class="op">&lt;*&gt;</span> <span class="dt">Stable</span> m ys <span class="ot">=</span> <span class="dt">Stable</span> (n<span class="op">+</span>m) (xs <span class="op">&lt;*&gt;</span> delayKey n ys)</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a><span class="ot">runStable ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Ord</span> k) <span class="ot">=&gt;</span> <span class="dt">Stable</span> k f a <span class="ot">-&gt;</span> f a</span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>runStable <span class="ot">=</span> runHeap <span class="op">.</span> heap</span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a><span class="ot">stable ::</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> k <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Stable</span> k f a</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>stable k fa <span class="ot">=</span> <span class="dt">Stable</span> <span class="dv">1</span> (phase (k <span class="op">:*</span> <span class="dv">0</span>) fa)</span></code></pre></div>
<p>This is a pure, optimally efficient implementation of <code
class="sourceCode haskell"><span class="dt">Phases</span></code> ordered
by an arbitrary total-ordered key.</p>
<h1 id="local-computation-in-a-monadic-heap">Local Computation in a
Monadic Heap</h1>
<p>In <span class="citation" data-cites="kidney_algebras_2021">(<a
href="#ref-kidney_algebras_2021" role="doc-biblioref">2021</a>)</span>,
I developed a monadic heap based on the free monad transformer.</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Search</span> k a <span class="ot">=</span> <span class="dt">Search</span> {<span class="ot"> runSearch ::</span> [<span class="dt">Either</span> a (k, <span class="dt">Search</span> k a)] }</span></code></pre></div>
<p>This type is equivalent to the <a
href="https://hackage.haskell.org/package/free-5.2/docs/Control-Monad-Trans-Free.html#t:FreeT">free
monad transformer</a> over the list monad and <code
class="sourceCode haskell">(,) k</code> functor (i.e. the writer
monad).</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Search</span> k a ≅ <span class="dt">FreeT</span> ((,) k) [] a</span></code></pre></div>
<p>In the paper <span class="citation"
data-cites="kidney_algebras_2021">(<a href="#ref-kidney_algebras_2021"
role="doc-biblioref">2021</a>)</span> we extended the type to become a
full monad transformer, replacing lists with <code
class="sourceCode haskell"><span class="dt">ListT</span></code>. This
let us order the effects according to the weight <code
class="sourceCode haskell">k</code>; however, for this example we only
need the simplified type, which lets us order the values according to
<code class="sourceCode haskell">k</code>.</p>
<p>This <code
class="sourceCode haskell"><span class="dt">Search</span></code> type
follows the structure of a pairing heap (although not as closely as the
version above). However, this type is interesting because
<em>semantically</em> it needs the weights to be stored as differences,
rather than absolute weights. As a free monad transformer, the <code
class="sourceCode haskell"><span class="dt">Search</span></code> type
layers effects on top of each other; we can later interpret those layers
by collapsing them together using the monadic <code
class="sourceCode haskell">join</code>. In the case of <code
class="sourceCode haskell"><span class="dt">Search</span></code>, those
layers are drawn from the list monad and the <code
class="sourceCode haskell">(,) k</code> functor (writer monad). That
means that if we have some heap representing the tree from above:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Search</span> [ <span class="dt">Right</span> (a, <span class="dt">Search</span> [ <span class="dt">Right</span> (b, <span class="dt">Search</span> [ <span class="dt">Right</span> (d, <span class="dt">Search</span> [<span class="dt">Left</span> x])</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>                                             , <span class="dt">Right</span> (e, <span class="dt">Search</span> [<span class="dt">Left</span> y])])</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>                          , <span class="dt">Right</span> (c, <span class="dt">Search</span> [<span class="dt">Left</span> z])])]</span></code></pre></div>
<p>When we collapse this computation down to the leaves, the weights we
will get are the following:</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a>[(a <span class="op">&lt;&gt;</span> b <span class="op">&lt;&gt;</span> d, x), (a <span class="op">&lt;&gt;</span> b <span class="op">&lt;&gt;</span> e, y), (a <span class="op">&lt;&gt;</span> c, z)]</span></code></pre></div>
<p>So, if we want the weights to line up properly, we need to store the
differences.</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeS ::</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> [(k, <span class="dt">Search</span> k a)] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (k, <span class="dt">Search</span> k a)</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>mergeS [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>mergeS (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Just</span> (mergeS&#39; x xs)</span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>    mergeS&#39; x1 [] <span class="ot">=</span> x1</span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a>    mergeS&#39; x1 [x2] <span class="ot">=</span> x1 <span class="op">&lt;+&gt;</span> x2</span>
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a>    mergeS&#39; x1 (x2<span class="op">:</span>x3<span class="op">:</span>xs) <span class="ot">=</span> (x1 <span class="op">&lt;+&gt;</span> x2) <span class="op">&lt;+&gt;</span> mergeS&#39; x3 xs</span>
<span id="cb36-8"><a href="#cb36-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb36-9"><a href="#cb36-9" aria-hidden="true" tabindex="-1"></a>    (xw, <span class="dt">Search</span> xs) <span class="op">&lt;+&gt;</span> (yw, <span class="dt">Search</span> ys)</span>
<span id="cb36-10"><a href="#cb36-10" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> xw <span class="op">&lt;=</span> yw  <span class="ot">=</span> (xw, <span class="dt">Search</span> (<span class="dt">Right</span> (yw ∸ xw, <span class="dt">Search</span> ys) <span class="op">:</span> xs))</span>
<span id="cb36-11"><a href="#cb36-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (yw, <span class="dt">Search</span> (<span class="dt">Right</span> (xw ∸ yw, <span class="dt">Search</span> xs) <span class="op">:</span> ys))</span>
<span id="cb36-12"><a href="#cb36-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb36-13"><a href="#cb36-13" aria-hidden="true" tabindex="-1"></a><span class="ot">popMins ::</span> <span class="dt">Monus</span> k <span class="ot">=&gt;</span> <span class="dt">Search</span> k a <span class="ot">-&gt;</span> ([a], <span class="dt">Maybe</span> (k, <span class="dt">Search</span> k a))</span>
<span id="cb36-14"><a href="#cb36-14" aria-hidden="true" tabindex="-1"></a>popMins <span class="ot">=</span> <span class="fu">fmap</span> mergeS <span class="op">.</span> partitionEithers <span class="op">.</span> runSearch</span></code></pre></div>
<h1 id="conclusion">Conclusion</h1>
<p>The technique of “don’t store the absolute value, store the
difference” seems to be generally quite useful; I think that monuses are
a handy algebra to keep in mind whenever that technique looks like it
might be needed. The <code
class="sourceCode haskell"><span class="dt">Key</span></code> monus
above is closely related to the factorial numbers, and the trick I used
in <a href="2019-03-24-permutations-by-sorting.html">this</a> post.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-amer_equationally_1984" class="csl-entry" role="listitem">
Amer, K. 1984. <span>“Equationally complete classes of commutative
monoids with monus.”</span> <em>algebra universalis</em> 18 (1)
(February): 129–131. doi:<a
href="https://doi.org/10.1007/BF01182254">10.1007/BF01182254</a>.
</div>
<div id="ref-blondal_generalized_2025" class="csl-entry"
role="listitem">
Blöndal, Baldur. 2025a. <span>“Generalized multi-phase
compiler/concurrency.”</span> <em>reddit</em>. <a
href="https://www.reddit.com/r/haskell/comments/1m25fw8/generalized_multiphase_compilerconcurrency/">https://www.reddit.com/r/haskell/comments/1m25fw8/generalized_multiphase_compilerconcurrency/</a>.
</div>
<div id="ref-blondal_phases_2025" class="csl-entry" role="listitem">
———. 2025b. <span>“Phases using <span>Vault</span>.”</span>
<em>reddit</em>. <a
href="https://www.reddit.com/r/haskell/comments/1msvwzd/phases_using_vault/">https://www.reddit.com/r/haskell/comments/1msvwzd/phases_using_vault/</a>.
</div>
<div id="ref-easterly_functions_2019" class="csl-entry" role="listitem">
Easterly, Noah. 2019. <span>“Functions and newtype wrappers for
traversing <span>Trees</span>: Rampion/tree-traversals.”</span> <a
href="https://github.com/rampion/tree-traversals">https://github.com/rampion/tree-traversals</a>.
</div>
<div id="ref-fredman_pairing_1986" class="csl-entry" role="listitem">
Fredman, Michael L., Robert Sedgewick, Daniel D. Sleator, and Robert E.
Tarjan. 1986. <span>“The pairing heap: <span>A</span> new form of
self-adjusting heap.”</span> <em>Algorithmica</em> 1 (1-4) (January):
111–129. doi:<a
href="https://doi.org/10.1007/BF01840439">10.1007/BF01840439</a>.
</div>
<div id="ref-gibbons_breadthfirst_2022" class="csl-entry"
role="listitem">
Gibbons, Jeremy, Donnacha Oisín Kidney, Tom Schrijvers, and Nicolas Wu.
2022. <span>“Breadth-<span>First Traversal</span>
via <span>Staging</span>.”</span> In <em>Mathematics of <span>Program
Construction</span></em>, ed by. Ekaterina Komendantskaya, 1–33. Cham:
Springer International Publishing. doi:<a
href="https://doi.org/10.1007/978-3-031-16912-0_1">10.1007/978-3-031-16912-0_1</a>.
</div>
<div id="ref-gibbons_phases_2023" class="csl-entry" role="listitem">
———. 2023. <span>“Phases in <span>Software Architecture</span>.”</span>
In <em>Proceedings of the 1st <span>ACM SIGPLAN International
Workshop</span> on <span>Functional Software Architecture</span></em>,
29–33. <span>FUNARCH</span> 2023. New York, NY, USA: Association for
Computing Machinery. doi:<a
href="https://doi.org/10.1145/3609025.3609479">10.1145/3609025.3609479</a>.
</div>
<div id="ref-kidney_algebras_2021" class="csl-entry" role="listitem">
Kidney, Donnacha Oisín, and Nicolas Wu. 2021. <span>“Algebras for
weighted search.”</span> <em>Proceedings of the ACM on Programming
Languages</em> 5 (ICFP) (August): 72:1–72:30. doi:<a
href="https://doi.org/10.1145/3473577">10.1145/3473577</a>.
</div>
<div id="ref-kidney_formalising_2025" class="csl-entry" role="listitem">
———. 2025. <span>“Formalising <span>Graph Algorithms</span> with
<span>Coinduction</span>.”</span> <em>Proc. ACM Program. Lang.</em> 9
(POPL) (January): 56:1657–56:1686. doi:<a
href="https://doi.org/10.1145/3704892">10.1145/3704892</a>.
</div>
<div id="ref-larkin_backtobasics_2013" class="csl-entry"
role="listitem">
Larkin, Daniel H., Siddhartha Sen, and Robert E. Tarjan. 2013. <span>“A
<span class="nocase">Back-to-Basics Empirical Study</span> of
<span>Priority Queues</span>.”</span> In <em>2014
<span>Proceedings</span> of the <span>Meeting</span> on <span>Algorithm
Engineering</span> and <span>Experiments</span>
(<span>ALENEX</span>)</em>, 61–72. Proceedings. <span>Society for
Industrial and Applied Mathematics</span>. doi:<a
href="https://doi.org/10.1137/1.9781611973198.7">10.1137/1.9781611973198.7</a>.
</div>
<div id="ref-visscher_phases_2025" class="csl-entry" role="listitem">
Visscher, Sjoerd. 2025. <span>“Phases with any <span>Ord</span> key
type.”</span> <a
href="https://gist.github.com/sjoerdvisscher/bf282a050f0681e2f737908e254c4061">https://gist.github.com/sjoerdvisscher/bf282a050f0681e2f737908e254c4061</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Note that there are many related structures that all
fall under the umbrella notion of “monus”; the structure that I am
defining here is the same structure I worked with in <span
class="citation" data-cites="kidney_algebras_2021">(<a
href="#ref-kidney_algebras_2021" role="doc-biblioref">2021</a>)</span>
and <span class="citation" data-cites="kidney_formalising_2025">(<a
href="#ref-kidney_formalising_2025"
role="doc-biblioref">2025</a>)</span>.<a href="#fnref1"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Tue, 03 Mar 2026 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2026-03-03-monus-heaps.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>POPL Paper—Hyperfunctions: Communicating Continuations</title>
    <link>https://doisinkidney.com/posts/2025-11-18-hyperfunctions.html</link>
    <description><![CDATA[<div class="info">
    Posted on November 18, 2025
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: 
    
</div>

<p>New paper: “Hyperfunctions: Communicating Continuations”, by myself
and <a href="https://zenzike.com/">Nicolas Wu</a>, will be published at
<a href="https://popl26.sigplan.org">POPL 2026</a>.</p>
<p>The preprint is available <a
href="../pdfs/hyperfunctions.pdf">here</a>.</p>
<p>The work contained in the paper started with <a
href="2021-03-14-hyperfunctions.html">a post on this blog in 2021</a>. I
had read a paper by <span class="citation"
data-cites="launchbury_zip_2000">Launchbury, Krstić, and Sauerwein (<a
href="#ref-launchbury_zip_2000" role="doc-biblioref">2000</a>)</span>
and I recognised that their hyperfunction construction was quite similar
to some types I had used to implement breadth-first traversal (in
particular, the Queue in <a
href="2019-05-14-corecursive-implicit-queues.html">this post</a>). After
that, I started seeing hyperfunctions in lots of different settings,
rediscovered by different authors, and almost always accompanied by some
remark about how difficult it was to understand the type.</p>
<p>My hope with this paper is to clarify and explain <em>what</em>
hyperfunctions can do, and <em>where</em> they might be useful. Ideally,
the paper will save some future programmer from having to reinvent the
type.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-launchbury_zip_2000" class="csl-entry" role="listitem">
Launchbury, John, Sava Krstić, and Timothy E. Sauerwein. 2000. <em>Zip
<span>Fusion</span> with <span>Hyperfunctions</span></em>. Oregon
Graduate Institute. <a
href="https://launchbury.blog/wp-content/uploads/2019/01/zip-fusion-with-hyperfunctions.pdf">https://launchbury.blog/wp-content/uploads/2019/01/zip-fusion-with-hyperfunctions.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Tue, 18 Nov 2025 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2025-11-18-hyperfunctions.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>POPL Paper—Formalising Graph Algorithms with Coinduction</title>
    <link>https://doisinkidney.com/posts/2024-11-08-formalising-graphs-coinduction.html</link>
    <description><![CDATA[<div class="info">
    Posted on November  8, 2024
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>New paper: “Formalising Graph Algorithms with Coinduction”, by myself
and <a href="https://zenzike.com/">Nicolas Wu</a>, will be published at
<a href="https://popl25.sigplan.org">POPL 2025</a>.</p>
<p>The preprint is available <a
href="../pdfs/formalising-graphs-coinduction.pdf">here</a>.</p>
<p>The talk is <a href="https://youtu.be/sgNT2w_f-o4">here</a>.</p>
<p>The paper is about representing graphs (especially in functional
languages). We argue in the paper that graphs are naturally
<em>coinductive</em>, rather than inductive, and that many of the
problems with graphs in functional languages go away once you give up on
induction and pattern-matching, and embrace the coinductive way of doing
things.</p>
<p>Of course, coinduction comes with its own set of problems, especially
when working in a total language or proof assistant. Another big focus
of the paper was figuring out a representation that was amenable to
formalisation (we formalised the paper in Cubical Agda). Picking a good
representation for formalisation is a tricky thing: often a design
decision you make early on only looks like a mistake after a few
thousand lines of proofs, and modern formal proofs tend to be brittle,
meaning that it’s difficult to change an early definition without also
having to change everything that depends on it. On top of this, we
decided to use quotients for an important part of the representation,
and (as anyone who’s worked with quotients and coinduction will tell
you) productivity proofs in the presence of quotients can be a real
pain.</p>
<p>All that said, I think the representation we ended up with in the
paper is quite nice. We start with a similar representation to the one
we had in our <a href="../pdfs/algebras-for-weighted-search.pdf">ICFP
paper</a> in 2021: a graph over vertices of type <code>a</code> is
simply a function <code>a -&gt; [a]</code> that returns the neighbours
of a supplied vertex (this is the same representation as in <a
href="2018-12-18-traversing-graphs.html">this post</a>). Despite the
simplicity, it turns out that this type is enough to implement a decent
number of search algorithms. The really interesting thing is that the
arrow methods (from <a
href="https://hackage.haskell.org/package/base-4.20.0.1/docs/Control-Arrow.html">Control.Arrow</a>)
work on this type, and they define an algebra on graphs similar to the
one from <span class="citation"
data-cites="mokhov_algebraic_2017">Mokhov (<a
href="#ref-mokhov_algebraic_2017" role="doc-biblioref">2017</a>)</span>.
For example, <a
href="https://hackage.haskell.org/package/base-4.20.0.1/docs/Control-Arrow.html#v:-60--43--62-">the
<code>&lt;+&gt;</code> operator</a> is the same as the <em>overlay</em>
operation in <span class="citation"
data-cites="mokhov_algebraic_2017">Mokhov (<a
href="#ref-mokhov_algebraic_2017"
role="doc-biblioref">2017</a>)</span>.</p>
<p>That simple type gets expanded upon and complicated: eventually, we
represent a possibly-infinite collection as a function that takes a
depth and then returns everything in the search space up to that depth.
It’s a little like representing an infinite list as the partial
application of the <code>take</code> function. The paper spends a lot of
time picking an algebra that properly represents the depth, and figuring
out coherency conditions etc.</p>
<p>One thing I’m especially proud of is that all the Agda code snippets
in the paper are hyperlinked to <a
href="https://github.com/oisdk/formalising-graph-algorithms-with-coinduction">a
rendered html version of the code</a>. Usually, when I want more info on
some code snippet in a paper, I don’t <em>really</em> want to spend an
hour or so downloading some artefact, installing a VM, etc. What I
actually want is just to see all of the definitions the snippet relies
on, and the 30 or so lines of code preceding it. With this paper, that’s
exactly what you get: if you click on any Agda code in the paper, you’re
brought to the source of that code block, and every definition is
clickable so you can browse <em>without having to install
anything</em>.</p>
<p>I think the audience for this paper is anyone who is interested in
graphs in functional languages. It should be especially interesting to
people who have dabbled in formalising some graphs, but who might have
been stung by an uncooperative proof assistant. The techniques in the
second half of the paper might help you to convince Agda (or Idris, or
Rocq) to accept your coinductive and quotient-heavy arguments.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-mokhov_algebraic_2017" class="csl-entry" role="listitem">
Mokhov, Andrey. 2017. <span>“Algebraic <span>Graphs</span> with
<span>Class</span> (<span>Functional Pearl</span>).”</span> In
<em>Proceedings of the 10th <span>ACM SIGPLAN International
Symposium</span> on <span>Haskell</span></em>, 2–13. Haskell 2017. New
York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/3122955.3122956">10.1145/3122955.3122956</a>.
</div>
</div>
]]></description>
    <pubDate>Fri, 08 Nov 2024 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2024-11-08-formalising-graphs-coinduction.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>POPL Paper—Algebraic Effects Meet Hoare Logic in Cubical Agda</title>
    <link>https://doisinkidney.com/posts/2023-11-07-algebraic-free-monads.html</link>
    <description><![CDATA[<div class="info">
    Posted on November  7, 2023
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>New paper: “Algebraic Effects Meet Hoare Logic in Cubical Agda”, by
myself, <a href="https://yangzhixuan.github.io">Zhixuan Yang</a>, and <a
href="https://zenzike.com/">Nicolas Wu</a>, will be published at POPL
2024.</p>
<p>The preprint is available <a
href="../pdfs/algebraic-free-monads.pdf">here</a>.</p>
]]></description>
    <pubDate>Tue, 07 Nov 2023 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2023-11-07-algebraic-free-monads.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Lazily Grouping in Haskell</title>
    <link>https://doisinkidney.com/posts/2022-10-17-lazy-group-on.html</link>
    <description><![CDATA[<div class="info">
    Posted on October 17, 2022
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Here’s a cool trick:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">minimum</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">minimum</span> <span class="ot">=</span> <span class="fu">head</span> <span class="op">.</span> <span class="fu">sort</span></span></code></pre></div>
<p>This is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
in Haskell, not
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>
as you might expect. And this isn’t because Haskell is using some weird
linear-time sorting algorithm; indeed, the following is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">maximum</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="fu">maximum</span> <span class="ot">=</span> <span class="fu">last</span> <span class="op">.</span> <span class="fu">sort</span></span></code></pre></div>
<p>No: since the implementation of <code>minimum</code> above only
demands the first element of the list, and since <code>sort</code> has
been carefully implemented, only a linear amount of work will be done to
retrieve it.</p>
<p>It’s not easy to structure programs to have the same property as
<code>sort</code> does above: to be maximally lazy, such that
unnecessary work is not performed. Today I was working on a maximally
lazy implementation of the following program:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOn ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k,[a])]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>groupOn <span class="ot">=</span> <span class="op">...</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupOn (<span class="ot">`rem`</span> <span class="dv">2</span>) [<span class="dv">1</span><span class="op">..</span><span class="dv">5</span>]</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">1</span>,[<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">5</span>]),(<span class="dv">0</span>,[<span class="dv">2</span>,<span class="dv">4</span>])]</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupOn (<span class="ot">`rem`</span> <span class="dv">3</span>) [<span class="dv">5</span>,<span class="dv">8</span>,<span class="dv">3</span>,<span class="dv">6</span>,<span class="dv">2</span>]</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">2</span>,[<span class="dv">5</span>,<span class="dv">8</span>,<span class="dv">2</span>]),(<span class="dv">0</span>,[<span class="dv">3</span>,<span class="dv">6</span>])]</span></code></pre></div>
<p>This function groups the elements of a list according to some key
function. The desired behaviour here is a little subtle: we don’t want
to just group adjacent elements, for instance.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>groupOn (<span class="ot">`rem`</span> <span class="dv">3</span>) [<span class="dv">5</span>,<span class="dv">8</span>,<span class="dv">3</span>,<span class="dv">6</span>,<span class="dv">2</span>] ≢ [(<span class="dv">2</span>,[<span class="dv">5</span>,<span class="dv">8</span>]),(<span class="dv">0</span>,[<span class="dv">3</span>,<span class="dv">6</span>]),(<span class="dv">2</span>,[<span class="dv">2</span>])]</span></code></pre></div>
<p>And we don’t want to reorder the elements of the list by the
keys:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>groupOn (<span class="ot">`rem`</span> <span class="dv">3</span>) [<span class="dv">5</span>,<span class="dv">8</span>,<span class="dv">3</span>,<span class="dv">6</span>,<span class="dv">2</span>] ≢ [(<span class="dv">0</span>,[<span class="dv">3</span>,<span class="dv">6</span>]),(<span class="dv">2</span>,[<span class="dv">5</span>,<span class="dv">8</span>,<span class="dv">2</span>])]</span></code></pre></div>
<p>These constraints make it especially tricky to make this function
lazy. In fact, at first glance, it seems impossible. What should, for
instance, <code>groupOn id [1..]</code> return? It can’t even fill out
the first group, since it will never find another <code>1</code>.
However, it <em>can</em> fill out the first key. And, in fact, the
second. And it can fill out the first element of the first group.
Precisely:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>groupOn <span class="fu">id</span> [<span class="dv">1</span><span class="op">..</span>] ≡ [(<span class="dv">1</span>,<span class="dv">1</span><span class="op">:</span>⊥), (<span class="dv">2</span>,<span class="dv">2</span><span class="op">:</span>⊥), (<span class="dv">3</span>,<span class="dv">3</span><span class="op">:</span>⊥), <span class="op">...</span></span></code></pre></div>
<p>Another example is <code>groupOn id (repeat 1)</code>, or
<code>groupOn id (cycle [1,2,3])</code>. These each have
partially-defined answers:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>groupOn <span class="fu">id</span> (<span class="fu">repeat</span> <span class="dv">1</span>)      ≡ (<span class="dv">1</span>,<span class="fu">repeat</span> <span class="dv">1</span>)<span class="op">:</span>⊥</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>groupOn <span class="fu">id</span> (<span class="fu">cycle</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]) ≡ (<span class="dv">1</span>,<span class="fu">repeat</span> <span class="dv">1</span>)<span class="op">:</span>(<span class="dv">2</span>,<span class="fu">repeat</span> <span class="dv">2</span>)<span class="op">:</span>(<span class="dv">3</span>,<span class="fu">repeat</span> <span class="dv">3</span>)<span class="op">:</span>⊥</span></code></pre></div>
<p>So there is some kind of well-defined lazy semantics for this
function. The puzzle I was interested in was defining an efficient
implementation for these semantics.</p>
<h1 id="the-slow-case">The Slow Case</h1>
<p>The first approximation to a solution I could think of is the
following:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOn ::</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k, [a])]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>groupOn k <span class="ot">=</span> Map.toList <span class="op">.</span> Map.fromListWith (<span class="op">++</span>) <span class="op">.</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> (k x, [x]))</span></code></pre></div>
<p>In fact, if you don’t care about laziness, this is probably the best
solution: it’s
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>,
it performs well (practically as well as asymptotically), and it has the
expected results.</p>
<p>However, there are problems. Primarily this solution cares about
ordering, which we don’t want. We want to emit the results in the same
order that they were in the original list, and we don’t necessarily want
to require an ordering on the elements (for the efficient solution we
will relax this last constraint).</p>
<p>Instead, let’s implement our own “map” type that is inefficient, but
more general.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Map</span> a b <span class="ot">=</span> [(a,b)]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">insertWith ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>insertWith f k v [] <span class="ot">=</span> [(k,v)]</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>insertWith f k v ((k&#39;,v&#39;)<span class="op">:</span>xs)</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> k <span class="op">==</span> k&#39;   <span class="ot">=</span> (k&#39;,f v v&#39;) <span class="op">:</span> xs</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (k&#39;,v&#39;) <span class="op">:</span> insertWith f k v xs</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOn ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k, [a])]</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>groupOn k <span class="ot">=</span> <span class="fu">foldr</span> (<span class="fu">uncurry</span> (insertWith (<span class="op">++</span>))) [] <span class="op">.</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> (k x, [x]))</span></code></pre></div>
<p>The problem here is that it’s not lazy enough.
<code>insertWith</code> is strict in its last argument, which means that
using <code>foldr</code> doesn’t gain us anything laziness-wise.</p>
<p>There is some extra information we can use to drive the result: we
know that the result will have keys that are in the same order as they
appear in the list, with duplicates removed:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOn ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k, [a])]</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>groupOn k xs <span class="ot">=</span> <span class="fu">map</span> _ ks</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    ks <span class="ot">=</span> <span class="fu">map</span> k xs</span></code></pre></div>
<p>From here, we can get what the values should be from each key by
filtering the original list:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOn ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k,[a])]</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>groupOn key xs <span class="ot">=</span> <span class="fu">map</span> (\k <span class="ot">-&gt;</span> (k, <span class="fu">filter</span> ((k<span class="op">==</span>) <span class="op">.</span> key) xs)) (nub (<span class="fu">map</span> key xs))</span></code></pre></div>
<p>Using a kind of <a
href="https://en.wikipedia.org/wiki/Schwartzian_transform">Schwartzian
transform</a> yields the following slight improvement:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOn ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k,[a])]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>groupOn key xs <span class="ot">=</span> <span class="fu">map</span> (\k <span class="ot">-&gt;</span> (k , <span class="fu">map</span> <span class="fu">snd</span> (<span class="fu">filter</span> ((k<span class="op">==</span>) <span class="op">.</span> <span class="fu">fst</span>) ks))) (nub (<span class="fu">map</span> <span class="fu">fst</span> ks))</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    ks <span class="ot">=</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> (key x, x)) xs</span></code></pre></div>
<p>But this traverses the same list multiple times unnecessarily. The
problem is that we’re repeating a lot of work between <code>nub</code>
and the rest of the algorithm.</p>
<p>The following is much better:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOn ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k,[a])]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>groupOn key <span class="ot">=</span> go <span class="op">.</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> (key x, x))</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> []</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    go ((k,x)<span class="op">:</span>xs) <span class="ot">=</span> (k,x<span class="op">:</span><span class="fu">map</span> <span class="fu">snd</span> y) <span class="op">:</span> go ys</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>        (y,ys) <span class="ot">=</span> partition ((k<span class="op">==</span>)<span class="op">.</span><span class="fu">fst</span>) xs</span></code></pre></div>
<p>First, we perform the Schwartzian transform optimisation. The work of
the algorithm is done in the <code>go</code> helper. The idea is to
filter out duplicates as we encounter them: when we encounter
<code>(k,x)</code> we can keep it immediately, but then we split the
rest of the list into the components that have the same key as this
element, and the ones that differ. The ones that have the same key can
form the collection for this key, and those that differ are what we
recurse on.</p>
<p>This partitioning also avoids re-traversing elements we know to be
already accounted for in a previous group. I think that this is the most
efficient (modulo some inlining and strictness improvements) algorithm
that can do <code>groupOn</code> with just an <code>Eq</code>
constraint.</p>
<h1 id="a-faster-version">A Faster Version</h1>
<p>The reason that the <code>groupOn</code> above is slow is that every
element returned has to traverse the entire rest of the list to remove
duplicates. This is a classic pattern of quadratic behaviour: we can
improve it by using the same trick as quick sort, by partitioning the
list into lesser and greater elements on every call.</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOnOrd ::</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k,[a])]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>groupOnOrd key <span class="ot">=</span> go <span class="op">.</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> (key x, x))</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> []</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    go ((k,x)<span class="op">:</span>xs) <span class="ot">=</span> (k,x<span class="op">:</span>e) <span class="op">:</span> go lt <span class="op">++</span> go gt</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>        (e,lt,gt) <span class="ot">=</span> <span class="fu">foldr</span> split ([],[],[]) xs</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>        split ky<span class="op">@</span>(k&#39;,y) <span class="op">~</span>(e,lt,gt) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> k&#39; k <span class="kw">of</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>          <span class="dt">LT</span> <span class="ot">-&gt;</span> (e, ky<span class="op">:</span>lt, gt)</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>          <span class="dt">EQ</span> <span class="ot">-&gt;</span> (y<span class="op">:</span>e, lt, gt)</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>          <span class="dt">GT</span> <span class="ot">-&gt;</span> (e, lt, ky<span class="op">:</span>gt)</span></code></pre></div>
<p>While this is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>,
and it does group elements, it also reorders the underlying list. Let’s
fix that by tagging the incoming elements with their positions, and then
using those positions to order them back into their original
configuration:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOnOrd ::</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k,[a])]</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>groupOnOrd k <span class="ot">=</span> <span class="fu">map</span> (\(_,k,xs) <span class="ot">-&gt;</span> (k,xs)) <span class="op">.</span> go <span class="op">.</span> <span class="fu">zipWith</span> (\i x <span class="ot">-&gt;</span> (i, k x, x)) [<span class="dv">0</span><span class="op">..</span>]</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> []</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    go ((i, k, x)<span class="op">:</span>xs) <span class="ot">=</span> (i, k, x <span class="op">:</span> e) <span class="op">:</span> merge (go l) (go g)</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>        (e, l, g) <span class="ot">=</span> <span class="fu">foldr</span> split ([],[],[]) xs</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>        split ky<span class="op">@</span>(_,k&#39;,y) <span class="op">~</span>(e, l, g) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> k&#39; k <span class="kw">of</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>          <span class="dt">LT</span> <span class="ot">-&gt;</span> (e  , ky <span class="op">:</span> l,      g)</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>          <span class="dt">EQ</span> <span class="ot">-&gt;</span> (y<span class="op">:</span>e,      l,      g)</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>          <span class="dt">GT</span> <span class="ot">-&gt;</span> (e  ,      l, ky <span class="op">:</span> g)</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>    merge [] gt <span class="ot">=</span> gt</span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>    merge lt [] <span class="ot">=</span> lt</span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>    merge (l<span class="op">@</span>(i,_,_)<span class="op">:</span>lt) (g<span class="op">@</span>(j,_,_)<span class="op">:</span>gt)</span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> i <span class="op">&lt;=</span> j    <span class="ot">=</span> l <span class="op">:</span> merge lt (g<span class="op">:</span>gt)</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> g <span class="op">:</span> merge (l<span class="op">:</span>lt) gt</span></code></pre></div>
<p>This is close, but still not right. This isn’t yet <em>lazy</em>. The
<code>merge</code> function is strict in both arguments.</p>
<p>However, we have all the information we need to unshuffle the lists
without having to inspect them. In <code>split</code>, we know which
direction we put each element: we can store that info without using
indices.</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupOnOrd ::</span> <span class="dt">Ord</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> k) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [(k,[a])]</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>groupOnOrd k <span class="ot">=</span> catMaybes <span class="op">.</span> go <span class="op">.</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> (k x, x))</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> []</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>    go ((k,x)<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Just</span> (k, x <span class="op">:</span> e) <span class="op">:</span> merge m (go l) (go g)</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>        (e, m, l, g) <span class="ot">=</span> <span class="fu">foldr</span> split ([],[],[],[]) xs</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>        split ky<span class="op">@</span>(k&#39;,y) <span class="op">~</span>(e, m, l, g) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> k&#39; k <span class="kw">of</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>          <span class="dt">LT</span> <span class="ot">-&gt;</span> (  e, <span class="dt">LT</span> <span class="op">:</span> m, ky <span class="op">:</span> l,      g)</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>          <span class="dt">EQ</span> <span class="ot">-&gt;</span> (y<span class="op">:</span>e, <span class="dt">EQ</span> <span class="op">:</span> m,      l,      g)</span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>          <span class="dt">GT</span> <span class="ot">-&gt;</span> (  e, <span class="dt">GT</span> <span class="op">:</span> m,      l, ky <span class="op">:</span> g)</span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>    merge []        lt     gt     <span class="ot">=</span> []</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>    merge (<span class="dt">EQ</span> <span class="op">:</span> xs) lt     gt     <span class="ot">=</span> <span class="dt">Nothing</span> <span class="op">:</span> merge xs lt gt</span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>    merge (<span class="dt">LT</span> <span class="op">:</span> xs) (l<span class="op">:</span>lt) gt     <span class="ot">=</span> l       <span class="op">:</span> merge xs lt gt</span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>    merge (<span class="dt">GT</span> <span class="op">:</span> xs) lt     (g<span class="op">:</span>gt) <span class="ot">=</span> g       <span class="op">:</span> merge xs lt gt</span></code></pre></div>
<p>What we generate here is a <code>[Ordering]</code>: this list tells
us the result of all the compare operations on the input list. Then, in
<code>merge</code>, we invert the action of <code>split</code>,
rebuilding the original list without inspecting either <code>lt</code>
or <code>gt</code>.</p>
<p>And this solution works! It’s
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>,
and fully lazy.</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">map</span> <span class="fu">fst</span> <span class="op">.</span> groupOnOrd <span class="fu">id</span> <span class="op">$</span> [<span class="dv">1</span><span class="op">..</span>]</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span><span class="op">..</span>]</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupOnOrd <span class="fu">id</span> <span class="op">$</span> <span class="fu">cycle</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>(<span class="dv">1</span>,<span class="fu">repeat</span> <span class="dv">1</span>)<span class="op">:</span>(<span class="dv">2</span>,<span class="fu">repeat</span> <span class="dv">2</span>)<span class="op">:</span>(<span class="dv">3</span>,<span class="fu">repeat</span> <span class="dv">3</span>)<span class="op">:</span>⊥</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupOnOrd (<span class="ot">`rem`</span> <span class="dv">3</span>) [<span class="dv">1</span><span class="op">..</span>]</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>(<span class="dv">1</span>,[<span class="dv">1</span>,<span class="dv">4</span><span class="op">..</span>])<span class="op">:</span>(<span class="dv">2</span>,[<span class="dv">2</span>,<span class="dv">5</span><span class="op">..</span>])<span class="op">:</span>(<span class="dv">0</span>,[<span class="dv">3</span>,<span class="dv">6</span><span class="op">..</span>])<span class="op">:</span>⊥</span></code></pre></div>
<p>The finished version of these two functions, along with some
benchmarks, is available <a
href="https://gist.github.com/oisdk/0822477aaced58a5ba937c3d11c19639">here</a>.</p>
]]></description>
    <pubDate>Mon, 17 Oct 2022 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2022-10-17-lazy-group-on.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Depth Comonads</title>
    <link>https://doisinkidney.com/posts/2022-05-03-depth-comonads.html</link>
    <description><![CDATA[<div class="info">
    Posted on May  3, 2022
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<style>
.ascii-art {
    font-size: 30px;
}
.column {
    float: left;
    width: 50%;
}
.row:after {
    content: "";
    display: table;
    clear: both;
}
</style>
<p>I haven’t written much on this blog recently: since starting a PhD
all of my writing output has gone towards paper drafts and similar
things. Recently, though, I’ve been thinking about streams, monoids, and
comonads and I haven’t managed to wrangle those thoughts into something
coherent enough for a paper. This blog post is a collection of those
(pretty disorganised) thoughts. The hope is that writing them down will
force me to clarify things, but consider this a warning that the rest of
this post may well be muddled and confusing.</p>
<!--
<pre class="Agda"><a id="791" class="Symbol">{-#</a> <a id="795" class="Keyword">OPTIONS</a> <a id="803" class="Pragma">--no-positivity-check</a> <a id="825" class="Pragma">--allow-unsolved-metas</a> <a id="848" class="Pragma">--guardedness</a> <a id="862" class="Symbol">#-}</a>


<a id="868" class="Keyword">open</a> <a id="873" class="Keyword">import</a> <a id="880" href="../code/depth-comonads/DepthComonads.Prelude.html" class="Module">DepthComonads.Prelude</a>
<a id="902" class="Keyword">open</a> <a id="907" class="Keyword">import</a> <a id="914" href="../code/depth-comonads/DepthComonads.Nat.html" class="Module">DepthComonads.Nat</a>
<a id="932" class="Keyword">open</a> <a id="937" class="Keyword">import</a> <a id="944" href="../code/depth-comonads/DepthComonads.Algebra.html" class="Module">DepthComonads.Algebra</a>
<a id="966" class="Keyword">open</a> <a id="971" class="Keyword">import</a> <a id="978" href="../code/depth-comonads/DepthComonads.Relation.Binary.html" class="Module">DepthComonads.Relation.Binary</a> <a id="1008" class="Keyword">renaming</a> <a id="1017" class="Symbol">(</a><a id="1018" href="../code/depth-comonads/DepthComonads.Relation.Binary.html#2523" class="Record">TotalOrder</a> <a id="1029" class="Symbol">to</a> <a id="1032" class="Record">PolyTotalOrder</a><a id="1046" class="Symbol">)</a>

<a id="1049" class="Keyword">open</a> <a id="1054" href="../code/depth-comonads/DepthComonads.Algebra.html#4107" class="Module">Functor</a> <a id="1062" class="Symbol">⦃</a> <a id="1064" class="Symbol">...</a> <a id="1068" class="Symbol">⦄</a>
<a id="1070" class="Keyword">open</a> <a id="1075" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Module">Monoid</a> <a id="1082" class="Symbol">⦃</a> <a id="1084" class="Symbol">...</a> <a id="1088" class="Symbol">⦄</a>
<a id="1090" class="Comment">-- open PolyTotalOrder ⦃ ... ⦄ hiding (refl; _≟_)</a>

<a id="TotalOrder"></a><a id="1141" href="#1141" class="Function">TotalOrder</a> <a id="1152" class="Symbol">:</a> <a id="1154" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="1159" href="../code/depth-comonads/DepthComonads.Level.html#253" class="Generalizable">a</a> <a id="1161" class="Symbol">→</a> <a id="1163" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="1168" class="Symbol">_</a>
<a id="1170" href="#1141" class="Function">TotalOrder</a> <a id="1181" href="#1181" class="Bound">A</a> <a id="1183" class="Symbol">=</a> <a id="1185" href="#1032" class="Record">PolyTotalOrder</a> <a id="1200" href="#1181" class="Bound">A</a> <a id="1202" href="../code/depth-comonads/Agda.Primitive.html#764" class="Primitive">ℓzero</a> <a id="1208" href="../code/depth-comonads/Agda.Primitive.html#764" class="Primitive">ℓzero</a>

<a id="1215" class="Keyword">variable</a>
  <a id="1226" href="#1226" class="Generalizable">𝐹</a> <a id="1228" class="Symbol">:</a> <a id="1230" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="1235" class="Symbol">→</a> <a id="1237" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
</pre>-->
<h1 id="streams">Streams</h1>
<p>The first thing I want to talk about is streams.</p>
<pre class="Agda"><a id="1316" class="Keyword">record</a> <a id="Stream"></a><a id="1323" href="#1323" class="Record">Stream</a> <a id="1330" class="Symbol">(</a><a id="1331" href="#1331" class="Bound">A</a> <a id="1333" class="Symbol">:</a> <a id="1335" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="1339" class="Symbol">)</a> <a id="1341" class="Symbol">:</a> <a id="1343" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="1348" class="Keyword">where</a>
  <a id="1356" class="Keyword">coinductive</a>
  <a id="1370" class="Keyword">field</a> <a id="Stream.head"></a><a id="1376" href="#1376" class="Field">head</a> <a id="1381" class="Symbol">:</a> <a id="1383" href="#1331" class="Bound">A</a>
        <a id="Stream.tail"></a><a id="1393" href="#1393" class="Field">tail</a> <a id="1398" class="Symbol">:</a> <a id="1400" href="#1323" class="Record">Stream</a> <a id="1407" href="#1331" class="Bound">A</a>
</pre>
<!--
<pre class="Agda"><a id="1423" class="Keyword">open</a> <a id="1428" href="#1323" class="Module">Stream</a>
</pre>-->
<p>This representation is <em>coinductive</em>: the type above contains
infinite values. Agda, unlike Haskell, treats inductive and coinductive
types differently (this is why we need the <code>coinductive</code>
keyword in the definition). One of the differences is that it doesn’t
check termination for construction of these values:</p>
<div class="row">
<div class="column">
<pre class="Agda"><a id="alternating"></a><a id="1801" href="#1801" class="Function">alternating</a> <a id="1813" class="Symbol">:</a> <a id="1815" href="#1323" class="Record">Stream</a> <a id="1822" href="../code/depth-comonads/Agda.Builtin.Bool.html#163" class="Datatype">Bool</a>
<a id="1827" href="#1801" class="Function">alternating</a> <a id="1839" class="Symbol">.</a><a id="1840" href="#1376" class="Field">head</a>       <a id="1851" class="Symbol">=</a> <a id="1853" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a>
<a id="1858" href="#1801" class="Function">alternating</a> <a id="1870" class="Symbol">.</a><a id="1871" href="#1393" class="Field">tail</a> <a id="1876" class="Symbol">.</a><a id="1877" href="#1376" class="Field">head</a> <a id="1882" class="Symbol">=</a> <a id="1884" href="../code/depth-comonads/Agda.Builtin.Bool.html#182" class="InductiveConstructor">false</a>
<a id="1890" href="#1801" class="Function">alternating</a> <a id="1902" class="Symbol">.</a><a id="1903" href="#1393" class="Field">tail</a> <a id="1908" class="Symbol">.</a><a id="1909" href="#1393" class="Field">tail</a> <a id="1914" class="Symbol">=</a> <a id="1916" href="#1801" class="Function">alternating</a>
</pre>
</div>
<div class="column">
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">alternating ::</span> [<span class="dt">Bool</span>]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>alternating <span class="ot">=</span> <span class="dt">True</span> <span class="op">:</span> <span class="dt">False</span> <span class="op">:</span> alternating</span></code></pre></div>
</div>
</div>
<p>We have the equivalent in Haskell on the right. We’re also using some
fancy syntax for the Agda code: copatterns <span class="citation"
data-cites="abel_wellfounded_2013">(<a href="#ref-abel_wellfounded_2013"
role="doc-biblioref">Abel and Pientka 2013</a>)</span>.</p>
<p>Note that this type is only definable in a language with some notion
of laziness. If we tried to define a value like <code>alternating</code>
above in OCaml we would loop. Haskell has no problem, and Agda—through
its coinduction mechanism—can handle it as well.</p>
<p>Update 4-5-22: thanks to Arnaud Spiwack (<a
href="https://twitter.com/aspiwack/status/1521745731161313282">@aspiwack</a>)
for correcting me on this, it turns out the definition of
<code>alternating</code> above <em>can</em> be written in Ocaml, even
without laziness. Apparently Ocaml has a facility for strict cyclic data
structures. Also, I should be a little more precise with what I’m saying
above: even without the extra facility for strict cycles, you can of
course write a lazy list with some kind of lazy wrapper type.</p>
<p>There is, however, an isomorphic type that can be defined without
coinduction:</p>
<div class="row">
<div class="column">
<pre class="Agda"><a id="ℕ-Stream"></a><a id="2573" href="#2573" class="Function">ℕ-Stream</a> <a id="2582" class="Symbol">:</a> <a id="2584" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="2589" class="Symbol">→</a> <a id="2591" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="2596" href="#2573" class="Function">ℕ-Stream</a> <a id="2605" href="#2605" class="Bound">A</a> <a id="2607" class="Symbol">=</a> <a id="2609" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a> <a id="2611" class="Symbol">→</a> <a id="2613" href="#2605" class="Bound">A</a>
</pre>
</div>
<div class="column">
<pre class="Agda"><a id="ℕ-alternating"></a><a id="2651" href="#2651" class="Function">ℕ-alternating</a> <a id="2665" class="Symbol">:</a> <a id="2667" href="#2573" class="Function">ℕ-Stream</a> <a id="2676" href="../code/depth-comonads/Agda.Builtin.Bool.html#163" class="Datatype">Bool</a>
<a id="2681" href="#2651" class="Function">ℕ-alternating</a> <a id="2695" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>          <a id="2709" class="Symbol">=</a> <a id="2711" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a>
<a id="2716" href="#2651" class="Function">ℕ-alternating</a> <a id="2730" class="Symbol">(</a><a id="2731" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="2735" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a><a id="2739" class="Symbol">)</a>    <a id="2744" class="Symbol">=</a> <a id="2746" href="../code/depth-comonads/Agda.Builtin.Bool.html#182" class="InductiveConstructor">false</a>
<a id="2752" href="#2651" class="Function">ℕ-alternating</a> <a id="2766" class="Symbol">(</a><a id="2767" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="2771" class="Symbol">(</a><a id="2772" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="2776" href="#2776" class="Bound">n</a><a id="2777" class="Symbol">))</a> <a id="2780" class="Symbol">=</a> <a id="2782" href="#2651" class="Function">ℕ-alternating</a> <a id="2796" href="#2776" class="Bound">n</a>
</pre>
</div>
</div>
<p>(notice that, in this form, the function <code>ℕ-alternating</code>
is the same function as <code>even : ℕ → Bool</code>)</p>
<p>In fact, we can convert from the coinductive representation to the
inductive one. This conversion function is more familiarly recognisable
as the indexing function:</p>
<pre class="Agda"><a id="_[_]"></a><a id="3088" href="#3088" class="Function Operator">_[_]</a> <a id="3093" class="Symbol">:</a> <a id="3095" href="#1323" class="Record">Stream</a> <a id="3102" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="3104" class="Symbol">→</a> <a id="3106" href="#2573" class="Function">ℕ-Stream</a> <a id="3115" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="3117" href="#3117" class="Bound">xs</a> <a id="3120" href="#3088" class="Function Operator">[</a> <a id="3122" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>  <a id="3128" href="#3088" class="Function Operator">]</a> <a id="3130" class="Symbol">=</a> <a id="3132" href="#3117" class="Bound">xs</a> <a id="3135" class="Symbol">.</a><a id="3136" href="#1376" class="Field">head</a>
<a id="3141" href="#3141" class="Bound">xs</a> <a id="3144" href="#3088" class="Function Operator">[</a> <a id="3146" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="3150" href="#3150" class="Bound">n</a> <a id="3152" href="#3088" class="Function Operator">]</a> <a id="3154" class="Symbol">=</a> <a id="3156" href="#3141" class="Bound">xs</a> <a id="3159" class="Symbol">.</a><a id="3160" href="#1393" class="Field">tail</a> <a id="3165" href="#3088" class="Function Operator">[</a> <a id="3167" href="#3150" class="Bound">n</a> <a id="3169" href="#3088" class="Function Operator">]</a>
</pre>
<p>I’m not just handwaving when I say the two representations are
isomorphic: we can prove this isomorphism, and, in Cubical Agda, we can
use this to transport programs on one representation to the other.</p>
<details>
<summary>
Proof of isomorphism
</summary>
<pre class="Agda"><a id="tabulate"></a><a id="3437" href="#3437" class="Function">tabulate</a> <a id="3446" class="Symbol">:</a> <a id="3448" href="#2573" class="Function">ℕ-Stream</a> <a id="3457" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="3459" class="Symbol">→</a> <a id="3461" href="#1323" class="Record">Stream</a> <a id="3468" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="3470" href="#3437" class="Function">tabulate</a> <a id="3479" href="#3479" class="Bound">xs</a> <a id="3482" class="Symbol">.</a><a id="3483" href="#1376" class="Field">head</a> <a id="3488" class="Symbol">=</a> <a id="3490" href="#3479" class="Bound">xs</a> <a id="3493" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>
<a id="3498" href="#3437" class="Function">tabulate</a> <a id="3507" href="#3507" class="Bound">xs</a> <a id="3510" class="Symbol">.</a><a id="3511" href="#1393" class="Field">tail</a> <a id="3516" class="Symbol">=</a> <a id="3518" href="#3437" class="Function">tabulate</a> <a id="3527" class="Symbol">(</a><a id="3528" href="#3507" class="Bound">xs</a> <a id="3531" href="../code/depth-comonads/DepthComonads.Function.html#125" class="Function Operator">∘</a> <a id="3533" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a><a id="3536" class="Symbol">)</a>

<a id="stream-rinv"></a><a id="3539" href="#3539" class="Function">stream-rinv</a> <a id="3551" class="Symbol">:</a> <a id="3553" class="Symbol">(</a><a id="3554" href="#3554" class="Bound">xs</a> <a id="3557" class="Symbol">:</a> <a id="3559" href="#1323" class="Record">Stream</a> <a id="3566" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="3567" class="Symbol">)</a> <a id="3569" class="Symbol">→</a> <a id="3571" href="#3437" class="Function">tabulate</a> <a id="3580" class="Symbol">(</a><a id="3581" href="#3554" class="Bound">xs</a> <a id="3584" href="#3088" class="Function Operator">[_]</a><a id="3587" class="Symbol">)</a> <a id="3589" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="3591" href="#3554" class="Bound">xs</a>
<a id="3594" href="#3539" class="Function">stream-rinv</a> <a id="3606" href="#3606" class="Bound">xs</a> <a id="3609" href="#3609" class="Bound">i</a> <a id="3611" class="Symbol">.</a><a id="3612" href="#1376" class="Field">head</a> <a id="3617" class="Symbol">=</a> <a id="3619" href="#3606" class="Bound">xs</a> <a id="3622" class="Symbol">.</a><a id="3623" href="#1376" class="Field">head</a>
<a id="3628" href="#3539" class="Function">stream-rinv</a> <a id="3640" href="#3640" class="Bound">xs</a> <a id="3643" href="#3643" class="Bound">i</a> <a id="3645" class="Symbol">.</a><a id="3646" href="#1393" class="Field">tail</a> <a id="3651" class="Symbol">=</a> <a id="3653" href="#3539" class="Function">stream-rinv</a> <a id="3665" class="Symbol">(</a><a id="3666" href="#3640" class="Bound">xs</a> <a id="3669" class="Symbol">.</a><a id="3670" href="#1393" class="Field">tail</a><a id="3674" class="Symbol">)</a> <a id="3676" href="#3643" class="Bound">i</a>

<a id="stream-linv"></a><a id="3679" href="#3679" class="Function">stream-linv</a> <a id="3691" class="Symbol">:</a> <a id="3693" class="Symbol">(</a><a id="3694" href="#3694" class="Bound">xs</a> <a id="3697" class="Symbol">:</a> <a id="3699" href="#2573" class="Function">ℕ-Stream</a> <a id="3708" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="3709" class="Symbol">)</a> <a id="3711" class="Symbol">(</a><a id="3712" href="#3712" class="Bound">n</a> <a id="3714" class="Symbol">:</a> <a id="3716" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a><a id="3717" class="Symbol">)</a> <a id="3719" class="Symbol">→</a> <a id="3721" href="#3437" class="Function">tabulate</a> <a id="3730" href="#3694" class="Bound">xs</a> <a id="3733" href="#3088" class="Function Operator">[</a> <a id="3735" href="#3712" class="Bound">n</a> <a id="3737" href="#3088" class="Function Operator">]</a> <a id="3739" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="3741" href="#3694" class="Bound">xs</a> <a id="3744" href="#3712" class="Bound">n</a>
<a id="3746" href="#3679" class="Function">stream-linv</a> <a id="3758" href="#3758" class="Bound">xs</a> <a id="3761" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>    <a id="3769" class="Symbol">=</a> <a id="3771" href="Cubical.Foundations.Id.html#560" class="Function">refl</a>
<a id="3776" href="#3679" class="Function">stream-linv</a> <a id="3788" href="#3788" class="Bound">xs</a> <a id="3791" class="Symbol">(</a><a id="3792" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="3796" href="#3796" class="Bound">n</a><a id="3797" class="Symbol">)</a> <a id="3799" class="Symbol">=</a> <a id="3801" href="#3679" class="Function">stream-linv</a> <a id="3813" class="Symbol">(</a><a id="3814" href="#3788" class="Bound">xs</a> <a id="3817" href="../code/depth-comonads/DepthComonads.Function.html#125" class="Function Operator">∘</a> <a id="3819" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a><a id="3822" class="Symbol">)</a> <a id="3824" href="#3796" class="Bound">n</a>

<a id="stream-reps"></a><a id="3827" href="#3827" class="Function">stream-reps</a> <a id="3839" class="Symbol">:</a> <a id="3841" href="#2573" class="Function">ℕ-Stream</a> <a id="3850" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="3852" href="../code/depth-comonads/DepthComonads.Function.Isomorphism.html#308" class="Function Operator">⇔</a> <a id="3854" href="#1323" class="Record">Stream</a> <a id="3861" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="3863" href="#3827" class="Function">stream-reps</a> <a id="3875" class="Symbol">.</a><a id="3876" href="Cubical.Foundations.Isomorphism.html#882" class="Field">fun</a> <a id="3880" class="Symbol">=</a> <a id="3882" href="#3437" class="Function">tabulate</a>
<a id="3891" href="#3827" class="Function">stream-reps</a> <a id="3903" class="Symbol">.</a><a id="3904" href="Cubical.Foundations.Isomorphism.html#898" class="Field">inv</a> <a id="3908" class="Symbol">=</a> <a id="3910" href="#3088" class="Function Operator">_[_]</a>
<a id="3915" href="#3827" class="Function">stream-reps</a> <a id="3927" class="Symbol">.</a><a id="3928" href="Cubical.Foundations.Isomorphism.html#914" class="Field">rightInv</a> <a id="3937" class="Symbol">=</a> <a id="3939" href="#3539" class="Function">stream-rinv</a>
<a id="3951" href="#3827" class="Function">stream-reps</a> <a id="3963" class="Symbol">.</a><a id="3964" href="Cubical.Foundations.Isomorphism.html#945" class="Field">leftInv</a> <a id="3972" href="#3972" class="Bound">xs</a> <a id="3975" class="Symbol">=</a> <a id="3977" href="Cubical.Foundations.Id.html#807" class="Function">funExt</a> <a id="3984" class="Symbol">(</a><a id="3985" href="#3679" class="Function">stream-linv</a> <a id="3997" href="#3972" class="Bound">xs</a><a id="3999" class="Symbol">)</a>
</pre>
</details>
<p>One final observation about streams: another way to define a stream
is as the cofree comonad of the identity functor.</p>
<pre class="Agda"><a id="4142" class="Keyword">record</a> <a id="Cofree"></a><a id="4149" href="#4149" class="Record">Cofree</a> <a id="4156" class="Symbol">(</a><a id="4157" href="#4157" class="Bound">F</a> <a id="4159" class="Symbol">:</a> <a id="4161" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="4166" class="Symbol">→</a> <a id="4168" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="4172" class="Symbol">)</a> <a id="4174" class="Symbol">(</a><a id="4175" href="#4175" class="Bound">A</a> <a id="4177" class="Symbol">:</a> <a id="4179" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="4183" class="Symbol">)</a> <a id="4185" class="Symbol">:</a> <a id="4187" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="4192" class="Keyword">where</a>
  <a id="4200" class="Keyword">coinductive</a>
  <a id="4214" class="Keyword">field</a> <a id="Cofree.root"></a><a id="4220" href="#4220" class="Field">root</a> <a id="4225" class="Symbol">:</a> <a id="4227" href="#4175" class="Bound">A</a>
        <a id="Cofree.step"></a><a id="4237" href="#4237" class="Field">step</a> <a id="4242" class="Symbol">:</a> <a id="4244" href="#4157" class="Bound">F</a> <a id="4246" class="Symbol">(</a><a id="4247" href="#4149" class="Record">Cofree</a> <a id="4254" href="#4157" class="Bound">F</a> <a id="4256" href="#4175" class="Bound">A</a><a id="4257" class="Symbol">)</a>

<a id="𝒞-Stream"></a><a id="4260" href="#4260" class="Function">𝒞-Stream</a> <a id="4269" class="Symbol">:</a> <a id="4271" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="4276" class="Symbol">→</a> <a id="4278" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="4283" href="#4260" class="Function">𝒞-Stream</a> <a id="4292" class="Symbol">=</a> <a id="4294" href="#4149" class="Record">Cofree</a> <a id="4301" href="../code/depth-comonads/DepthComonads.Function.html#561" class="Function">id</a>
</pre>
<!--
<pre class="Agda"><a id="4318" class="Keyword">open</a> <a id="4323" href="#4149" class="Module">Cofree</a>
</pre>-->
<p>Concretely, the <code>Cofree F A</code> type is a possibly infinite
tree, with branches shaped like <code>F</code>, and internal nodes
labelled with <code>A</code>. It has the following characteristic
function:</p>
<pre class="Agda"><a id="4522" class="Symbol">{-#</a> <a id="4526" class="Keyword">NON_TERMINATING</a> <a id="4542" class="Symbol">#-}</a>
<a id="trace"></a><a id="4546" href="#4546" class="Function">trace</a> <a id="4552" class="Symbol">:</a> <a id="4554" class="Symbol">⦃</a> <a id="4556" href="#4556" class="Bound">_</a> <a id="4558" class="Symbol">:</a> <a id="4560" href="../code/depth-comonads/DepthComonads.Algebra.html#4107" class="Record">Functor</a> <a id="4568" href="#1226" class="Generalizable">𝐹</a> <a id="4570" class="Symbol">⦄</a> <a id="4572" class="Symbol">→</a> <a id="4574" class="Symbol">(</a><a id="4575" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="4577" class="Symbol">→</a> <a id="4579" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a><a id="4580" class="Symbol">)</a> <a id="4582" class="Symbol">→</a> <a id="4584" class="Symbol">(</a><a id="4585" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="4587" class="Symbol">→</a> <a id="4589" href="#1226" class="Generalizable">𝐹</a> <a id="4591" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="4592" class="Symbol">)</a> <a id="4594" class="Symbol">→</a> <a id="4596" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="4598" class="Symbol">→</a> <a id="4600" href="#4149" class="Record">Cofree</a> <a id="4607" href="#1226" class="Generalizable">𝐹</a> <a id="4609" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a>
<a id="4611" href="#4546" class="Function">trace</a> <a id="4617" href="#4617" class="Bound">ϕ</a> <a id="4619" href="#4619" class="Bound">ρ</a> <a id="4621" href="#4621" class="Bound">x</a> <a id="4623" class="Symbol">.</a><a id="4624" href="#4220" class="Field">root</a> <a id="4629" class="Symbol">=</a> <a id="4631" href="#4617" class="Bound">ϕ</a> <a id="4633" href="#4621" class="Bound">x</a>
<a id="4635" href="#4546" class="Function">trace</a> <a id="4641" href="#4641" class="Bound">ϕ</a> <a id="4643" href="#4643" class="Bound">ρ</a> <a id="4645" href="#4645" class="Bound">x</a> <a id="4647" class="Symbol">.</a><a id="4648" href="#4237" class="Field">step</a> <a id="4653" class="Symbol">=</a> <a id="4655" href="../code/depth-comonads/DepthComonads.Algebra.html#4153" class="Field">map</a> <a id="4659" class="Symbol">(</a><a id="4660" href="#4546" class="Function">trace</a> <a id="4666" href="#4641" class="Bound">ϕ</a> <a id="4668" href="#4643" class="Bound">ρ</a><a id="4669" class="Symbol">)</a> <a id="4671" class="Symbol">(</a><a id="4672" href="#4643" class="Bound">ρ</a> <a id="4674" href="#4645" class="Bound">x</a><a id="4675" class="Symbol">)</a>
</pre>
<p>Like how the free monad turns any functor into a monad, the cofree
comonad turns any functor into a comonad. Comonads are less popular and
widely-used than monads, as there are less well-known examples of them.
I have found it helpful to think about comonads through spatial
analogies. A lot of comonads can represent a kind of walk through some
space: the <code>extract</code> operation tells you “what is immediately
here”, and the <code>duplicate</code> operation tells you “what can I
see from each point”. For the stream, these two operations are inhabited
by <code>head</code> and the following:</p>
<pre class="Agda"><a id="duplicate"></a><a id="5257" href="#5257" class="Function">duplicate</a> <a id="5267" class="Symbol">:</a> <a id="5269" href="#1323" class="Record">Stream</a> <a id="5276" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="5278" class="Symbol">→</a> <a id="5280" href="#1323" class="Record">Stream</a> <a id="5287" class="Symbol">(</a><a id="5288" href="#1323" class="Record">Stream</a> <a id="5295" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="5296" class="Symbol">)</a>
<a id="5298" href="#5257" class="Function">duplicate</a> <a id="5308" href="#5308" class="Bound">xs</a> <a id="5311" class="Symbol">.</a><a id="5312" href="#1376" class="Field">head</a> <a id="5317" class="Symbol">=</a> <a id="5319" href="#5308" class="Bound">xs</a>
<a id="5322" href="#5257" class="Function">duplicate</a> <a id="5332" href="#5332" class="Bound">xs</a> <a id="5335" class="Symbol">.</a><a id="5336" href="#1393" class="Field">tail</a> <a id="5341" class="Symbol">=</a> <a id="5343" href="#5257" class="Function">duplicate</a> <a id="5353" class="Symbol">(</a><a id="5354" href="#5332" class="Bound">xs</a> <a id="5357" class="Symbol">.</a><a id="5358" href="#1393" class="Field">tail</a><a id="5362" class="Symbol">)</a>
</pre>
<h1 id="generalising-streams">Generalising Streams</h1>
<p>There were three key observations in the last section:</p>
<ol>
<li>Streams are coinductive. This requires a different termination
checker in Agda, and a different evaluation model in strict
languages.</li>
<li>They have an isomorphic representation based on <em>indexing</em>.
This isomorphic representation doesn’t need coinduction or
laziness.</li>
<li>They are a special case of the cofree comonad.</li>
</ol>
<p>Going forward, we’re going to look at generalisations of streams, and
we’re going to see what these observations mean in the contexts of the
new generalisations.</p>
<p>The thing we’ll be generalising is the index of the stream.
Currently, streams are basically structures that assign a value to every
<code>ℕ</code>: what does a stream of—for instance—rational numbers look
like? To drive the intuition for this generalisation let’s first look at
the comonad instance on the <code>ℕ-Stream</code> type:</p>
<pre class="Agda"><a id="ℕ-extract"></a><a id="6260" href="#6260" class="Function">ℕ-extract</a> <a id="6270" class="Symbol">:</a> <a id="6272" href="#2573" class="Function">ℕ-Stream</a> <a id="6281" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="6283" class="Symbol">→</a> <a id="6285" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="6287" href="#6260" class="Function">ℕ-extract</a> <a id="6297" href="#6297" class="Bound">xs</a> <a id="6300" class="Symbol">=</a> <a id="6302" href="#6297" class="Bound">xs</a> <a id="6305" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>

<a id="ℕ-duplicate"></a><a id="6311" href="#6311" class="Function">ℕ-duplicate</a> <a id="6323" class="Symbol">:</a> <a id="6325" href="#2573" class="Function">ℕ-Stream</a> <a id="6334" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="6336" class="Symbol">→</a> <a id="6338" href="#2573" class="Function">ℕ-Stream</a> <a id="6347" class="Symbol">(</a><a id="6348" href="#2573" class="Function">ℕ-Stream</a> <a id="6357" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="6358" class="Symbol">)</a>
<a id="6360" href="#6311" class="Function">ℕ-duplicate</a> <a id="6372" href="#6372" class="Bound">xs</a> <a id="6375" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>    <a id="6383" class="Symbol">=</a> <a id="6385" href="#6372" class="Bound">xs</a>
<a id="6388" href="#6311" class="Function">ℕ-duplicate</a> <a id="6400" href="#6400" class="Bound">xs</a> <a id="6403" class="Symbol">(</a><a id="6404" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="6408" href="#6408" class="Bound">n</a><a id="6409" class="Symbol">)</a> <a id="6411" class="Symbol">=</a> <a id="6413" href="#6311" class="Function">ℕ-duplicate</a> <a id="6425" class="Symbol">(</a><a id="6426" href="#6400" class="Bound">xs</a> <a id="6429" href="../code/depth-comonads/DepthComonads.Function.html#125" class="Function Operator">∘</a> <a id="6431" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a><a id="6434" class="Symbol">)</a> <a id="6436" href="#6408" class="Bound">n</a>
</pre>
<p>This is the same instance as is on the <code>Stream</code> type,
transported along the isomorphism between the two types (we could have
transported the instance automatically, using <code>subst</code> or
<code>transport</code>; I have written it out here manually in full for
illustration purposes).</p>
<p>The <code>ℕ-duplicate</code> method here can changed a little to
reveal something interesting:</p>
<pre class="Agda"><a id="ℕ-duplicate₂"></a><a id="6800" href="#6800" class="Function">ℕ-duplicate₂</a> <a id="6813" class="Symbol">:</a> <a id="6815" href="#2573" class="Function">ℕ-Stream</a> <a id="6824" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="6826" class="Symbol">→</a> <a id="6828" href="#2573" class="Function">ℕ-Stream</a> <a id="6837" class="Symbol">(</a><a id="6838" href="#2573" class="Function">ℕ-Stream</a> <a id="6847" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="6848" class="Symbol">)</a>
<a id="6850" href="#6800" class="Function">ℕ-duplicate₂</a> <a id="6863" href="#6863" class="Bound">xs</a> <a id="6866" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>    <a id="6874" href="#6874" class="Bound">m</a> <a id="6876" class="Symbol">=</a> <a id="6878" href="#6863" class="Bound">xs</a> <a id="6881" href="#6874" class="Bound">m</a>
<a id="6883" href="#6800" class="Function">ℕ-duplicate₂</a> <a id="6896" href="#6896" class="Bound">xs</a> <a id="6899" class="Symbol">(</a><a id="6900" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="6904" href="#6904" class="Bound">n</a><a id="6905" class="Symbol">)</a> <a id="6907" href="#6907" class="Bound">m</a> <a id="6909" class="Symbol">=</a> <a id="6911" href="#6800" class="Function">ℕ-duplicate₂</a> <a id="6924" class="Symbol">(</a><a id="6925" href="#6896" class="Bound">xs</a> <a id="6928" href="../code/depth-comonads/DepthComonads.Function.html#125" class="Function Operator">∘</a> <a id="6930" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a><a id="6933" class="Symbol">)</a> <a id="6935" href="#6904" class="Bound">n</a> <a id="6937" href="#6907" class="Bound">m</a>

<a id="ℕ-duplicate₃"></a><a id="6940" href="#6940" class="Function">ℕ-duplicate₃</a> <a id="6953" class="Symbol">:</a> <a id="6955" href="#2573" class="Function">ℕ-Stream</a> <a id="6964" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="6966" class="Symbol">→</a> <a id="6968" href="#2573" class="Function">ℕ-Stream</a> <a id="6977" class="Symbol">(</a><a id="6978" href="#2573" class="Function">ℕ-Stream</a> <a id="6987" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="6988" class="Symbol">)</a>
<a id="6990" href="#6940" class="Function">ℕ-duplicate₃</a> <a id="7003" href="#7003" class="Bound">xs</a> <a id="7006" href="#7006" class="Bound">n</a> <a id="7008" href="#7008" class="Bound">m</a> <a id="7010" class="Symbol">=</a> <a id="7012" href="#7003" class="Bound">xs</a> <a id="7015" class="Symbol">(</a><a id="7016" href="#7034" class="Function">go</a> <a id="7019" href="#7006" class="Bound">n</a> <a id="7021" href="#7008" class="Bound">m</a><a id="7022" class="Symbol">)</a>
  <a id="7026" class="Keyword">where</a>
  <a id="7034" href="#7034" class="Function">go</a> <a id="7037" class="Symbol">:</a> <a id="7039" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a> <a id="7041" class="Symbol">→</a> <a id="7043" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a> <a id="7045" class="Symbol">→</a> <a id="7047" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a>
  <a id="7051" href="#7034" class="Function">go</a> <a id="7054" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>    <a id="7062" href="#7062" class="Bound">m</a> <a id="7064" class="Symbol">=</a> <a id="7066" href="#7062" class="Bound">m</a>
  <a id="7070" href="#7034" class="Function">go</a> <a id="7073" class="Symbol">(</a><a id="7074" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="7078" href="#7078" class="Bound">n</a><a id="7079" class="Symbol">)</a> <a id="7081" href="#7081" class="Bound">m</a> <a id="7083" class="Symbol">=</a> <a id="7085" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="7089" class="Symbol">(</a><a id="7090" href="#7034" class="Function">go</a> <a id="7093" href="#7078" class="Bound">n</a> <a id="7095" href="#7081" class="Bound">m</a><a id="7096" class="Symbol">)</a>

<a id="ℕ-duplicate₄"></a><a id="7099" href="#7099" class="Function">ℕ-duplicate₄</a> <a id="7112" class="Symbol">:</a> <a id="7114" href="#2573" class="Function">ℕ-Stream</a> <a id="7123" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="7125" class="Symbol">→</a> <a id="7127" href="#2573" class="Function">ℕ-Stream</a> <a id="7136" class="Symbol">(</a><a id="7137" href="#2573" class="Function">ℕ-Stream</a> <a id="7146" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="7147" class="Symbol">)</a>
<a id="7149" href="#7099" class="Function">ℕ-duplicate₄</a> <a id="7162" href="#7162" class="Bound">xs</a> <a id="7165" href="#7165" class="Bound">n</a> <a id="7167" href="#7167" class="Bound">m</a> <a id="7169" class="Symbol">=</a> <a id="7171" href="#7162" class="Bound">xs</a> <a id="7174" class="Symbol">(</a><a id="7175" href="#7165" class="Bound">n</a> <a id="7177" href="../code/depth-comonads/Agda.Builtin.Nat.html#325" class="Primitive Operator">+</a> <a id="7179" href="#7167" class="Bound">m</a><a id="7180" class="Symbol">)</a>
</pre>
<p>In other words, <code>duplicate</code> basically adds indices.</p>
<p>There is something distinctly <em>monoidal</em> about what’s going on
here: taking the <code>(ℕ, +, 0)</code> monoid as focus, the
<code>extract</code> method above corresponds to the monoidal empty
element, and the <code>duplicate</code> method corresponds to the binary
operator on monoids. In actual fact, there is a comonad for any function
from a monoid, often called the <code>Traced</code> comonad.</p>
<!--
<pre class="Agda"><a id="7605" class="Keyword">variable</a> <a id="7614" href="#7614" class="Generalizable">E</a> <a id="7616" class="Symbol">:</a> <a id="7618" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
</pre>-->
<pre class="Agda"><a id="Traced"></a><a id="7636" href="#7636" class="Function">Traced</a> <a id="7643" class="Symbol">:</a> <a id="7645" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="7650" class="Symbol">→</a> <a id="7652" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="7657" class="Symbol">→</a> <a id="7659" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="7664" href="#7636" class="Function">Traced</a> <a id="7671" href="#7671" class="Bound">E</a> <a id="7673" href="#7673" class="Bound">A</a> <a id="7675" class="Symbol">=</a> <a id="7677" href="#7671" class="Bound">E</a> <a id="7679" class="Symbol">→</a> <a id="7681" href="#7673" class="Bound">A</a>

<a id="extractᵀ"></a><a id="7684" href="#7684" class="Function">extractᵀ</a> <a id="7693" class="Symbol">:</a> <a id="7695" class="Symbol">⦃</a> <a id="7697" href="#7697" class="Bound">_</a> <a id="7699" class="Symbol">:</a> <a id="7701" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="7708" href="#7614" class="Generalizable">E</a> <a id="7710" class="Symbol">⦄</a> <a id="7712" class="Symbol">→</a> <a id="7714" href="#7636" class="Function">Traced</a> <a id="7721" href="#7614" class="Generalizable">E</a> <a id="7723" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="7725" class="Symbol">→</a> <a id="7727" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="7729" href="#7684" class="Function">extractᵀ</a> <a id="7738" href="#7738" class="Bound">xs</a> <a id="7741" class="Symbol">=</a> <a id="7743" href="#7738" class="Bound">xs</a> <a id="7746" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a>

<a id="duplicateᵀ"></a><a id="7749" href="#7749" class="Function">duplicateᵀ</a> <a id="7760" class="Symbol">:</a> <a id="7762" class="Symbol">⦃</a> <a id="7764" href="#7764" class="Bound">_</a> <a id="7766" class="Symbol">:</a> <a id="7768" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="7775" href="#7614" class="Generalizable">E</a> <a id="7777" class="Symbol">⦄</a> <a id="7779" class="Symbol">→</a> <a id="7781" href="#7636" class="Function">Traced</a> <a id="7788" href="#7614" class="Generalizable">E</a> <a id="7790" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="7792" class="Symbol">→</a> <a id="7794" href="#7636" class="Function">Traced</a> <a id="7801" href="#7614" class="Generalizable">E</a> <a id="7803" class="Symbol">(</a><a id="7804" href="#7636" class="Function">Traced</a> <a id="7811" href="#7614" class="Generalizable">E</a> <a id="7813" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="7814" class="Symbol">)</a>
<a id="7816" href="#7749" class="Function">duplicateᵀ</a> <a id="7827" href="#7827" class="Bound">xs</a> <a id="7830" href="#7830" class="Bound">e₁</a> <a id="7833" href="#7833" class="Bound">e₂</a> <a id="7836" class="Symbol">=</a> <a id="7838" href="#7827" class="Bound">xs</a> <a id="7841" class="Symbol">(</a><a id="7842" href="#7830" class="Bound">e₁</a> <a id="7845" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="7847" href="#7833" class="Bound">e₂</a><a id="7849" class="Symbol">)</a>
</pre>
<h1 id="reifying-traced">Reifying Traced</h1>
<p>The second observation we made about streams was that they had an
isomorphic representation which didn’t need coinduction. What we can see
above, with <code>Traced</code>, is a representation that <em>also</em>
doesn’t need coinduction. So what is the corresponding coinductive
representation? What does a generalised <em>reified</em> stream look
like?</p>
<p>So the first approach to reifying a function to a data structure is
to simply represent the function as a list of pairs.</p>
<pre class="Agda"><a id="C-Traced"></a><a id="8330" href="#8330" class="Function">C-Traced</a> <a id="8339" class="Symbol">:</a> <a id="8341" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="8346" class="Symbol">→</a> <a id="8348" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="8353" class="Symbol">→</a> <a id="8355" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="8360" href="#8330" class="Function">C-Traced</a> <a id="8369" href="#8369" class="Bound">E</a> <a id="8371" href="#8371" class="Bound">A</a> <a id="8373" class="Symbol">=</a> <a id="8375" href="#1323" class="Record">Stream</a> <a id="8382" class="Symbol">(</a><a id="8383" href="#8369" class="Bound">E</a> <a id="8385" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="8387" href="#8371" class="Bound">A</a><a id="8388" class="Symbol">)</a>
</pre>
<p>This representation obviously isn’t ideal: it isn’t possible to
construct an isomorphism between <code>C-Traced</code> and
<code>Traced</code>. We can—kind of—go in one direction, but even that
function isn’t terminating:</p>
<pre class="Agda"><a id="8604" class="Symbol">{-#</a> <a id="8608" class="Keyword">NON_TERMINATING</a> <a id="8624" class="Symbol">#-}</a>
<a id="lookup-env"></a><a id="8628" href="#8628" class="Function">lookup-env</a> <a id="8639" class="Symbol">:</a> <a id="8641" class="Symbol">⦃</a> <a id="8643" href="#8643" class="Bound">_</a> <a id="8645" class="Symbol">:</a> <a id="8647" href="../code/depth-comonads/DepthComonads.Discrete.html#228" class="Record">IsDiscrete</a> <a id="8658" href="#7614" class="Generalizable">E</a> <a id="8660" class="Symbol">⦄</a> <a id="8662" class="Symbol">→</a> <a id="8664" href="#8330" class="Function">C-Traced</a> <a id="8673" href="#7614" class="Generalizable">E</a> <a id="8675" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="8677" class="Symbol">→</a> <a id="8679" href="#7636" class="Function">Traced</a> <a id="8686" href="#7614" class="Generalizable">E</a> <a id="8688" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="8690" href="#8628" class="Function">lookup-env</a> <a id="8701" href="#8701" class="Bound">xs</a> <a id="8704" href="#8704" class="Bound">x</a> <a id="8706" class="Symbol">=</a> <a id="8708" href="../code/depth-comonads/DepthComonads.Bool.html#563" class="Function Operator">if</a> <a id="8711" href="../code/depth-comonads/DepthComonads.Dec.html#354" class="Field">does</a> <a id="8716" class="Symbol">(</a><a id="8717" href="#8704" class="Bound">x</a> <a id="8719" href="../code/depth-comonads/DepthComonads.Discrete.html#289" class="Field Operator">≟</a> <a id="8721" href="#8701" class="Bound">xs</a> <a id="8724" class="Symbol">.</a><a id="8725" href="#1376" class="Field">head</a> <a id="8730" class="Symbol">.</a><a id="8731" href="../code/depth-comonads/Agda.Builtin.Sigma.html#252" class="Field">fst</a><a id="8734" class="Symbol">)</a>
                     <a id="8757" href="../code/depth-comonads/DepthComonads.Bool.html#563" class="Function Operator">then</a> <a id="8762" href="#8701" class="Bound">xs</a> <a id="8765" class="Symbol">.</a><a id="8766" href="#1376" class="Field">head</a> <a id="8771" class="Symbol">.</a><a id="8772" href="../code/depth-comonads/Agda.Builtin.Sigma.html#264" class="Field">snd</a>
                     <a id="8797" href="../code/depth-comonads/DepthComonads.Bool.html#563" class="Function Operator">else</a> <a id="8802" href="#8628" class="Function">lookup-env</a> <a id="8813" class="Symbol">(</a><a id="8814" href="#8701" class="Bound">xs</a> <a id="8817" class="Symbol">.</a><a id="8818" href="#1393" class="Field">tail</a><a id="8822" class="Symbol">)</a> <a id="8824" href="#8704" class="Bound">x</a>
</pre>
<p>I’m not too concerned with being fast and loose with termination and
isomorphisms for the time being, though. At the moment, I’m just
interested in exploring the relationship between streams and the
indexing functions.</p>
<p>As a result, let’s try and push on this representation a little and
see if it’s possible to get something interesting and <em>almost</em>
isomorphic.</p>
<h1 id="segmented-streams">Segmented Streams</h1>
<p>To get a slightly nicer representation we can exploit the monoid a
little bit. We can do this by storing <em>offsets</em> instead of the
absolute indices for each entry. The data structure I have in mind here
looks a little like this:</p>
<pre class="ascii-art">
┏━━━━━━━━━━┳━━━━━━┳━━━━━━┉
┃x         ┃y     ┃z     ┉
┡━━━━━━━━━━╇━━━━━━╇━━━━━━┉
╵⇤a╌╌╌╌╌╌╌⇥╵⇤b╌╌╌⇥╵⇤c╌╌╌╌┈
</pre>
<p>Above is a stream containing the values <code>x</code>,
<code>y</code>, and <code>z</code>. Instead of each value corresponding
to a single entry in the stream, however, they each correspond to a
<em>segment</em>. The value <code>x</code>, for instance, labels the
first segment in the stream, which has a length given by <code>a</code>.
<code>y</code> labels the second segment, with length <code>b</code>,
<code>z</code> with length <code>c</code>, and so on.</p>
<p>The <code>Traced</code> version of the above structure might be
something like this:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">str ::</span> <span class="dt">Traced</span> m a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>str i <span class="op">|</span> i <span class="op">&lt;</span> a         <span class="ot">=</span> x</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> i <span class="op">&lt;</span> a <span class="op">+</span> b     <span class="ot">=</span> y</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> i <span class="op">&lt;</span> a <span class="op">+</span> b <span class="op">+</span> c <span class="ot">=</span> z</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="op">...</span></span></code></pre></div>
<p>So the index-value mapping is also segmented. The stream, in this
way, is kind of like a ruler, where different values mark out different
quantities along the ruler, and the index function takes in a quantity
and tells you which entry in the ruler that quantity corresponds to.</p>
<p>In code, we might represent the above data structure with the
following type:</p>
<pre class="Agda"><a id="10503" class="Keyword">record</a> <a id="Segments"></a><a id="10510" href="#10510" class="Record">Segments</a> <a id="10519" class="Symbol">(</a><a id="10520" href="#10520" class="Bound">E</a> <a id="10522" class="Symbol">:</a> <a id="10524" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="10528" class="Symbol">)</a> <a id="10530" class="Symbol">(</a><a id="10531" href="#10531" class="Bound">A</a> <a id="10533" class="Symbol">:</a> <a id="10535" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="10539" class="Symbol">)</a> <a id="10541" class="Symbol">:</a> <a id="10543" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="10548" class="Keyword">where</a>
  <a id="10556" class="Keyword">field</a>
    <a id="Segments.length"></a><a id="10566" href="#10566" class="Field">length</a> <a id="10573" class="Symbol">:</a> <a id="10575" href="#10520" class="Bound">E</a>
    <a id="Segments.label"></a><a id="10581" href="#10581" class="Field">label</a>  <a id="10588" class="Symbol">:</a> <a id="10590" href="#10531" class="Bound">A</a>
    <a id="Segments.next"></a><a id="10596" href="#10596" class="Field">next</a>   <a id="10603" class="Symbol">:</a> <a id="10605" href="#10510" class="Record">Segments</a> <a id="10614" href="#10520" class="Bound">E</a> <a id="10616" href="#10531" class="Bound">A</a>

<a id="10619" class="Keyword">open</a> <a id="10624" href="#10510" class="Module">Segments</a>
</pre>
<p>The question is, then, how do we convert <em>this</em> structure to
an <code>Traced</code> representation?</p>
<h1 id="monuses">Monuses</h1>
<p>We need some extra operations on the monoid in the segments in order
to enable this conversion to the <code>Traced</code> representation. The
extra operations are encapsulated by the monus algebra: I wrote about
this in the paper I submitted with Nicolas Wu to ICFP last year <span
class="citation" data-cites="kidney_algebras_2021">(<a
href="#ref-kidney_algebras_2021" role="doc-biblioref">2021</a>)</span>.
It’s a simple algebra on monoids which basically encapsulates monoids
which are ordered in a sensible way.</p>
<p>The basic idea is that we construct an order on monoids which says “x
is smaller than y if there is some z that we can add to x to get to
y”.</p>
<pre class="Agda"><a id="_≼_"></a><a id="11285" href="#11285" class="Function Operator">_≼_</a> <a id="11289" class="Symbol">:</a> <a id="11291" class="Symbol">⦃</a> <a id="11293" href="#11293" class="Bound">_</a> <a id="11295" class="Symbol">:</a> <a id="11297" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="11304" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="11306" class="Symbol">⦄</a> <a id="11308" class="Symbol">→</a> <a id="11310" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="11312" class="Symbol">→</a> <a id="11314" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="11316" class="Symbol">→</a> <a id="11318" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="11323" class="Symbol">_</a>
<a id="11325" href="#11325" class="Bound">x</a> <a id="11327" href="#11285" class="Function Operator">≼</a> <a id="11329" href="#11329" class="Bound">y</a> <a id="11331" class="Symbol">=</a> <a id="11333" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">∃</a> <a id="11335" href="#11335" class="Bound">z</a> <a id="11337" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">×</a> <a id="11339" class="Symbol">(</a><a id="11340" href="#11329" class="Bound">y</a> <a id="11342" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="11344" href="#11325" class="Bound">x</a> <a id="11346" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="11348" href="#11335" class="Bound">z</a><a id="11349" class="Symbol">)</a>
</pre>
<p>A monus is a monoid where we can extract that <code>z</code>, when it
exists. On the monoid <code>(ℕ, +, 0)</code>, for instance, this order
corresponds to the normal ordering on <code>ℕ</code>.</p>
<!--

<pre class="Agda"><a id="11529" class="Keyword">open</a> <a id="11534" class="Keyword">import</a> <a id="11541" href="../code/depth-comonads/DepthComonads.Nat.Properties.html" class="Module">DepthComonads.Nat.Properties</a>

<a id="11571" class="Keyword">instance</a>
  <a id="ℕ-+-monoid"></a><a id="11582" href="#11582" class="Function">ℕ-+-monoid</a> <a id="11593" class="Symbol">:</a> <a id="11595" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="11602" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a>
  <a id="11606" href="#11582" class="Function">ℕ-+-monoid</a> <a id="11617" class="Symbol">=</a> <a id="11619" class="Keyword">record</a> <a id="11626" class="Symbol">{</a> <a id="11628" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">_∙_</a>   <a id="11634" class="Symbol">=</a> <a id="11636" href="../code/depth-comonads/Agda.Builtin.Nat.html#325" class="Primitive Operator">_+_</a>
                      <a id="11662" class="Symbol">;</a> <a id="11664" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a>     <a id="11670" class="Symbol">=</a> <a id="11672" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>
                      <a id="11699" class="Symbol">;</a> <a id="11701" href="../code/depth-comonads/DepthComonads.Algebra.html#1572" class="Field">assoc</a> <a id="11707" class="Symbol">=</a> <a id="11709" href="../code/depth-comonads/DepthComonads.Nat.Properties.html#200" class="Function">+-assoc</a>
                      <a id="11739" class="Symbol">;</a> <a id="11741" href="../code/depth-comonads/DepthComonads.Algebra.html#1623" class="Field">ε∙</a>    <a id="11747" class="Symbol">=</a> <a id="11749" class="Symbol">λ</a> <a id="11751" href="#11751" class="Bound">_</a> <a id="11753" class="Symbol">→</a> <a id="11755" href="Cubical.Foundations.Id.html#560" class="Function">refl</a>
                      <a id="11782" class="Symbol">;</a> <a id="11784" href="../code/depth-comonads/DepthComonads.Algebra.html#1650" class="Field">∙ε</a>    <a id="11790" class="Symbol">=</a> <a id="11792" href="../code/depth-comonads/DepthComonads.Nat.Properties.html#301" class="Function">+0</a>
                      <a id="11817" class="Symbol">}</a>
</pre>
-->
<p>Extracting the <code>z</code> above corresponds to a kind of
difference operator:</p>
<pre class="Agda"><a id="_∸_"></a><a id="11907" href="#11907" class="Function Operator">_∸_</a> <a id="11911" class="Symbol">:</a> <a id="11913" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a> <a id="11915" class="Symbol">→</a> <a id="11917" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a> <a id="11919" class="Symbol">→</a> <a id="11921" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a>
<a id="11923" href="#11923" class="Bound">x</a>     <a id="11929" href="#11907" class="Function Operator">∸</a> <a id="11931" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>  <a id="11937" class="Symbol">=</a> <a id="11939" href="#11923" class="Bound">x</a>
<a id="11941" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="11945" href="#11945" class="Bound">x</a> <a id="11947" href="#11907" class="Function Operator">∸</a> <a id="11949" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="11953" href="#11953" class="Bound">y</a> <a id="11955" class="Symbol">=</a> <a id="11957" href="#11945" class="Bound">x</a> <a id="11959" href="#11907" class="Function Operator">∸</a> <a id="11961" href="#11953" class="Bound">y</a>
<a id="11963" class="CatchallClause Symbol">_</a><a id="11964" class="CatchallClause">     </a><a id="11969" href="#11907" class="CatchallClause Function Operator">∸</a><a id="11970" class="CatchallClause"> </a><a id="11971" class="CatchallClause Symbol">_</a>     <a id="11977" class="Symbol">=</a> <a id="11979" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>
</pre>
<p>This operator is sometimes called the monus. It is a kind of partial,
or truncating, subtraction:</p>
<pre class="Agda"><a id="12093" href="#12093" class="Function">_</a> <a id="12095" class="Symbol">:</a> <a id="12097" class="Number">5</a> <a id="12099" href="#11907" class="Function Operator">∸</a> <a id="12101" class="Number">2</a> <a id="12103" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="12105" class="Number">3</a>
<a id="12107" class="Symbol">_</a> <a id="12109" class="Symbol">=</a> <a id="12111" href="Cubical.Foundations.Id.html#560" class="Function">refl</a>

<a id="12117" href="#12117" class="Function">_</a> <a id="12119" class="Symbol">:</a> <a id="12121" class="Number">2</a> <a id="12123" href="#11907" class="Function Operator">∸</a> <a id="12125" class="Number">5</a> <a id="12127" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="12129" class="Number">0</a>
<a id="12131" class="Symbol">_</a> <a id="12133" class="Symbol">=</a> <a id="12135" href="Cubical.Foundations.Id.html#560" class="Function">refl</a>
</pre>
<p>And, indeed, this operator “extracts” the <code>z</code>, when it
exists.</p>
<pre class="Agda"><a id="∸‿is-monus"></a><a id="12213" href="#12213" class="Function">∸‿is-monus</a> <a id="12224" class="Symbol">:</a> <a id="12226" class="Symbol">∀</a> <a id="12228" href="#12228" class="Bound">x</a> <a id="12230" href="#12230" class="Bound">y</a> <a id="12232" class="Symbol">→</a> <a id="12234" class="Symbol">(</a><a id="12235" href="#12235" class="Bound">x≼y</a> <a id="12239" class="Symbol">:</a> <a id="12241" href="#12228" class="Bound">x</a> <a id="12243" href="#11285" class="Function Operator">≼</a> <a id="12245" href="#12230" class="Bound">y</a><a id="12246" class="Symbol">)</a> <a id="12248" class="Symbol">→</a> <a id="12250" href="#12230" class="Bound">y</a> <a id="12252" href="#11907" class="Function Operator">∸</a> <a id="12254" href="#12228" class="Bound">x</a> <a id="12256" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="12258" href="../code/depth-comonads/Agda.Builtin.Sigma.html#252" class="Field">fst</a> <a id="12262" href="#12235" class="Bound">x≼y</a>
<a id="12266" href="#12213" class="Function">∸‿is-monus</a> <a id="12277" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>    <a id="12285" class="Symbol">_</a>       <a id="12293" class="Symbol">(</a><a id="12294" href="#12294" class="Bound">z</a> <a id="12296" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="12298" href="#12298" class="Bound">y≡0+z</a><a id="12303" class="Symbol">)</a> <a id="12305" class="Symbol">=</a> <a id="12307" href="#12298" class="Bound">y≡0+z</a>
<a id="12313" href="#12213" class="Function">∸‿is-monus</a> <a id="12324" class="Symbol">(</a><a id="12325" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="12329" href="#12329" class="Bound">x</a><a id="12330" class="Symbol">)</a> <a id="12332" class="Symbol">(</a><a id="12333" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="12337" href="#12337" class="Bound">y</a><a id="12338" class="Symbol">)</a> <a id="12340" class="Symbol">(</a><a id="12341" href="#12341" class="Bound">z</a> <a id="12343" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="12345" href="#12345" class="Bound">y≡x+z</a><a id="12350" class="Symbol">)</a> <a id="12352" class="Symbol">=</a> <a id="12354" href="#12213" class="Function">∸‿is-monus</a> <a id="12365" href="#12329" class="Bound">x</a> <a id="12367" href="#12337" class="Bound">y</a> <a id="12369" class="Symbol">(</a><a id="12370" href="#12341" class="Bound">z</a> <a id="12372" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="12374" href="../code/depth-comonads/DepthComonads.Nat.Properties.html#415" class="Function">suc-inj</a> <a id="12382" href="#12345" class="Bound">y≡x+z</a><a id="12387" class="Symbol">)</a>
<a id="12389" href="#12213" class="Function">∸‿is-monus</a> <a id="12400" class="Symbol">(</a><a id="12401" href="../code/depth-comonads/Agda.Builtin.Nat.html#223" class="InductiveConstructor">suc</a> <a id="12405" href="#12405" class="Bound">x</a><a id="12406" class="Symbol">)</a> <a id="12408" href="../code/depth-comonads/Agda.Builtin.Nat.html#210" class="InductiveConstructor">zero</a>    <a id="12416" class="Symbol">(</a><a id="12417" href="#12417" class="Bound">z</a> <a id="12419" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="12421" href="#12421" class="Bound">0≡x+z</a><a id="12426" class="Symbol">)</a> <a id="12428" class="Symbol">=</a> <a id="12430" href="../code/depth-comonads/DepthComonads.Empty.html#172" class="Function">⊥-elim</a> <a id="12437" class="Symbol">(</a><a id="12438" href="../code/depth-comonads/DepthComonads.Nat.Properties.html#535" class="Function">zero≢suc</a> <a id="12447" href="#12421" class="Bound">0≡x+z</a><a id="12452" class="Symbol">)</a>
</pre>
<!--

<pre class="Agda"><a id="12469" class="Keyword">open</a> <a id="12474" class="Keyword">import</a> <a id="12481" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html" class="Module">DepthComonads.Algebra.Monus</a> <a id="12509" class="Keyword">renaming</a> <a id="12518" class="Symbol">(</a><a id="12519" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#4916" class="Record">TMAPOM</a> <a id="12526" class="Symbol">to</a> <a id="12529" class="Record">Monus</a><a id="12534" class="Symbol">)</a>
<a id="12536" class="Keyword">open</a> <a id="12541" href="#12529" class="Module">Monus</a> <a id="12547" class="Symbol">⦃</a> <a id="12549" class="Symbol">...</a> <a id="12553" class="Symbol">⦄</a> <a id="12555" class="Keyword">hiding</a> <a id="12562" class="Symbol">(</a><a id="12563" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Function Operator">_∙_</a><a id="12566" class="Symbol">;</a> <a id="12568" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Function">ε</a><a id="12569" class="Symbol">;</a> <a id="12571" href="../code/depth-comonads/DepthComonads.Algebra.html#1572" class="Function">assoc</a><a id="12576" class="Symbol">;</a> <a id="12578" href="../code/depth-comonads/DepthComonads.Algebra.html#1650" class="Function">∙ε</a><a id="12580" class="Symbol">;</a> <a id="12582" href="../code/depth-comonads/DepthComonads.Algebra.html#1623" class="Function">ε∙</a><a id="12584" class="Symbol">;</a> <a id="12586" href="../code/depth-comonads/DepthComonads.Algebra.html#2675" class="Function">monoid</a><a id="12592" class="Symbol">)</a>
</pre>
-->
<p>Our definition of a monus is simple: a monus is anything where the
order ≼, sometimes called the “algebraic preorder”, is total and
antisymmetric. This is precisely what lets us write a function which
takes the <code>Segments</code> type and converts it back to the
<code>Traced</code> type.</p>
<pre class="Agda"><a id="12879" class="Symbol">{-#</a> <a id="12883" class="Keyword">NON_TERMINATING</a> <a id="12899" class="Symbol">#-}</a>
<a id="Segments→Traced"></a><a id="12903" href="#12903" class="Function">Segments→Traced</a> <a id="12919" class="Symbol">:</a> <a id="12921" class="Symbol">⦃</a> <a id="12923" href="#12923" class="Bound">_</a> <a id="12925" class="Symbol">:</a> <a id="12927" href="#12529" class="Record">Monus</a> <a id="12933" href="#7614" class="Generalizable">E</a> <a id="12935" class="Symbol">⦄</a> <a id="12937" class="Symbol">→</a> <a id="12939" href="#10510" class="Record">Segments</a> <a id="12948" href="#7614" class="Generalizable">E</a> <a id="12950" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="12952" class="Symbol">→</a> <a id="12954" href="#7636" class="Function">Traced</a> <a id="12961" href="#7614" class="Generalizable">E</a> <a id="12963" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="12965" href="#12903" class="Function">Segments→Traced</a> <a id="12981" href="#12981" class="Bound">xs</a> <a id="12984" href="#12984" class="Bound">i</a> <a id="12986" class="Keyword">with</a> <a id="12991" href="#12981" class="Bound">xs</a> <a id="12994" class="Symbol">.</a><a id="12995" href="#10566" class="Field">length</a> <a id="13002" href="../code/depth-comonads/DepthComonads.Relation.Binary.html#3314" class="Function Operator">≤?</a> <a id="13005" href="#12984" class="Bound">i</a>
<a id="13007" class="Symbol">...</a> <a id="13011" class="Symbol">|</a> <a id="13013" href="../code/depth-comonads/DepthComonads.Dec.html#420" class="InductiveConstructor">yes</a> <a id="13017" class="Symbol">(</a><a id="13018" href="#13018" class="Bound">j</a> <a id="13020" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="13022" href="#13022" class="Bound">i≡xsₗ∙j</a><a id="13029" class="Symbol">)</a> <a id="13031" class="Symbol">=</a> <a id="13033" href="#12903" class="Function">Segments→Traced</a> <a id="13049" class="Symbol">(</a><a id="13050" class="Bound">xs</a> <a id="13053" class="Symbol">.</a><a id="13054" href="#10596" class="Field">next</a><a id="13058" class="Symbol">)</a> <a id="13060" href="#13018" class="Bound">j</a>
<a id="13062" class="Symbol">...</a> <a id="13066" class="Symbol">|</a> <a id="13068" href="../code/depth-comonads/DepthComonads.Dec.html#454" class="InductiveConstructor">no</a>  <a id="13072" class="Symbol">_</a>             <a id="13086" class="Symbol">=</a> <a id="13088" class="Bound">xs</a> <a id="13091" class="Symbol">.</a><a id="13092" href="#10581" class="Field">label</a>
</pre>
<p>This function takes an index, and checks if that length is greater
than or equal to the first segment in the stream of segments. If it is,
then it continues searching through the rest of the segments with the
index reduced by the size of that first segment. If not, then it returns
the label of the first segment.</p>
<p>Taking the old example, we are basically converting to ∸ from +:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">str ::</span> <span class="dt">Traced</span> m a</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>str i <span class="op">|</span> i         <span class="op">&lt;</span> a <span class="ot">=</span> x</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> i ∸ a     <span class="op">&lt;</span> b <span class="ot">=</span> y</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> i ∸ a ∸ b <span class="op">&lt;</span> c <span class="ot">=</span> z</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="op">...</span></span></code></pre></div>
<p>The first issue here is that this definition is not terminating. That
might seem an insurmountable problem at first—we are searching through
an infinite stream, after all—but notice that there is one parameter
which is decreasing on each recursive call: the index. Well, it only
decreases if the segment is non-zero: this can be enforced by changing
the definition of the segments type:</p>
<pre class="Agda"><a id="14004" class="Keyword">record</a> <a id="ℱ-Segments"></a><a id="14011" href="#14011" class="Record">ℱ-Segments</a> <a id="14022" class="Symbol">(</a><a id="14023" href="#14023" class="Bound">E</a> <a id="14025" class="Symbol">:</a> <a id="14027" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="14031" class="Symbol">)</a> <a id="14033" class="Symbol">⦃</a> <a id="14035" href="#14035" class="Bound">_</a> <a id="14037" class="Symbol">:</a> <a id="14039" href="#12529" class="Record">Monus</a> <a id="14045" href="#14023" class="Bound">E</a> <a id="14047" class="Symbol">⦄</a> <a id="14049" class="Symbol">(</a><a id="14050" href="#14050" class="Bound">A</a> <a id="14052" class="Symbol">:</a> <a id="14054" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="14058" class="Symbol">)</a> <a id="14060" class="Symbol">:</a> <a id="14062" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="14067" class="Keyword">where</a>
  <a id="14075" class="Keyword">coinductive</a>
  <a id="14089" class="Keyword">field</a>
    <a id="ℱ-Segments.label"></a><a id="14099" href="#14099" class="Field">label</a>    <a id="14108" class="Symbol">:</a> <a id="14110" href="#14050" class="Bound">A</a>
    <a id="ℱ-Segments.length"></a><a id="14116" href="#14116" class="Field">length</a>   <a id="14125" class="Symbol">:</a> <a id="14127" href="#14023" class="Bound">E</a>
    <a id="ℱ-Segments.length≢ε"></a><a id="14133" href="#14133" class="Field">length≢ε</a> <a id="14142" class="Symbol">:</a> <a id="14144" class="Field">length</a> <a id="14151" href="../code/depth-comonads/DepthComonads.Path.html#561" class="Function Operator">≢</a> <a id="14153" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a>
    <a id="ℱ-Segments.next"></a><a id="14159" href="#14159" class="Field">next</a>     <a id="14168" class="Symbol">:</a> <a id="14170" href="#14011" class="Record">ℱ-Segments</a> <a id="14181" href="#14023" class="Bound">E</a> <a id="14183" href="#14050" class="Bound">A</a>

<a id="14186" class="Keyword">open</a> <a id="14191" href="#14011" class="Module">ℱ-Segments</a>
</pre>
<p>This type allows us to write the following definition:</p>
<pre class="Agda"><a id="14267" class="Keyword">module</a> <a id="14274" href="#14274" class="Module">_</a> <a id="14276" class="Symbol">⦃</a> <a id="14278" href="#14278" class="Bound">_</a> <a id="14280" class="Symbol">:</a> <a id="14282" href="#12529" class="Record">Monus</a> <a id="14288" href="#7614" class="Generalizable">E</a> <a id="14290" class="Symbol">⦄</a> <a id="14292" class="Symbol">(</a><a id="14293" href="#14293" class="Bound">wf</a> <a id="14296" class="Symbol">:</a> <a id="14298" href="../code/depth-comonads/DepthComonads.WellFounded.html#230" class="Function">WellFounded</a> <a id="14310" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#2522" class="Function Operator">_≺_</a><a id="14313" class="Symbol">)</a> <a id="14315" class="Keyword">where</a>
  <a id="14323" href="#14323" class="Function">wf-index</a> <a id="14332" class="Symbol">:</a> <a id="14334" href="#14011" class="Record">ℱ-Segments</a> <a id="14345" href="#14288" class="Bound">E</a> <a id="14347" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="14349" class="Symbol">→</a> <a id="14351" class="Symbol">(</a><a id="14352" href="#14352" class="Bound">i</a> <a id="14354" class="Symbol">:</a> <a id="14356" href="#14288" class="Bound">E</a><a id="14357" class="Symbol">)</a> <a id="14359" class="Symbol">→</a> <a id="14361" href="../code/depth-comonads/DepthComonads.WellFounded.html#113" class="Datatype">Acc</a> <a id="14365" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#2522" class="Function Operator">_≺_</a> <a id="14369" href="#14352" class="Bound">i</a> <a id="14371" class="Symbol">→</a> <a id="14373" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
  <a id="14377" href="#14323" class="Function">wf-index</a> <a id="14386" href="#14386" class="Bound">xs</a> <a id="14389" href="#14389" class="Bound">i</a> <a id="14391" href="#14391" class="Bound">a</a> <a id="14393" class="Keyword">with</a> <a id="14398" href="#14386" class="Bound">xs</a> <a id="14401" class="Symbol">.</a><a id="14402" href="#14116" class="Field">length</a> <a id="14409" href="../code/depth-comonads/DepthComonads.Relation.Binary.html#3314" class="Function Operator">≤?</a> <a id="14412" href="#14389" class="Bound">i</a>
  <a id="14416" class="Symbol">...</a> <a id="14420" class="Symbol">|</a> <a id="14422" href="../code/depth-comonads/DepthComonads.Dec.html#454" class="InductiveConstructor">no</a> <a id="14425" class="Symbol">_</a> <a id="14427" class="Symbol">=</a> <a id="14429" class="Bound">xs</a> <a id="14432" class="Symbol">.</a><a id="14433" href="#14099" class="Field">label</a>
  <a id="14441" href="#14323" class="Function">wf-index</a> <a id="14450" href="#14450" class="Bound">xs</a> <a id="14453" href="#14453" class="Bound">i</a> <a id="14455" class="Symbol">(</a><a id="14456" href="../code/depth-comonads/DepthComonads.WellFounded.html#189" class="InductiveConstructor">acc</a> <a id="14460" href="#14460" class="Bound">wf</a><a id="14462" class="Symbol">)</a> <a id="14464" class="Symbol">|</a> <a id="14466" href="../code/depth-comonads/DepthComonads.Dec.html#420" class="InductiveConstructor">yes</a> <a id="14470" class="Symbol">(</a><a id="14471" href="#14471" class="Bound">j</a> <a id="14473" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="14475" href="#14475" class="Bound">i≡xsₗ∙j</a><a id="14482" class="Symbol">)</a> <a id="14484" class="Symbol">=</a>
    <a id="14490" href="#14323" class="Function">wf-index</a> <a id="14499" class="Symbol">(</a><a id="14500" href="#14450" class="Bound">xs</a> <a id="14503" class="Symbol">.</a><a id="14504" href="#14159" class="Field">next</a><a id="14508" class="Symbol">)</a> <a id="14510" href="#14471" class="Bound">j</a> <a id="14512" class="Symbol">(</a><a id="14513" href="#14460" class="Bound">wf</a> <a id="14516" href="#14471" class="Bound">j</a> <a id="14518" class="Symbol">(</a><a id="14519" href="#14450" class="Bound">xs</a> <a id="14522" class="Symbol">.</a><a id="14523" href="#14116" class="Field">length</a> <a id="14530" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="14532" href="#14475" class="Bound">i≡xsₗ∙j</a> <a id="14540" href="Cubical.Foundations.Id.html#737" class="Function Operator">;</a> <a id="14542" href="../code/depth-comonads/DepthComonads.Algebra.html#2733" class="Function">comm</a> <a id="14547" class="Symbol">_</a> <a id="14549" class="Symbol">_</a> <a id="14551" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="14553" href="#14450" class="Bound">xs</a> <a id="14556" class="Symbol">.</a><a id="14557" href="#14133" class="Field">length≢ε</a><a id="14565" class="Symbol">))</a>

  <a id="14571" href="#14571" class="Function">ℱ-Segments→Traced</a> <a id="14589" class="Symbol">:</a> <a id="14591" href="#14011" class="Record">ℱ-Segments</a> <a id="14602" href="#14288" class="Bound">E</a> <a id="14604" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="14606" class="Symbol">→</a> <a id="14608" href="#7636" class="Function">Traced</a> <a id="14615" href="#14288" class="Bound">E</a> <a id="14617" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
  <a id="14621" href="#14571" class="Function">ℱ-Segments→Traced</a> <a id="14639" href="#14639" class="Bound">xs</a> <a id="14642" href="#14642" class="Bound">i</a> <a id="14644" class="Symbol">=</a> <a id="14646" href="#14323" class="Function">wf-index</a> <a id="14655" href="#14639" class="Bound">xs</a> <a id="14658" href="#14642" class="Bound">i</a> <a id="14660" class="Symbol">(</a><a id="14661" href="#14293" class="Bound">wf</a> <a id="14664" href="#14642" class="Bound">i</a><a id="14665" class="Symbol">)</a>
</pre>
<h1 id="trying-to-build-an-isomorphism">Trying to build an
isomorphism</h1>
<p>So the <code>ℱ-Segments</code> type is interesting, but it only
really gives one side of the isomorphism. There is no way to write a
function <code>Traced E A → ℱ-Segments E A</code>.</p>
<p>The problem is that there’s no way to get the “next” segment from a
function <code>E → A</code>. We can find the label of the first segment,
by applying the function to <code>ε</code>, but there’s no real way to
figure out the <em>size</em> of this segment. We can change
<code>Traced</code> little to <em>provide</em> this size, though.</p>
<pre class="Agda"><a id="Ind"></a><a id="15166" href="#15166" class="Function">Ind</a> <a id="15170" class="Symbol">:</a> <a id="15172" class="Symbol">∀</a> <a id="15174" href="#15174" class="Bound">E</a> <a id="15176" class="Symbol">→</a> <a id="15178" class="Symbol">⦃</a> <a id="15180" href="#15180" class="Bound">_</a> <a id="15182" class="Symbol">:</a> <a id="15184" href="#12529" class="Record">Monus</a> <a id="15190" href="#15174" class="Bound">E</a> <a id="15192" class="Symbol">⦄</a> <a id="15194" class="Symbol">→</a> <a id="15196" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="15201" class="Symbol">→</a> <a id="15203" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="15208" href="#15166" class="Function">Ind</a> <a id="15212" href="#15212" class="Bound">E</a> <a id="15214" href="#15214" class="Bound">A</a> <a id="15216" class="Symbol">=</a> <a id="15218" href="#15212" class="Bound">E</a> <a id="15220" class="Symbol">→</a> <a id="15222" href="#15214" class="Bound">A</a> <a id="15224" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="15226" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">Σ[</a> <a id="15229" href="#15229" class="Bound">length</a> <a id="15236" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">⦂</a> <a id="15238" href="#15212" class="Bound">E</a> <a id="15240" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">]</a> <a id="15242" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">×</a> <a id="15244" class="Symbol">(</a><a id="15245" href="#15229" class="Bound">length</a> <a id="15252" href="../code/depth-comonads/DepthComonads.Path.html#561" class="Function Operator">≢</a> <a id="15254" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a><a id="15255" class="Symbol">)</a>
</pre>
<p>This new type will return a tuple consisting of the value indicated
by the supplied index, along with the distance to the next segment. For
instance, on the example stream given in the diagram earlier, supplying
an index <code>i</code> that is bigger than <code>a</code> but smaller
than <code>a + b</code>, this function should return <code>y</code>
along with some <code>j</code> such that <code>i + j ≡ a + b</code>.
Diagrammatically:</p>
<pre class="ascii-art">
╷⇤i╌╌╌╌╌╌╌╌⇥╷⇤j╌╌⇥╷
┢━━━━━━━━┳━━┷━━━━━╈━━━━━━┉
┃x       ┃y       ┃z     ┉
┡━━━━━━━━╇━━━━━━━━╇━━━━━━┉
╵⇤a╌╌╌╌╌⇥╵⇤b╌╌╌╌╌⇥╵⇤c╌╌╌╌┈
</pre>
<p>This can be implemented in code like so:</p>
<pre class="Agda"><a id="15841" class="Keyword">module</a> <a id="15848" href="#15848" class="Module">_</a> <a id="15850" class="Symbol">⦃</a> <a id="15852" href="#15852" class="Bound">_</a> <a id="15854" class="Symbol">:</a> <a id="15856" href="#12529" class="Record">Monus</a> <a id="15862" href="#7614" class="Generalizable">E</a> <a id="15864" class="Symbol">⦄</a> <a id="15866" class="Keyword">where</a>
  <a id="15874" href="#15874" class="Function">wf-ind</a> <a id="15881" class="Symbol">:</a> <a id="15883" href="#14011" class="Record">ℱ-Segments</a> <a id="15894" href="#15862" class="Bound">E</a> <a id="15896" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="15898" class="Symbol">→</a> <a id="15900" class="Symbol">(</a><a id="15901" href="#15901" class="Bound">i</a> <a id="15903" class="Symbol">:</a> <a id="15905" href="#15862" class="Bound">E</a><a id="15906" class="Symbol">)</a> <a id="15908" class="Symbol">→</a> <a id="15910" href="../code/depth-comonads/DepthComonads.WellFounded.html#113" class="Datatype">Acc</a> <a id="15914" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#2522" class="Function Operator">_≺_</a> <a id="15918" href="#15901" class="Bound">i</a> <a id="15920" class="Symbol">→</a> <a id="15922" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="15924" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="15926" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">∃</a> <a id="15928" href="#15928" class="Bound">length</a> <a id="15935" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">×</a> <a id="15937" class="Symbol">(</a><a id="15938" href="#15928" class="Bound">length</a> <a id="15945" href="../code/depth-comonads/DepthComonads.Path.html#561" class="Function Operator">≢</a> <a id="15947" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a><a id="15948" class="Symbol">)</a>
  <a id="15952" href="#15874" class="Function">wf-ind</a> <a id="15959" href="#15959" class="Bound">xs</a> <a id="15962" href="#15962" class="Bound">i</a> <a id="15964" class="Symbol">_</a> <a id="15966" class="Keyword">with</a> <a id="15971" href="#15959" class="Bound">xs</a> <a id="15974" class="Symbol">.</a><a id="15975" href="#14116" class="Field">length</a> <a id="15982" href="../code/depth-comonads/DepthComonads.Relation.Binary.html#3314" class="Function Operator">≤?</a> <a id="15985" href="#15962" class="Bound">i</a>
  <a id="15989" class="Symbol">...</a> <a id="15993" class="Symbol">|</a> <a id="15995" href="../code/depth-comonads/DepthComonads.Dec.html#454" class="InductiveConstructor">no</a> <a id="15998" href="#15998" class="Bound">xsₗ≰i</a> <a id="16004" class="Symbol">=</a>
    <a id="16010" class="Keyword">let</a> <a id="16014" href="#16014" class="Bound">j</a> <a id="16016" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16018" class="Symbol">_</a> <a id="16020" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16022" href="#16022" class="Bound">j≢ε</a> <a id="16026" class="Symbol">=</a> <a id="16028" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#4426" class="Function">&lt;⇒≺</a> <a id="16032" class="Bound">i</a> <a id="16034" class="Symbol">(</a><a id="16035" class="Bound">xs</a> <a id="16038" class="Symbol">.</a><a id="16039" href="#14116" class="Field">length</a><a id="16045" class="Symbol">)</a> <a id="16047" href="#15998" class="Bound">xsₗ≰i</a>
    <a id="16057" class="Keyword">in</a> <a id="16060" class="Bound">xs</a> <a id="16063" class="Symbol">.</a><a id="16064" href="#14099" class="Field">label</a> <a id="16070" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16072" href="#16014" class="Bound">j</a> <a id="16074" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16076" href="#16022" class="Bound">j≢ε</a>
  <a id="16082" href="#15874" class="Function">wf-ind</a> <a id="16089" href="#16089" class="Bound">xs</a> <a id="16092" href="#16092" class="Bound">i</a> <a id="16094" class="Symbol">(</a><a id="16095" href="../code/depth-comonads/DepthComonads.WellFounded.html#189" class="InductiveConstructor">acc</a> <a id="16099" href="#16099" class="Bound">wf</a><a id="16101" class="Symbol">)</a> <a id="16103" class="Symbol">|</a> <a id="16105" href="../code/depth-comonads/DepthComonads.Dec.html#420" class="InductiveConstructor">yes</a> <a id="16109" class="Symbol">(</a><a id="16110" href="#16110" class="Bound">j</a> <a id="16112" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16114" href="#16114" class="Bound">i≡xsₗ∙j</a><a id="16121" class="Symbol">)</a> <a id="16123" class="Symbol">=</a>
    <a id="16129" href="#15874" class="Function">wf-ind</a> <a id="16136" class="Symbol">(</a><a id="16137" href="#16089" class="Bound">xs</a> <a id="16140" class="Symbol">.</a><a id="16141" href="#14159" class="Field">next</a><a id="16145" class="Symbol">)</a> <a id="16147" href="#16110" class="Bound">j</a> <a id="16149" class="Symbol">(</a><a id="16150" href="#16099" class="Bound">wf</a> <a id="16153" href="#16110" class="Bound">j</a> <a id="16155" class="Symbol">(</a><a id="16156" href="#16089" class="Bound">xs</a> <a id="16159" class="Symbol">.</a><a id="16160" href="#14116" class="Field">length</a> <a id="16167" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16169" href="#16114" class="Bound">i≡xsₗ∙j</a> <a id="16177" href="Cubical.Foundations.Id.html#737" class="Function Operator">;</a> <a id="16179" href="../code/depth-comonads/DepthComonads.Algebra.html#2733" class="Function">comm</a> <a id="16184" class="Symbol">_</a> <a id="16186" class="Symbol">_</a> <a id="16188" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16190" href="#16089" class="Bound">xs</a> <a id="16193" class="Symbol">.</a><a id="16194" href="#14133" class="Field">length≢ε</a><a id="16202" class="Symbol">))</a>

  <a id="16208" href="#16208" class="Function">ℱ-Segments→Ind</a> <a id="16223" class="Symbol">:</a> <a id="16225" href="../code/depth-comonads/DepthComonads.WellFounded.html#230" class="Function">WellFounded</a> <a id="16237" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#2522" class="Function Operator">_≺_</a> <a id="16241" class="Symbol">→</a> <a id="16243" href="#14011" class="Record">ℱ-Segments</a> <a id="16254" href="#15862" class="Bound">E</a> <a id="16256" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="16258" class="Symbol">→</a> <a id="16260" href="#15166" class="Function">Ind</a> <a id="16264" href="#15862" class="Bound">E</a> <a id="16266" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
  <a id="16270" href="#16208" class="Function">ℱ-Segments→Ind</a> <a id="16285" href="#16285" class="Bound">wf</a> <a id="16288" href="#16288" class="Bound">xs</a> <a id="16291" href="#16291" class="Bound">i</a> <a id="16293" class="Symbol">=</a> <a id="16295" href="#15874" class="Function">wf-ind</a> <a id="16302" href="#16288" class="Bound">xs</a> <a id="16305" href="#16291" class="Bound">i</a> <a id="16307" class="Symbol">(</a><a id="16308" href="#16285" class="Bound">wf</a> <a id="16311" href="#16291" class="Bound">i</a><a id="16312" class="Symbol">)</a>
</pre>
<p>Again, if the monus has finite descending chains, this function is
terminating. And the nice thing about this is that it’s possible to
write a function in the other direction:</p>
<pre class="Agda"><a id="Ind→ℱ-Segments"></a><a id="16500" href="#16500" class="Function">Ind→ℱ-Segments</a> <a id="16515" class="Symbol">:</a> <a id="16517" class="Symbol">⦃</a> <a id="16519" href="#16519" class="Bound">_</a> <a id="16521" class="Symbol">:</a> <a id="16523" href="#12529" class="Record">Monus</a> <a id="16529" href="#7614" class="Generalizable">E</a> <a id="16531" class="Symbol">⦄</a> <a id="16533" class="Symbol">→</a> <a id="16535" href="#15166" class="Function">Ind</a> <a id="16539" href="#7614" class="Generalizable">E</a> <a id="16541" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="16543" class="Symbol">→</a> <a id="16545" href="#14011" class="Record">ℱ-Segments</a> <a id="16556" href="#7614" class="Generalizable">E</a> <a id="16558" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="16560" href="#16500" class="Function">Ind→ℱ-Segments</a> <a id="16575" href="#16575" class="Bound">ind</a> <a id="16579" class="Symbol">=</a>
  <a id="16583" class="Keyword">let</a> <a id="16587" href="#16587" class="Bound">x</a> <a id="16589" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16591" href="#16591" class="Bound">s</a> <a id="16593" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="16595" href="#16595" class="Bound">s≢ε</a> <a id="16599" class="Symbol">=</a> <a id="16601" href="#16575" class="Bound">ind</a> <a id="16605" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a>
  <a id="16609" class="Keyword">in</a> <a id="16612" class="Symbol">λ</a> <a id="16614" class="Keyword">where</a> <a id="16620" class="Symbol">.</a><a id="16621" href="#14099" class="Field">label</a>    <a id="16630" class="Symbol">→</a> <a id="16632" href="#16587" class="Bound">x</a>
             <a id="16647" class="Symbol">.</a><a id="16648" href="#14116" class="Field">length</a>   <a id="16657" class="Symbol">→</a> <a id="16659" href="#16591" class="Bound">s</a>
             <a id="16674" class="Symbol">.</a><a id="16675" href="#14133" class="Field">length≢ε</a> <a id="16684" class="Symbol">→</a> <a id="16686" href="#16595" class="Bound">s≢ε</a>
             <a id="16703" class="Symbol">.</a><a id="16704" href="#14159" class="Field">next</a>     <a id="16713" class="Symbol">→</a> <a id="16715" href="#16500" class="Function">Ind→ℱ-Segments</a> <a id="16730" class="Symbol">(</a><a id="16731" href="#16575" class="Bound">ind</a> <a id="16735" href="../code/depth-comonads/DepthComonads.Function.html#125" class="Function Operator">∘</a> <a id="16737" class="Symbol">(</a><a id="16738" href="#16591" class="Bound">s</a> <a id="16740" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙_</a><a id="16742" class="Symbol">))</a>
</pre>
<p>The problem here is that this isomorphism is only half correct. We
can prove that converting to <code>Ind</code> and back is the identity,
but not the other direction. There are too many functions in
<code>Ind</code>.</p>
<p>Nonetheless, it’s still interesting!</p>
<h1 id="state-comonad">State Comonad</h1>
<p>There is a comonad on state <span class="citation"
data-cites="waern_made_2018 kmett_state_2018">(<a
href="#ref-waern_made_2018" role="doc-biblioref">Waern 2018</a>; <a
href="#ref-kmett_state_2018" role="doc-biblioref">Kmett 2018</a>)</span>
that is different from store. Notice that above the <code>Ind</code>
type has the same type (almost) as <code>State E A</code>.</p>
<p>This is interesting in two ways: first, it gives some concrete,
spatial intuition for what’s going on with the state comonad.</p>
<p>Second, it gives a kind of interesting <em>monad</em> instance on the
stream. If we apply the <code>Ind→ℱ-Segments</code> function to the
implementation of <code>join</code> on state, we <em>should</em> get a
<code>join</code> on <code>ℱ-Segments</code>. And we do!</p>
<p>First, we need to redefine <code>Ind</code> to the following:</p>
<pre class="Agda"><a id="𝒜-Ind"></a><a id="17567" href="#17567" class="Function">𝒜-Ind</a> <a id="17573" class="Symbol">:</a> <a id="17575" class="Symbol">∀</a> <a id="17577" href="#17577" class="Bound">E</a> <a id="17579" class="Symbol">→</a> <a id="17581" class="Symbol">⦃</a> <a id="17583" href="#17583" class="Bound">_</a> <a id="17585" class="Symbol">:</a> <a id="17587" href="#12529" class="Record">Monus</a> <a id="17593" href="#17577" class="Bound">E</a> <a id="17595" class="Symbol">⦄</a> <a id="17597" class="Symbol">→</a> <a id="17599" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="17604" class="Symbol">→</a> <a id="17606" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="17611" href="#17567" class="Function">𝒜-Ind</a> <a id="17617" href="#17617" class="Bound">E</a> <a id="17619" href="#17619" class="Bound">A</a> <a id="17621" class="Symbol">=</a> <a id="17623" class="Symbol">(</a><a id="17624" href="#17624" class="Bound">i</a> <a id="17626" class="Symbol">:</a> <a id="17628" href="#17617" class="Bound">E</a><a id="17629" class="Symbol">)</a> <a id="17631" class="Symbol">→</a> <a id="17633" href="#17619" class="Bound">A</a> <a id="17635" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="17637" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">Σ[</a> <a id="17640" href="#17640" class="Bound">length</a> <a id="17647" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">⦂</a> <a id="17649" href="#17617" class="Bound">E</a> <a id="17651" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">]</a> <a id="17653" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">×</a> <a id="17655" class="Symbol">(</a><a id="17656" href="#17624" class="Bound">i</a> <a id="17658" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#2522" class="Function Operator">≺</a> <a id="17660" href="#17640" class="Bound">length</a><a id="17666" class="Symbol">)</a>
</pre>
<p>This is actually isomorphic to the previous definition, but we return
the absolute value of the next segment, rather than the distance to the
next segment.</p>
<pre class="Agda"><a id="𝒜-iso"></a><a id="17834" href="#17834" class="Function">𝒜-iso</a> <a id="17840" class="Symbol">:</a> <a id="17842" class="Symbol">⦃</a> <a id="17844" href="#17844" class="Bound">_</a> <a id="17846" class="Symbol">:</a> <a id="17848" href="#12529" class="Record">Monus</a> <a id="17854" href="#7614" class="Generalizable">E</a> <a id="17856" class="Symbol">⦄</a> <a id="17858" class="Symbol">→</a> <a id="17860" href="#17567" class="Function">𝒜-Ind</a> <a id="17866" href="#7614" class="Generalizable">E</a> <a id="17868" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="17870" href="../code/depth-comonads/DepthComonads.Function.Isomorphism.html#308" class="Function Operator">⇔</a> <a id="17872" href="#15166" class="Function">Ind</a> <a id="17876" href="#7614" class="Generalizable">E</a> <a id="17878" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="17880" href="#17834" class="Function">𝒜-iso</a> <a id="17886" class="Symbol">.</a><a id="17887" href="Cubical.Foundations.Isomorphism.html#882" class="Field">fun</a> <a id="17891" href="#17891" class="Bound">xs</a> <a id="17894" href="#17894" class="Bound">i</a> <a id="17896" class="Symbol">=</a>
  <a id="17900" class="Keyword">let</a> <a id="17904" href="#17904" class="Bound">x</a> <a id="17906" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17908" href="#17908" class="Bound">s</a> <a id="17910" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17912" href="#17912" class="Bound">k</a> <a id="17914" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17916" href="#17916" class="Bound">s≡i∙k</a> <a id="17922" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17924" href="#17924" class="Bound">k≢ε</a> <a id="17928" class="Symbol">=</a> <a id="17930" href="#17891" class="Bound">xs</a> <a id="17933" href="#17894" class="Bound">i</a>
  <a id="17937" class="Keyword">in</a>  <a id="17941" href="#17904" class="Bound">x</a> <a id="17943" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17945" href="#17912" class="Bound">k</a> <a id="17947" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17949" href="#17924" class="Bound">k≢ε</a>
<a id="17953" href="#17834" class="Function">𝒜-iso</a> <a id="17959" class="Symbol">.</a><a id="17960" href="Cubical.Foundations.Isomorphism.html#898" class="Field">inv</a> <a id="17964" href="#17964" class="Bound">xs</a> <a id="17967" href="#17967" class="Bound">i</a> <a id="17969" class="Symbol">=</a>
  <a id="17973" class="Keyword">let</a> <a id="17977" href="#17977" class="Bound">x</a> <a id="17979" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17981" href="#17981" class="Bound">s</a> <a id="17983" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="17985" href="#17985" class="Bound">s≢ε</a> <a id="17989" class="Symbol">=</a> <a id="17991" href="#17964" class="Bound">xs</a> <a id="17994" href="#17967" class="Bound">i</a>
  <a id="17998" class="Keyword">in</a>  <a id="18002" href="#17977" class="Bound">x</a> <a id="18004" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18006" href="#17967" class="Bound">i</a> <a id="18008" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="18010" href="#17981" class="Bound">s</a> <a id="18012" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18014" href="#17981" class="Bound">s</a> <a id="18016" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18018" href="Cubical.Foundations.Id.html#560" class="Function">refl</a> <a id="18023" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18025" href="#17985" class="Bound">s≢ε</a>
<a id="18029" href="#17834" class="Function">𝒜-iso</a> <a id="18035" class="Symbol">.</a><a id="18036" href="Cubical.Foundations.Isomorphism.html#914" class="Field">rightInv</a> <a id="18045" class="Symbol">_</a> <a id="18047" class="Symbol">=</a> <a id="18049" href="Cubical.Foundations.Id.html#560" class="Function">refl</a>
<a id="18054" href="#17834" class="Function">𝒜-iso</a> <a id="18060" class="Symbol">.</a><a id="18061" href="Cubical.Foundations.Isomorphism.html#945" class="Field">leftInv</a>  <a id="18070" href="#18070" class="Bound">xs</a> <a id="18073" href="#18073" class="Bound">p</a> <a id="18075" href="#18075" class="Bound">i</a> <a id="18077" class="Symbol">=</a>
  <a id="18082" class="Keyword">let</a> <a id="18086" href="#18086" class="Bound">x</a> <a id="18088" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18090" href="#18090" class="Bound">s</a>           <a id="18102" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18104" href="#18104" class="Bound">k</a> <a id="18106" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18108" href="#18108" class="Bound">s≡i∙k</a>                   <a id="18132" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18134" href="#18134" class="Bound">k≢ε</a> <a id="18138" class="Symbol">=</a> <a id="18140" href="#18070" class="Bound">xs</a> <a id="18143" href="#18075" class="Bound">i</a>
  <a id="18147" class="Keyword">in</a>  <a id="18151" href="#18086" class="Bound">x</a> <a id="18153" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18155" href="#18108" class="Bound">s≡i∙k</a> <a id="18161" class="Symbol">(</a><a id="18162" href="Cubical.Core.Primitives.html#539" class="Primitive Operator">~</a> <a id="18164" href="#18073" class="Bound">p</a><a id="18165" class="Symbol">)</a> <a id="18167" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18169" href="#18104" class="Bound">k</a> <a id="18171" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18173" class="Symbol">(λ</a> <a id="18176" href="#18176" class="Bound">q</a> <a id="18178" class="Symbol">→</a> <a id="18180" href="#18108" class="Bound">s≡i∙k</a> <a id="18186" class="Symbol">(</a><a id="18187" href="Cubical.Core.Primitives.html#539" class="Primitive Operator">~</a> <a id="18189" href="#18073" class="Bound">p</a> <a id="18191" href="Cubical.Core.Primitives.html#490" class="Primitive Operator">∨</a> <a id="18193" href="#18176" class="Bound">q</a><a id="18194" class="Symbol">))</a> <a id="18197" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18199" href="#18134" class="Bound">k≢ε</a>
</pre>
<p>The implementation of <code>join</code> on this type is the
following:</p>
<pre class="Agda"><a id="𝒜-join"></a><a id="18271" href="#18271" class="Function">𝒜-join</a> <a id="18278" class="Symbol">:</a> <a id="18280" class="Symbol">⦃</a> <a id="18282" href="#18282" class="Bound">_</a> <a id="18284" class="Symbol">:</a> <a id="18286" href="#12529" class="Record">Monus</a> <a id="18292" href="#7614" class="Generalizable">E</a> <a id="18294" class="Symbol">⦄</a> <a id="18296" class="Symbol">→</a> <a id="18298" href="#17567" class="Function">𝒜-Ind</a> <a id="18304" href="#7614" class="Generalizable">E</a> <a id="18306" class="Symbol">(</a><a id="18307" href="#17567" class="Function">𝒜-Ind</a> <a id="18313" href="#7614" class="Generalizable">E</a> <a id="18315" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="18316" class="Symbol">)</a> <a id="18318" class="Symbol">→</a> <a id="18320" href="#17567" class="Function">𝒜-Ind</a> <a id="18326" href="#7614" class="Generalizable">E</a> <a id="18328" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="18330" href="#18271" class="Function">𝒜-join</a> <a id="18337" href="#18337" class="Bound">xs</a> <a id="18340" href="#18340" class="Bound">i</a> <a id="18342" class="Symbol">=</a>
  <a id="18346" class="Keyword">let</a> <a id="18350" href="#18350" class="Bound">x</a> <a id="18352" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18354" href="#18354" class="Bound">j</a> <a id="18356" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18358" href="#18358" class="Bound">i&lt;j</a> <a id="18362" class="Symbol">=</a> <a id="18364" href="#18337" class="Bound">xs</a> <a id="18367" href="#18340" class="Bound">i</a>
      <a id="18375" href="#18375" class="Bound">y</a> <a id="18377" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18379" href="#18379" class="Bound">k</a> <a id="18381" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18383" href="#18383" class="Bound">k&lt;j</a> <a id="18387" class="Symbol">=</a> <a id="18389" href="#18350" class="Bound">x</a> <a id="18391" href="#18354" class="Bound">j</a>
  <a id="18395" class="Keyword">in</a>  <a id="18399" href="#18375" class="Bound">y</a> <a id="18401" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18403" href="#18379" class="Bound">k</a> <a id="18405" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="18407" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#5397" class="Function">≺-trans</a> <a id="18415" href="#18358" class="Bound">i&lt;j</a> <a id="18419" href="#18383" class="Bound">k&lt;j</a>
</pre>
<p>This is the same definition of <code>join</code> as for
<code>State</code>, modulo the <code>&lt;</code> fiddling.</p>
<p>On a stream, this operation corresponds to taking a stream of streams
and collapsing it to a single stream. It does this by taking a prefix of
each internal stream equal in size to the segment of the outer entry.
Diagrammatically:</p>
<pre class="ascii-art">
┏━━━━━━━━━━┳━━━━━━┳━━━━━━┉
┃xs        ┃ys    ┃zs    ┉
┡━━━━━━━━━━╇━━━━━━╇━━━━━━┉
╵⇤a╌╌╌╌╌╌╌⇥╵⇤b╌╌╌⇥╵⇤c╌╌╌╌┈
          ╱        ╲
         ╱          ╲
        ╱            ╲
       ╱              ╲
      ╱                ╲
     ╷⇤b╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌⇥╷
     ┢━━━━━━━┳━━━━━━┳━━━┷┉
ys = ┃xʸ     ┃yʸ    ┃zʸ  ┉
     ┡━━━━━━━╇━━━━━━╇━━━━┉
     ╵⇤aʸ╌╌╌⇥╵⇤bʸ╌╌⇥╵⇤cʸ╌┈
</pre>
<p>Here we start with a stream consisting of the streams
<code>xs</code>, <code>ys</code>, and <code>zs</code>, followed by some
other streams. Zooming in on <code>ys</code>, we see that it is in a
segment of length <code>b</code>, and consists of three values
<code>xʸ</code>, <code>yʸ</code>, and <code>zʸ</code>, with segment
lengths <code>aʸ</code>, <code>bʸ</code>, and <code>cʸ</code>,
respectively.</p>
<p>Calling <code>join</code> on this stream will give us the following
stream:</p>
<pre class="ascii-art">
┏━┉━┳━━━━┳━━━━┳━━━━━┳━━━━┉
┃ ┉ ┃xʸ  ┃yʸ  ┃zʸ   ┃    ┉
┡━┉━╇━━━━╇━━━━╇━━━━━╇━━━━┉
│   │⇤aʸ⇥╵⇤bʸ⇥╵⇤╌╌┈⇥│
╵⇤a⇥╵⇤b╌╌╌╌╌╌╌╌╌╌╌╌⇥╵⇤c╌╌┈
</pre>
<p>Again, we’re focusing on the <code>ys</code> section here, which
occupies the segment from <code>a</code> to <code>a ∙ b</code>. After
<code>join</code>, this segment is occupied by three elements,
<code>xʸ</code>, <code>yʸ</code>, and <code>zʸ</code>.</p>
<p>Notice that this isn’t quite the normal <code>join</code> on streams.
That <code>join</code> takes a stream of streams, and turns the
<code>i</code>th entry into the <code>i</code>th entry in the underlying
stream. It’s a diagonalisation, in other words.</p>
<p>This one is kind of similar, but it takes chunks of the outer
stream.</p>
<h1 id="theory">Theory</h1>
<p>All of this so far is very hand-wavy. We have an almost isomorphism
(a split surjection, to be precise), but not much in the way of concrete
theoretical insights, just some vague gesturing towards spatial
metaphors and so on.</p>
<p>Thankfully, there are two separate areas of more serious research
that seem related to the stuff I’ve talked about here. The first is
update monads and directed containers, and the second is graded
comonads. I think I understand graded comonads and the related work
better out of the two, but update monads and directed containers seems
more closely related to what I’m doing here.</p>
<h1 id="update-monads-and-directed-containers">Update Monads and
Directed Containers</h1>
<p>There are a few papers on this topic: <span class="citation"
data-cites="ahman_when_2012">Ahman, Chapman, and Uustalu (<a
href="#ref-ahman_when_2012" role="doc-biblioref">2012</a>)</span>, <span
class="citation"
data-cites="ahman_distributive_2013 ahman_update_2014 ahman_directed_2016">Ahman
and Uustalu (<a href="#ref-ahman_distributive_2013"
role="doc-biblioref">2013</a>; <a href="#ref-ahman_update_2014"
role="doc-biblioref">Ahman and Uustalu 2014</a>; <a
href="#ref-ahman_directed_2016" role="doc-biblioref">Ahman and Uustalu
2016</a>)</span>.</p>
<p>The first of these, “When Is a Container a Comonad?” constructs, as
the title suggests, a class for containers which are comonads in a
standard way.</p>
<p>Here’s the definition of a container:</p>
<pre class="Agda"><a id="Container"></a><a id="21080" href="#21080" class="Function">Container</a> <a id="21090" class="Symbol">:</a> <a id="21092" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type₁</a>
<a id="21098" href="#21080" class="Function">Container</a> <a id="21108" class="Symbol">=</a> <a id="21110" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">Σ[</a> <a id="21113" href="#21113" class="Bound">Shape</a> <a id="21119" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">⦂</a> <a id="21121" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="21126" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">]</a> <a id="21128" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">×</a> <a id="21130" class="Symbol">(</a><a id="21131" href="#21113" class="Bound">Shape</a> <a id="21137" class="Symbol">→</a> <a id="21139" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="21143" class="Symbol">)</a>

<a id="⟦_⟧"></a><a id="21146" href="#21146" class="Function Operator">⟦_⟧</a> <a id="21150" class="Symbol">:</a> <a id="21152" href="#21080" class="Function">Container</a> <a id="21162" class="Symbol">→</a> <a id="21164" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="21169" class="Symbol">→</a> <a id="21171" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="21176" href="#21146" class="Function Operator">⟦</a> <a id="21178" href="#21178" class="Bound">S</a> <a id="21180" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="21182" href="#21182" class="Bound">P</a> <a id="21184" href="#21146" class="Function Operator">⟧</a> <a id="21186" href="#21186" class="Bound">X</a> <a id="21188" class="Symbol">=</a> <a id="21190" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">Σ[</a> <a id="21193" href="#21193" class="Bound">s</a> <a id="21195" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">⦂</a> <a id="21197" href="#21178" class="Bound">S</a> <a id="21199" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">]</a> <a id="21201" href="../code/depth-comonads/DepthComonads.Sigma.html#407" class="Function">×</a> <a id="21203" class="Symbol">(</a><a id="21204" href="#21182" class="Bound">P</a> <a id="21206" href="#21193" class="Bound">s</a> <a id="21208" class="Symbol">→</a> <a id="21210" href="#21186" class="Bound">X</a><a id="21211" class="Symbol">)</a>
</pre>
<p>Containers are a generic way to describe a class of well-behaved
functors. Any container is a pair of a shape and position. Lists, for
instance, are containers, where their shape is described by the natural
numbers (the shape here is the length of the list). The positions in
such a list are the numbers smaller than the length, in
dependently-typed programming we usually use the <code>Fin</code> type
for this:</p>
<pre class="Agda"><a id="Fin"></a><a id="21625" href="#21625" class="Function">Fin</a> <a id="21629" class="Symbol">:</a> <a id="21631" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a> <a id="21633" class="Symbol">→</a> <a id="21635" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="21640" href="#21625" class="Function">Fin</a> <a id="21644" href="#21644" class="Bound">n</a> <a id="21646" class="Symbol">=</a> <a id="21648" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">∃</a> <a id="21650" href="#21650" class="Bound">m</a> <a id="21652" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">×</a> <a id="21654" class="Symbol">(</a><a id="21655" href="#21650" class="Bound">m</a> <a id="21657" href="../code/depth-comonads/DepthComonads.Nat.html#220" class="Function Operator">&lt;ℕ</a> <a id="21660" href="#21644" class="Bound">n</a><a id="21661" class="Symbol">)</a>
</pre>
<p>The container version of lists, then, is the following:</p>
<pre class="Agda"><a id="ℒ𝒾𝓈𝓉"></a><a id="21729" href="#21729" class="Function">ℒ𝒾𝓈𝓉</a> <a id="21734" class="Symbol">:</a> <a id="21736" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="21741" class="Symbol">→</a> <a id="21743" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="21748" href="#21729" class="Function">ℒ𝒾𝓈𝓉</a> <a id="21753" class="Symbol">=</a> <a id="21755" href="#21146" class="Function Operator">⟦</a> <a id="21757" href="../code/depth-comonads/Agda.Builtin.Nat.html#192" class="Datatype">ℕ</a> <a id="21759" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="21761" href="#21625" class="Function">Fin</a> <a id="21765" href="#21146" class="Function Operator">⟧</a>
</pre>
<p>Here’s the same list represented in the standard way, and as a
container:</p>
<div class="row">
<div class="column">
<pre class="Agda"><a id="someBools"></a><a id="21890" href="#21890" class="Function">someBools</a> <a id="21900" class="Symbol">:</a> <a id="21902" href="../code/depth-comonads/Agda.Builtin.List.html#148" class="Datatype">List</a> <a id="21907" href="../code/depth-comonads/Agda.Builtin.Bool.html#163" class="Datatype">Bool</a>
<a id="21912" href="#21890" class="Function">someBools</a> <a id="21922" class="Symbol">=</a> <a id="21924" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a> <a id="21929" href="../code/depth-comonads/Agda.Builtin.List.html#200" class="InductiveConstructor Operator">∷</a> <a id="21931" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a> <a id="21936" href="../code/depth-comonads/Agda.Builtin.List.html#200" class="InductiveConstructor Operator">∷</a> <a id="21938" href="../code/depth-comonads/Agda.Builtin.Bool.html#182" class="InductiveConstructor">false</a> <a id="21944" href="../code/depth-comonads/Agda.Builtin.List.html#200" class="InductiveConstructor Operator">∷</a> <a id="21946" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a> <a id="21951" href="../code/depth-comonads/Agda.Builtin.List.html#200" class="InductiveConstructor Operator">∷</a> <a id="21953" href="../code/depth-comonads/Agda.Builtin.List.html#185" class="InductiveConstructor">[]</a>
</pre>
</div>
<div class="column">
<pre class="Agda"><a id="someBools′"></a><a id="21992" href="#21992" class="Function">someBools′</a> <a id="22003" class="Symbol">:</a> <a id="22005" href="#21729" class="Function">ℒ𝒾𝓈𝓉</a> <a id="22010" href="../code/depth-comonads/Agda.Builtin.Bool.html#163" class="Datatype">Bool</a>
<a id="22015" href="#21992" class="Function">someBools′</a> <a id="22026" class="Symbol">.</a><a id="22027" href="../code/depth-comonads/Agda.Builtin.Sigma.html#252" class="Field">fst</a> <a id="22031" class="Symbol">=</a> <a id="22033" class="Number">4</a>
<a id="22035" href="#21992" class="Function">someBools′</a> <a id="22046" class="Symbol">.</a><a id="22047" href="../code/depth-comonads/Agda.Builtin.Sigma.html#264" class="Field">snd</a> <a id="22051" class="Symbol">(</a><a id="22052" class="Number">0</a> <a id="22054" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="22056" class="Symbol">_)</a> <a id="22059" class="Symbol">=</a> <a id="22061" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a>
<a id="22066" href="#21992" class="Function">someBools′</a> <a id="22077" class="Symbol">.</a><a id="22078" href="../code/depth-comonads/Agda.Builtin.Sigma.html#264" class="Field">snd</a> <a id="22082" class="Symbol">(</a><a id="22083" class="Number">1</a> <a id="22085" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="22087" class="Symbol">_)</a> <a id="22090" class="Symbol">=</a> <a id="22092" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a>
<a id="22097" href="#21992" class="Function">someBools′</a> <a id="22108" class="Symbol">.</a><a id="22109" href="../code/depth-comonads/Agda.Builtin.Sigma.html#264" class="Field">snd</a> <a id="22113" class="Symbol">(</a><a id="22114" class="Number">2</a> <a id="22116" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="22118" class="Symbol">_)</a> <a id="22121" class="Symbol">=</a> <a id="22123" href="../code/depth-comonads/Agda.Builtin.Bool.html#182" class="InductiveConstructor">false</a>
<a id="22129" href="#21992" class="Function">someBools′</a> <a id="22140" class="Symbol">.</a><a id="22141" href="../code/depth-comonads/Agda.Builtin.Sigma.html#264" class="Field">snd</a> <a id="22145" class="Symbol">(</a><a id="22146" class="Number">3</a> <a id="22148" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="22150" class="Symbol">_)</a> <a id="22153" class="Symbol">=</a> <a id="22155" href="../code/depth-comonads/Agda.Builtin.Bool.html#188" class="InductiveConstructor">true</a>
</pre>
</div>
</div>
<p>The benefit of using containers is that it gives a standard, generic,
and composable way to construct functors that have some nice properties
(like strict positivity). They’re pretty annoying to use in practice,
though, which is a shame.</p>
<p>Directed containers are container that have three extra
operations.</p>
<ul>
<li>A <code>tail</code>-like operation, where a position can be
converted into the shape of containers that the suffix from that
position.</li>
<li>A <code>head</code>-like operation, where you can always return the
root position.</li>
<li>A <code>+</code>-like operation, where you take a position on some
tail and translate it into a position on the original container, by
adding it.</li>
</ul>
<p>As the paper observes, these are very similar to a
“dependently-typed” version of the monoid methods. This seems to me to
be very similar to the indexing stuff we were doing earlier on.</p>
<p>The real interesting part is in the paper “Update Monads:
Cointerpreting Directed Containers” <span class="citation"
data-cites="ahman_update_2014">(<a href="#ref-ahman_update_2014"
role="doc-biblioref">Ahman and Uustalu 2014</a>)</span>. This paper
presents a variant on state monads, called “update monads”.</p>
<p>These are monads that use a monoid action:</p>
<pre class="Agda"><a id="23249" class="Keyword">record</a> <a id="RightAction"></a><a id="23256" href="#23256" class="Record">RightAction</a> <a id="23268" class="Symbol">(</a><a id="23269" href="#23269" class="Bound">𝑃</a> <a id="23271" class="Symbol">:</a> <a id="23273" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="23277" class="Symbol">)</a> <a id="23279" class="Symbol">(</a><a id="23280" href="#23280" class="Bound">𝑆</a> <a id="23282" class="Symbol">:</a> <a id="23284" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="23288" class="Symbol">)</a> <a id="23290" class="Symbol">:</a> <a id="23292" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="23297" class="Keyword">where</a>
  <a id="23305" class="Keyword">infixl</a> <a id="23312" class="Number">5</a> <a id="23314" href="#23359" class="Field Operator">_↓_</a>
  <a id="23320" class="Keyword">field</a>
    <a id="23330" class="Symbol">⦃</a> <a id="RightAction.monoid⟨𝑃⟩"></a><a id="23332" href="#23332" class="Field">monoid⟨𝑃⟩</a> <a id="23342" class="Symbol">⦄</a> <a id="23344" class="Symbol">:</a> <a id="23346" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="23353" href="#23269" class="Bound">𝑃</a>
    <a id="RightAction._↓_"></a><a id="23359" href="#23359" class="Field Operator">_↓_</a> <a id="23363" class="Symbol">:</a> <a id="23365" href="#23280" class="Bound">𝑆</a> <a id="23367" class="Symbol">→</a> <a id="23369" href="#23269" class="Bound">𝑃</a> <a id="23371" class="Symbol">→</a> <a id="23373" href="#23280" class="Bound">𝑆</a>
    <a id="RightAction.↓-assoc"></a><a id="23379" href="#23379" class="Field">↓-assoc</a> <a id="23387" class="Symbol">:</a> <a id="23389" class="Symbol">∀</a> <a id="23391" href="#23391" class="Bound">x</a> <a id="23393" href="#23393" class="Bound">y</a> <a id="23395" href="#23395" class="Bound">z</a> <a id="23397" class="Symbol">→</a> <a id="23399" class="Symbol">(</a><a id="23400" href="#23391" class="Bound">x</a> <a id="23402" href="#23359" class="Field Operator">↓</a> <a id="23404" href="#23393" class="Bound">y</a><a id="23405" class="Symbol">)</a> <a id="23407" href="#23359" class="Field Operator">↓</a> <a id="23409" href="#23395" class="Bound">z</a> <a id="23411" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="23413" href="#23391" class="Bound">x</a> <a id="23415" href="#23359" class="Field Operator">↓</a> <a id="23417" class="Symbol">(</a><a id="23418" href="#23393" class="Bound">y</a> <a id="23420" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="23422" href="#23395" class="Bound">z</a><a id="23423" class="Symbol">)</a>
    <a id="RightAction.↓-ε"></a><a id="23429" href="#23429" class="Field">↓-ε</a> <a id="23433" class="Symbol">:</a> <a id="23435" class="Symbol">∀</a> <a id="23437" href="#23437" class="Bound">x</a> <a id="23439" class="Symbol">→</a> <a id="23441" href="#23437" class="Bound">x</a> <a id="23443" href="#23359" class="Field Operator">↓</a> <a id="23445" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="23447" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="23449" href="#23437" class="Bound">x</a>
</pre>
<!--
<pre class="Agda"><a id="23465" class="Keyword">open</a> <a id="23470" href="#23256" class="Module">RightAction</a> <a id="23482" class="Symbol">⦃</a> <a id="23484" class="Symbol">...</a> <a id="23488" class="Symbol">⦄</a>
<a id="23490" class="Keyword">variable</a> <a id="23499" href="#23499" class="Generalizable">𝑃</a> <a id="23501" href="#23501" class="Generalizable">𝑆</a> <a id="23503" class="Symbol">:</a> <a id="23505" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
</pre>-->
<p>A (right) monoid action is a monoid along with a function
<code>↓</code> that “acts” on some other set, in a way that coheres with
the monoid methods. The definition is given above. One way to think
about it is that if a monoid <code>𝑃</code> has an action on
<code>𝑆</code> it means that elements of <code>𝑃</code> can kind of be
transformed into elements of <code>𝑆 → 𝑆</code>.</p>
This can be used to construct a monad that looks suspiciously like the
state monad:
<pre class="Agda"><a id="Upd"></a><a id="23934" href="#23934" class="Function">Upd</a> <a id="23938" class="Symbol">:</a> <a id="23940" class="Symbol">(</a><a id="23941" href="#23941" class="Bound">𝑃</a> <a id="23943" href="#23943" class="Bound">𝑆</a> <a id="23945" class="Symbol">:</a> <a id="23947" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="23951" class="Symbol">)</a> <a id="23953" class="Symbol">⦃</a> <a id="23955" href="#23955" class="Bound">_</a> <a id="23957" class="Symbol">:</a> <a id="23959" href="#23256" class="Record">RightAction</a> <a id="23971" href="#23941" class="Bound">𝑃</a> <a id="23973" href="#23943" class="Bound">𝑆</a> <a id="23975" class="Symbol">⦄</a> <a id="23977" class="Symbol">→</a> <a id="23979" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="23984" class="Symbol">→</a> <a id="23986" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="23991" href="#23934" class="Function">Upd</a> <a id="23995" href="#23995" class="Bound">𝑃</a> <a id="23997" href="#23997" class="Bound">𝑆</a> <a id="23999" href="#23999" class="Bound">X</a> <a id="24001" class="Symbol">=</a> <a id="24003" href="#23997" class="Bound">𝑆</a> <a id="24005" class="Symbol">→</a> <a id="24007" href="#23995" class="Bound">𝑃</a> <a id="24009" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="24011" href="#23999" class="Bound">X</a>

<a id="η"></a><a id="24014" href="#24014" class="Function">η</a> <a id="24016" class="Symbol">:</a> <a id="24018" class="Symbol">⦃</a> <a id="24020" href="#24020" class="Bound">_</a> <a id="24022" class="Symbol">:</a> <a id="24024" href="#23256" class="Record">RightAction</a> <a id="24036" href="#23499" class="Generalizable">𝑃</a> <a id="24038" href="#23501" class="Generalizable">𝑆</a> <a id="24040" class="Symbol">⦄</a> <a id="24042" class="Symbol">→</a> <a id="24044" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="24046" class="Symbol">→</a> <a id="24048" href="#23934" class="Function">Upd</a> <a id="24052" href="#23499" class="Generalizable">𝑃</a> <a id="24054" href="#23501" class="Generalizable">𝑆</a> <a id="24056" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="24058" href="#24014" class="Function">η</a> <a id="24060" href="#24060" class="Bound">x</a> <a id="24062" href="#24062" class="Bound">s</a> <a id="24064" class="Symbol">=</a> <a id="24066" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="24068" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="24070" href="#24060" class="Bound">x</a>

<a id="μ"></a><a id="24073" href="#24073" class="Function">μ</a> <a id="24075" class="Symbol">:</a> <a id="24077" class="Symbol">⦃</a> <a id="24079" href="#24079" class="Bound">_</a> <a id="24081" class="Symbol">:</a> <a id="24083" href="#23256" class="Record">RightAction</a> <a id="24095" href="#23499" class="Generalizable">𝑃</a> <a id="24097" href="#23501" class="Generalizable">𝑆</a> <a id="24099" class="Symbol">⦄</a> <a id="24101" class="Symbol">→</a> <a id="24103" href="#23934" class="Function">Upd</a> <a id="24107" href="#23499" class="Generalizable">𝑃</a> <a id="24109" href="#23501" class="Generalizable">𝑆</a> <a id="24111" class="Symbol">(</a><a id="24112" href="#23934" class="Function">Upd</a> <a id="24116" href="#23499" class="Generalizable">𝑃</a> <a id="24118" href="#23501" class="Generalizable">𝑆</a> <a id="24120" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a><a id="24121" class="Symbol">)</a> <a id="24123" class="Symbol">→</a> <a id="24125" href="#23934" class="Function">Upd</a> <a id="24129" href="#23499" class="Generalizable">𝑃</a> <a id="24131" href="#23501" class="Generalizable">𝑆</a> <a id="24133" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="24135" href="#24073" class="Function">μ</a> <a id="24137" href="#24137" class="Bound">xs</a> <a id="24140" href="#24140" class="Bound">s</a> <a id="24142" class="Symbol">=</a> <a id="24144" class="Keyword">let</a> <a id="24148" href="#24148" class="Bound">p</a> <a id="24150" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="24152" href="#24152" class="Bound">x</a> <a id="24154" class="Symbol">=</a> <a id="24156" href="#24137" class="Bound">xs</a> <a id="24159" href="#24140" class="Bound">s</a>
             <a id="24174" href="#24174" class="Bound">q</a> <a id="24176" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="24178" href="#24178" class="Bound">y</a> <a id="24180" class="Symbol">=</a> <a id="24182" href="#24152" class="Bound">x</a> <a id="24184" class="Symbol">(</a><a id="24185" href="#24140" class="Bound">s</a> <a id="24187" href="#23359" class="Field Operator">↓</a> <a id="24189" href="#24148" class="Bound">p</a><a id="24190" class="Symbol">)</a>
         <a id="24201" class="Keyword">in</a>  <a id="24205" class="Symbol">(</a><a id="24206" href="#24148" class="Bound">p</a> <a id="24208" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="24210" href="#24174" class="Bound">q</a> <a id="24212" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="24214" href="#24178" class="Bound">y</a><a id="24215" class="Symbol">)</a>
</pre>
<p>It turns out that the dependently-typed version of this gives
directed containers.</p>
<h1 id="grading-and-the-cofree-comonad">Grading and the Cofree
Comonad</h1>
<p>I’m still in the early stages of understanding all of this material,
but at the moment graded comonads and transformers are concepts that I’m
much more familiar and comfortable with.</p>
<p>The idea behind graded monads and comonads is similar to the idea
behind any indexed monad: we’re adding an extra type parameter to the
monad or type, which can constrain the operations involved. The
<em>graded</em> monads and comonads use a monoid as that index. This
works particularly nicely, in my opinion: just allowing any index at all
sometimes feels a little unstructured. The grading construction seems to
constrain things to the right degree: the use of the monoid, as well,
works really well with comonads.</p>
<p>That preamble out of the way, here’s the definition of a graded
comonad:</p>
<!--
<pre class="Agda"><a id="25119" class="Keyword">variable</a> <a id="25128" href="#25128" class="Generalizable">x</a> <a id="25130" href="#25130" class="Generalizable">y</a> <a id="25132" href="#25132" class="Generalizable">z</a> <a id="25134" class="Symbol">:</a> <a id="25136" href="#23501" class="Generalizable">𝑆</a>
<a id="25138" class="Keyword">variable</a> <a id="25147" href="#25147" class="Generalizable">A₀</a> <a id="25150" href="#25150" class="Generalizable">B₀</a> <a id="25153" href="#25153" class="Generalizable">C₀</a> <a id="25156" href="#25156" class="Generalizable">D₀</a> <a id="25159" class="Symbol">:</a> <a id="25161" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
</pre>-->
<pre class="Agda"><a id="25179" class="Keyword">record</a> <a id="GradedComonad"></a><a id="25186" href="#25186" class="Record">GradedComonad</a> <a id="25200" class="Symbol">(</a><a id="25201" href="#25201" class="Bound">𝑆</a> <a id="25203" class="Symbol">:</a> <a id="25205" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="25209" class="Symbol">)</a> <a id="25211" class="Symbol">⦃</a> <a id="25213" href="#25213" class="Bound">_</a> <a id="25215" class="Symbol">:</a> <a id="25217" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="25224" href="#25201" class="Bound">𝑆</a> <a id="25226" class="Symbol">⦄</a> <a id="25228" class="Symbol">(</a><a id="25229" href="#25229" class="Bound">𝐶</a> <a id="25231" class="Symbol">:</a> <a id="25233" href="#25201" class="Bound">𝑆</a> <a id="25235" class="Symbol">→</a> <a id="25237" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="25242" class="Symbol">→</a> <a id="25244" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="25248" class="Symbol">)</a> <a id="25250" class="Symbol">:</a> <a id="25252" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type₁</a> <a id="25258" class="Keyword">where</a>
  <a id="25266" class="Keyword">field</a>
    <a id="GradedComonad.extract"></a><a id="25276" href="#25276" class="Field">extract</a> <a id="25284" class="Symbol">:</a> <a id="25286" href="#25229" class="Bound">𝐶</a> <a id="25288" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="25290" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="25292" class="Symbol">→</a> <a id="25294" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
    <a id="GradedComonad.extend"></a><a id="25300" href="#25300" class="Field">extend</a>  <a id="25308" class="Symbol">:</a> <a id="25310" class="Symbol">(</a><a id="25311" href="#25229" class="Bound">𝐶</a> <a id="25313" href="#25130" class="Generalizable">y</a> <a id="25315" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="25317" class="Symbol">→</a> <a id="25319" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a><a id="25320" class="Symbol">)</a> <a id="25322" class="Symbol">→</a> <a id="25324" href="#25229" class="Bound">𝐶</a> <a id="25326" class="Symbol">(</a><a id="25327" href="#25128" class="Generalizable">x</a> <a id="25329" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="25331" href="#25130" class="Generalizable">y</a><a id="25332" class="Symbol">)</a> <a id="25334" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="25336" class="Symbol">→</a> <a id="25338" href="#25229" class="Bound">𝐶</a> <a id="25340" href="#25128" class="Generalizable">x</a> <a id="25342" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a>
</pre>
This also has a few laws, which are expressed cleaner using cokleisli
composition:
<pre class="Agda">  <a id="GradedComonad._=&lt;=_"></a><a id="25437" href="#25437" class="Function Operator">_=&lt;=_</a> <a id="25443" class="Symbol">:</a> <a id="25445" class="Symbol">(</a><a id="25446" href="#25229" class="Bound">𝐶</a> <a id="25448" href="#25128" class="Generalizable">x</a> <a id="25450" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a> <a id="25452" class="Symbol">→</a> <a id="25454" href="../code/depth-comonads/DepthComonads.Level.html#297" class="Generalizable">C</a><a id="25455" class="Symbol">)</a> <a id="25457" class="Symbol">→</a> <a id="25459" class="Symbol">(</a><a id="25460" href="#25229" class="Bound">𝐶</a> <a id="25462" href="#25130" class="Generalizable">y</a> <a id="25464" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="25466" class="Symbol">→</a> <a id="25468" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a><a id="25469" class="Symbol">)</a> <a id="25471" class="Symbol">→</a> <a id="25473" href="#25229" class="Bound">𝐶</a> <a id="25475" class="Symbol">(</a><a id="25476" href="#25128" class="Generalizable">x</a> <a id="25478" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="25480" href="#25130" class="Generalizable">y</a><a id="25481" class="Symbol">)</a> <a id="25483" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="25485" class="Symbol">→</a> <a id="25487" href="../code/depth-comonads/DepthComonads.Level.html#297" class="Generalizable">C</a>
  <a id="25491" class="Symbol">(</a><a id="25492" href="#25492" class="Bound">g</a> <a id="25494" href="#25437" class="Function Operator">=&lt;=</a> <a id="25498" href="#25498" class="Bound">f</a><a id="25499" class="Symbol">)</a> <a id="25501" href="#25501" class="Bound">x</a> <a id="25503" class="Symbol">=</a> <a id="25505" href="#25492" class="Bound">g</a> <a id="25507" class="Symbol">(</a><a id="25508" href="#25300" class="Field">extend</a> <a id="25515" href="#25498" class="Bound">f</a> <a id="25517" href="#25501" class="Bound">x</a><a id="25518" class="Symbol">)</a>

  <a id="25523" class="Keyword">field</a>
    <a id="GradedComonad.idˡ"></a><a id="25533" href="#25533" class="Field">idˡ</a> <a id="25537" class="Symbol">:</a> <a id="25539" class="Symbol">(</a><a id="25540" href="#25540" class="Bound">f</a> <a id="25542" class="Symbol">:</a> <a id="25544" href="#25229" class="Bound">𝐶</a> <a id="25546" href="#25128" class="Generalizable">x</a> <a id="25548" href="#25147" class="Generalizable">A₀</a> <a id="25551" class="Symbol">→</a> <a id="25553" href="#25150" class="Generalizable">B₀</a><a id="25555" class="Symbol">)</a> <a id="25557" class="Symbol">→</a> <a id="25559" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#190" class="Postulate">PathP</a> <a id="25565" class="Symbol">(λ</a> <a id="25568" href="#25568" class="Bound">i</a> <a id="25570" class="Symbol">→</a> <a id="25572" href="#25229" class="Bound">𝐶</a> <a id="25574" class="Symbol">(</a><a id="25575" href="../code/depth-comonads/DepthComonads.Algebra.html#1623" class="Field">ε∙</a> <a id="25578" href="#25128" class="Generalizable">x</a> <a id="25580" href="#25568" class="Bound">i</a><a id="25581" class="Symbol">)</a> <a id="25583" href="#25147" class="Generalizable">A₀</a> <a id="25586" class="Symbol">→</a> <a id="25588" href="#25150" class="Generalizable">B₀</a><a id="25590" class="Symbol">)</a> <a id="25592" class="Symbol">(</a><a id="25593" href="#25276" class="Field">extract</a> <a id="25601" href="#25437" class="Function Operator">=&lt;=</a> <a id="25605" href="#25540" class="Bound">f</a><a id="25606" class="Symbol">)</a> <a id="25608" href="#25540" class="Bound">f</a>
    <a id="GradedComonad.idʳ"></a><a id="25614" href="#25614" class="Field">idʳ</a> <a id="25618" class="Symbol">:</a> <a id="25620" class="Symbol">(</a><a id="25621" href="#25621" class="Bound">f</a> <a id="25623" class="Symbol">:</a> <a id="25625" href="#25229" class="Bound">𝐶</a> <a id="25627" href="#25128" class="Generalizable">x</a> <a id="25629" href="#25147" class="Generalizable">A₀</a> <a id="25632" class="Symbol">→</a> <a id="25634" href="#25150" class="Generalizable">B₀</a><a id="25636" class="Symbol">)</a> <a id="25638" class="Symbol">→</a> <a id="25640" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#190" class="Postulate">PathP</a> <a id="25646" class="Symbol">(λ</a> <a id="25649" href="#25649" class="Bound">i</a> <a id="25651" class="Symbol">→</a> <a id="25653" href="#25229" class="Bound">𝐶</a> <a id="25655" class="Symbol">(</a><a id="25656" href="../code/depth-comonads/DepthComonads.Algebra.html#1650" class="Field">∙ε</a> <a id="25659" href="#25128" class="Generalizable">x</a> <a id="25661" href="#25649" class="Bound">i</a><a id="25662" class="Symbol">)</a> <a id="25664" href="#25147" class="Generalizable">A₀</a> <a id="25667" class="Symbol">→</a> <a id="25669" href="#25150" class="Generalizable">B₀</a><a id="25671" class="Symbol">)</a> <a id="25673" class="Symbol">(</a><a id="25674" href="#25621" class="Bound">f</a> <a id="25676" href="#25437" class="Function Operator">=&lt;=</a> <a id="25680" href="#25276" class="Field">extract</a><a id="25687" class="Symbol">)</a> <a id="25689" href="#25621" class="Bound">f</a>
    <a id="GradedComonad.c-assoc"></a><a id="25695" href="#25695" class="Field">c-assoc</a> <a id="25703" class="Symbol">:</a> <a id="25705" class="Symbol">(</a><a id="25706" href="#25706" class="Bound">f</a> <a id="25708" class="Symbol">:</a> <a id="25710" href="#25229" class="Bound">𝐶</a> <a id="25712" href="#25128" class="Generalizable">x</a> <a id="25714" href="#25153" class="Generalizable">C₀</a> <a id="25717" class="Symbol">→</a> <a id="25719" href="#25156" class="Generalizable">D₀</a><a id="25721" class="Symbol">)</a> <a id="25723" class="Symbol">(</a><a id="25724" href="#25724" class="Bound">g</a> <a id="25726" class="Symbol">:</a> <a id="25728" href="#25229" class="Bound">𝐶</a> <a id="25730" href="#25130" class="Generalizable">y</a> <a id="25732" href="#25150" class="Generalizable">B₀</a> <a id="25735" class="Symbol">→</a> <a id="25737" href="#25153" class="Generalizable">C₀</a><a id="25739" class="Symbol">)</a> <a id="25741" class="Symbol">(</a><a id="25742" href="#25742" class="Bound">h</a> <a id="25744" class="Symbol">:</a> <a id="25746" href="#25229" class="Bound">𝐶</a> <a id="25748" href="#25132" class="Generalizable">z</a> <a id="25750" href="#25147" class="Generalizable">A₀</a> <a id="25753" class="Symbol">→</a> <a id="25755" href="#25150" class="Generalizable">B₀</a><a id="25757" class="Symbol">)</a> <a id="25759" class="Symbol">→</a>
          <a id="25771" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#190" class="Postulate">PathP</a> <a id="25777" class="Symbol">(λ</a> <a id="25780" href="#25780" class="Bound">i</a> <a id="25782" class="Symbol">→</a> <a id="25784" href="#25229" class="Bound">𝐶</a> <a id="25786" class="Symbol">(</a><a id="25787" href="../code/depth-comonads/DepthComonads.Algebra.html#1572" class="Field">assoc</a> <a id="25793" href="#25128" class="Generalizable">x</a> <a id="25795" href="#25130" class="Generalizable">y</a> <a id="25797" href="#25132" class="Generalizable">z</a> <a id="25799" href="#25780" class="Bound">i</a><a id="25800" class="Symbol">)</a> <a id="25802" href="#25147" class="Generalizable">A₀</a> <a id="25805" class="Symbol">→</a> <a id="25807" href="#25156" class="Generalizable">D₀</a><a id="25809" class="Symbol">)</a> <a id="25811" class="Symbol">((</a><a id="25813" href="#25706" class="Bound">f</a> <a id="25815" href="#25437" class="Function Operator">=&lt;=</a> <a id="25819" href="#25724" class="Bound">g</a><a id="25820" class="Symbol">)</a> <a id="25822" href="#25437" class="Function Operator">=&lt;=</a> <a id="25826" href="#25742" class="Bound">h</a><a id="25827" class="Symbol">)</a> <a id="25829" class="Symbol">(</a><a id="25830" href="#25706" class="Bound">f</a> <a id="25832" href="#25437" class="Function Operator">=&lt;=</a> <a id="25836" class="Symbol">(</a><a id="25837" href="#25724" class="Bound">g</a> <a id="25839" href="#25437" class="Function Operator">=&lt;=</a> <a id="25843" href="#25742" class="Bound">h</a><a id="25844" class="Symbol">))</a>
</pre>
<p>This seems to clearly be related to the stream constructions. Grading
is all about the monoidal information about a comonad: the streams above
are a comonad which indexes its entries with a monoid.</p>
<p>There are now two constructions I want to show that suggest a link
between the stream constructions and graded comonads. First of these is
the <em>Cofree degrading comonad</em>:</p>
<pre class="Agda"><a id="26228" class="Keyword">record</a> <a id="G-CofreeF"></a><a id="26235" href="#26235" class="Record">G-CofreeF</a> <a id="26245" class="Symbol">(</a><a id="26246" href="#26246" class="Bound">𝐹</a> <a id="26248" class="Symbol">:</a> <a id="26250" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="26255" class="Symbol">→</a> <a id="26257" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="26261" class="Symbol">)</a> <a id="26263" class="Symbol">(</a><a id="26264" href="#26264" class="Bound">𝐶</a> <a id="26266" class="Symbol">:</a> <a id="26268" href="#23501" class="Generalizable">𝑆</a> <a id="26270" class="Symbol">→</a> <a id="26272" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="26277" class="Symbol">→</a> <a id="26279" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="26283" class="Symbol">)</a> <a id="26285" class="Symbol">(</a><a id="26286" href="#26286" class="Bound">A</a> <a id="26288" class="Symbol">:</a> <a id="26290" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="26294" class="Symbol">)</a> <a id="26296" class="Symbol">:</a> <a id="26298" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="26303" class="Keyword">where</a>
  <a id="26311" class="Keyword">coinductive</a><a id="26322" class="Symbol">;</a> <a id="26324" class="Keyword">constructor</a> <a id="_◃_"></a><a id="26336" href="#26336" class="CoinductiveConstructor Operator">_◃_</a>
  <a id="26342" class="Keyword">field</a> <a id="G-CofreeF.here"></a><a id="26348" href="#26348" class="Field">here</a> <a id="26353" class="Symbol">:</a> <a id="26355" href="#26286" class="Bound">A</a>
        <a id="G-CofreeF.step"></a><a id="26365" href="#26365" class="Field">step</a> <a id="26370" class="Symbol">:</a> <a id="26372" href="#26246" class="Bound">𝐹</a> <a id="26374" class="Symbol">(</a><a id="26375" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">∃</a> <a id="26377" href="#26377" class="Bound">w</a> <a id="26379" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">×</a> <a id="26381" href="#26264" class="Bound">𝐶</a> <a id="26383" href="#26377" class="Bound">w</a> <a id="26385" class="Symbol">(</a><a id="26386" href="#26235" class="Record">G-CofreeF</a> <a id="26396" href="#26246" class="Bound">𝐹</a> <a id="26398" href="#26264" class="Bound">𝐶</a> <a id="26400" href="#26286" class="Bound">A</a><a id="26401" class="Symbol">))</a>
<a id="26404" class="Keyword">open</a> <a id="26409" href="#26235" class="Module">G-CofreeF</a>

<a id="G-Cofree"></a><a id="26420" href="#26420" class="Function">G-Cofree</a> <a id="26429" class="Symbol">:</a> <a id="26431" class="Symbol">⦃</a> <a id="26433" href="#26433" class="Bound">_</a> <a id="26435" class="Symbol">:</a> <a id="26437" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="26444" href="#23501" class="Generalizable">𝑆</a> <a id="26446" class="Symbol">⦄</a> <a id="26448" class="Symbol">→</a> <a id="26450" class="Symbol">(</a><a id="26451" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="26456" class="Symbol">→</a> <a id="26458" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="26462" class="Symbol">)</a> <a id="26464" class="Symbol">→</a> <a id="26466" class="Symbol">(</a><a id="26467" href="#23501" class="Generalizable">𝑆</a> <a id="26469" class="Symbol">→</a> <a id="26471" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="26476" class="Symbol">→</a> <a id="26478" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="26482" class="Symbol">)</a> <a id="26484" class="Symbol">→</a> <a id="26486" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="26491" class="Symbol">→</a> <a id="26493" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
<a id="26498" href="#26420" class="Function">G-Cofree</a> <a id="26507" href="#26507" class="Bound">𝐹</a> <a id="26509" href="#26509" class="Bound">𝐶</a> <a id="26511" href="#26511" class="Bound">A</a> <a id="26513" class="Symbol">=</a> <a id="26515" href="#26509" class="Bound">𝐶</a> <a id="26517" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="26519" class="Symbol">(</a><a id="26520" href="#26235" class="Record">G-CofreeF</a> <a id="26530" href="#26507" class="Bound">𝐹</a> <a id="26532" href="#26509" class="Bound">𝐶</a> <a id="26534" href="#26511" class="Bound">A</a><a id="26535" class="Symbol">)</a>
</pre>
<p>This construction is similar to the cofree comonad transformer: it is
based on the cofree comonad, but with an extra (graded) comonad wrapped
around each level. For any functor 𝐹 and graded comonad 𝐶,
<code>G-Cofree 𝐹 𝐶</code> is a comonad. The implementation of
<code>extract</code> is simple:</p>
<!--
<pre class="Agda"><a id="26825" class="Keyword">open</a> <a id="26830" href="#25186" class="Module">GradedComonad</a> <a id="26844" class="Symbol">⦃</a> <a id="26846" class="Symbol">...</a> <a id="26850" class="Symbol">⦄</a>

<a id="26853" class="Keyword">variable</a>
  <a id="26864" href="#26864" class="Generalizable">𝐶</a> <a id="26866" class="Symbol">:</a> <a id="26868" href="#23501" class="Generalizable">𝑆</a> <a id="26870" class="Symbol">→</a> <a id="26872" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="26877" class="Symbol">→</a> <a id="26879" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
</pre>-->
<pre class="Agda"><a id="extract′"></a><a id="26896" href="#26896" class="Function">extract′</a> <a id="26905" class="Symbol">:</a> <a id="26907" class="Symbol">⦃</a> <a id="26909" href="#26909" class="Bound">_</a> <a id="26911" class="Symbol">:</a> <a id="26913" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="26920" href="#23501" class="Generalizable">𝑆</a> <a id="26922" class="Symbol">⦄</a> <a id="26924" class="Symbol">⦃</a> <a id="26926" href="#26926" class="Bound">_</a> <a id="26928" class="Symbol">:</a> <a id="26930" href="#25186" class="Record">GradedComonad</a> <a id="26944" href="#23501" class="Generalizable">𝑆</a> <a id="26946" href="#26864" class="Generalizable">𝐶</a> <a id="26948" class="Symbol">⦄</a> <a id="26950" class="Symbol">→</a> <a id="26952" href="#26420" class="Function">G-Cofree</a> <a id="26961" href="#1226" class="Generalizable">𝐹</a> <a id="26963" href="#26864" class="Generalizable">𝐶</a> <a id="26965" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="26967" class="Symbol">→</a> <a id="26969" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a>
<a id="26971" href="#26896" class="Function">extract′</a> <a id="26980" class="Symbol">=</a> <a id="26982" href="#26348" class="Field">here</a> <a id="26987" href="../code/depth-comonads/DepthComonads.Function.html#125" class="Function Operator">∘</a> <a id="26989" href="#25276" class="Field">extract</a>
</pre>
<p><code>extend</code> is more complex. First, we need a version of
<code>extend</code> which takes a proof that the grade is of the right
form:</p>
<pre class="Agda"><a id="27127" class="Keyword">module</a> <a id="27134" href="#27134" class="Module">_</a> <a id="27136" class="Symbol">{</a> <a id="27138" href="#27138" class="Bound">𝐶</a> <a id="27140" class="Symbol">:</a> <a id="27142" href="#23501" class="Generalizable">𝑆</a> <a id="27144" class="Symbol">→</a> <a id="27146" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="27151" class="Symbol">→</a> <a id="27153" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="27158" class="Symbol">}</a> <a id="27160" class="Keyword">where</a>
  <a id="27168" href="#27168" class="Function Operator">extend[_]</a> <a id="27178" class="Symbol">:</a> <a id="27180" class="Symbol">⦃</a> <a id="27182" href="#27182" class="Symbol">_</a> <a id="27184" class="Symbol">:</a> <a id="27186" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="27193" href="#27142" class="Bound">𝑆</a> <a id="27195" class="Symbol">⦄</a> <a id="27197" class="Symbol">⦃</a> <a id="27199" href="#27199" class="Symbol">_</a> <a id="27201" class="Symbol">:</a> <a id="27203" href="#25186" class="Record">GradedComonad</a> <a id="27217" href="#27142" class="Bound">𝑆</a> <a id="27219" href="#27138" class="Bound">𝐶</a> <a id="27221" class="Symbol">⦄</a> <a id="27223" class="Symbol">→</a>
              <a id="27239" href="#25128" class="Generalizable">x</a> <a id="27241" href="../code/depth-comonads/DepthComonads.Algebra.html#1530" class="Field Operator">∙</a> <a id="27243" href="#25130" class="Generalizable">y</a> <a id="27245" href="../code/depth-comonads/Agda.Builtin.Cubical.Path.html#381" class="Function Operator">≡</a> <a id="27247" href="#25132" class="Generalizable">z</a> <a id="27249" class="Symbol">→</a> <a id="27251" class="Symbol">(</a><a id="27252" href="#27138" class="Bound">𝐶</a> <a id="27254" href="#25130" class="Generalizable">y</a> <a id="27256" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="27258" class="Symbol">→</a> <a id="27260" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a><a id="27261" class="Symbol">)</a> <a id="27263" class="Symbol">→</a> <a id="27265" href="#27138" class="Bound">𝐶</a> <a id="27267" href="#25132" class="Generalizable">z</a> <a id="27269" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="27271" class="Symbol">→</a> <a id="27273" href="#27138" class="Bound">𝐶</a> <a id="27275" href="#25128" class="Generalizable">x</a> <a id="27277" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a>
  <a id="27281" href="#27168" class="Function Operator">extend[</a> <a id="27289" href="#27289" class="Bound">p</a> <a id="27291" href="#27168" class="Function Operator">]</a> <a id="27293" href="#27293" class="Bound">k</a> <a id="27295" class="Symbol">=</a> <a id="27297" href="Cubical.Foundations.Prelude.html#7588" class="Function">subst</a> <a id="27303" class="Symbol">(λ</a> <a id="27306" href="#27306" class="Bound">z</a> <a id="27308" class="Symbol">→</a> <a id="27310" href="#27138" class="Bound">𝐶</a> <a id="27312" href="#27306" class="Bound">z</a> <a id="27314" class="Symbol">_</a> <a id="27316" class="Symbol">→</a> <a id="27318" class="Symbol">_)</a> <a id="27321" href="#27289" class="Bound">p</a> <a id="27323" class="Symbol">(</a><a id="27324" href="#25300" class="Field">extend</a> <a id="27331" href="#27293" class="Bound">k</a><a id="27332" class="Symbol">)</a>
</pre>
<p>Then we can implement the characteristic function on the free
comonad: <code>traceT</code>. On graded comonads it has the following
form:</p>
<pre class="Agda"><a id="27471" class="Keyword">module</a> <a id="Trace"></a><a id="27478" href="#27478" class="Module">Trace</a> <a id="27484" class="Symbol">⦃</a> <a id="27486" href="#27486" class="Bound">_</a> <a id="27488" class="Symbol">:</a> <a id="27490" href="../code/depth-comonads/DepthComonads.Algebra.html#1492" class="Record">Monoid</a> <a id="27497" href="#23501" class="Generalizable">𝑆</a> <a id="27499" class="Symbol">⦄</a> <a id="27501" class="Symbol">⦃</a> <a id="27503" href="#27503" class="Bound">_</a> <a id="27505" class="Symbol">:</a> <a id="27507" href="#25186" class="Record">GradedComonad</a> <a id="27521" href="#23501" class="Generalizable">𝑆</a> <a id="27523" href="#26864" class="Generalizable">𝐶</a> <a id="27525" class="Symbol">⦄</a> <a id="27527" class="Symbol">⦃</a> <a id="27529" href="#27529" class="Bound">_</a> <a id="27531" class="Symbol">:</a> <a id="27533" href="../code/depth-comonads/DepthComonads.Algebra.html#4107" class="Record">Functor</a> <a id="27541" href="#1226" class="Generalizable">𝐹</a> <a id="27543" class="Symbol">⦄</a> <a id="27545" class="Keyword">where</a>
  <a id="27553" class="Keyword">module</a> <a id="27560" href="#27560" class="Module">_</a> <a id="27562" class="Symbol">{</a><a id="27563" href="#27563" class="Bound">A</a> <a id="27565" href="#27565" class="Bound">B</a><a id="27566" class="Symbol">}</a> <a id="27568" class="Keyword">where</a>
    <a id="27578" class="Symbol">{-#</a> <a id="27582" class="Keyword">NON_TERMINATING</a> <a id="27598" class="Symbol">#-}</a>
    <a id="27606" href="#27606" class="Function">traceT</a> <a id="27613" class="Symbol">:</a> <a id="27615" class="Symbol">(</a><a id="27616" href="#27523" class="Bound">𝐶</a> <a id="27618" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="27620" href="#27563" class="Bound">A</a> <a id="27622" class="Symbol">→</a> <a id="27624" href="#27565" class="Bound">B</a><a id="27625" class="Symbol">)</a> <a id="27627" class="Symbol">→</a> <a id="27629" class="Symbol">(</a><a id="27630" href="#27523" class="Bound">𝐶</a> <a id="27632" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="27634" href="#27563" class="Bound">A</a> <a id="27636" class="Symbol">→</a> <a id="27638" href="#27541" class="Bound">𝐹</a> <a id="27640" class="Symbol">(</a><a id="27641" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">∃</a> <a id="27643" href="#27643" class="Bound">w</a> <a id="27645" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">×</a> <a id="27647" href="#27523" class="Bound">𝐶</a> <a id="27649" href="#27643" class="Bound">w</a> <a id="27651" href="#27563" class="Bound">A</a><a id="27652" class="Symbol">))</a> <a id="27655" class="Symbol">→</a> <a id="27657" href="#27523" class="Bound">𝐶</a> <a id="27659" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="27661" href="#27563" class="Bound">A</a> <a id="27663" class="Symbol">→</a> <a id="27665" href="#26420" class="Function">G-Cofree</a> <a id="27674" href="#27541" class="Bound">𝐹</a> <a id="27676" href="#27523" class="Bound">𝐶</a> <a id="27678" href="#27565" class="Bound">B</a>
    <a id="27684" href="#27606" class="Function">traceT</a> <a id="27691" href="#27691" class="Bound">ϕ</a> <a id="27693" href="#27693" class="Bound">ρ</a> <a id="27695" class="Symbol">=</a> <a id="27697" href="#27717" class="Function">ψ</a>
      <a id="27705" class="Keyword">where</a>
      <a id="27717" href="#27717" class="Function">ψ</a> <a id="27719" class="Symbol">:</a> <a id="27721" href="#27523" class="Bound">𝐶</a> <a id="27723" href="#25128" class="Generalizable">x</a> <a id="27725" href="#27563" class="Bound">A</a> <a id="27727" class="Symbol">→</a> <a id="27729" href="#27523" class="Bound">𝐶</a> <a id="27731" href="#25128" class="Generalizable">x</a> <a id="27733" class="Symbol">(</a><a id="27734" href="#26235" class="Record">G-CofreeF</a> <a id="27744" href="#27541" class="Bound">𝐹</a> <a id="27746" href="#27523" class="Bound">𝐶</a> <a id="27748" href="#27565" class="Bound">B</a><a id="27749" class="Symbol">)</a>
      <a id="27757" href="#27717" class="Function">ψ</a> <a id="27759" class="Symbol">=</a> <a id="27761" href="#27168" class="Function Operator">extend[</a> <a id="27769" href="../code/depth-comonads/DepthComonads.Algebra.html#1650" class="Field">∙ε</a> <a id="27772" class="Symbol">_</a> <a id="27774" href="#27168" class="Function Operator">]</a> <a id="27776" class="Symbol">λ</a> <a id="27778" href="#27778" class="Bound">x</a> <a id="27780" class="Symbol">→</a> <a id="27782" href="#27691" class="Bound">ϕ</a> <a id="27784" href="#27778" class="Bound">x</a> <a id="27786" href="#26336" class="CoinductiveConstructor Operator">◃</a> <a id="27788" href="../code/depth-comonads/DepthComonads.Algebra.html#4153" class="Field">map</a> <a id="27792" class="Symbol">(</a><a id="27793" href="../code/depth-comonads/DepthComonads.Sigma.html#1401" class="Function">map₂</a> <a id="27798" href="#27717" class="Function">ψ</a><a id="27799" class="Symbol">)</a> <a id="27801" class="Symbol">(</a><a id="27802" href="#27693" class="Bound">ρ</a> <a id="27804" href="#27778" class="Bound">x</a><a id="27805" class="Symbol">)</a>
</pre>
<p>This function is basically the unfold for the free degrading comonad.
If <code>G-Cofree</code> is a internally-labelled tree, then
<code>ϕ</code> above is the labelling function, and <code>ρ</code> is
the “next” function, returning the children for some root.</p>
<p>Using this, we can implement <code>extend</code>:</p>
<pre class="Agda">  <a id="Trace.extend′"></a><a id="28086" href="#28086" class="Function">extend′</a> <a id="28094" class="Symbol">:</a> <a id="28096" class="Symbol">(</a><a id="28097" href="#26420" class="Function">G-Cofree</a> <a id="28106" href="#27541" class="Bound">𝐹</a> <a id="28108" href="#27523" class="Bound">𝐶</a> <a id="28110" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="28112" class="Symbol">→</a> <a id="28114" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a><a id="28115" class="Symbol">)</a> <a id="28117" class="Symbol">→</a> <a id="28119" href="#26420" class="Function">G-Cofree</a> <a id="28128" href="#27541" class="Bound">𝐹</a> <a id="28130" href="#27523" class="Bound">𝐶</a> <a id="28132" href="../code/depth-comonads/DepthComonads.Level.html#269" class="Generalizable">A</a> <a id="28134" class="Symbol">→</a> <a id="28136" href="#26420" class="Function">G-Cofree</a> <a id="28145" href="#27541" class="Bound">𝐹</a> <a id="28147" href="#27523" class="Bound">𝐶</a> <a id="28149" href="../code/depth-comonads/DepthComonads.Level.html#283" class="Generalizable">B</a>
  <a id="28153" href="#28086" class="Function">extend′</a> <a id="28161" href="#28161" class="Bound">f</a> <a id="28163" class="Symbol">=</a> <a id="28165" href="#27606" class="Function">traceT</a> <a id="28172" href="#28161" class="Bound">f</a> <a id="28174" class="Symbol">(</a><a id="28175" href="#26365" class="Field">step</a> <a id="28180" href="../code/depth-comonads/DepthComonads.Function.html#125" class="Function Operator">∘</a> <a id="28182" href="#25276" class="Field">extract</a><a id="28189" class="Symbol">)</a>
</pre>
<p>The relation between this and the stream is that the stream can be
defined in terms of this:
<code>Stream W = G-Cofree id (GC-Id W)</code>.</p>
<p>Finally, the last construction I want to introduce is the
following:</p>
<pre class="Agda"><a id="28400" class="Keyword">module</a> <a id="28407" href="#28407" class="Module">_</a> <a id="28409" class="Symbol">⦃</a> <a id="28411" href="#28411" class="Bound">_</a> <a id="28413" class="Symbol">:</a> <a id="28415" href="#12529" class="Record">Monus</a> <a id="28421" href="#23501" class="Generalizable">𝑆</a> <a id="28423" class="Symbol">⦄</a> <a id="28425" class="Keyword">where</a>
  <a id="28433" class="Keyword">data</a> <a id="28438" href="#28438" class="Datatype">Prefix-F⊙</a> <a id="28448" class="Symbol">(</a><a id="28449" href="#28449" class="Bound">𝐹</a> <a id="28451" class="Symbol">:</a> <a id="28453" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="28458" class="Symbol">→</a> <a id="28460" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28464" class="Symbol">)</a> <a id="28466" class="Symbol">(</a><a id="28467" href="#28467" class="Bound">𝐶</a> <a id="28469" class="Symbol">:</a> <a id="28471" href="#28421" class="Bound">𝑆</a> <a id="28473" class="Symbol">→</a> <a id="28475" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="28480" class="Symbol">→</a> <a id="28482" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28486" class="Symbol">)</a> <a id="28488" class="Symbol">(</a><a id="28489" href="#28489" class="Bound">i</a> <a id="28491" href="#28491" class="Bound">j</a> <a id="28493" class="Symbol">:</a> <a id="28495" href="#28421" class="Bound">𝑆</a><a id="28496" class="Symbol">)</a> <a id="28498" class="Symbol">(</a><a id="28499" href="#28499" class="Bound">A</a> <a id="28501" class="Symbol">:</a> <a id="28503" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28507" class="Symbol">)</a> <a id="28509" class="Symbol">:</a> <a id="28511" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="28516" class="Keyword">where</a>
    <a id="28527" href="#28527" class="InductiveConstructor">prefix</a> <a id="28534" class="Symbol">:</a> <a id="28536" class="Symbol">((</a><a id="28538" href="#28538" class="Bound">i≤j</a> <a id="28542" class="Symbol">:</a> <a id="28544" href="#28489" class="Bound">i</a> <a id="28546" href="../code/depth-comonads/DepthComonads.Relation.Binary.html#1444" class="Function Operator">≤</a> <a id="28548" href="#28491" class="Bound">j</a><a id="28549" class="Symbol">)</a> <a id="28551" class="Symbol">→</a> <a id="28553" href="#28499" class="Bound">A</a> <a id="28555" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="28557" href="#28449" class="Bound">𝐹</a> <a id="28559" class="Symbol">(</a><a id="28560" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">∃</a> <a id="28562" href="#28562" class="Bound">k</a> <a id="28564" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">×</a> <a id="28566" href="#28467" class="Bound">𝐶</a> <a id="28568" href="#28562" class="Bound">k</a> <a id="28570" class="Symbol">(</a><a id="28571" href="#28438" class="Datatype">Prefix-F⊙</a> <a id="28581" href="#28449" class="Bound">𝐹</a> <a id="28583" href="#28467" class="Bound">𝐶</a> <a id="28585" href="#28562" class="Bound">k</a> <a id="28587" class="Symbol">(</a><a id="28588" href="../code/depth-comonads/Agda.Builtin.Sigma.html#252" class="Field">fst</a> <a id="28592" href="#28538" class="Bound">i≤j</a><a id="28595" class="Symbol">)</a> <a id="28597" href="#28499" class="Bound">A</a><a id="28598" class="Symbol">)))</a> <a id="28602" class="Symbol">→</a> <a id="28604" href="#28438" class="Datatype">Prefix-F⊙</a> <a id="28614" href="#28449" class="Bound">𝐹</a> <a id="28616" href="#28467" class="Bound">𝐶</a> <a id="28618" href="#28489" class="Bound">i</a> <a id="28620" href="#28491" class="Bound">j</a> <a id="28622" href="#28499" class="Bound">A</a>

  <a id="28627" href="#28627" class="Function">Prefix⊙</a> <a id="28635" class="Symbol">:</a> <a id="28637" class="Symbol">(</a><a id="28638" href="#28638" class="Bound">𝐹</a> <a id="28640" class="Symbol">:</a> <a id="28642" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="28647" class="Symbol">→</a> <a id="28649" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28653" class="Symbol">)</a> <a id="28655" class="Symbol">(</a><a id="28656" href="#28656" class="Bound">𝐶</a> <a id="28658" class="Symbol">:</a> <a id="28660" href="#28421" class="Bound">𝑆</a> <a id="28662" class="Symbol">→</a> <a id="28664" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="28669" class="Symbol">→</a> <a id="28671" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28675" class="Symbol">)</a> <a id="28677" class="Symbol">(</a><a id="28678" href="#28678" class="Bound">j</a> <a id="28680" class="Symbol">:</a> <a id="28682" href="#28421" class="Bound">𝑆</a><a id="28683" class="Symbol">)</a> <a id="28685" class="Symbol">(</a><a id="28686" href="#28686" class="Bound">A</a> <a id="28688" class="Symbol">:</a> <a id="28690" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28694" class="Symbol">)</a> <a id="28696" class="Symbol">→</a> <a id="28698" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
  <a id="28705" href="#28627" class="Function">Prefix⊙</a> <a id="28713" href="#28713" class="Bound">𝐹</a> <a id="28715" href="#28715" class="Bound">𝐶</a> <a id="28717" href="#28717" class="Bound">j</a> <a id="28719" href="#28719" class="Bound">A</a> <a id="28721" class="Symbol">=</a> <a id="28723" href="#28715" class="Bound">𝐶</a> <a id="28725" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="28727" class="Symbol">(</a><a id="28728" href="#28438" class="Datatype">Prefix-F⊙</a> <a id="28738" href="#28713" class="Bound">𝐹</a> <a id="28740" href="#28715" class="Bound">𝐶</a> <a id="28742" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="28744" href="#28717" class="Bound">j</a> <a id="28746" href="#28719" class="Bound">A</a><a id="28747" class="Symbol">)</a>

  <a id="28752" href="#28752" class="Function">Prefix</a> <a id="28759" class="Symbol">:</a> <a id="28761" class="Symbol">(</a><a id="28762" href="#28762" class="Bound">𝐹</a> <a id="28764" class="Symbol">:</a> <a id="28766" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="28771" class="Symbol">→</a> <a id="28773" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28777" class="Symbol">)</a> <a id="28779" class="Symbol">(</a><a id="28780" href="#28780" class="Bound">𝐶</a> <a id="28782" class="Symbol">:</a> <a id="28784" href="#28421" class="Bound">𝑆</a> <a id="28786" class="Symbol">→</a> <a id="28788" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a> <a id="28793" class="Symbol">→</a> <a id="28795" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28799" class="Symbol">)</a> <a id="28801" class="Symbol">(</a><a id="28802" href="#28802" class="Bound">A</a> <a id="28804" class="Symbol">:</a> <a id="28806" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="28810" class="Symbol">)</a> <a id="28812" class="Symbol">→</a> <a id="28814" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a>
  <a id="28821" href="#28752" class="Function">Prefix</a> <a id="28828" href="#28828" class="Bound">𝐹</a> <a id="28830" href="#28830" class="Bound">𝐶</a> <a id="28832" href="#28832" class="Bound">A</a> <a id="28834" class="Symbol">=</a> <a id="28836" class="Symbol">∀</a> <a id="28838" class="Symbol">{</a><a id="28839" href="#28839" class="Bound">i</a><a id="28840" class="Symbol">}</a> <a id="28842" class="Symbol">→</a> <a id="28844" href="#28627" class="Function">Prefix⊙</a> <a id="28852" href="#28828" class="Bound">𝐹</a> <a id="28854" href="#28830" class="Bound">𝐶</a> <a id="28856" href="#28839" class="Bound">i</a> <a id="28858" href="#28832" class="Bound">A</a>
</pre>
<p>This type is designed to mimic sized type definitions. It has an
implicit parameter which can be set, by the user of the type, to some
arbitrary depth. Basically the parameter means “explore to this depth”;
by using the <code>∀</code> we say that it is defined up to any
arbitrary depth.</p>
<p>When the <code>≺</code> relation on the monus is well founded it is
possible to implement <code>traceT</code>:</p>
<pre class="Agda">  <a id="29239" class="Keyword">module</a> <a id="29246" href="#29246" class="Module">_</a> <a id="29248" class="Symbol">⦃</a> <a id="29250" href="#29250" class="Bound">_</a> <a id="29252" class="Symbol">:</a> <a id="29254" href="#25186" class="Record">GradedComonad</a> <a id="29268" href="#28421" class="Bound">𝑆</a> <a id="29270" href="#26864" class="Generalizable">𝐶</a> <a id="29272" class="Symbol">⦄</a> <a id="29274" class="Symbol">⦃</a> <a id="29276" href="#29276" class="Bound">_</a> <a id="29278" class="Symbol">:</a> <a id="29280" href="../code/depth-comonads/DepthComonads.Algebra.html#4107" class="Record">Functor</a> <a id="29288" href="#1226" class="Generalizable">𝐹</a> <a id="29290" class="Symbol">⦄</a> <a id="29292" class="Symbol">(</a><a id="29293" href="#29293" class="Bound">wf</a> <a id="29296" class="Symbol">:</a> <a id="29298" href="../code/depth-comonads/DepthComonads.WellFounded.html#230" class="Function">WellFounded</a> <a id="29310" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#2522" class="Function Operator">_≺_</a><a id="29313" class="Symbol">)</a> <a id="29315" class="Symbol">{</a><a id="29316" href="#29316" class="Bound">A</a> <a id="29318" href="#29318" class="Bound">B</a> <a id="29320" class="Symbol">:</a> <a id="29322" href="../code/depth-comonads/Agda.Primitive.html#326" class="Primitive">Type</a><a id="29326" class="Symbol">}</a> <a id="29328" class="Keyword">where</a>
    <a id="29338" href="#29338" class="Function">traceT</a> <a id="29345" class="Symbol">:</a> <a id="29347" class="Symbol">(</a><a id="29348" href="#29270" class="Bound">𝐶</a> <a id="29350" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="29352" href="#29316" class="Bound">A</a> <a id="29354" class="Symbol">→</a> <a id="29356" href="#29318" class="Bound">B</a><a id="29357" class="Symbol">)</a> <a id="29359" class="Symbol">→</a> <a id="29361" class="Symbol">(</a><a id="29362" href="#29270" class="Bound">𝐶</a> <a id="29364" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="29366" href="#29316" class="Bound">A</a> <a id="29368" class="Symbol">→</a> <a id="29370" href="#29288" class="Bound">𝐹</a> <a id="29372" class="Symbol">(</a><a id="29373" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">∃</a> <a id="29375" href="#29375" class="Bound">w</a> <a id="29377" href="../code/depth-comonads/DepthComonads.Sigma.html#260" class="Function">×</a> <a id="29379" class="Symbol">(</a><a id="29380" href="#29375" class="Bound">w</a> <a id="29382" href="../code/depth-comonads/DepthComonads.Path.html#561" class="Function Operator">≢</a> <a id="29384" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a><a id="29385" class="Symbol">)</a> <a id="29387" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="29389" href="#29270" class="Bound">𝐶</a> <a id="29391" href="#29375" class="Bound">w</a> <a id="29393" href="#29316" class="Bound">A</a><a id="29394" class="Symbol">))</a> <a id="29397" class="Symbol">→</a> <a id="29399" href="#29270" class="Bound">𝐶</a> <a id="29401" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a> <a id="29403" href="#29316" class="Bound">A</a> <a id="29405" class="Symbol">→</a> <a id="29407" href="#28752" class="Function">Prefix</a> <a id="29414" href="#29288" class="Bound">𝐹</a> <a id="29416" href="#29270" class="Bound">𝐶</a> <a id="29418" href="#29318" class="Bound">B</a>
    <a id="29424" href="#29338" class="Function">traceT</a> <a id="29431" href="#29431" class="Bound">ϕ</a> <a id="29433" href="#29433" class="Bound">ρ</a> <a id="29435" href="#29435" class="Bound">xs</a> <a id="29438" class="Symbol">=</a> <a id="29440" href="#27168" class="Function Operator">extend[</a> <a id="29448" href="../code/depth-comonads/DepthComonads.Algebra.html#1650" class="Field">∙ε</a> <a id="29451" class="Symbol">_</a> <a id="29453" href="#27168" class="Function Operator">]</a> <a id="29455" class="Symbol">(λ</a> <a id="29458" href="#29458" class="Bound">xs′</a> <a id="29462" class="Symbol">→</a> <a id="29464" href="#28527" class="InductiveConstructor">prefix</a> <a id="29471" class="Symbol">λ</a> <a id="29473" href="#29473" class="Bound">_</a> <a id="29475" class="Symbol">→</a> <a id="29477" href="#29431" class="Bound">ϕ</a> <a id="29479" href="#29458" class="Bound">xs′</a> <a id="29483" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a>  <a id="29486" href="../code/depth-comonads/DepthComonads.Algebra.html#4153" class="Field">map</a> <a id="29490" class="Symbol">(</a><a id="29491" href="../code/depth-comonads/DepthComonads.Sigma.html#1401" class="Function">map₂</a> <a id="29496" class="Symbol">(</a><a id="29497" href="#29537" class="Function">ψ</a> <a id="29499" class="Symbol">(</a><a id="29500" href="#29293" class="Bound">wf</a> <a id="29503" class="Symbol">_)))</a> <a id="29508" class="Symbol">(</a><a id="29509" href="#29433" class="Bound">ρ</a> <a id="29511" href="#29435" class="Bound">xs</a><a id="29513" class="Symbol">))</a> <a id="29516" href="#29435" class="Bound">xs</a>
      <a id="29525" class="Keyword">where</a>
      <a id="29537" href="#29537" class="Function">ψ</a> <a id="29539" class="Symbol">:</a> <a id="29541" href="../code/depth-comonads/DepthComonads.WellFounded.html#113" class="Datatype">Acc</a> <a id="29545" href="../code/depth-comonads/DepthComonads.Algebra.Monus.html#2522" class="Function Operator">_≺_</a> <a id="29549" href="#25130" class="Generalizable">y</a> <a id="29551" class="Symbol">→</a> <a id="29553" class="Symbol">(</a><a id="29554" href="#25128" class="Generalizable">x</a> <a id="29556" href="../code/depth-comonads/DepthComonads.Path.html#561" class="Function Operator">≢</a> <a id="29558" href="../code/depth-comonads/DepthComonads.Algebra.html#1555" class="Field">ε</a><a id="29559" class="Symbol">)</a> <a id="29561" href="../code/depth-comonads/DepthComonads.Sigma.html#542" class="Function Operator">×</a> <a id="29563" href="#29270" class="Bound">𝐶</a> <a id="29565" href="#25128" class="Generalizable">x</a> <a id="29567" href="#29316" class="Bound">A</a> <a id="29569" class="Symbol">→</a> <a id="29571" href="#29270" class="Bound">𝐶</a> <a id="29573" href="#25128" class="Generalizable">x</a> <a id="29575" class="Symbol">(</a><a id="29576" href="#28438" class="Datatype">Prefix-F⊙</a> <a id="29586" href="#29288" class="Bound">𝐹</a> <a id="29588" href="#29270" class="Bound">𝐶</a> <a id="29590" href="#25128" class="Generalizable">x</a> <a id="29592" href="#25130" class="Generalizable">y</a> <a id="29594" href="#29318" class="Bound">B</a><a id="29595" class="Symbol">)</a>
      <a id="29603" href="#29537" class="Function">ψ</a> <a id="29605" class="Symbol">(</a><a id="29606" href="../code/depth-comonads/DepthComonads.WellFounded.html#189" class="InductiveConstructor">acc</a> <a id="29610" href="#29610" class="Bound">wf</a><a id="29612" class="Symbol">)</a> <a id="29614" class="Symbol">(</a><a id="29615" href="#29615" class="Bound">x≢ε</a> <a id="29619" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29621" href="#29621" class="Bound">xs</a><a id="29623" class="Symbol">)</a> <a id="29625" class="Symbol">=</a>
        <a id="29635" href="#27168" class="Function Operator">extend[</a> <a id="29643" href="../code/depth-comonads/DepthComonads.Algebra.html#1650" class="Field">∙ε</a> <a id="29646" class="Symbol">_</a> <a id="29648" href="#27168" class="Function Operator">]</a>
          <a id="29660" class="Symbol">(λ</a> <a id="29663" href="#29663" class="Bound">x</a> <a id="29665" class="Symbol">→</a> <a id="29667" href="#28527" class="InductiveConstructor">prefix</a>
            <a id="29686" class="Symbol">λ</a> <a id="29688" class="Symbol">{</a> <a id="29690" class="Symbol">(</a><a id="29691" href="#29691" class="Bound">k</a> <a id="29693" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29695" href="#29695" class="Bound">y≡x∙k</a><a id="29700" class="Symbol">)</a> <a id="29702" class="Symbol">→</a>
              <a id="29718" href="#29431" class="Bound">ϕ</a> <a id="29720" href="#29663" class="Bound">x</a> <a id="29722" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29724" href="../code/depth-comonads/DepthComonads.Algebra.html#4153" class="Field">map</a>
                <a id="29744" class="Symbol">(λ</a> <a id="29747" class="Symbol">{</a> <a id="29749" class="Symbol">(</a><a id="29750" href="#29750" class="Bound">w</a> <a id="29752" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29754" href="#29754" class="Bound">w≢ε</a> <a id="29758" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29760" href="#29760" class="Bound">xs</a><a id="29762" class="Symbol">)</a> <a id="29764" class="Symbol">→</a>
                  <a id="29784" href="#29750" class="Bound">w</a> <a id="29786" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29788" href="#29537" class="Function">ψ</a> <a id="29790" class="Symbol">(</a><a id="29791" href="#29610" class="Bound">wf</a> <a id="29794" href="#29691" class="Bound">k</a> <a id="29796" class="Symbol">(_</a> <a id="29799" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29801" href="#29695" class="Bound">y≡x∙k</a> <a id="29807" href="Cubical.Foundations.Id.html#737" class="Function Operator">;</a> <a id="29809" href="../code/depth-comonads/DepthComonads.Algebra.html#2733" class="Function">comm</a> <a id="29814" class="Symbol">_</a> <a id="29816" class="Symbol">_</a> <a id="29818" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29820" href="#29615" class="Bound">x≢ε</a><a id="29823" class="Symbol">))</a> <a id="29826" class="Symbol">(</a><a id="29827" href="#29754" class="Bound">w≢ε</a> <a id="29831" href="../code/depth-comonads/Agda.Builtin.Sigma.html#236" class="InductiveConstructor Operator">,</a> <a id="29833" href="#29760" class="Bound">xs</a><a id="29835" class="Symbol">)})</a> <a id="29839" class="Symbol">(</a><a id="29840" href="#29433" class="Bound">ρ</a> <a id="29842" href="#29663" class="Bound">x</a><a id="29843" class="Symbol">)})</a>
          <a id="29857" href="#29621" class="Bound">xs</a>
</pre>
<h1 id="conclusion">Conclusion</h1>
<p>Comonads are much less widely used than monads in Haskell and similar
languages. Part of the reason, I think, is that they’re too powerful in
a non-linear language. Monads are often used to model sublanguages where
it’s possible to introduce “special” variables which interact with the
monadic context.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>pyth <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>]</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>]</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  z <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>]</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  guard (x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y <span class="op">==</span> z<span class="op">*</span>z)</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">return</span> (x,y,z)</span></code></pre></div>
<p>The <code>x</code> variable here semantically spans over the range
<code>[1..10]</code>. In the following two examples we see the semantics
of state and maybe:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sum</span><span class="ot"> ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sum</span> xs <span class="ot">=</span> <span class="fu">flip</span> evalState <span class="dv">0</span> <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  put <span class="dv">0</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  for_ xs <span class="op">$</span> \x <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    n <span class="ot">&lt;-</span> get</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    put (n <span class="op">+</span> x)</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>  m <span class="ot">&lt;-</span> get</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  <span class="fu">return</span> m</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">E</span> <span class="ot">=</span> <span class="dt">Lit</span> <span class="dt">Int</span> <span class="op">|</span> <span class="dt">E</span> <span class="op">:+:</span> <span class="dt">E</span> <span class="op">|</span> <span class="dt">E</span> <span class="op">:/:</span> <span class="dt">E</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ot">eval ::</span> <span class="dt">E</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Int</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>eval (<span class="dt">Lit</span> n) <span class="ot">=</span> n</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>eval (xs <span class="op">:+:</span> ys) <span class="ot">=</span> <span class="kw">do</span> x <span class="ot">&lt;-</span> eval xs</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>                      y <span class="ot">&lt;-</span> eval ys</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>                      <span class="fu">return</span> (x <span class="op">+</span> y)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>eval (xs <span class="op">:/:</span> ys) <span class="ot">=</span> <span class="kw">do</span> x <span class="ot">&lt;-</span> eval xs</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>                      y <span class="ot">&lt;-</span> eval ys</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>                      guard (y <span class="op">/=</span> <span class="dv">0</span>)</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>                      <span class="fu">return</span> (x <span class="op">/</span> y)</span></code></pre></div>
</div>
</div>
<p>The variables <code>n</code> and <code>m</code> introduced in the
state example are “special” because their values depend on the
computations that came before. In the maybe example the variables
introduced could be <code>Nothing</code>.</p>
<p>You can’t do the same thing with comonads because you’re always able
to extract the “special” variable with
<code>extract :: m a -&gt; a</code>. Instead of having special variable
<em>introduction</em>, comonads let you have special variable
<em>elimination</em>. But, since Haskell isn’t linear, you can always
just discard a variable so this isn’t much use.</p>
<p>Looking at the maybe example, we have a function
<code>eval :: E -&gt; Maybe Int</code> that introduces an
<code>Int</code> variable with a “catch”: it is wrapped in a
<code>Maybe</code>. We want to use the <code>eval</code> function as if
it were a normal function <code>E -&gt; Int</code>, with all of the
bookkeeping managed for us: that’s what monads and do notation (kind of)
allow us to do.</p>
<p>An analagous example with comonads might be having a function
<code>consume :: m V -&gt; String</code>. This “handles” a
<code>V</code> value, but the “catch” is that it needs an <code>m</code>
context to do so. If we want to treat the <code>consume</code> function
as if it were a normal function <code>V -&gt; String</code> then
comonads <span class="citation" data-cites="orchard_notation_2013">(and
codo notation <a href="#ref-orchard_notation_2013"
role="doc-biblioref">Orchard and Mycroft 2013</a>)</span> would be a
perfect fit.</p>
<p>The reason that this analagous case doesn’t arise very often is that
we don’t have many handlers that look like <code>m V -&gt; String</code>
in Haskell. Why? Because if we want to “handle” a <code>V</code> we can
just discard it: as a non-linear language, you do not need to perform
any ceremony to discard a variable in Haskell.</p>
<p>Graded comonads, though, seem to be much more useful than normal
comonads. I think it is becuase they basically get rid of the
<code>m a -&gt; a</code> function, changing it into a much more
restricted form. In this way, they give a kind of small linear language,
but just for the monoidal type parameter.</p>
<p>And there are a lot of uses for the graded comonads. Above we’ve used
them for termination checking. A recursive function might have the form
<code>a -&gt; b</code>, where <code>a</code> is the thing being recursed
on. If we’re using well-founded recursion to show that it’s terminating,
though, we add an extra parameter, an <code>Acc _&lt;_</code> proof,
turning this function into <code>Acc _&lt;_ w × a -&gt; b</code>. The
<code>Acc _&lt;_</code> here is the graded comonad, and this recursive
function is precisely the “handler”.</p>
<p>Other examples might be privacy or permissions: a function might be
able to work on some value, but only if it has particular
<em>permission</em> regarding that value. The permission here is the
monoid.</p>
<p>There are other examples I’m sure, those are just the couple that I
have been thinking about.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-abel_wellfounded_2013" class="csl-entry" role="listitem">
Abel, Andreas, and Brigitte Pientka. 2013. <span>“Wellfounded
<span>Recursion</span> with <span>Copatterns</span>”</span> (0) (June):
25. <a
href="http://www2.tcs.ifi.lmu.de/%7Eabel/icfp13-long.pdf">http://www2.tcs.ifi.lmu.de/%7Eabel/icfp13-long.pdf</a>.
</div>
<div id="ref-ahman_when_2012" class="csl-entry" role="listitem">
Ahman, Danel, James Chapman, and Tarmo Uustalu. 2012. <span>“When
<span>Is</span> a <span>Container</span> a <span>Comonad</span>?”</span>
In <em>Foundations of <span>Software Science</span> and
<span>Computational Structures</span></em>, 74–88. Lecture
<span>Notes</span> in <span>Computer Science</span>. <span>Springer,
Berlin, Heidelberg</span>. doi:<a
href="https://doi.org/10.1007/978-3-642-28729-9_5">10.1007/978-3-642-28729-9_5</a>.
</div>
<div id="ref-ahman_distributive_2013" class="csl-entry" role="listitem">
Ahman, Danel, and Tarmo Uustalu. 2013. <span>“Distributive laws of
directed containers.”</span> <em>Progress in Informatics</em> (10)
(March): 3. doi:<a
href="https://doi.org/10.2201/NiiPi.2013.10.2">10.2201/NiiPi.2013.10.2</a>.
</div>
<div id="ref-ahman_update_2014" class="csl-entry" role="listitem">
———. 2014. <span>“Update <span>Monads</span>: <span>Cointerpreting
Directed Containers</span>”</span>: 23 pages. doi:<a
href="https://doi.org/10.4230/LIPICS.TYPES.2013.1">10.4230/LIPICS.TYPES.2013.1</a>.
</div>
<div id="ref-ahman_directed_2016" class="csl-entry" role="listitem">
———. 2016. <span>“Directed <span>Containers</span> as
<span>Categories</span>”</span> (April). doi:<a
href="https://doi.org/10.4204/EPTCS.207.5">10.4204/EPTCS.207.5</a>.
</div>
<div id="ref-kidney_algebras_2021" class="csl-entry" role="listitem">
Kidney, Donnacha Oisín, and Nicolas Wu. 2021. <span>“Algebras for
weighted search.”</span> <em>Proceedings of the ACM on Programming
Languages</em> 5 (ICFP) (August): 72:1–72:30. doi:<a
href="https://doi.org/10.1145/3473577">10.1145/3473577</a>.
</div>
<div id="ref-kmett_state_2018" class="csl-entry" role="listitem">
Kmett, Edward. 2018. <span>“The <span>State Comonad</span>.”</span>
Blog. <em>The Comonad.Reader</em>. <a
href="http://comonad.com/reader/2018/the-state-comonad/">http://comonad.com/reader/2018/the-state-comonad/</a>.
</div>
<div id="ref-orchard_notation_2013" class="csl-entry" role="listitem">
Orchard, Dominic, and Alan Mycroft. 2013. <span>“A <span>Notation</span>
for <span>Comonads</span>.”</span> In <em>Implementation and
<span>Application</span> of <span>Functional Languages</span></em>, ed
by. Ralf Hinze, 1–17. Lecture <span>Notes</span> in <span>Computer
Science</span>. <span>Berlin, Heidelberg</span>: <span>Springer</span>.
doi:<a
href="https://doi.org/10.1007/978-3-642-41582-1_1">10.1007/978-3-642-41582-1_1</a>.
</div>
<div id="ref-waern_made_2018" class="csl-entry" role="listitem">
Waern, Love. 2018. <span>“I made a monad that <span>I</span> haven’t
seen before, and <span>I</span> have a few questions about it.”</span>
Reddit {{Post}}. <em>reddit.com/r/haskell</em>. <a
href="https://www.reddit.com/r/haskell/comments/7oav51/i_made_a_monad_that_i_havent_seen_before_and_i/">https://www.reddit.com/r/haskell/comments/7oav51/i_made_a_monad_that_i_havent_seen_before_and_i/</a>.
</div>
</div>
]]></description>
    <pubDate>Tue, 03 May 2022 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2022-05-03-depth-comonads.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Weighted Search Package</title>
    <link>https://doisinkidney.com/posts/2021-08-29-weighted-search-package.html</link>
    <description><![CDATA[<div class="info">
    Posted on August 29, 2021
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>I have packaged up the more interesting bits from the <a
href="https://dl.acm.org/doi/abs/10.1145/3473577">Algebras for Weighted
Search</a> paper and put it up on hackage.</p>
<p>You can see it <a
href="https://hackage.haskell.org/package/monus-weighted-search">here</a>.</p>
<p>It contains the <code>HeapT</code> monad, the <code>Monus</code>
class, and an implementation of Dijkstra’s algorithm, the Viterbi
algorithm, and probabilistic parsing.</p>
<p>Check it out!</p>
]]></description>
    <pubDate>Sun, 29 Aug 2021 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2021-08-29-weighted-search-package.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>ICFP Paper—Algebras for Weighted Search</title>
    <link>https://doisinkidney.com/posts/2021-06-21-icfp-paper.html</link>
    <description><![CDATA[<div class="info">
    Posted on June 21, 2021
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>The paper “Algebras for Weighted Search” has just been accepted
unconditionally to ICFP. I wrote it with my supervisor, <a
href="http://zenzike.com/">Nicolas Wu</a>, and it covers a lot of the
topics I’ve written about on this blog (including hyperfunctions and
breadth-first traversals).</p>
<p>The preprint is available <a
href="../pdfs/algebras-for-weighted-search.pdf">here</a>.</p>
]]></description>
    <pubDate>Mon, 21 Jun 2021 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2021-06-21-icfp-paper.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Hyperfunctions</title>
    <link>https://doisinkidney.com/posts/2021-03-14-hyperfunctions.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 14, 2021
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Check out this type:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> a <span class="op">-&amp;&gt;</span> b <span class="ot">=</span> <span class="dt">Hyp</span> {<span class="ot"> invoke ::</span> (b <span class="op">-&amp;&gt;</span> a) <span class="ot">-&gt;</span> b }</span></code></pre></div>
<p>This a hyperfunction <span class="citation"
data-cites="launchbury_coroutining_2013 launchbury_zip_2000 krstic_category_2000">(<a
href="#ref-launchbury_coroutining_2013" role="doc-biblioref">J.
Launchbury, Krstic, and Sauerwein 2013</a>; <a
href="#ref-launchbury_zip_2000" role="doc-biblioref">2000</a>; <a
href="#ref-krstic_category_2000" role="doc-biblioref">2000</a>)</span>,
and I think it’s one of the weirdest and most interesting newtypes you
can write in Haskell.</p>
<p>The first thing to notice is that the recursion pattern is weird. For
a type to refer to itself recursively on the <em>left</em> of a function
arrow is pretty unusual, but on top of that the recursion is
<em>non-regular</em>. That means that the recursive reference has
different type parameters to its parent: <code>a -&amp;&gt; b</code> is
on the left-hand-side of the equals sign, but on the right we refer to
<code>b -&amp;&gt; a</code>.</p>
<p>Being weird is reason enough to write about them, but what’s really
shocking about hyperfunctions is that they’re <em>useful</em>. Once I
saw the definition I realised that a bunch of optimisation code I had
written (to fuse away zips in particular) was actually using
hyperfunctions <span class="citation"
data-cites="ghani_monadic_2005">(<a href="#ref-ghani_monadic_2005"
role="doc-biblioref">Ghani et al. 2005</a>)</span>. After that, I saw
them all over the place: in coroutine implementations, queues,
breadth-first traversals, etc.</p>
<p>Anyways, since coming across hyperfunctions a few months ago I
thought I’d do a writeup on them. I’m kind of surprised they’re not more
well-known, to be honest: they’re like a slightly more enigmatic <a
href="https://hackage.haskell.org/package/mtl-2.2.2/docs/Control-Monad-Cont.html"><code>Cont</code></a>
monad, with a far cooler name. Let’s get into it!</p>
<h1 id="what-are-hyperfunctions">What Are Hyperfunctions?</h1>
<p>The newtype noise kind of hides what’s going on with hyperfunctions:
expanding the definition out might make things slightly clearer.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> a <span class="op">-&amp;&gt;</span> b <span class="ot">=</span> (b <span class="op">-&amp;&gt;</span> a) <span class="ot">-&gt;</span> b</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=</span> ((a <span class="op">-&amp;&gt;</span> b) <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=</span> (((b <span class="op">-&amp;&gt;</span> a) <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=</span> ((((<span class="op">...</span> <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>So a value of type <code>a -&amp;&gt; b</code> is kind of an
infinitely left-nested function type. One thing worth noticing is that
all the <code>a</code>s are in negative positions and all the
<code>b</code>s in positive. This negative and positive business
basically refers to the position of arguments in relation to a function
arrow: to the left are negatives, and to the right are positives, but
two negatives cancel out.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>((((<span class="op">...</span> <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>           <span class="op">+</span>     <span class="op">-</span>     <span class="op">+</span>     <span class="op">-</span>     <span class="op">+</span></span></code></pre></div>
<p>All the things in negative positions are kind of like the things a
function “consumes”, and positive positions are the things “produced”.
It’s worth fiddling around with very nested function types to get a feel
for this notion. For hyperfunctions, though, it’s enough to know that
<code>a -&amp;&gt; b</code> does indeed (kind of) take in a bunch of
<code>a</code>s, and it kind of produces <code>b</code>s.</p>
<p>By the way, one of the ways to get to grips with polarity in this
sense is to play around with the Cont monad, codensity monad, or
selection monad <span class="citation"
data-cites="hedges_selection_2015">(<a href="#ref-hedges_selection_2015"
role="doc-biblioref">Hedges 2015</a>)</span>. If you do, you may notice
one of the interesting parallels about hyperfunctions: the type
<code>a -&amp;&gt; a</code> is in fact the fixpoint of the continuation
monad (<code>Fix (Cont a)</code>). Suspicious!</p>
<h1 id="hyperfunctions-are-everywhere">Hyperfunctions Are
Everywhere</h1>
<p>Before diving further into the properties of the type itself, I’d
like to give some examples of how it can show up in pretty standard
optimisation code.</p>
<h3 id="zips">Zips</h3>
<p>Let’s say you wanted to write <code>zip</code> with
<code>foldr</code> (I have already described this particular algorithm
in a <a href="2020-08-22-some-more-list-algorithms.html">previous
post</a>). Not <code>foldr</code> on the left argument, mind you, but
<code>foldr</code> on <em>both</em>. If you proceed mechanically,
replacing every recursive function with <code>foldr</code>, you can
actually arrive at a definition:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs ys <span class="ot">=</span> <span class="fu">foldr</span> xf xb xs (<span class="fu">foldr</span> yf yb ys)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    xf x xk yk <span class="ot">=</span> yk x xk</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    xb _ <span class="ot">=</span> []</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    yf y yk x xk <span class="ot">=</span> (x,y) <span class="op">:</span> xk yk</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    yb _ _ <span class="ot">=</span> []</span></code></pre></div>
<p>In an untyped language, or a language with recursive types, such a
definition would be totally fine. In Haskell, though, the compiler will
complain with the following:</p>
<pre><code>• Occurs check: cannot construct the infinite type:
    t0 ~ a -&gt; (t0 -&gt; [(a, b)]) -&gt; [(a, b)]</code></pre>
<p>Seasoned Haskellers will know, though, that this is not a type error:
no, this is a type <em>recipe</em>. The compiler is telling you what
parameters it wants you to stick in the newtype:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Zip</span> a b <span class="ot">=</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Zip</span> {<span class="ot"> runZip ::</span> a <span class="ot">-&gt;</span> (<span class="dt">Zip</span> a b <span class="ot">-&gt;</span> [(a,b)]) <span class="ot">-&gt;</span> [(a,b)] }</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> <span class="kw">forall</span> a b<span class="op">.</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs ys <span class="ot">=</span> xz yz</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="ot">    xz ::</span> <span class="dt">Zip</span> a b <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    xz <span class="ot">=</span> <span class="fu">foldr</span> f b xs</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>        f x xk yk <span class="ot">=</span> runZip yk x xk</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>        b _ <span class="ot">=</span> []</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a><span class="ot">    yz ::</span> <span class="dt">Zip</span> a b</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>    yz <span class="ot">=</span> <span class="fu">foldr</span> f b ys</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>        f y yk <span class="ot">=</span> <span class="dt">Zip</span> (\x xk <span class="ot">-&gt;</span> (x,y) <span class="op">:</span> xk yk)</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>        b <span class="ot">=</span> <span class="dt">Zip</span> (\_ _ <span class="ot">-&gt;</span> [])</span></code></pre></div>
<p>And here we see the elusive hyperfunction: hidden behind a slight
change of parameter order, <code>Zip a b</code> is in fact the same as
<code>[(a,b)] -&amp;&gt; (a -&gt; [(a,b)])</code>.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> <span class="kw">forall</span> a b<span class="op">.</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs ys <span class="ot">=</span> invoke xz yz</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    xz ::</span> (a <span class="ot">-&gt;</span> [(a,b)]) <span class="op">-&amp;&gt;</span> [(a,b)]</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    xz <span class="ot">=</span> <span class="fu">foldr</span> f b xs</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>        f x xk <span class="ot">=</span> <span class="dt">Hyp</span> (\yk <span class="ot">-&gt;</span> invoke yk xk x)</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>        b <span class="ot">=</span> <span class="dt">Hyp</span> (\_ <span class="ot">-&gt;</span> [])</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="ot">    yz ::</span> [(a,b)] <span class="op">-&amp;&gt;</span> (a <span class="ot">-&gt;</span> [(a,b)])</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>    yz <span class="ot">=</span> <span class="fu">foldr</span> f b ys</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>        f y yk <span class="ot">=</span> <span class="dt">Hyp</span> (\xk x <span class="ot">-&gt;</span> (x,y) <span class="op">:</span> invoke xk yk)</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>        b <span class="ot">=</span> <span class="dt">Hyp</span> (\_ _ <span class="ot">-&gt;</span> [])</span></code></pre></div>
<h3 id="bfts">BFTs</h3>
<p>In <a href="2019-05-14-corecursive-implicit-queues.html">another
previous post</a> I derived the following function to do a breadth-first
traversal of a tree:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> a <span class="op">:&amp;</span> [<span class="dt">Tree</span> a]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q</span> a <span class="ot">=</span> <span class="dt">Q</span> {<span class="ot"> q ::</span> (<span class="dt">Q</span> a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> [a] }</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="ot">bfe ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>bfe t <span class="ot">=</span> q (f t b) e</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Q</span> a <span class="ot">-&gt;</span> <span class="dt">Q</span> a</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&amp;</span> xs) fw <span class="ot">=</span> <span class="dt">Q</span> (\bw <span class="ot">-&gt;</span> x <span class="op">:</span> q fw (bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> f) xs))</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="ot">    b ::</span> <span class="dt">Q</span> a</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> <span class="dt">Q</span> (\k <span class="ot">-&gt;</span> k b)</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a><span class="ot">    e ::</span> <span class="dt">Q</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    e (<span class="dt">Q</span> q) <span class="ot">=</span> q e</span></code></pre></div>
<p>That <code>Q</code> type there is another hyperfunction.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfe ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>bfe t <span class="ot">=</span> invoke (f t e) e</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> ([a] <span class="op">-&amp;&gt;</span> [a]) <span class="ot">-&gt;</span> ([a] <span class="op">-&amp;&gt;</span> [a])</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&amp;</span> xs) fw <span class="ot">=</span> <span class="dt">Hyp</span> (\bw <span class="ot">-&gt;</span> x <span class="op">:</span> invoke fw (<span class="dt">Hyp</span> (invoke bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> f) xs)))</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="ot">    e ::</span> [a] <span class="op">-&amp;&gt;</span> [a]</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> <span class="dt">Hyp</span> (\k <span class="ot">-&gt;</span> invoke k e)</span></code></pre></div>
<p>One of the problems I had with the above function was that it didn’t
terminate: it could enumerate all the elements of the tree but it didn’t
know when to stop. A similar program <span class="citation"
data-cites="allison_circular_2006 smith_lloyd_2009">(<a
href="#ref-allison_circular_2006" role="doc-biblioref">Allison 2006</a>;
described and translated to Haskell in <a href="#ref-smith_lloyd_2009"
role="doc-biblioref">Smith 2009</a>)</span> manages to solve the problem
with a counter. Will it shock you to find out this solution can also be
encoded with a hyperfunction?</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>bfe t <span class="ot">=</span> invoke (f t (<span class="dt">Hyp</span> b)) e <span class="dv">1</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> [a]) <span class="op">-&amp;&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> [a])</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>                <span class="ot">-&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> [a]) <span class="op">-&amp;&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> [a])</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&amp;</span> xs) fw <span class="ot">=</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Hyp</span> (\bw n <span class="ot">-&gt;</span> x <span class="op">:</span> invoke fw (<span class="dt">Hyp</span> (\k m <span class="ot">-&gt;</span> invoke bw (<span class="fu">foldr</span> f k xs) (m<span class="op">+</span><span class="dv">1</span>))) n)</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="ot">    e ::</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> [a]) <span class="op">-&amp;&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> [a])</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> <span class="dt">Hyp</span> (\k <span class="ot">-&gt;</span> invoke k e)</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>    b x <span class="dv">0</span> <span class="ot">=</span> []</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>    b x n <span class="ot">=</span> invoke x (<span class="dt">Hyp</span> b) (n<span class="op">-</span><span class="dv">1</span>)</span></code></pre></div>
<p><span class="citation" data-cites="smith_lloyd_2009">(my version here
is actually a good bit different from the one in <a
href="#ref-smith_lloyd_2009" role="doc-biblioref">Smith 2009</a>, but
the basic idea is the same)</span></p>
<h3 id="coroutines">Coroutines</h3>
<p>Hyperfunctions seem to me to be quite deeply related to coroutines.
At the very least several of the types involved in coroutine
implementations are actual hyperfunctions. The <code>ProdPar</code> and
<code>ConsPar</code> types from <span class="citation"
data-cites="pieters_faster_2019">Pieters and Schrijvers (<a
href="#ref-pieters_faster_2019" role="doc-biblioref">2019</a>)</span>
are good examples:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ProdPar</span> a b <span class="ot">=</span> <span class="dt">ProdPar</span> (<span class="dt">ConsPar</span> a b <span class="ot">-&gt;</span> b)</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ConsPar</span> a b <span class="ot">=</span> <span class="dt">ConsPar</span> (a <span class="ot">-&gt;</span> <span class="dt">ProdPar</span> a b <span class="ot">-&gt;</span> b)</span></code></pre></div>
<p><code>ProdPar a b</code> is isomorphic to
<code>(a -&gt; b) -&amp;&gt; b</code>, and <code>ConsPar a b</code> to
<code>b -&amp;&gt; (a -&gt; b)</code>, as witnessed by the following
functions:</p>
<details>
<summary>
Conversion functions between <code>ProdPar</code>, <code>ConsPar</code>
and hyperfunctions
</summary>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fromP ::</span> <span class="dt">ProdPar</span> a b <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="op">-&amp;&gt;</span> b</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>fromP (<span class="dt">ProdPar</span> x) <span class="ot">=</span> <span class="dt">Hyp</span> (x <span class="op">.</span> toC)</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ot">toC ::</span>  b <span class="op">-&amp;&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">ConsPar</span> a b</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>toC (<span class="dt">Hyp</span> h) <span class="ot">=</span> <span class="dt">ConsPar</span> (\x p <span class="ot">-&gt;</span> h (fromP p) x)</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a><span class="ot">toP ::</span> (a <span class="ot">-&gt;</span> b) <span class="op">-&amp;&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">ProdPar</span> a b</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>toP (<span class="dt">Hyp</span> x) <span class="ot">=</span> <span class="dt">ProdPar</span> (x <span class="op">.</span> fromC)</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a><span class="ot">fromC ::</span> <span class="dt">ConsPar</span> a b <span class="ot">-&gt;</span> b <span class="op">-&amp;&gt;</span> (a <span class="ot">-&gt;</span> b)</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>fromC (<span class="dt">ConsPar</span> p) <span class="ot">=</span> <span class="dt">Hyp</span> (\h x <span class="ot">-&gt;</span> p x (toP h))</span></code></pre></div>
</details>
<p>In fact this reveals a little about what was happening in the
<code>zip</code> function: we convert the left-hand list to a
<code>ProdPar</code> (producer), and the right-hand to a consumer, and
apply them to each other.</p>
<h1 id="hyperfunctions-are-weird">Hyperfunctions Are Weird</h1>
<p>Aside from just being kind of weird intuitively, hyperfunctions are
weird <em>in theory</em>. Set-theoretically, for instance, you cannot
form the set of <code>a -&amp;&gt; b</code>: if you tried, you’d run
into those pesky size restrictions which stop us from making things like
“the set of all sets”. Haskell types, however, are not sets, precisely
because we can define things like <code>a -&amp;&gt; b</code>.</p>
<p>For slightly different reasons to the set theory restrictions, we
can’t define the type of hyperfunctions in Agda. The following will get
an error:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> <span class="ot">_</span>↬<span class="ot">_</span> <span class="ot">(</span>A <span class="ot">:</span> Type a<span class="ot">)</span> <span class="ot">(</span>B <span class="ot">:</span> Type b<span class="ot">)</span> <span class="ot">:</span> Type <span class="ot">(</span>a ℓ⊔ b<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">inductive</span><span class="ot">;</span> <span class="kw">constructor</span> hyp</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span> invoke <span class="ot">:</span> <span class="ot">(</span>B ↬ A<span class="ot">)</span> <span class="ot">→</span> B</span></code></pre></div>
<p>And for good reason! Agda doesn’t allow recursive types where the
recursive call is in a negative position. If we turn off the positivity
checker, we can write Curry’s paradox (example proof taken from <a
href="https://stackoverflow.com/a/51253757/4892417">here</a>):</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>yes? <span class="ot">:</span> ⊥ ↬ ⊥</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>yes? <span class="ot">.</span>invoke h <span class="ot">=</span> h <span class="ot">.</span>invoke h</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>no! <span class="ot">:</span> <span class="ot">(</span>⊥ ↬ ⊥<span class="ot">)</span> <span class="ot">→</span> ⊥</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>no! h <span class="ot">=</span> h <span class="ot">.</span>invoke h</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>boom <span class="ot">:</span> ⊥</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>boom <span class="ot">=</span> no! yes?</span></code></pre></div>
<p>Note that this isn’t an issue with the termination checker: the above
example passes all the normal termination conditions without issue (yes,
even if <code>↬</code> is marked as <code>coinductive</code>). It’s
directly because the type itself is not positive.</p>
<p>Interestingly, there is a slightly different, and nearly equivalent,
definition of hyperfunctions which doesn’t allow us to write the above
proof:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> <span class="ot">_</span>↬<span class="ot">_</span> <span class="ot">(</span>A <span class="ot">:</span> Type a<span class="ot">)</span> <span class="ot">(</span>B <span class="ot">:</span> Type b<span class="ot">)</span> <span class="ot">:</span> Type <span class="ot">(</span>a ℓ⊔ b<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">inductive</span><span class="ot">;</span> <span class="kw">constructor</span> hyp</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span> invoke <span class="ot">:</span> <span class="ot">((</span>A ↬ B<span class="ot">)</span> <span class="ot">→</span> A<span class="ot">)</span> <span class="ot">→</span> B</span></code></pre></div>
<p>This is basically a slightly expanded out version of the
hyperfunction type, and importantly it’s <em>positive</em>. Not
<em>strictly</em> positive however, since the recursive call does occur
to the left of a function arrow: it’s just positive, in that it’s to the
left of an even number of function arrows.</p>
<p>I found in a blog post by <span class="citation"
data-cites="sjoberg_why_2015">Sjöberg (<a href="#ref-sjoberg_why_2015"
role="doc-biblioref">2015</a>)</span> some interesting discussion
regarding the question of this extra strictness: in Coq, allowing
certain positive but not <em>strictly</em> positive types does indeed
introduce an inconsistency <span class="citation"
data-cites="coquand_inductively_1990">(<a
href="#ref-coquand_inductively_1990" role="doc-biblioref">Coquand and
Paulin 1990</a>)</span>. However this inconsistency relies on an
impredicative universe, which Agda doesn’t have. As far as I understand
it, it would likely be safe to allow types like <code>↬</code> above in
Agda <span class="citation" data-cites="coquand_agda_2013">(<a
href="#ref-coquand_agda_2013" role="doc-biblioref">Coquand
2013</a>)</span>, although I’m not certain that with all of Agda’s newer
features that’s still the case.</p>
<p>The connection between non-strictly-positive types and breadth-first
traversals has been noticed before: <span class="citation"
data-cites="berger_martin_2019">Berger, Matthes, and Setzer (<a
href="#ref-berger_martin_2019" role="doc-biblioref">2019</a>)</span>
make the argument for their inclusion in Agda and Coq using a
breadth-first traversal algorithm by <span class="citation"
data-cites="hofmann_non_1993">Hofmann (<a href="#ref-hofmann_non_1993"
role="doc-biblioref">1993</a>)</span>, which uses the following
type:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Rou</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Over</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Next</span> ((<span class="dt">Rou</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>]) <span class="ot">-&gt;</span> [<span class="dt">Int</span>])</span></code></pre></div>
<p>Now this type <em>isn’t</em> a hyperfunction (but it’s close); we’ll
see soon what kind of thing it is.</p>
<h1 id="hyperfunctions-are-a-category">Hyperfunctions Are a
Category</h1>
<p>So we’ve seen that hyperfunctions show up kind of incidentally
through certain optimisations, and we’ve seen that they occupy a strange
space in terms of their theoretical interpretation: we haven’t yet seen
much about the type itself in isolation. Luckily Ed Kmett has already
written the <a
href="https://hackage.haskell.org/package/hyperfunctions">hyperfunctions
package</a> <span class="citation"
data-cites="kmett_hyperfunctions_2015">(<a
href="#ref-kmett_hyperfunctions_2015"
role="doc-biblioref">2015</a>)</span>, where a laundry list of instances
are provided, which can tell us a little more about what hyperfunctions
can actually do on their own.</p>
<p>The <code>Category</code> instance gives us the following:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Category</span> (<span class="op">-&amp;&gt;</span>) <span class="kw">where</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">id</span> <span class="ot">=</span> <span class="dt">Hyp</span> (\k <span class="ot">-&gt;</span> invoke k <span class="fu">id</span>)</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  f <span class="op">.</span> g <span class="ot">=</span> <span class="dt">Hyp</span> (\k <span class="ot">-&gt;</span> invoke f (g <span class="op">.</span> k))</span></code></pre></div>
<p>We’ve actually seen the identity function a few times: we used it as
the base case for recursion in the breadth-first traversal
algorithms.</p>
<p>Composition we actually have used as well but it’s more obscured. An
analogy to help clear things up is to think of hyperfunctions as a kind
of <em>stack</em>. <code>id</code> is the empty stack, and we can use
the following function to push items onto the stack:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">push ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a <span class="op">-&amp;&gt;</span> b <span class="ot">-&gt;</span> a <span class="op">-&amp;&gt;</span> b</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>push f q <span class="ot">=</span> <span class="dt">Hyp</span> (\k <span class="ot">-&gt;</span> f (invoke k q))</span></code></pre></div>
<p>Understood in this sense, composition acts like a zipping operation
on stacks, since we have the following law:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>push f p <span class="op">.</span> push g q ≡ push (f <span class="op">.</span> g) (p <span class="op">.</span> q)</span></code></pre></div>
<p>While we can’t really pop elements off the top of the stack directly,
we can get close with <code>invoke</code>, since it satisfies the
following law:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>invoke (push f p) q ≡ f (invoke q p)</span></code></pre></div>
<p>Along with the <code>id</code> implementation we have, this will let
us run a hyperfunction, basically folding over the contents of the
stack:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">run ::</span> a <span class="op">-&amp;&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>run f <span class="ot">=</span> invoke f <span class="fu">id</span></span></code></pre></div>
<p>This analogy helps us understand how the breadth-first traversals
worked: the hyperfunctions are kind of like stacks with
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
<code>push</code> and <code>zip</code>, which is precisely what you need
for an efficient breadth-first traversal.</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfe ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>bfe <span class="ot">=</span> run <span class="op">.</span> f</span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&amp;</span> xs) <span class="ot">=</span> push (x<span class="op">:</span>) (zips (<span class="fu">map</span> f xs))</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>    zips <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">.</span>) <span class="fu">id</span></span></code></pre></div>
<p>Finally, hyperfunctions are of course monads:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> ((<span class="op">-&amp;&gt;</span>) a) <span class="kw">where</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  m <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="dt">Hyp</span> (\k <span class="ot">-&gt;</span> invoke (f (invoke m (<span class="dt">Hyp</span> (invoke k <span class="op">.</span> (<span class="op">&gt;&gt;=</span>f))))) k)</span></code></pre></div>
<p>I won’t pretend to understand what’s going on here, but it looks a
little like a nested reader monad. Perhaps there’s some intuition to be
gained from noticing that
<code>a -&amp;&gt; a ~ Fix (Cont a)</code>.</p>
<h1 id="hyper-arrows-are">Hyper Arrows Are…?</h1>
<p>As I said in the introduction I’m kind of surprised there’s not more
research out there on hyperfunctions. Aside from the excellent papers by
<span class="citation" data-cites="launchbury_coroutining_2013">J.
Launchbury, Krstic, and Sauerwein (<a
href="#ref-launchbury_coroutining_2013"
role="doc-biblioref">2013</a>)</span> there’s just not much out there.
Maybe it’s that there’s not that much theoretical depth to them, but all
the same there are some clear questions worth looking into.</p>
<p>For example: is there a hyperfunction monad transformer? Or, failing
that, can you thread a monad through the type at any point, and do you
get anything interesting out?</p>
<p>I have made a little headway on this question, while fiddling with
one of the <code>bfe</code> definitions above. Basically I wanted to
remove the <code>Int</code> counter for the terminating
<code>bfe</code>, and I wanted to use a <code>Maybe</code> somewhere
instead. I ended up generalising from <code>Maybe</code> to any
<code>m</code>, yielding the following type:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">HypM</span> m a b <span class="ot">=</span> <span class="dt">HypM</span> {<span class="ot"> invokeM ::</span> m ((<span class="dt">HypM</span> m a b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b) }</span></code></pre></div>
<p>This does the job for the breadth-first traversal:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>bfe t <span class="ot">=</span> r (f t e)</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">HypM</span> <span class="dt">Maybe</span> [a] [a] <span class="ot">-&gt;</span> <span class="dt">HypM</span> <span class="dt">Maybe</span> [a] [a]</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&amp;</span> xs) fw <span class="ot">=</span> <span class="dt">HypM</span> (<span class="dt">Just</span> (\bw <span class="ot">-&gt;</span> x <span class="op">:</span> fromMaybe (\k <span class="ot">-&gt;</span> k e) (invokeM fw) (bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> f) xs)))</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    e ::</span> <span class="dt">HypM</span> <span class="dt">Maybe</span> [a] [a]</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> <span class="dt">HypM</span> <span class="dt">Nothing</span></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a><span class="ot">    r ::</span> <span class="dt">HypM</span> <span class="dt">Maybe</span> [a] [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>    r <span class="ot">=</span> <span class="fu">maybe</span> [] (\k <span class="ot">-&gt;</span> k r) <span class="op">.</span> invokeM</span></code></pre></div>
<p>(In fact, when <code>m</code> is specialised to <code>Maybe</code> we
have the same type as <code>Rou</code>)</p>
<p>This type has a very practical use, as it happens, which is related
to the church-encoded list monad transformer:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ListT</span> m a <span class="ot">=</span> <span class="dt">ListT</span> {<span class="ot"> runListT ::</span> <span class="kw">forall</span> b<span class="op">.</span> (a <span class="ot">-&gt;</span> m b <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m b <span class="ot">-&gt;</span> m b }</span></code></pre></div>
<p>Just like <code>-&amp;&gt;</code> allowed us to write
<code>zip</code> on folds (i.e. using <code>foldr</code>),
<code>HypM</code> will allow us to write <code>zipM</code> on
<code>ListT</code>:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipM ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">ListT</span> m a <span class="ot">-&gt;</span> <span class="dt">ListT</span> m b <span class="ot">-&gt;</span> <span class="dt">ListT</span> m (a,b)</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>zipM xs ys <span class="ot">=</span> <span class="dt">ListT</span> (\c n <span class="ot">-&gt;</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>    xf x xk <span class="ot">=</span> <span class="fu">pure</span> (\yk <span class="ot">-&gt;</span> yk (<span class="dt">HypM</span> xk) x)</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>    xb <span class="ot">=</span> <span class="fu">pure</span> (\_ <span class="ot">-&gt;</span> n)</span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>    yf y yk <span class="ot">=</span> <span class="fu">pure</span> (\xk x <span class="ot">-&gt;</span> c (x, y) (join (invokeM xk <span class="op">&lt;*&gt;</span> yk)))</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>    yb <span class="ot">=</span> <span class="fu">pure</span> (\_ _ <span class="ot">-&gt;</span> n)</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span> join (runListT xs xf xb <span class="op">&lt;*&gt;</span> runListT ys yf yb))</span></code></pre></div>
<p>I actually think this function could be used to seriously improve the
running time of several of the functions on <a
href="https://hackage.haskell.org/package/logict-0.7.1.0/docs/Control-Monad-Logic.html#g:2"><code>LogicT</code></a>:
my reading of them suggests that <code>interleave</code> is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>
(or worse), but the zip above could be trivially repurposed to give a
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
<code>interleave</code>. This would also have knock-on effects on, for
instance, <code>&gt;&gt;-</code> and so on.</p>
<p>Another question is regarding the arrows of the hyperfunction. We’ve
seen that a hyperfunction kind of adds “stacking” to functions, can it
do the same for other arrows? Basically, does the following type do
anything useful?</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">HypP</span> p a b <span class="ot">=</span> <span class="dt">HypP</span> {<span class="ot"> invokeP ::</span> p (<span class="dt">HypP</span> p b a) b }</span></code></pre></div>
<p>Along a similar vein, many of the breadth-first enumeration
algorithms seem to use “hyperfunctions over the endomorphism monoid”.
Basically, they all produce hyperfunctions of the type
<code>[a] -&amp;&gt; [a]</code>, and use them quite similarly to how we
would use difference lists. But we know that there are Cayley transforms
in other monoidal categories, for instance in the applicative monoidal
category: can we construct the “hyperfunction” version of those?</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-allison_circular_2006" class="csl-entry" role="listitem">
Allison, Lloyd. 2006. <span>“Circular <span>Programs</span> and
<span>Self</span>-<span>Referential Structures</span>.”</span>
<em>Software: Practice and Experience</em> 19 (2) (October): 99–109.
doi:<a
href="https://doi.org/10.1002/spe.4380190202">10.1002/spe.4380190202</a>.
<a
href="http://users.monash.edu/~lloyd/tildeFP/1989SPE/">http://users.monash.edu/~lloyd/tildeFP/1989SPE/</a>.
</div>
<div id="ref-berger_martin_2019" class="csl-entry" role="listitem">
Berger, Ulrich, Ralph Matthes, and Anton Setzer. 2019. <span>“Martin
<span>Hofmann</span>’s <span>Case</span> for
<span>Non</span>-<span>Strictly Positive Data Types</span>.”</span> In
<em>24th international conference on types for proofs and programs
(<span>TYPES</span> 2018)</em>, ed by. Peter Dybjer, José Espírito
Santo, and Luís Pinto, 130:22. Leibniz international proceedings in
informatics (<span>LIPIcs</span>). <span>Dagstuhl, Germany</span>:
<span>Schloss DagstuhlLeibniz-Zentrum fuer Informatik</span>. doi:<a
href="https://doi.org/10.4230/LIPIcs.TYPES.2018.1">10.4230/LIPIcs.TYPES.2018.1</a>.
<a
href="http://drops.dagstuhl.de/opus/volltexte/2019/11405">http://drops.dagstuhl.de/opus/volltexte/2019/11405</a>.
</div>
<div id="ref-coquand_agda_2013" class="csl-entry" role="listitem">
Coquand, Thierry. 2013. <span>“[<span>Agda</span>] defining coinductive
types.”</span> <a
href="https://lists.chalmers.se/pipermail/agda/2013/006189.html">https://lists.chalmers.se/pipermail/agda/2013/006189.html</a>.
</div>
<div id="ref-coquand_inductively_1990" class="csl-entry"
role="listitem">
Coquand, Thierry, and Christine Paulin. 1990. <span>“Inductively defined
types.”</span> In <em><span>COLOG</span>-88</em>, ed by. Per Martin-Löf
and Grigori Mints, 50–66. Lecture <span>Notes</span> in <span>Computer
Science</span>. <span>Berlin, Heidelberg</span>: <span>Springer</span>.
doi:<a
href="https://doi.org/10.1007/3-540-52335-9_47">10.1007/3-540-52335-9_47</a>.
</div>
<div id="ref-ghani_monadic_2005" class="csl-entry" role="listitem">
Ghani, Neil, Patricia Johann, Tarmo Uustalu, and Varmo Vene. 2005.
<span>“Monadic augment and generalised short cut fusion.”</span> In
<em>Proceedings of the tenth <span>ACM SIGPLAN</span> international
conference on <span>Functional</span> programming</em>, 294–305.
<span>ICFP</span> ’05. <span>New York, NY, USA</span>: <span>Association
for Computing Machinery</span>. doi:<a
href="https://doi.org/10.1145/1086365.1086403">10.1145/1086365.1086403</a>.
<a
href="https://doi.org/10.1145/1086365.1086403">https://doi.org/10.1145/1086365.1086403</a>.
</div>
<div id="ref-hedges_selection_2015" class="csl-entry" role="listitem">
Hedges, Jules. 2015. <span>“The selection monad as a <span>CPS</span>
transformation.”</span> <em>arXiv:1503.06061 [cs]</em> (March). <a
href="http://arxiv.org/abs/1503.06061">http://arxiv.org/abs/1503.06061</a>.
</div>
<div id="ref-hofmann_non_1993" class="csl-entry" role="listitem">
Hofmann, Martin. 1993. <span>“Non <span>Strictly Positive
Datatypes</span> in <span>System F</span>.”</span> <a
href="https://www.seas.upenn.edu/~sweirich/types/archive/1993/msg00027.html">https://www.seas.upenn.edu/~sweirich/types/archive/1993/msg00027.html</a>.
</div>
<div id="ref-kmett_hyperfunctions_2015" class="csl-entry"
role="listitem">
Kmett, Edward. 2015. <span>“Hyperfunctions:
<span>Hyperfunctions</span>.”</span> <a
href="https://hackage.haskell.org/package/hyperfunctions">https://hackage.haskell.org/package/hyperfunctions</a>.
</div>
<div id="ref-krstic_category_2000" class="csl-entry" role="listitem">
Krstic, Sava, and John Launchbury. 2000. <span>“A <span>Category</span>
of <span>Hyperfunctions</span>.”</span> <a
href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.2421">http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.2421</a>.
</div>
<div id="ref-launchbury_coroutining_2013" class="csl-entry"
role="listitem">
Launchbury, J., S. Krstic, and T. E. Sauerwein. 2013. <span>“Coroutining
<span>Folds</span> with <span>Hyperfunctions</span>.”</span>
<em>Electron. Proc. Theor. Comput. Sci.</em> 129 (September): 121–135.
doi:<a
href="https://doi.org/10.4204/EPTCS.129.9">10.4204/EPTCS.129.9</a>. <a
href="http://arxiv.org/abs/1309.5135">http://arxiv.org/abs/1309.5135</a>.
</div>
<div id="ref-launchbury_zip_2000" class="csl-entry" role="listitem">
Launchbury, John, Sava Krstic, and Timothy E. Sauerwein. 2000. <em>Zip
<span>Fusion</span> with <span>Hyperfunctions</span></em>. <a
href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.4961">http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.36.4961</a>.
</div>
<div id="ref-pieters_faster_2019" class="csl-entry" role="listitem">
Pieters, Ruben P., and Tom Schrijvers. 2019. <span>“Faster
<span>Coroutine Pipelines</span>: <span>A Reconstruction</span>.”</span>
In <em>Practical <span>Aspects</span> of <span>Declarative
Languages</span></em>, ed by. José Júlio Alferes and Moa Johansson,
133–149. Lecture <span>Notes</span> in <span>Computer Science</span>.
<span>Cham</span>: <span>Springer International Publishing</span>.
doi:<a
href="https://doi.org/10.1007/978-3-030-05998-9_9">10.1007/978-3-030-05998-9_9</a>.
<a
href="https://people.cs.kuleuven.be/~tom.schrijvers/portfolio/padl2019.html">https://people.cs.kuleuven.be/~tom.schrijvers/portfolio/padl2019.html</a>.
</div>
<div id="ref-sjoberg_why_2015" class="csl-entry" role="listitem">
Sjöberg, Vilhelm. 2015. <span>“Why must inductive types be strictly
positive?”</span> <em>Code and stuff</em>. <a
href="https://vilhelms.github.io/posts/why-must-inductive-types-be-strictly-positive/">https://vilhelms.github.io/posts/why-must-inductive-types-be-strictly-positive/</a>.
</div>
<div id="ref-smith_lloyd_2009" class="csl-entry" role="listitem">
Smith, Leon P. 2009. <span>“Lloyd <span>Allison</span>’s
<span>Corecursive Queues</span>: <span>Why Continuations
Matter</span>.”</span> <em>The Monad.Reader</em> 14 (14) (July): 28. <a
href="https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf">https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Sun, 14 Mar 2021 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2021-03-14-hyperfunctions.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Master's Thesis</title>
    <link>https://doisinkidney.com/posts/2021-01-04-masters-thesis.html</link>
    <description><![CDATA[<div class="info">
    Posted on January  4, 2021
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>The final version of my master’s thesis got approved recently so I
thought I’d post it here for people who might be interested.</p>
<p><a href="https://cora.ucc.ie/handle/10468/11338">Here’s the
university record</a>.</p>
<p><a href="../pdfs/masters-thesis.pdf">Here’s the pdf</a>.</p>
<p>And all of the theorems in the thesis have been formalised in Agda.
The code is organised to follow the structure of the pdf <a
href="../code/masters-thesis/README.html">here</a>.</p>
<p>The title of the thesis is “Finiteness in Cubical Type Theory”:
basically it’s all about formalising the notion of “this type is finite”
in CuTT. I also wanted to write something that could serve as a kind of
introduction to some components of modern dependent type theory which
didn’t go the standard length-indexed vector route.</p>
]]></description>
    <pubDate>Mon, 04 Jan 2021 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2021-01-04-masters-thesis.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Trees indexed by a Cayley Monoid</title>
    <link>https://doisinkidney.com/posts/2020-12-27-cayley-trees.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 27, 2020
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>The Cayley monoid is well-known in Haskell (difference lists, for
instance, are a specific instance of the Cayley monoid), because it
gives us
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(1)</annotation></semantics></math>
<code>&lt;&gt;</code>. What’s less well known is that it’s also
important in dependently typed programming, because it gives us
definitional associativity. In other words, the type
<code>x . (y . z)</code> is definitionally equal to
<code>(x . y) . z</code> in the Cayley monoid.</p>
<details>
<summary>
Some helpers and extra code
</summary>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Nat</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Nat</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> (<span class="op">+</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>) (<span class="ot">m ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Nat</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span>   <span class="op">+</span> m <span class="ot">=</span> m</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">S</span> n <span class="op">+</span> m <span class="ot">=</span> <span class="dt">S</span> (n <span class="op">+</span> m)</span></code></pre></div>
</details>
<p>I used a form of the type-level Cayley monoid in a <a
href="2020-02-15-taba.html">previous post</a> to type vector reverse
without proofs. I figured out the other day another way to use it to
type tree flattening.</p>
<p>Say we have a size-indexed tree and vector:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> (<span class="ot">a ::</span> <span class="dt">Type</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Leaf</span><span class="ot">  ::</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a (<span class="dt">S</span> <span class="dt">Z</span>)</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:*:) ::</span> <span class="dt">Tree</span> a n <span class="ot">-&gt;</span> <span class="dt">Tree</span> a m <span class="ot">-&gt;</span> <span class="dt">Tree</span> a (n <span class="op">+</span> m)</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Vec</span> (<span class="ot">a ::</span> <span class="dt">Type</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">Vec</span> a <span class="dt">Z</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:-) ::</span> a <span class="ot">-&gt;</span> <span class="dt">Vec</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> a (<span class="dt">S</span> n)</span></code></pre></div>
<p>And we want to flatten it to a list in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(n)</annotation></semantics></math>
time:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeToList ::</span> <span class="dt">Tree</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> a n</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>treeToList xs <span class="ot">=</span> go xs <span class="dt">Nil</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">Tree</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> a m <span class="ot">-&gt;</span> <span class="dt">Vec</span> a (n <span class="op">+</span> m)</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Leaf</span>    x) ks <span class="ot">=</span> x <span class="op">:-</span> ks</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    go (xs <span class="op">:*:</span> ys) ks <span class="ot">=</span> go xs (go ys ks)</span></code></pre></div>
<p>Haskell would complain specifically that you hadn’t proven the monoid
laws:</p>
<pre><code>• Couldn&#39;t match type ‘n’ with ‘n + &#39;Z’
• Could not deduce: (n2 + (m1 + m)) ~ ((n2 + m1) + m)</code></pre>
<p>But it seems difficult at first to figure out how we can apply the
same trick as we used for vector reverse: there’s no real way for the
<code>Tree</code> type to hold a function from <code>Nat</code> to
<code>Nat</code>.</p>
<p>To solve this problem we can borrow a trick that Haskellers had to
use in the good old days before type families to represent type-level
functions: types (or more usually classes) with multiple parameters.</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree&#39;</span> (<span class="ot">a ::</span> <span class="dt">Type</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>) (<span class="ot">m ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Leaf</span><span class="ot">  ::</span> a <span class="ot">-&gt;</span> <span class="dt">Tree&#39;</span> a n (<span class="dt">S</span> n)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:*:) ::</span> <span class="dt">Tree&#39;</span> a n2 n3</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">Tree&#39;</span> a n1 n2</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">Tree&#39;</span> a n1 n3</span></code></pre></div>
<p>The <code>Tree'</code> type here has three parameters: we’re
interested in the last two. The first of these is actually an argument
to a function in disguise; the second is its result. To make it back
into a normal size-indexed tree, we apply that function to zero:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Tree</span> a <span class="ot">=</span> <span class="dt">Tree&#39;</span> a <span class="dt">Z</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ot">three ::</span> <span class="dt">Tree</span> <span class="dt">Int</span> (<span class="dt">S</span> (<span class="dt">S</span> (<span class="dt">S</span> <span class="dt">Z</span>)))</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>three <span class="ot">=</span> (<span class="dt">Leaf</span> <span class="dv">1</span> <span class="op">:*:</span> <span class="dt">Leaf</span> <span class="dv">2</span>) <span class="op">:*:</span> <span class="dt">Leaf</span> <span class="dv">3</span></span></code></pre></div>
<p>This makes the <code>treeToList</code> function typecheck without
complaint:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeToList ::</span> <span class="dt">Tree</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> a n</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>treeToList xs <span class="ot">=</span> go xs <span class="dt">Nil</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">Tree&#39;</span> a x y <span class="ot">-&gt;</span> <span class="dt">Vec</span> a x <span class="ot">-&gt;</span> <span class="dt">Vec</span> a y</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Leaf</span>    x) ks <span class="ot">=</span> x <span class="op">:-</span> ks</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    go (xs <span class="op">:*:</span> ys) ks <span class="ot">=</span> go xs (go ys ks)</span></code></pre></div>
]]></description>
    <pubDate>Sun, 27 Dec 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-12-27-cayley-trees.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Enumerating Trees</title>
    <link>https://doisinkidney.com/posts/2020-12-14-enumerating-trees.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 14, 2020
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>, <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Consider the following puzzle:</p>
<blockquote>
<p>Given a list of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
labels, list all the trees with those labels in order.</p>
</blockquote>
<p>For instance, given the labels [1,2,3,4], the answer (for binary
trees) is the following:</p>
<pre><code>┌1     ┌1      ┌1     ┌1     ┌1
┤      ┤      ┌┤     ┌┤     ┌┤
│┌2    │ ┌2   ││┌2   │└2    │└2
└┤     │┌┤    │└┤    ┤     ┌┤
 │┌3   ││└3   │ └3   │┌3   │└3
 └┤    └┤     ┤      └┤    ┤
  └4    └4    └4      └4   └4</code></pre>
<p>This problem (the “enumeration” problem) turns out to be quite
fascinating and deep, with connections to parsing and monoids. It’s also
just a classic algorithmic problem which is fun to try and solve.</p>
<p>The most general version of the algorithm is on forests of rose
trees:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Rose</span> a <span class="ot">=</span> a <span class="op">:&amp;</span> <span class="dt">Forest</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Forest</span> a <span class="ot">=</span> [<span class="dt">Rose</span> a]</span></code></pre></div>
<p>It’s worth having a go at attempting it yourself, but if you’d just
like to see the slick solutions the following is one I’m especially
proud of:</p>
<details>
<summary>
Solution to the Enumeration Problem on Forests of Rose Trees
</summary>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">enumForests ::</span> [a] <span class="ot">-&gt;</span> [<span class="dt">Forest</span> a]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>enumForests <span class="ot">=</span> foldrM f []</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    f x xs <span class="ot">=</span> <span class="fu">zipWith</span> ((<span class="op">:</span>) <span class="op">.</span> (<span class="op">:&amp;</span>) x) (inits xs) (tails xs)</span></code></pre></div>
</details>
<p>In the rest of this post I’ll go through the intuition behind
solutions like the one above and I’ll try to elucidate some of the
connections to other areas of computer science.</p>
<h1 id="a-first-approach-trying-to-enumerate-directly">A First Approach:
Trying to Enumerate Directly</h1>
<p>I first came across the enumeration problem when I was writing my
master’s thesis: I needed to prove (in Agda) that there were finitely
many binary trees of a given size, and that I could list them (this
proof was part of a larger verified solver for the countdown problem).
My first few attempts were unsuccessful: the algorithm presented in the
countdown paper <span class="citation"
data-cites="hutton_countdown_2002">(<a href="#ref-hutton_countdown_2002"
role="doc-biblioref">Hutton 2002</a>)</span> was not structurally
recursive, and did not seem amenable to Agda-style proofs.</p>
<p>Instead, I looked for a type which was isomorphic to binary trees,
and which might be easier to reason about. One such type is Dyck
words.</p>
<h1 id="dyck-words">Dyck Words</h1>
<p>A “Dyck word” is a string of balanced parentheses.</p>
<pre><code>()()
(()())()
(())()</code></pre>
<p>It’s (apparently) well-known that these strings are isomorphic to
binary trees (although the imperative descriptions of algorithms which
actually computed this isomorphism addled my brain), but what made them
interesting for me was that they are a <em>flat</em> type, structured
like a linked list, and as such should be reasonably straightforward to
prove to be finite.</p>
<p>Our first task, then, is to write down a type for Dyck words. The
following is a first possibility:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Paren</span> <span class="ot">=</span> <span class="dt">LParen</span> <span class="op">|</span> <span class="dt">RParen</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Dyck</span> <span class="ot">=</span> [<span class="dt">Paren</span>]</span></code></pre></div>
<p>But this type isn’t correct. It includes many values which
<em>don’t</em> represent balanced parentheses, i.e. the expressions
<code>[LParen,RParen] :: Dyck</code> are well-typed. To describe dyck
words properly we’ll need to reach for the GADTs:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">DyckSuff</span> (<span class="ot">n ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Done</span><span class="ot"> ::</span> <span class="dt">DyckSuff</span> <span class="dt">Z</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Open</span><span class="ot"> ::</span> <span class="dt">DyckSuff</span> (<span class="dt">S</span> n) <span class="ot">-&gt;</span> <span class="dt">DyckSuff</span> n</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Clos</span><span class="ot"> ::</span> <span class="dt">DyckSuff</span> n     <span class="ot">-&gt;</span> <span class="dt">DyckSuff</span> (<span class="dt">S</span> n)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Dyck</span> <span class="ot">=</span> <span class="dt">DyckSuff</span> <span class="dt">Z</span></span></code></pre></div>
<p>The first type here represents suffixes of Dyck words; a value of
type <code>DyckSuff n</code> represents a string of parentheses which is
balanced except for <code>n</code> extraneous closing parentheses.
<code>DyckSuff Z</code>, then, has no extraneous closing parens, and as
such is a proper Dyck word.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Done</span><span class="ot"> ::</span> <span class="dt">Dyck</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>()()</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Done</span><span class="ot"> ::</span> <span class="dt">DyckSuff</span> (<span class="dt">S</span> <span class="dt">Z</span>)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>)()</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Done</span><span class="ot"> ::</span> <span class="dt">Dyck</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>(()())()</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Open</span> <span class="op">$</span> <span class="dt">Clos</span> <span class="op">$</span> <span class="dt">Done</span><span class="ot"> ::</span> <span class="dt">Dyck</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>(())()</span></code></pre></div>
<p>The next task is to actually enumerate these words. Here’s an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(n)</annotation></semantics></math>
algorithm which does just that:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">enumDyck ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [<span class="dt">Dyck</span>]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>enumDyck sz <span class="ot">=</span> go <span class="dt">Zy</span> sz <span class="dt">Done</span> []</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    go, zero, left,<span class="ot"> right ::</span> <span class="dt">Natty</span> n <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">DyckSuff</span> n <span class="ot">-&gt;</span> [<span class="dt">Dyck</span>] <span class="ot">-&gt;</span> [<span class="dt">Dyck</span>]</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    go n m k <span class="ot">=</span> zero n m k <span class="op">.</span> left n m k <span class="op">.</span> right n m k</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    zero <span class="dt">Zy</span> <span class="dv">0</span> k <span class="ot">=</span> (k<span class="op">:</span>)</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    zero _  _ _ <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    left (<span class="dt">Sy</span> n) m k <span class="ot">=</span> go n m (<span class="dt">Open</span> k)</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>    left <span class="dt">Zy</span>     _ _ <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>    right _ <span class="dv">0</span> _ <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    right n m k <span class="ot">=</span> go (<span class="dt">Sy</span> n) (m<span class="op">-</span><span class="dv">1</span>) (<span class="dt">Clos</span> k)</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">mapM_</span> <span class="fu">print</span> (enumDyck <span class="dv">3</span>)</span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;()()()&quot;</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;(())()&quot;</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;()(())&quot;</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;(()())&quot;</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;((()))&quot;</span></span></code></pre></div>
<p>A variant of this function was what I needed in my thesis: I also
needed to prove that it produced every possible value of the type
<code>Dyck</code>, which was not too difficult.</p>
<p>The difficult part is still ahead, though: now we need to convert
between this type and a binary tree.</p>
<h1 id="conversion">Conversion</h1>
<p>First, for the conversion algorithms we’ll actually need another
GADT:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Stack</span> (<span class="ot">a ::</span> <span class="dt">Type</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">Stack</span> a <span class="dt">Z</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:-) ::</span> a <span class="ot">-&gt;</span> <span class="dt">Stack</span> a n <span class="ot">-&gt;</span> <span class="dt">Stack</span> a (<span class="dt">S</span> n)</span></code></pre></div>
<p>The familiar length-indexed vector will be extremely useful for the
next few bits of code: it will act as a stack in our stack-based
algorithms. Here’s one of those algorithms now:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dyckToTree ::</span> <span class="dt">Dyck</span> <span class="ot">-&gt;</span> <span class="dt">Tree</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>dyckToTree dy <span class="ot">=</span> go dy (<span class="dt">Leaf</span> <span class="op">:-</span> <span class="dt">Nil</span>)</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">DyckSuff</span> n <span class="ot">-&gt;</span> <span class="dt">Stack</span> <span class="dt">Tree</span> (<span class="dt">S</span> n) <span class="ot">-&gt;</span> <span class="dt">Tree</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Open</span> d) ts               <span class="ot">=</span> go d (<span class="dt">Leaf</span> <span class="op">:-</span> ts)</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Clos</span> d) (t1 <span class="op">:-</span> t2 <span class="op">:-</span> ts) <span class="ot">=</span> go d (t2 <span class="op">:*:</span> t1 <span class="op">:-</span> ts)</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    go <span class="dt">Done</span>     (t  <span class="op">:-</span> <span class="dt">Nil</span>)      <span class="ot">=</span> t</span></code></pre></div>
<p>This might be familiar: it’s actually shift-reduce parsing dressed up
with some types. The nice thing about it is that it’s completely total:
all pattern-matches are accounted for here, and when written in Agda
it’s clearly structurally terminating.</p>
<p>The function in the other direction is similarly simple:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeToDyck ::</span> <span class="dt">Tree</span> <span class="ot">-&gt;</span> <span class="dt">Dyck</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>treeToDyck t <span class="ot">=</span> go t <span class="dt">Done</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">Tree</span> <span class="ot">-&gt;</span> <span class="dt">DyckSuff</span> n <span class="ot">-&gt;</span> <span class="dt">DyckSuff</span> n</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>    go <span class="dt">Leaf</span>        <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    go (xs <span class="op">:*:</span> ys) <span class="ot">=</span> go xs <span class="op">.</span> <span class="dt">Open</span> <span class="op">.</span> go ys <span class="op">.</span> <span class="dt">Clos</span></span></code></pre></div>
<h1 id="a-compiler">A Compiler</h1>
<p>Much of this stuff has been on my mind recently because of <a
href="https://www.youtube.com/watch?v=T_IINWzQhow">this</a> <span
class="citation" data-cites="riley_program_2020">(<a
href="#ref-riley_program_2020" role="doc-biblioref">2020</a>)</span>
video on the computerphile channel, in which Graham Hutton goes through
using QuickCheck to test an interesting compiler. The compiler itself is
explored more in depth in <span class="citation"
data-cites="bahr_calculating_2015">Bahr and Hutton (<a
href="#ref-bahr_calculating_2015" role="doc-biblioref">2015</a>)</span>,
where the algorithms developed are really quite similar to those that we
have here.</p>
<p>The advantage of the code above is that it’s all <em>total</em>: we
will never pop items off the stack that aren’t there. This is a nice
addition, and it’s surprisingly simple to add: let’s see if we can add
it to the compiler presented in the paper.</p>
<p>The first thing we need to change is we need to add a payload to our
tree type: the one above is just the <em>shape</em> of a binary tree,
but the language presented in the paper contains values.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Expr</span> (<span class="ot">a ::</span> <span class="dt">Type</span>) <span class="kw">where</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Val</span><span class="ot">   ::</span> a <span class="ot">-&gt;</span> <span class="dt">Expr</span> a</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:+:) ::</span> <span class="dt">Expr</span> a <span class="ot">-&gt;</span> <span class="dt">Expr</span> a <span class="ot">-&gt;</span> <span class="dt">Expr</span> a</span></code></pre></div>
<p>We’ll need to change the definition of <code>Dyck</code>
similarly:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Code</span> (<span class="ot">n ::</span> <span class="dt">Nat</span>) (<span class="ot">a ::</span> <span class="dt">Type</span>)<span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HALT</span><span class="ot"> ::</span> <span class="dt">Code</span> (<span class="dt">S</span> <span class="dt">Z</span>) a</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">PUSH</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Code</span> (<span class="dt">S</span> n) a <span class="ot">-&gt;</span> <span class="dt">Code</span> n a</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">ADD</span><span class="ot">  ::</span> <span class="dt">Code</span> (<span class="dt">S</span> n) a <span class="ot">-&gt;</span> <span class="dt">Code</span> (<span class="dt">S</span> (<span class="dt">S</span> n)) a</span></code></pre></div>
<p>After making it so that these data structures can now store contents,
there are two other changes worth pointing out:</p>
<ul>
<li>The names have been changed, to match those in the paper. It’s a
little clearer now that the Dyck word is a bit like code for a simple
stack machine.</li>
<li>The numbering on <code>Code</code> has changed. Now, the
<code>HALT</code> constructor has a parameter of <code>1</code> (well,
<code>S Z</code>), where its corresponding constructor in
<code>Dyck</code> (<code>Done</code>) had <code>0</code>. Why is this? I
am not entirely sure! To get this stuff to all work out nicely took a
huge amount of trial and error, I would love to see a more principled
reason why the numbering changed here.</li>
</ul>
<p>With these definitions we can actually transcribe the
<code>exec</code> and <code>comp</code> functions almost verbatim <span
class="citation" data-cites="bahr_calculating_2015">(from page 11 and 12
of <a href="#ref-bahr_calculating_2015"
role="doc-biblioref">2015</a>)</span>.</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">exec ::</span> <span class="dt">Code</span> n <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Stack</span> <span class="dt">Int</span> (n <span class="op">+</span> m) <span class="ot">-&gt;</span> <span class="dt">Stack</span> <span class="dt">Int</span> (<span class="dt">S</span> m)</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>exec <span class="dt">HALT</span>         st              <span class="ot">=</span> st</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>exec (<span class="dt">PUSH</span> v is)  st              <span class="ot">=</span> exec is (v <span class="op">:-</span> st)</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>exec (<span class="dt">ADD</span>    is) (t1 <span class="op">:-</span> t2 <span class="op">:-</span> st) <span class="ot">=</span> exec is (t2 <span class="op">+</span> t1 <span class="op">:-</span> st)</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="ot">comp ::</span> <span class="dt">Expr</span> a <span class="ot">-&gt;</span> <span class="dt">Code</span> <span class="dt">Z</span> a</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>comp e <span class="ot">=</span> comp&#39; e <span class="dt">HALT</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a><span class="ot">    comp&#39; ::</span> <span class="dt">Expr</span> a <span class="ot">-&gt;</span> <span class="dt">Code</span> (<span class="dt">S</span> n) a <span class="ot">-&gt;</span> <span class="dt">Code</span> n a</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>    comp&#39; (<span class="dt">Val</span>     x) <span class="ot">=</span> <span class="dt">PUSH</span> x</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>    comp&#39; (xs <span class="op">:+:</span> ys) <span class="ot">=</span> comp&#39; xs <span class="op">.</span> comp&#39; ys <span class="op">.</span> <span class="dt">ADD</span></span></code></pre></div>
<h1 id="proving-the-isomorphism">Proving the Isomorphism</h1>
<p>As I have mentioned, a big benefit of all of this stuff is that it
can be translated into Agda readily. The real benefit of <em>that</em>
is that we can show the two representations of programs are fully
isomorphic. I have proven this <a
href="https://github.com/oisdk/agda-playground/blob/d7234c276f063dbb4a2d2cbcedb86dd48501a908/Data/Dyck/Payload.agda">here</a>:
the proof is surprisingly short (about 20 lines), and the rest of the
code follows the Haskell stuff quite closely. I got the idea for much of
the proof from <a
href="https://gist.github.com/Boarders/9d83f9cbcfaffb04cf2464588fc46df9">this</a>
bit of code by <a href="https://boarders.github.io/">Callan McGill</a>
<span class="citation" data-cites="mcgill_compiler_2020">(<a
href="#ref-mcgill_compiler_2020"
role="doc-biblioref">2020</a>)</span>.</p>
<p>I’ll include it here as a reference.</p>
<details>
<summary>
Agda Code
</summary>
<div class="sourceCode" id="cb15"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> <span class="kw">import</span> Prelude</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> <span class="kw">import</span> Data<span class="ot">.</span>Nat <span class="kw">using</span> <span class="ot">(_</span>+<span class="ot">_)</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> <span class="kw">import</span> Data<span class="ot">.</span>Vec<span class="ot">.</span>Iterated <span class="kw">using</span> <span class="ot">(</span>Vec<span class="ot">;</span> <span class="ot">_</span>∷<span class="ot">_;</span> []<span class="ot">;</span> foldlN<span class="ot">;</span> head<span class="ot">)</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">variable</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    n <span class="ot">:</span> ℕ</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- Binary trees: definition and associated functions</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Tree <span class="ot">(</span>A <span class="ot">:</span> Type a<span class="ot">)</span> <span class="ot">:</span> Type a <span class="kw">where</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>  [<span class="ot">_</span>] <span class="ot">:</span> A <span class="ot">→</span> Tree A</span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>*<span class="ot">_</span> <span class="ot">:</span> Tree A <span class="ot">→</span> Tree A <span class="ot">→</span> Tree A</span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a><span class="co">-- Programs: definition and associated functions</span></span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Prog <span class="ot">(</span>A <span class="ot">:</span> Type a<span class="ot">)</span> <span class="ot">:</span> ℕ <span class="ot">→</span> Type a <span class="kw">where</span></span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a>  halt <span class="ot">:</span> Prog A <span class="dv">1</span></span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a>  push <span class="ot">:</span> A <span class="ot">→</span> Prog A <span class="ot">(</span><span class="dv">1</span> + n<span class="ot">)</span> <span class="ot">→</span> Prog A n</span>
<span id="cb15-24"><a href="#cb15-24" aria-hidden="true" tabindex="-1"></a>  pull <span class="ot">:</span> Prog A <span class="ot">(</span><span class="dv">1</span> + n<span class="ot">)</span> <span class="ot">→</span> Prog A <span class="ot">(</span><span class="dv">2</span> + n<span class="ot">)</span></span>
<span id="cb15-25"><a href="#cb15-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-26"><a href="#cb15-26" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-27"><a href="#cb15-27" aria-hidden="true" tabindex="-1"></a><span class="co">-- Conversion from a Prog to a Tree</span></span>
<span id="cb15-28"><a href="#cb15-28" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-29"><a href="#cb15-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-30"><a href="#cb15-30" aria-hidden="true" tabindex="-1"></a>prog→tree⊙ <span class="ot">:</span> Prog A n <span class="ot">→</span> Vec <span class="ot">(</span>Tree A<span class="ot">)</span> n <span class="ot">→</span> Tree A</span>
<span id="cb15-31"><a href="#cb15-31" aria-hidden="true" tabindex="-1"></a>prog→tree⊙ halt        <span class="ot">(</span>v ∷ []<span class="ot">)</span>       <span class="ot">=</span> v</span>
<span id="cb15-32"><a href="#cb15-32" aria-hidden="true" tabindex="-1"></a>prog→tree⊙ <span class="ot">(</span>push v is<span class="ot">)</span> st             <span class="ot">=</span> prog→tree⊙ is <span class="ot">(</span>[ v ] ∷ st<span class="ot">)</span></span>
<span id="cb15-33"><a href="#cb15-33" aria-hidden="true" tabindex="-1"></a>prog→tree⊙ <span class="ot">(</span>pull   is<span class="ot">)</span> <span class="ot">(</span>t₁ ∷ t₂ ∷ st<span class="ot">)</span> <span class="ot">=</span> prog→tree⊙ is <span class="ot">(</span>t₂ * t₁ ∷ st<span class="ot">)</span></span>
<span id="cb15-34"><a href="#cb15-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-35"><a href="#cb15-35" aria-hidden="true" tabindex="-1"></a>prog→tree <span class="ot">:</span> Prog A zero <span class="ot">→</span> Tree A</span>
<span id="cb15-36"><a href="#cb15-36" aria-hidden="true" tabindex="-1"></a>prog→tree ds <span class="ot">=</span> prog→tree⊙ ds []</span>
<span id="cb15-37"><a href="#cb15-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-38"><a href="#cb15-38" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-39"><a href="#cb15-39" aria-hidden="true" tabindex="-1"></a><span class="co">-- Conversion from a Tree to a Prog</span></span>
<span id="cb15-40"><a href="#cb15-40" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-41"><a href="#cb15-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-42"><a href="#cb15-42" aria-hidden="true" tabindex="-1"></a>tree→prog⊙ <span class="ot">:</span> Tree A <span class="ot">→</span> Prog A <span class="ot">(</span>suc n<span class="ot">)</span> <span class="ot">→</span> Prog A n</span>
<span id="cb15-43"><a href="#cb15-43" aria-hidden="true" tabindex="-1"></a>tree→prog⊙ [ x ]     <span class="ot">=</span> push x</span>
<span id="cb15-44"><a href="#cb15-44" aria-hidden="true" tabindex="-1"></a>tree→prog⊙ <span class="ot">(</span>xs * ys<span class="ot">)</span> <span class="ot">=</span> tree→prog⊙ xs ∘ tree→prog⊙ ys ∘ pull</span>
<span id="cb15-45"><a href="#cb15-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-46"><a href="#cb15-46" aria-hidden="true" tabindex="-1"></a>tree→prog <span class="ot">:</span> Tree A <span class="ot">→</span> Prog A zero</span>
<span id="cb15-47"><a href="#cb15-47" aria-hidden="true" tabindex="-1"></a>tree→prog tr <span class="ot">=</span> tree→prog⊙ tr halt</span>
<span id="cb15-48"><a href="#cb15-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-49"><a href="#cb15-49" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-50"><a href="#cb15-50" aria-hidden="true" tabindex="-1"></a><span class="co">-- Proof of isomorphism</span></span>
<span id="cb15-51"><a href="#cb15-51" aria-hidden="true" tabindex="-1"></a><span class="co">--------------------------------------------------------------------------------</span></span>
<span id="cb15-52"><a href="#cb15-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-53"><a href="#cb15-53" aria-hidden="true" tabindex="-1"></a>tree→prog→tree⊙ <span class="ot">:</span> <span class="ot">(</span>e <span class="ot">:</span> Tree A<span class="ot">)</span> <span class="ot">(</span>is <span class="ot">:</span> Prog A <span class="ot">(</span><span class="dv">1</span> + n<span class="ot">))</span> <span class="ot">(</span>st <span class="ot">:</span> Vec <span class="ot">(</span>Tree A<span class="ot">)</span> n<span class="ot">)</span> <span class="ot">→</span></span>
<span id="cb15-54"><a href="#cb15-54" aria-hidden="true" tabindex="-1"></a>  prog→tree⊙ <span class="ot">(</span>tree→prog⊙ e is<span class="ot">)</span> st ≡ prog→tree⊙ is <span class="ot">(</span>e ∷ st<span class="ot">)</span></span>
<span id="cb15-55"><a href="#cb15-55" aria-hidden="true" tabindex="-1"></a>tree→prog→tree⊙ [ x ]     is st <span class="ot">=</span> refl</span>
<span id="cb15-56"><a href="#cb15-56" aria-hidden="true" tabindex="-1"></a>tree→prog→tree⊙ <span class="ot">(</span>xs * ys<span class="ot">)</span> is st <span class="ot">=</span> tree→prog→tree⊙ xs <span class="ot">_</span> st <span class="ot">;</span></span>
<span id="cb15-57"><a href="#cb15-57" aria-hidden="true" tabindex="-1"></a>                                  tree→prog→tree⊙ ys <span class="ot">(</span>pull is<span class="ot">)</span> <span class="ot">(</span>xs ∷ st<span class="ot">)</span></span>
<span id="cb15-58"><a href="#cb15-58" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-59"><a href="#cb15-59" aria-hidden="true" tabindex="-1"></a>tree→prog→tree <span class="ot">:</span> <span class="ot">(</span>e <span class="ot">:</span> Tree A<span class="ot">)</span> <span class="ot">→</span> prog→tree <span class="ot">(</span>tree→prog e<span class="ot">)</span> ≡ e</span>
<span id="cb15-60"><a href="#cb15-60" aria-hidden="true" tabindex="-1"></a>tree→prog→tree e <span class="ot">=</span> tree→prog→tree⊙ e halt []</span>
<span id="cb15-61"><a href="#cb15-61" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-62"><a href="#cb15-62" aria-hidden="true" tabindex="-1"></a>prog→tree→prog⊙ <span class="ot">:</span> <span class="ot">(</span>is <span class="ot">:</span> Prog A n<span class="ot">)</span> <span class="ot">(</span>st <span class="ot">:</span> Vec <span class="ot">(</span>Tree A<span class="ot">)</span> n<span class="ot">)</span> <span class="ot">→</span></span>
<span id="cb15-63"><a href="#cb15-63" aria-hidden="true" tabindex="-1"></a> tree→prog <span class="ot">(</span>prog→tree⊙ is st<span class="ot">)</span> ≡ foldlN <span class="ot">(</span>Prog A<span class="ot">)</span> tree→prog⊙ is st</span>
<span id="cb15-64"><a href="#cb15-64" aria-hidden="true" tabindex="-1"></a>prog→tree→prog⊙  halt       st <span class="ot">=</span> refl</span>
<span id="cb15-65"><a href="#cb15-65" aria-hidden="true" tabindex="-1"></a>prog→tree→prog⊙ <span class="ot">(</span>push i is<span class="ot">)</span> st <span class="ot">=</span> prog→tree→prog⊙ is <span class="ot">(</span>[ i ] ∷ st<span class="ot">)</span></span>
<span id="cb15-66"><a href="#cb15-66" aria-hidden="true" tabindex="-1"></a>prog→tree→prog⊙ <span class="ot">(</span>pull is<span class="ot">)</span> <span class="ot">(</span>t₁ ∷ t₂ ∷ ts<span class="ot">)</span> <span class="ot">=</span> prog→tree→prog⊙ is <span class="ot">((</span>t₂ * t₁<span class="ot">)</span> ∷ ts<span class="ot">)</span></span>
<span id="cb15-67"><a href="#cb15-67" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-68"><a href="#cb15-68" aria-hidden="true" tabindex="-1"></a>prog→tree→prog <span class="ot">:</span> <span class="ot">(</span>is <span class="ot">:</span> Prog A <span class="dv">0</span><span class="ot">)</span> <span class="ot">→</span> tree→prog <span class="ot">(</span>prog→tree is<span class="ot">)</span> ≡ is</span>
<span id="cb15-69"><a href="#cb15-69" aria-hidden="true" tabindex="-1"></a>prog→tree→prog is <span class="ot">=</span> prog→tree→prog⊙ is []</span>
<span id="cb15-70"><a href="#cb15-70" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-71"><a href="#cb15-71" aria-hidden="true" tabindex="-1"></a>prog-iso <span class="ot">:</span> Prog A zero ⇔ Tree A</span>
<span id="cb15-72"><a href="#cb15-72" aria-hidden="true" tabindex="-1"></a>prog-iso <span class="ot">.</span>fun <span class="ot">=</span> prog→tree</span>
<span id="cb15-73"><a href="#cb15-73" aria-hidden="true" tabindex="-1"></a>prog-iso <span class="ot">.</span>inv <span class="ot">=</span> tree→prog</span>
<span id="cb15-74"><a href="#cb15-74" aria-hidden="true" tabindex="-1"></a>prog-iso <span class="ot">.</span>rightInv <span class="ot">=</span> tree→prog→tree</span>
<span id="cb15-75"><a href="#cb15-75" aria-hidden="true" tabindex="-1"></a>prog-iso <span class="ot">.</span>leftInv  <span class="ot">=</span> prog→tree→prog</span></code></pre></div>
</details>
<h1 id="folds-and-whatnot">Folds and Whatnot</h1>
<p>Another thing I’ll mention is that all of the <code>exec</code>
functions presented are <em>folds</em>. In particular, they’re
<em>left</em> folds. Here’s how we’d rewrite <code>exec</code> to make
that fact clear:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldlCode ::</span> (∀ n<span class="op">.</span> a <span class="ot">-&gt;</span> b n <span class="ot">-&gt;</span> b (<span class="dt">S</span> n))</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> (∀ n<span class="op">.</span> b (<span class="dt">S</span> (<span class="dt">S</span> n)) <span class="ot">-&gt;</span> b (<span class="dt">S</span> n))</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> b m</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">Code</span> m a <span class="ot">-&gt;</span> b (<span class="dt">S</span> <span class="dt">Z</span>)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>foldlCode _ _ h  <span class="dt">HALT</span>       <span class="ot">=</span> h</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>foldlCode p a h (<span class="dt">PUSH</span> x xs) <span class="ot">=</span> foldlCode p a (p x h) xs</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>foldlCode p a h (<span class="dt">ADD</span>    xs) <span class="ot">=</span> foldlCode p a (a   h) xs</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a><span class="ot">shift ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Stack</span> <span class="dt">Int</span> n <span class="ot">-&gt;</span> <span class="dt">Stack</span> <span class="dt">Int</span> (<span class="dt">S</span> n)</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>shift x xs <span class="ot">=</span> x <span class="op">:-</span> xs</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a><span class="ot">reduce ::</span> <span class="dt">Stack</span> <span class="dt">Int</span> (<span class="dt">S</span> (<span class="dt">S</span> n)) <span class="ot">-&gt;</span> <span class="dt">Stack</span> <span class="dt">Int</span> (<span class="dt">S</span> n)</span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>reduce (t1 <span class="op">:-</span> t2 <span class="op">:-</span> st) <span class="ot">=</span> t2 <span class="op">+</span> t1 <span class="op">:-</span> st</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a><span class="ot">execFold ::</span> <span class="dt">Code</span> <span class="dt">Z</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>execFold <span class="ot">=</span> pop <span class="op">.</span> foldlCode shift reduce <span class="dt">Nil</span></span></code></pre></div>
<p>I think the “foldl-from-foldr” trick could be a nice way to explain
the introduction of continuations in <span class="citation"
data-cites="bahr_calculating_2015">Bahr and Hutton (<a
href="#ref-bahr_calculating_2015"
role="doc-biblioref">2015</a>)</span>.</p>
<h1 id="direct-enumeration">Direct Enumeration</h1>
<p>It turns out that you can follow relatively straightforward rewriting
steps from the Dyck-based enumeration algorithm to get to one which
avoids Dyck words entirely:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">enumTrees ::</span> [a] <span class="ot">-&gt;</span> [<span class="dt">Expr</span> a]</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>enumTrees <span class="ot">=</span> <span class="fu">fmap</span> (<span class="fu">foldl1</span> (<span class="fu">flip</span> (<span class="op">:+:</span>))) <span class="op">.</span> foldlM f []</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    f []         v <span class="ot">=</span> [[<span class="dt">Val</span> v]]</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>    f [t1]       v <span class="ot">=</span> [[<span class="dt">Val</span> v, t1]]</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>    f (t1<span class="op">:</span>t2<span class="op">:</span>st) v <span class="ot">=</span> (<span class="dt">Val</span> v <span class="op">:</span> t1 <span class="op">:</span> t2 <span class="op">:</span> st) <span class="op">:</span> f ((t2 <span class="op">:+:</span> t1) <span class="op">:</span> st) v</span></code></pre></div>
<p>Maybe in a future post I’ll go through the derivation of this
algorithm.</p>
<p>It turns out that the Dyck-based enumeration can be applied without
much difficulty to rose trees as well:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Rose</span> a <span class="ot">=</span> a <span class="op">:&amp;</span> <span class="dt">Forest</span> a</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Forest</span> a <span class="ot">=</span> [<span class="dt">Rose</span> a]</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="ot">dyckToForest ::</span> <span class="dt">Dyck</span> <span class="ot">-&gt;</span> <span class="dt">Forest</span> ()</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>dyckToForest dy <span class="ot">=</span> go dy ([] <span class="op">:-</span> <span class="dt">Nil</span>)</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">DyckSuff</span> n <span class="ot">-&gt;</span> <span class="dt">Stack</span> (<span class="dt">Forest</span> ()) (<span class="dt">S</span> n) <span class="ot">-&gt;</span> <span class="dt">Forest</span> ()</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Open</span> d) ts               <span class="ot">=</span> go d ([] <span class="op">:-</span> ts)</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Clos</span> d) (t1 <span class="op">:-</span> t2 <span class="op">:-</span> ts) <span class="ot">=</span> go d ((() <span class="op">:&amp;</span> t2 <span class="op">:</span> t1) <span class="op">:-</span> ts)</span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>    go <span class="dt">Done</span>     (t  <span class="op">:-</span> <span class="dt">Nil</span>)      <span class="ot">=</span> t</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a><span class="ot">forestToDyck ::</span> <span class="dt">Forest</span> () <span class="ot">-&gt;</span> <span class="dt">Dyck</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>forestToDyck t <span class="ot">=</span> go t <span class="dt">Done</span></span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">Forest</span> () <span class="ot">-&gt;</span> <span class="dt">DyckSuff</span> n <span class="ot">-&gt;</span> <span class="dt">DyckSuff</span> n</span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>    go []          <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>    go ((() <span class="op">:&amp;</span> x)<span class="op">:</span>xs) <span class="ot">=</span> go x <span class="op">.</span> <span class="dt">Open</span> <span class="op">.</span> go xs <span class="op">.</span> <span class="dt">Clos</span></span></code></pre></div>
<p>And again, following relatively mechanical derivations, we arrive at
an elegant algorithm:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">enumForests ::</span> [a] <span class="ot">-&gt;</span> [<span class="dt">Forest</span> a]</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>enumForests <span class="ot">=</span> foldrM f []</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    f x xs <span class="ot">=</span> <span class="fu">zipWith</span> ((<span class="op">:</span>) <span class="op">.</span> (<span class="op">:&amp;</span>) x) (inits xs) (tails xs)</span></code></pre></div>
<h1 id="related-work">Related Work</h1>
<p>While researching this post I found that enumeration of trees has
been studied <em>extensively</em> elsewhere: see <span class="citation"
data-cites="knuth_art_2006">Knuth (<a href="#ref-knuth_art_2006"
role="doc-biblioref">2006</a>)</span>, for example, or the excellent
blog post by <span class="citation"
data-cites="tychonievich_enumerating_2013">Tychonievich (<a
href="#ref-tychonievich_enumerating_2013"
role="doc-biblioref">2013</a>)</span>, or the entire field of <a
href="https://en.wikipedia.org/wiki/Boltzmann_sampler">Boltzmann
sampling</a>. This post has only scratched the surface of all of that: I
hope to write much more on the topic in the future.</p>
<h1 id="code">Code</h1>
<p>As I mentioned, the Agda code for this stuff can be found <a
href="https://github.com/oisdk/agda-playground/blob/d7234c276f063dbb4a2d2cbcedb86dd48501a908/Data/Dyck/Payload.agda">here</a>,
I have also put all of the Haskell code in one place <a
href="https://gist.github.com/oisdk/438b6e790481c908d9460ffb1196a759">here</a>.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-bahr_calculating_2015" class="csl-entry" role="listitem">
Bahr, Patrick, and Graham Hutton. 2015. <span>“Calculating correct
compilers.”</span> <em>Journal of Functional Programming</em> 25 (e14)
(September). doi:<a
href="https://doi.org/10.1017/S0956796815000180">10.1017/S0956796815000180</a>.
<a
href="https://nottingham-repository.worktribe.com/output/761112">https://nottingham-repository.worktribe.com/output/761112</a>.
</div>
<div id="ref-hutton_countdown_2002" class="csl-entry" role="listitem">
Hutton, Graham. 2002. <span>“The <span>Countdown Problem</span>.”</span>
<em>J. Funct. Program.</em> 12 (6) (November): 609–616. doi:<a
href="https://doi.org/10.1017/S0956796801004300">10.1017/S0956796801004300</a>.
<a
href="http://www.cs.nott.ac.uk/~pszgmh/countdown.pdf">http://www.cs.nott.ac.uk/~pszgmh/countdown.pdf</a>.
</div>
<div id="ref-knuth_art_2006" class="csl-entry" role="listitem">
Knuth, Donald E. 2006. <em>The <span>Art</span> of <span>Computer
Programming</span>, <span>Volume</span> 4, <span>Fascicle</span> 4:
<span>Generating All Trees</span>–<span>History</span> of
<span>Combinatorial Generation</span> (<span>Art</span> of
<span>Computer Programming</span>)</em>. <span>Addison-Wesley
Professional</span>. <a
href="http://www.cs.utsa.edu/~wagner/knuth/fasc4a.pdf">http://www.cs.utsa.edu/~wagner/knuth/fasc4a.pdf</a>.
</div>
<div id="ref-mcgill_compiler_2020" class="csl-entry" role="listitem">
McGill, Callan. 2020. <span>“Compiler correctness for addition
language.”</span> <a
href="https://gist.github.com/Boarders/9d83f9cbcfaffb04cf2464588fc46df9">https://gist.github.com/Boarders/9d83f9cbcfaffb04cf2464588fc46df9</a>.
</div>
<div id="ref-riley_program_2020" class="csl-entry" role="listitem">
Riley, Sean. 2020. <span>“Program <span>Correctness</span> -
<span>Computerphile</span>.”</span> <span>University of
Nottingham</span>. <a
href="https://www.youtube.com/watch?v=T_IINWzQhow">https://www.youtube.com/watch?v=T_IINWzQhow</a>.
</div>
<div id="ref-tychonievich_enumerating_2013" class="csl-entry"
role="listitem">
Tychonievich, Luther. 2013. <span>“Enumerating
<span>Trees</span>.”</span> <em>Luther’s Meanderings</em>. <a
href="https://www.cs.virginia.edu/~lat7h/blog/posts/434.html">https://www.cs.virginia.edu/~lat7h/blog/posts/434.html</a>.
</div>
</div>
]]></description>
    <pubDate>Mon, 14 Dec 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-12-14-enumerating-trees.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Queue for Effectful Breadth-First Traversals</title>
    <link>https://doisinkidney.com/posts/2020-11-23-applicative-queue.html</link>
    <description><![CDATA[<div class="info">
    Posted on November 23, 2020
</div>
<div class="info">
    
        Part 10 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>We pick up the story again at the question of a breadth-first
(Applicative) traversal of a rose tree <span class="citation"
data-cites="gibbons_breadthfirst_2015">(<a
href="#ref-gibbons_breadthfirst_2015" role="doc-biblioref">Gibbons
2015</a>)</span>. In the last post, I finally came up with an
implementation I was happy with:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> a <span class="op">:&amp;</span> [<span class="dt">Tree</span> a]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>bft f (x <span class="op">:&amp;</span> xs) <span class="ot">=</span> liftA2 (<span class="op">:&amp;</span>) (f x) (bftF f xs)</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="ot">bftF ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> [<span class="dt">Tree</span> a] <span class="ot">-&gt;</span> f [<span class="dt">Tree</span> b]</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>bftF t <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">head</span> <span class="op">.</span> <span class="fu">foldr</span> (<span class="op">&lt;*&gt;</span>) (<span class="fu">pure</span> []) <span class="op">.</span> <span class="fu">foldr</span> f [<span class="fu">pure</span> ([]<span class="op">:</span>)]</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&amp;</span> xs) (q <span class="op">:</span> qs) <span class="ot">=</span> liftA2 c (t x) q <span class="op">:</span> <span class="fu">foldr</span> f (p qs) xs</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    p []     <span class="ot">=</span> [<span class="fu">pure</span> ([]<span class="op">:</span>)]</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    p (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="fu">fmap</span> (([]<span class="op">:</span>)<span class="op">.</span>) x <span class="op">:</span> xs</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    c x k (xs <span class="op">:</span> ks) <span class="ot">=</span> ((x <span class="op">:&amp;</span> xs) <span class="op">:</span> y) <span class="op">:</span> ys</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> (y <span class="op">:</span> ys) <span class="ot">=</span> k ks</span></code></pre></div>
<p>It has the correct semantics and asymptotics.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>tree <span class="ot">=</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="dv">1</span> <span class="op">:&amp;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>      [ <span class="dv">2</span> <span class="op">:&amp;</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>          [ <span class="dv">5</span> <span class="op">:&amp;</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>              [ <span class="dv">9</span>  <span class="op">:&amp;</span> []</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>              , <span class="dv">10</span> <span class="op">:&amp;</span> []]</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>          , <span class="dv">6</span> <span class="op">:&amp;</span> []]</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>      , <span class="dv">3</span> <span class="op">:&amp;</span> []</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>      , <span class="dv">4</span> <span class="op">:&amp;</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>          [ <span class="dv">7</span> <span class="op">:&amp;</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>              [ <span class="dv">11</span> <span class="op">:&amp;</span> []</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>              , <span class="dv">12</span> <span class="op">:&amp;</span> []]</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>          , <span class="dv">8</span> <span class="op">:&amp;</span> []]]</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> bft <span class="fu">print</span> tree</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a><span class="dv">3</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a><span class="dv">4</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a><span class="dv">5</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a><span class="dv">6</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a><span class="dv">7</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a><span class="dv">8</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a><span class="dv">9</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a><span class="dv">10</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a><span class="dv">11</span></span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a><span class="dv">12</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>() <span class="op">:&amp;</span></span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>   [ () <span class="op">:&amp;</span></span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>        [ () <span class="op">:&amp;</span></span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a>             [ () <span class="op">:&amp;</span> []</span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a>             , () <span class="op">:&amp;</span> []]</span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a>        , () <span class="op">:&amp;</span> []]</span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>   , () <span class="op">:&amp;</span>   []</span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a>   , () <span class="op">:&amp;</span></span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>        [ () <span class="op">:&amp;</span></span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>             [ () <span class="op">:&amp;</span> []</span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a>             , () <span class="op">:&amp;</span> []]</span>
<span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a>        , () <span class="op">:&amp;</span> []]]</span></code></pre></div>
<p>But it’s quite difficult to understand, and doesn’t lend much insight
into what’s going on with the whole “breadth-first” notion. The
technique the function uses also isn’t reusable.</p>
<p>A much nicer function uses the <code>Phases</code> Applicative <span
class="citation" data-cites="easterly_functions_2019">(<a
href="#ref-easterly_functions_2019" role="doc-biblioref">Easterly
2019</a>)</span>:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    go (x <span class="op">:&amp;</span> xs) <span class="ot">=</span> liftA2 (<span class="op">:&amp;</span>) (<span class="dt">Lift</span> (f x)) (later (<span class="fu">traverse</span> go xs))</span></code></pre></div>
<p>But this function is quadratic.</p>
<p>So the task for this post today is to derive a type like the
<code>Phases</code> type with a <code>later</code> operation, but which
has the appropriate performance characteristics. At the end I’ll look
into what the theoretical properties of this type are.</p>
<h1 id="a-free-applicative">A Free Applicative</h1>
<p>At its core, the <code>Phases</code> type is basically a free
Applicative <span class="citation" data-cites="capriotti_free_2014">(<a
href="#ref-capriotti_free_2014" role="doc-biblioref">Capriotti and
Kaposi 2014</a>)</span>. I’ll reimplement it here as a slightly
different free Applicative (one that’s based on <code>liftA2</code>
rather than <code>&lt;*&gt;</code>):</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Free</span> f a <span class="kw">where</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Free</span> f a</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lift</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Free</span> f b <span class="ot">-&gt;</span> <span class="dt">Free</span> f c</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="ot">lower ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Free</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>lower (<span class="dt">Pure</span> x) <span class="ot">=</span> <span class="fu">pure</span> x</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>lower (<span class="dt">Lift</span> f x xs) <span class="ot">=</span> liftA2 f x (lower xs)</span></code></pre></div>
<p>The key with the <code>Phases</code> type is to observe that there’s
actually two possible implementations of <code>Applicative</code> for
the <code>Free</code> type above: one which makes it the “correct” free
applicative:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> (<span class="dt">Free</span> f) <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Pure</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  liftA2 c (<span class="dt">Pure</span> x) ys <span class="ot">=</span> <span class="fu">fmap</span> (c x) ys</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>  liftA2 c (<span class="dt">Lift</span> f x xs) ys <span class="ot">=</span> <span class="dt">Lift</span> (\x (y,z) <span class="ot">-&gt;</span> c (f x y) z) x (liftA2 (,) xs ys)</span></code></pre></div>
<p>And then one which <em>zips</em> effects together:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Free</span> f) <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Pure</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  liftA2 c (<span class="dt">Pure</span> x) ys <span class="ot">=</span> <span class="fu">fmap</span> (c x) ys</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  liftA2 c xs (<span class="dt">Pure</span> y) <span class="ot">=</span> <span class="fu">fmap</span> (<span class="fu">flip</span> c y) xs</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  liftA2 c (<span class="dt">Lift</span> f x xs) (<span class="dt">Lift</span> g y ys) <span class="ot">=</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Lift</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>      (\(x,y) (xs,ys) <span class="ot">-&gt;</span> c (f x xs) (g y ys))</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>      (liftA2 (,) x y)</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>      (liftA2 (,) xs ys)</span></code></pre></div>
<p>This second instance makes the <code>Free</code> type into not a free
Applicative at all: instead it’s some kind of Applicative transformer
which we can use to reorder effects. Since effects are combined only
when they’re at the same point in the list, we can use it to do our
breadth-first traversal.</p>
<p>As an aside, from this perspective it’s clear that this is some kind
of <code>FunList</code> <span class="citation"
data-cites="vanlaarhoven_nonregular_2009">(<a
href="#ref-vanlaarhoven_nonregular_2009" role="doc-biblioref">van
Laarhoven 2009</a>)</span>: this opens up a lot of interesting
curiosities about the type, since that type in particular is quite
well-studied.</p>
<p>Anyway, we’re able to do the <code>later</code> operation quite
simply:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">later ::</span> <span class="dt">Free</span> f a <span class="ot">-&gt;</span> <span class="dt">Free</span> f a</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>later <span class="ot">=</span> <span class="dt">Lift</span> (<span class="fu">const</span> <span class="fu">id</span>) (<span class="fu">pure</span> ())</span></code></pre></div>
<h1 id="making-it-efficient">Making it Efficient</h1>
<p>The problem at the moment is that the Applicative instance has an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
<code>liftA2</code> implementation: this translates into an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>
traversal overall.</p>
<p>If we were working in a more simple context of just enumerating the
contents of the tree, we might at this point look to something like
difference lists: these use the cayley transform on the list monoid to
turn the append operation from
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>.
It turns out that there is a similar cayley transformation for
Applicative functors <span class="citation"
data-cites="rivas_notions_2014 rivas_monoids_2015">(<a
href="#ref-rivas_notions_2014" role="doc-biblioref">Rivas and Jaskelioff
2014</a>; <a href="#ref-rivas_monoids_2015" role="doc-biblioref">Rivas,
Jaskelioff, and Schrijvers 2015</a>)</span>:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Day</span> f a <span class="ot">=</span> <span class="dt">Day</span> {<span class="ot"> runDay ::</span> ∀ b<span class="op">.</span> f b <span class="ot">-&gt;</span> f (a, b) }</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Functor</span> (<span class="dt">Day</span> f) <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f xs <span class="ot">=</span> <span class="dt">Day</span> (<span class="fu">fmap</span> (first f) <span class="op">.</span> runDay xs)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Day</span> f) <span class="kw">where</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Day</span> (<span class="fu">fmap</span> ((,) x))</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>  liftA2 c xs ys <span class="ot">=</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Day</span> (<span class="fu">fmap</span> (\(x,(y,z)) <span class="ot">-&gt;</span> (c x y, z)) <span class="op">.</span> runDay xs <span class="op">.</span> runDay ys)</span></code></pre></div>
<p>And with this type we can implement our queue of applicative
effects:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Queue</span> f <span class="ot">=</span> <span class="dt">Day</span> (<span class="dt">Free</span> f)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">runQueue ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Queue</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>runQueue <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">fst</span> <span class="op">.</span> lower <span class="op">.</span> <span class="fu">flip</span> runDay (<span class="dt">Pure</span> ())</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="ot">now ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Queue</span> f a</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>now xs <span class="ot">=</span> <span class="dt">Day</span> \<span class="kw">case</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span> x      <span class="ot">-&gt;</span> <span class="dt">Lift</span> (,) xs (<span class="dt">Pure</span> x)</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lift</span> f y ys <span class="ot">-&gt;</span> <span class="dt">Lift</span> (\(x,y) z <span class="ot">-&gt;</span> (x, f y z)) (liftA2 (,) xs y) ys</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="ot">later ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Queue</span> f a <span class="ot">-&gt;</span> <span class="dt">Queue</span> f a</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>later xs <span class="ot">=</span> <span class="dt">Day</span> \<span class="kw">case</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span> x      <span class="ot">-&gt;</span> <span class="dt">Lift</span> (<span class="fu">const</span> <span class="fu">id</span>) (<span class="fu">pure</span> ()) (runDay xs (<span class="dt">Pure</span> x))</span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lift</span> f y ys <span class="ot">-&gt;</span> <span class="dt">Lift</span> (\x (y,z) <span class="ot">-&gt;</span> (y, f x z)) y (runDay xs ys)</span></code></pre></div>
<p>As expected, this gives us the clean implementation of a
breadth-first traversal with the right asymptotics (I think):</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runQueue <span class="op">.</span> go</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    go (x <span class="op">:&amp;</span> xs) <span class="ot">=</span> liftA2 (<span class="op">:&amp;</span>) (now (f x)) (later (<span class="fu">traverse</span> go xs))</span></code></pre></div>
<p>(it’s worth pointing out that we haven’t actually used the
applicative instance on the free applicative at any point: we have
inlined all of the “zipping” to make it absolutely clear that everything
has stayed linear).</p>
<h1 id="so-whats-the-theory">So what’s the Theory?</h1>
<p>I have yet to really dive deep on any of the theory involved in this
type, I just quickly wrote up this post when I realised I was able to
use the cayley transform from the mentioned papers to implement the
proper breadth-first traversal. It certainly seems worth looking at
more!</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-capriotti_free_2014" class="csl-entry" role="listitem">
Capriotti, Paolo, and Ambrus Kaposi. 2014. <span>“Free <span>Applicative
Functors</span>.”</span> <em>Electronic Proceedings in Theoretical
Computer Science</em> 153 (June): 2–30. doi:<a
href="https://doi.org/10.4204/EPTCS.153.2">10.4204/EPTCS.153.2</a>. <a
href="http://www.paolocapriotti.com/assets/applicative.pdf">http://www.paolocapriotti.com/assets/applicative.pdf</a>.
</div>
<div id="ref-easterly_functions_2019" class="csl-entry" role="listitem">
Easterly, Noah. 2019. <span>“Functions and newtype wrappers for
traversing <span>Trees</span>: Rampion/tree-traversals.”</span> <a
href="https://github.com/rampion/tree-traversals">https://github.com/rampion/tree-traversals</a>.
</div>
<div id="ref-gibbons_breadthfirst_2015" class="csl-entry"
role="listitem">
Gibbons, Jeremy. 2015. <span>“Breadth-<span>First
Traversal</span>.”</span> <em>Patterns in Functional Programming</em>.
<a
href="https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/">https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/</a>.
</div>
<div id="ref-rivas_notions_2014" class="csl-entry" role="listitem">
Rivas, Exequiel, and Mauro Jaskelioff. 2014. <span>“Notions of
<span>Computation</span> as <span>Monoids</span>.”</span>
<em>arXiv:1406.4823 [cs, math]</em> (May). <a
href="http://arxiv.org/abs/1406.4823">http://arxiv.org/abs/1406.4823</a>.
</div>
<div id="ref-rivas_monoids_2015" class="csl-entry" role="listitem">
Rivas, Exequiel, Mauro Jaskelioff, and Tom Schrijvers. 2015. <span>“From
monoids to near-semirings: The essence of <span>MonadPlus</span> and
<span>Alternative</span>.”</span> In <em>Proceedings of the 17th
<span>International Symposium</span> on <span>Principles</span> and
<span>Practice</span> of <span>Declarative Programming</span></em>,
196–207. <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2790449.2790514">10.1145/2790449.2790514</a>.
<a
href="http://www.fceia.unr.edu.ar/~mauro/pubs/FromMonoidstoNearsemirings.pdf">http://www.fceia.unr.edu.ar/~mauro/pubs/FromMonoidstoNearsemirings.pdf</a>.
</div>
<div id="ref-vanlaarhoven_nonregular_2009" class="csl-entry"
role="listitem">
van Laarhoven, Twan. 2009. <span>“A non-regular data type
challenge.”</span> <em>Twan van Laarhoven’s Blog</em>. <a
href="https://twanvl.nl/blog/haskell/non-regular1">https://twanvl.nl/blog/haskell/non-regular1</a>.
</div>
</div>
]]></description>
    <pubDate>Mon, 23 Nov 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-11-23-applicative-queue.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>How to set up GitHub Actions for your Agda project</title>
    <link>https://doisinkidney.com/posts/2020-11-18-agda-github-action.html</link>
    <description><![CDATA[<div class="info">
    Posted on November 18, 2020
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<h2 id="update-2022-11-12">Update 2022-11-12</h2>
<p>The best approach to this now is probably to use this action,
specifically set up for Agda:</p>
<ul>
<li><a
href="https://github.com/wenkokke/setup-agda">github.com/wenkokke/setup-agda</a></li>
</ul>
<p>I’ll leave the rest of this post here, but bear in mind the advice is
outdated.</p>
<hr />
<p>Recently travis-ci.org announced that they were closing down, and
moving to travis-ci.com. For people who use the service, this basically
means that the free component is going away, and you’ll have to pay in
the future.</p>
<p>As a result, a lot of people are looking to move to another ci
service, so I thought I’d put this short guide together on how to use
GitHub actions to typecheck an Agda project and host the rendered code
through GitHub pages. The system I have is quite fast: for a quite large
project it takes about a minute from pushing for the action to
complete.</p>
<p>If you just want to use the same script as me, you can see it <a
href="https://github.com/oisdk/agda-playground/blob/master/.github/workflows/compile.yaml">here</a>:
the rest of this post will just be going through that script and
explaining it.</p>
<h1 id="setting-up-a-basic-action">Setting up a Basic Action</h1>
<p>First things first: in order to make an action, you need to put a
YAML file in the <code>.github/workflows</code> directory of your
repository. You can have the following lines at the start:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">name</span><span class="kw">:</span><span class="at"> Compile Agda and Deploy HTML</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">on</span><span class="kw">:</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="at">  </span><span class="fu">push</span><span class="kw">:</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">branches</span><span class="kw">:</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="kw">-</span><span class="at"> master</span></span></code></pre></div>
<p>This gives a name for the action (which will show up in the actions
tab online for the repo), and says that the action should be run
whenever there’s a push to the branch named <code>master</code>.</p>
<p>We then list the “jobs” the actions does: just one for this action,
called <code>build</code>:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">jobs</span><span class="kw">:</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="at">  </span><span class="fu">build</span><span class="kw">:</span></span></code></pre></div>
<h1 id="configuring-the-runner">Configuring The Runner</h1>
<p>GitHub actions run on GitHub’s servers, the specifications of which
can be seen <a
href="https://docs.github.com/en/free-pro-team@latest/actions/reference/specifications-for-github-hosted-runners">here</a>.
For this action we won’t need anything special, so we’ll just use the
following:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">runs-on</span><span class="kw">:</span><span class="at"> ubuntu-18.04</span></span></code></pre></div>
<p>Next we will have the matrix:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">strategy</span><span class="kw">:</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">matrix</span><span class="kw">:</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">cubical-ref</span><span class="kw">:</span><span class="at"> </span><span class="kw">[</span><span class="st">&quot;v0.2&quot;</span><span class="kw">]</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">agda-ref</span><span class="kw">:</span><span class="at"> </span><span class="kw">[</span><span class="st">&quot;v2.6.1.1&quot;</span><span class="kw">]</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">ghc-ver</span><span class="kw">:</span><span class="at"> </span><span class="kw">[</span><span class="st">&quot;8.10.2&quot;</span><span class="kw">]</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">cabal-ver</span><span class="kw">:</span><span class="at"> </span><span class="kw">[</span><span class="st">&quot;3.4.0.0&quot;</span><span class="kw">]</span></span></code></pre></div>
<p>I’m using this matrix as a crude system for environment variables; if
this was a CI for some software I wanted to deploy, you could include
multiple values for each variable here, to check that the whole thing
runs properly with each.</p>
<h1 id="caching">Caching</h1>
<p>We’re now onto the “steps” portion of the script, where we write
small bash-esque script to be run. As such we have the line:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">steps</span><span class="kw">:</span></span></code></pre></div>
<p>The first step is to cache all the cabal packages we’re going to
install. Agda takes about 45 minutes to install so this step is
crucial:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/cache@v2</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Cache cabal packages</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">id</span><span class="kw">:</span><span class="at"> cache-cabal</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="fu">        path</span><span class="kw">: </span><span class="ch">|</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>          ~/.cabal/packages</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>          ~/.cabal/store</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>          ~/.cabal/bin</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>          dist-newstyle</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">key</span><span class="kw">:</span><span class="at"> ${{ runner.os }}-${{ matrix.ghc-ver }}-${{ matrix.cabal-ver }}-${{ matrix.agda-ref }}</span></span></code></pre></div>
<p>The <code>path</code> field tells the action which folders to cache,
the <code>key</code> field tells it what key to store them under.</p>
<h1 id="installing-agda">Installing Agda</h1>
<p>To install Agda we first need to install cabal:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Install cabal</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">if</span><span class="kw">:</span><span class="at"> steps.cache-cabal.outputs.cache-hit != &#39;true&#39;</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/setup-haskell@v1.1.3</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">ghc-version</span><span class="kw">:</span><span class="at"> ${{ matrix.ghc-ver }}</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">cabal-version</span><span class="kw">:</span><span class="at"> ${{ matrix.cabal-ver }}</span></span></code></pre></div>
<p>The <code>if</code> field here allows us to skip this step if we had
a cache hit previously (i.e. if Agda is already installed).</p>
<p>Next we need to ensure that all of the programs installed by cabal
are in the path:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Put cabal programs in PATH</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">run</span><span class="kw">:</span><span class="at"> echo &quot;~/.cabal/bin&quot; &gt;&gt; $GITHUB_PATH</span></span></code></pre></div>
<p>And then we download and install Agda (along with some dependencies
that aren’t installed automatically):</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Download Agda from github</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">if</span><span class="kw">:</span><span class="at"> steps.cache-cabal.outputs.cache-hit != &#39;true&#39;</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/checkout@v2</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">repository</span><span class="kw">:</span><span class="at"> agda/agda</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">path</span><span class="kw">:</span><span class="at"> agda</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">ref</span><span class="kw">:</span><span class="at"> ${{ matrix.agda-ref }}</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Install Agda</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">if</span><span class="kw">:</span><span class="at"> steps.cache-cabal.outputs.cache-hit != &#39;true&#39;</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="fu">      run</span><span class="kw">: </span><span class="ch">|</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>        cabal update</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>        cabal install --overwrite-policy=always --ghc-options=&#39;-O2 +RTS -M6G -RTS&#39; alex-3.2.5</span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>        cabal install --overwrite-policy=always --ghc-options=&#39;-O2 +RTS -M6G -RTS&#39; happy-1.19.12</span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>        cd agda</span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>        mkdir -p doc</span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>        touch doc/user-manual.pdf</span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>        cabal install --overwrite-policy=always --ghc-options=&#39;-O1 +RTS -M6G -RTS&#39;</span></code></pre></div>
<p>The strange flags to <code>cabal install</code> here are
<em>probably</em> necessary: I was running out of memory when I tried to
install Agda without them. This might be fixed in future versions of
Agda.</p>
<h1 id="installing-agda-dependencies">Installing Agda Dependencies</h1>
<p>We next need to install any Agda libraries your code depends on. For
instance, in my project, I use the cubical library: since Agda doesn’t
have a package manager, we basically have to handle all the versioning
and so on manually. Also, in order to speed up the build we have to
cache the typecheck files for the library.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Checkout cubical library</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/checkout@v2</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">repository</span><span class="kw">:</span><span class="at"> agda/cubical</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">path</span><span class="kw">:</span><span class="at"> cubical</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">ref</span><span class="kw">:</span><span class="at"> ${{ matrix.cubical-ref }}</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Cache cubical library</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/cache@v2</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">id</span><span class="kw">:</span><span class="at"> cache-cubical</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">path</span><span class="kw">:</span><span class="at"> ~/cubical-build</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">key</span><span class="kw">:</span><span class="at"> ${{ runner.os }}-${{ matrix.agda-ver }}-${{ matrix.cubical-ref }}</span></span></code></pre></div>
<p>So the library is accessible as an import we need to put it in the
Agda library list:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Put cubical library in Agda library list</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="fu">      run</span><span class="kw">: </span><span class="ch">|</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>        mkdir -p ~/.agda/</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>        touch ~/.agda/libraries</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>        echo &quot;$GITHUB_WORKSPACE/cubical/cubical.agda-lib&quot; &gt; ~/.agda/libraries</span></code></pre></div>
<p>We then need to typecheck the library: this bit is a little tricky,
since not all files in the cubical library actually typecheck.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Compile cubical library</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">if</span><span class="kw">:</span><span class="at"> steps.cache-cubical.outputs.cache-hit != &#39;true&#39;</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="fu">      run</span><span class="kw">: </span><span class="ch">|</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>        cd $GITHUB_WORKSPACE/cubical</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>        agda Cubical/Core/Everything.agda</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>        agda Cubical/Foundations/Everything.agda</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>        find Cubical/Data -type f -name &quot;*.agda&quot; | while read -r code ; do</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>            agda $code</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>        done</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>        find Cubical/HITs -type f -name &quot;*.agda&quot; | while read -r code ; do</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>            agda $code</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>        done</span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>        cp -f -r _build/ ~/cubical-build</span></code></pre></div>
<p>Finally, if the cubical library was already typechecked then we don’t
need to do any of that, and we instead just retrieve it from the
cache:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Retrieve cubical library</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">if</span><span class="kw">:</span><span class="at"> steps.cache-cubical.outputs.cache-hit == &#39;true&#39;</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="fu">      run</span><span class="kw">: </span><span class="ch">|</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>        mkdir -p cubical/_build</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>        cp -f -r ~/cubical-build/* cubical/_build</span></code></pre></div>
<h1 id="typechecking-the-library">Typechecking the library</h1>
<p>Finally we have to typecheck the library itself. We want to cache the
output from this step as well, but importantly we want to support
incremental recompilation: i.e. if we only make a small change in one
file we don’t want to have to typecheck every other. We can do this with
<code>restore-keys</code> in the cache:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Checkout main</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/checkout@v2</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">path</span><span class="kw">:</span><span class="at"> main</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/cache@v2</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Cache main library</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">id</span><span class="kw">:</span><span class="at"> cache-main</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">path</span><span class="kw">:</span><span class="at"> ~/main-build</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">key</span><span class="kw">:</span><span class="at"> html-and-tex-${{ runner.os }}-${{ matrix.agda-ver }}-${{ matrix.cubical-ref }}-${{ hashFiles(&#39;main/**&#39;) }}</span></span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a><span class="fu">        restore-keys</span><span class="kw">: </span><span class="ch">|</span></span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>          html-and-tex-${{ runner.os }}-${{ matrix.agda-ver }}-${{ matrix.cubical-ref }}-</span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a>          html-and-tex-${{ runner.os }}-${{ matrix.agda-ver }}-</span>
<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Retrieve main library</span></span>
<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">if</span><span class="kw">:</span><span class="at"> steps.cache-main.outputs.cache-hit == &#39;true&#39;</span></span>
<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">run</span><span class="kw">:</span><span class="at"> cp -f -R ~/main-build/* $GITHUB_WORKSPACE/main</span></span></code></pre></div>
<p>Finally, we need to make an “Everything” file: this is an Agda module
which contains an import for every module in the project. Typechecking
this file is faster than typechecking each file individually.</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Compile main library</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">if</span><span class="kw">:</span><span class="at"> steps.cache-main.outputs.cache-hit != &#39;true&#39;</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="fu">      run</span><span class="kw">: </span><span class="ch">|</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>        mkdir -p ~/main-build/_build</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>        cp -f -R ~/main-build/_build $GITHUB_WORKSPACE/main/_build</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>        rm -r ~/main-build</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>        cd main</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>        find . -type f \( -name &quot;*.agda&quot; -o -name &quot;*.lagda&quot; \) &gt; FileList</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>        sort -o FileList FileList</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>        echo &quot;{-# OPTIONS --cubical #-}&quot; &gt; Everything.agda</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>        echo &quot;&quot; &gt;&gt; Everything.agda</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>        echo &quot;module Everything where&quot; &gt;&gt; Everything.agda</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>        echo &quot;&quot; &gt;&gt; Everything.agda</span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>        echo &quot;-- This file imports every module in the project. Click on&quot; &gt;&gt; Everything.agda</span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>        echo &quot;-- a module name to go to its source.&quot; &gt;&gt; Everything.agda</span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>        echo &quot;&quot; &gt;&gt; Everything.agda</span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>        cat FileList | cut -c 3-               \</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>                     | cut -f1 -d&#39;.&#39;           \</span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a>                     | sed &#39;s/\//\./g&#39;         \</span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a>                     | sed &#39;s/^/open import /&#39; \</span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a>                     &gt;&gt; Everything.agda</span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true" tabindex="-1"></a>        rm FileList</span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true" tabindex="-1"></a>        agda --html --html-dir=docs Everything.agda</span>
<span id="cb15-24"><a href="#cb15-24" aria-hidden="true" tabindex="-1"></a>        rm Everything.agda</span>
<span id="cb15-25"><a href="#cb15-25" aria-hidden="true" tabindex="-1"></a>        cd ..</span>
<span id="cb15-26"><a href="#cb15-26" aria-hidden="true" tabindex="-1"></a>        cp -f -R main/ ~/main-build/</span></code></pre></div>
<p>And then we need to deploy the generated <code>html</code> so we can
see the rendered library.</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Deploy html to github pages</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> peaceiris/actions-gh-pages@v3</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="at">      </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">github_token</span><span class="kw">:</span><span class="at"> ${{ secrets.GITHUB_TOKEN }}</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="at">        </span><span class="fu">publish_dir</span><span class="kw">:</span><span class="at"> main/docs</span></span></code></pre></div>
<p>This last step will need you to turn on the github pages setting in
your repository, and have it serve from the <code>gh-pages</code>
branch.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Hopefully this script will be useful to some other people! The first
time it runs it should take between 30 minutes and an hour; subsequently
it takes about a minute for me.</p>
]]></description>
    <pubDate>Wed, 18 Nov 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-11-18-agda-github-action.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Fun with Combinators</title>
    <link>https://doisinkidney.com/posts/2020-10-17-ski.html</link>
    <description><![CDATA[<div class="info">
    Posted on October 17, 2020
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Combinators&#39;." href="/tags/Combinators.html" rel="tag">Combinators</a>
    
</div>

<script src="../code/ski/script.js"></script>
<style>
input[type=text] {
    border:0;
    outline:0;
    font-size: 11px;
    font-family: menlo, monospace;
    width: 90%;
}
input[type=text]:focus {
    outline:none!important;
}
input[type=text]:invalid {
    color: red;
    box-shadow: none;
}
</style>
<p>There are a bunch of “minimal” computational models out there: Turing
machines, lambda calculus, PowerPoint <span class="citation"
data-cites="wildenhainTuringCompletenessMS2017">(<a
href="#ref-wildenhainTuringCompletenessMS2017"
role="doc-biblioref">Wildenhain 2017</a>)</span>, etc. These are
radically simple languages which are nonetheless Turing complete, so
theoretically “as powerful” as each other. Of those, lambda calculus is
my favourite to actually write programs in: it’s the one which is
closest to crawling out of the <a
href="https://en.wikipedia.org/wiki/Turing_tarpit">Turing
tarpit</a>.</p>
<p>In terms of implementation, though, it is <em>far</em> from simple.
Lambda calculus has <em>variables</em>, which introduce complexity into
the interpreter, especially if you want to do any kind of formal
reasoning about programs. We might want to reach for something even
lower-level than lambda calculus: this is where combinator calculi come
in.</p>
<p>You may have heard of SKI combinator calculus: it’s the “simplest” of
the calculi, but it’s not actually very easy to understand, and it’s
absolute murder to try use. So we’re going to start with
<code>BCKW</code>, a more obscure calculus, invented by Haskell
Curry.</p>
<p>There are 4 combinators in <code>BCKW</code>: <code>B</code>,
<code>C</code>, <code>K</code>, and <code>W</code> (shocking, I know).
You can think about these combinators as functions which manipulate the
beginning of strings:</p>
<pre><code>Bxyz ~&gt; x(yz)
Cxyz ~&gt; xzy
Kxy  ~&gt; x
Wxy  ~&gt; xyy</code></pre>
<p>Upper case letters are combinators, lower-case are variables. Note
that the calculus itself doesn’t need variables: I’m just using them
here to explain how each of the combinators work. In any actual programs
we write we won’t use variables.</p>
<p>Let’s work with some examples to get a sense for how these
combinators work.</p>
<p>The simplest combinator is <code>K</code>: it’s equivalent to the
<code>const</code> function from Haskell. It discards its second
argument, and returns the first. If you give a combinator more arguments
than it usually accepts, you just keep the extra arguments in the
output:</p>
<pre><code>Kxyz ~&gt; xz</code></pre>
<p><code>W</code> is the next combinator: it <em>duplicates</em> its
second argument.</p>
<pre><code>Wxy ~&gt; xyy</code></pre>
<p>We always start from the <em>left</em>, applying the rule for the
left-most combinator first.</p>
<pre><code>WKxyz ~&gt; Kxxyz ~&gt; xyz
KWxyz ~&gt; Wyz   ~&gt; yzz</code></pre>
<p>Next we have <code>C</code>: this is equivalent to the Haskell
function <code>flip</code>. It swaps the second and third arguments:</p>
<pre><code>Cxyz ~&gt; xzy</code></pre>
<p>Here’s a small little evaluator for expressions which use
<code>C</code>, <code>K</code>, and <code>W</code>. You can edit the
expression, and press enter to step through it.</p>
<p id="CKW">
</p>
<script>
repl(
  { input_id: "CKW"
  , output_lines: 3
  , initial_expr: "WKCxyz"
  , allowed_combos: [Comb.C, Comb.K, Comb.W]
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<p>The last combinator introduces parentheses, and it’s equivalent to
function composition.</p>
<pre><code>Bxyz ~&gt; x(yz)</code></pre>
<p>You can write parentheses yourself: implicitly, all expressions are
left-associated. That means that the following are all equal:</p>
<pre><code>xyz = (xy)z = (x)yz = ((x)y)z</code></pre>
<p>But <code>xyz</code> is <em>not</em> equal to, say,
<code>x(yz)</code>.</p>
<p>And here’s a puzzle to start flexing your combinator skills: one of
the combinators in SKI combinator calculus is <code>I</code>, which is
the identity function.</p>
<pre><code>Ix ~&gt; x</code></pre>
<p>Try write an expression which functions the same way as
<code>I</code>, using only the <code>BCKW</code> combinators. Use the
following evaluator to try and figure out how to do it: write an
expression after <code>λ&gt;</code> which functions the same as
<code>I</code>.</p>
<p id="BCKWtoI">
</p>
<script>
puzzle(
  { input_id: "BCKWtoI"
  , output_lines: 3
  , vars: "x"
  , expect: "x"
  , allowed_combos: [Comb.B, Comb.C, Comb.K, Comb.W]
  }
); </script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<p><code>CK</code> followed by any combinator will do the trick. So
<code>CKB</code>, <code>CKK</code>, <code>CKC</code>, etc.</p>
<pre><code>I = CKC</code></pre>
Update 19/10/2020: A few people have pointed out (<a
href="https://www.joachim-breitner.de/">Joachim Breitner</a> was the
first) that there is a shorter solution to this problem:
<code>WK</code>. I tend to prefer solutions that don’t include
<code>W</code>, since then we’re working in a subset of the language
that is both terminating and affine; although in this case the reason I
didn’t mention <code>WK</code> is that I just didn’t find it myself.
</details>
<h1 id="why-not-simpler-combinators">Why Not Simpler Combinators?</h1>
<p>Each of the combinators we’ve defined so far work a little weird:
they seem to skip over their first argument, and work on their second.
Indeed, there is another, equivalent combinator calculus which doesn’t
have this peculiarity:</p>
<pre><code>Bxyz ~&gt; x(yz)
Axy  ~&gt; y
Mx   ~&gt; xx
Txy  ~&gt; yx</code></pre>
<p><code>B</code> stays the same in this calculus, but the rest of the
combinators get switched out for seemingly simpler versions.
<code>K</code> goes to <code>A</code><a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"><sup>1</sup></a>:</p>
<pre><code>Axy ~&gt; y
Kxy ~&gt; x</code></pre>
<p>Which isn’t a huge change. It’s the other two where we see the real
difference. <code>W</code> has been swapped out for <code>M</code>:</p>
<pre><code>Wxy ~&gt; xyy
Mx  ~&gt; xx</code></pre>
<p>As you can see <code>W</code> basically does the same thing as
<code>M</code>, but while passing through its first argument. The
difference between <code>T</code> and <code>C</code> is similar:</p>
<pre><code>Cxyz ~&gt; xzy
Txy  ~&gt; yx</code></pre>
<p>So, first of all, it is pretty simple to show that <code>BCKW</code>
contains all of the <code>BAMT</code> combinators. Try find a way to
write <code>T</code> using only <code>BCKW</code> combinators (hint: you
might want to use your previous answer for writing <code>I</code> using
<code>BCKW</code>).</p>
<p id="BCKWtoT">
</p>
<script>
puzzle(
  { input_id: "BCKWtoT"
  , output_lines: 3
  , vars: "xy"
  , expect: "yx"
  , allowed_combos: [Comb.B, Comb.C, Comb.K, Comb.W]
  }
); </script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<p>So in fact all of the changed <code>BAMT</code> combinators can be
encoded using <code>BCKW</code> by putting <code>I</code> (or
<code>CKC</code> or what have you) after the corresponding
<code>BCKW</code> combinator. In other words:</p>
<pre><code>T = CI = C(CKC)
A = KI = K(CKC)
M = WI = W(CKC)</code></pre>
</details>
<p>It’s pretty easy to go from <code>BCKW</code> to <code>BAMT</code>,
then. However, it’s <em>extremely</em> difficult to go the other way.
Here, try to write <code>K</code> in terms of <code>BAMT</code> (this is
quite difficult, do not expect to get it!):</p>
<p id="BAMTtoK">
</p>
<script>
puzzle(
  { input_id: "BAMTtoK"
  , output_lines: 5
  , vars: "xy"
  , expect: "x"
  , allowed_combos: [Comb.B, Comb.A, Comb.M, Comb.T]
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<p>Either of the following would work:</p>
<pre><code>B(TA)(BBT)
B(B(TA)B)T</code></pre>
</details>
<p>So this is why we will stick to <code>BCKW</code> for the time being:
<code>BAMT</code> is just too painful to use.</p>
<h1 id="linear-types-and-combinators">Linear Types and Combinators</h1>
<p>One of the things <code>BCKW</code> has over <code>SKI</code> is that
each combinator represents a concrete capability. <code>K</code> and
<code>W</code> especially: without these combinators, we can neither
duplicate nor discard variables. This makes the languages without one or
both of these interesting (albeit not Turing-complete).</p>
<p>If we say that we can’t use <code>W</code>, we know that it will not
duplicate any input. In fact, encoded appropriately, we know that the
program can only decrease its size through execution. The
<code>BCK</code> system is in fact an encoding of <em>affine</em> logic,
which is all the rage nowadays. Rust uses affine types to guarantee
memory safety: by preventing duplication of references, you can know
that whenever you’re looking at a variable you’re free to modify it, or
destroy it if necessary (obviously Rust is a bit more complex than what
I’ve described here, but <code>BCK</code> is indeed the fundamental
basis for the system in the same way that <code>SK</code> can be the
basis for any programming language).</p>
<p>If we remove <code>K</code> as well we have a <em>linear</em>
language. This is even more restrictive, but is also quite actively
researched at the moment: linear types have been used to construct
languages for differential privacy, for instance.</p>
<p>There’s one small issue with <code>BC</code>: it doesn’t (strictly
speaking) have an equivalent to <code>I</code>. You can write an
expression which is <em>close</em>, but it will only actually compute
when applied to at least 3 arguments. See if you can find it.</p>
<p id="BCtoI">
</p>
<script>
puzzle(
  { input_id: "BCtoI"
  , output_lines: 4
  , vars: "xyz"
  , expect: "xyz"
  , allowed_combos: [Comb.B, Comb.C]
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<pre><code>BCC</code></pre>
</details>
<p>Usually we add <code>I</code>, though, to give us
<code>BCI</code>.</p>
<h1 id="the-minimal-combinators-s-and-k">The Minimal Combinators: S and
K</h1>
<p><code>S</code> is the only combinator we haven’t seen yet. It’s kind
of a combination of <code>B</code>, <code>C</code>, and
<code>W</code>:</p>
<pre><code>Sxyz ~&gt; xz(yz)</code></pre>
<p>It does parenthesising, reordering, <em>and</em> duplication. This
allows it to be powerful enough to be Turing complete only with the
addition of <code>K</code>. Try first to construct <code>I</code> given
only <code>S</code> and <code>K</code>:</p>
<p id="SKtoI">
</p>
<script>
puzzle(
  { input_id: "SKtoI"
  , output_lines: 3
  , vars: "x"
  , expect: "x"
  , allowed_combos: [Comb.S, Comb.K]
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<p><code>SK</code> followed by any combinator will suffice.</p>
<pre><code>I = SKK = SKS</code></pre>
</details>
<p>And now construct <code>S</code> from <code>BCKW</code>:</p>
<p id="BCKWtoS">
</p>
<script>
puzzle(
  { input_id: "BCKWtoS"
  , output_lines: 3
  , vars: "xyz"
  , expect: "xz(yz)"
  , allowed_combos: [Comb.B, Comb.C, Comb.K, Comb.W]
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<pre><code>S = B(BW)(BBC) = B(B(BW)C)(BB)</code></pre>
</details>
<p>Of course, to show that <code>SK</code> is universal we’d need to
show that it contains one of the other universal systems. We won’t do
that exhaustively here, but first just try to figure out <code>B</code>
and <code>W</code>:</p>
<p id="SKItoB">
</p>
<script>
puzzle(
  { input_id: "SKItoB"
  , output_lines: 3
  , vars: "xyz"
  , expect: "x(yz)"
  , normal: true
  , allowed_combos: [Comb.S, Comb.K, Comb.I]
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<pre><code>B = S(KS)K</code></pre>
</details>
<p id="SKItoW">
</p>
<script>
puzzle(
  { input_id: "SKItoW"
  , output_lines: 3
  , vars: "xy"
  , expect: "xyy"
  , allowed_combos: [Comb.S, Comb.K, Comb.I]
  , normal: true
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<pre><code>W = SS(SK) = SS(KI)</code></pre>
</details>
<h1 id="recursion">Recursion</h1>
<p>The next task is to encode the <code>Y</code> combinator. This is a
combinator that evaluates to the following:</p>
<pre><code>Yf ~&gt; f(Yf)</code></pre>
<p>As you can see, it encodes <em>recursion</em>. Like the
<code>fix</code> function in Haskell, this combinator allows us to do
recursion without explicit self-reference. And, of course, we can define
this combinator using the combinators we’ve seen before, since our
language is Turing complete. One encoding is <code>BM(CBM)</code>:</p>
<p id="Y">
</p>
<script>
repl(
  { input_id: "Y"
  , output_lines: 5
  , initial_expr: "BM(CBM)f"
  , normal: true
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<p>As you can see, <code>BM(CBM)</code>, when applied to <code>f</code>,
yields <code>f(M(CBMf))</code>, which is equivalent to
<code>f(BM(CBM)f)</code> (the <code>B</code> just hasn’t been applied
inside the <code>f</code>). So this is indeed a proper recursion
combinator.</p>
<h1 id="encoding-numbers">Encoding Numbers</h1>
<p>Let’s try doing a little bit of programming with these combinators
now.</p>
<p>In the lambda calculus, to encode numbers we often use the
<em>church</em> numerals: that’s what we’re going to do here, too. A
church numeral representing some number
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
is a function which takes two arguments, and applies the first argument
to the second
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
times. Here are some church numerals in Haskell:</p>
<pre><code>zero :: (a -&gt; a) -&gt; a -&gt; a
zero f x = x

one :: (a -&gt; a) -&gt; a -&gt; a
one f x = f x

two :: (a -&gt; a) -&gt; a -&gt; a
two f x = f (f x)

three :: (a -&gt; a) -&gt; a -&gt; a
three f x = f (f (f x))</code></pre>
<p>Encoding these numerals in combinators is a little more difficult.
Zero and one are obvious: they are <code>A</code> and <code>I</code>,
respectively. Try to figure out two and three:</p>
<p id="two">
</p>
<script>
puzzle(
  { input_id: "two"
  , output_lines: 2
  , normal: true
  , vars: "fx"
  , expect: "f(fx)"
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<code>WB</code>
</details>
<p id="three">
</p>
<script>
puzzle(
  { input_id: "three"
  , output_lines: 2
  , normal: true
  , vars: "fx"
  , expect: "f(f(fx))"
  }
);
</script>
<noscript>
Turn on JavaScript to allow interactive evaluation
</noscript>
<details>
<summary>
Answer
</summary>
<code>SB(WB)</code>
</details>
<p>It turns out that it’s pretty easy to encode numbers in a relatively
small amount of space, using a binary encoding. First, multiplication on
Church numerals is simply composition: so that’s <code>B</code> on our
combinators. We already have 2 defined, so the next thing we need for a
binary encoding is a successor function. And we know what <em>that</em>
is, from the answer to 3!</p>
<p>This means we can encode normal number in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
space (although it still takes linear time to evaluate). The following
repl allows for numbers:</p>
<p id="numbers">
</p>
<script>
repl({
  input_id: "numbers",
  normal: true,
  allow_numbers: true,
  initial_expr: "5fx"
});
</script>
<p>We could take up even less space if we allowed for non-normal forms.
4, for instance, could be encoded like so:</p>
<pre><code>M(WB)</code></pre>
<p>But we generally prefer to keep our encodings in normal form:
otherwise there’s some extra evaluation we have to pay for when we go to
use them.</p>
<h1 id="encoding-lambda-terms-as-combinators">Encoding Lambda Terms as
Combinators</h1>
<p>Once upon a time SKI combinators were used as a target for functional
compilers: Miranda, Haskell’s precursor, compiled down to a set of
combinators which included <code>SKI</code>. Nowadays, Haskell is
compiled to the “spineless tagless G-machine”: its compilation technique
took over from combinators in the late 80s, and has been the dominant
form since. Apparently the reason is that, on the current architecture
of most computers, combinator-based compilation targets just aren’t fast
enough. They generate too much garbage: as a result, switching to the
STG yielded about a 40% speedup.</p>
<p>A lot of this information comes from two talks, by the way:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=GawiQQCn3bk">An
Introduction to Combinator Compilers and Graph Reduction Machines</a>,
by <a href="https://twitter.com/graunked?lang=en">David Graunke</a>
<span class="citation"
data-cites="graunkeIntroductionCombinatorCompilers2016">(<a
href="#ref-graunkeIntroductionCombinatorCompilers2016"
role="doc-biblioref">2016</a>)</span>, which goes through a high-level
history and explanation of combinator compilers and why we switched away
from them. A very interesting tidbit in this talk was that some people
started making custom hardware to handle combinator calculi a little
better. Even more interesting is the fact that these days we have FPGAs
all over the place, so maybe combinator compilers are ripe for
reintroduction?</li>
<li><a href="https://www.youtube.com/watch?v=zhj_tUMwTe0">Combinators
Revisited</a>, by <a href="https://twitter.com/kmett">Edward Kmett</a>
<span class="citation" data-cites="kmettCombinatorsRevisited2018">(<a
href="#ref-kmettCombinatorsRevisited2018"
role="doc-biblioref">2018</a>)</span>, which goes through a little more
of the details of the problems with combinator compilers, and mentions
some of the places in which we’re tantalisingly close to making
combinator compilation work.</li>
</ul>
<p>So compilation to combinators was once upon a time an extremely
active area of research, but it has since fallen by the wayside a little
because our current hardware is unable to evaluate it efficiently. What
this means for us, though, is that there’s a large body of work on how
to compile lambda terms to combinators!</p>
<p>We use the following basic combinator set for compilation:
<code>SKIBC</code>. <code>S</code> is really the most important one
here: of course we only need it and <code>K</code>, but we use
<code>I</code> because it dramatically simplifies the expressions we
generate, and we use <code>B</code> and <code>C</code> because they are
special cases of <code>S</code>, as we’ll see in a second. The
translation works like so:</p>
<pre><code>\x. e1 e2 -&gt; S (\x. e1) (\x. e2)
\x. x     -&gt; I
\x. e     -&gt; K e</code></pre>
<p>The translation works bottom-up. We’re only interested in removing
the lambdas: combinator calculus does have application, after all, so
there’s nothing we need to do in that case. For that reason, the
algorithm is often called “abstraction elimination”, and it’s the one
the <a href="pointfree.io">pointfree.io</a> uses to automatically
pointfree Haskell expressions.</p>
<p>There are three forms of abstraction: abstraction into an expression
which is an application, abstraction which returns its argument, and
abstraction which returns something other than its argument. In the
first case, we use <code>S</code> to pass the argument down each branch
of the abstraction. In the second, we just use <code>I</code>. And in
the third case, we use <code>K</code> to just ignore the argument. We
won’t ever get <code>\x. \y. e</code>, since the algorithm works
bottom-up, so the <code>\y. e</code> is eliminated before looking at the
<code>\x. \y. e</code>.</p>
<p><code>B</code> and <code>C</code> work like special cases of
<code>S</code>: when we pass <code>x</code> down both branches of the
application in the first case, sometimes that work is unnecessary.
Sometimes one of the branches doesn’t use the passed variable: in this
case, we use <code>B</code> or <code>C</code>, depending on which branch
ignores the variable.</p>
<pre><code>\x. e1 e2, x ∉ e1 -&gt; B e1 (\x. e2)
\x. e1 e2, x ∉ e2 -&gt; C (\x. e1) e2</code></pre>
<p>There is one issue with this approach: it produces combinator
expressions which are of order
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>3</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^3)</annotation></semantics></math>
larger than the corresponding lambda expression. With some tricks (like
our usage of <code>C</code> and <code>B</code>) we can get that down to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>,
but that’s still a pretty unpleasant size increase.</p>
<p>The issue is that we’re basically passing the arguments as a
singly-linked list, where naive access is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix" mathvariant="script">(</mo><msup><mi>𝓃</mi><mn mathvariant="script">2</mn></msup><mo stretchy="false" form="postfix" mathvariant="script">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O(n^2)}</annotation></semantics></math>,
and more sophisticated access is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>.</p>
<p>Oleg Kiselyov wrote a <a
href="http://okmij.org/ftp/tagless-final/ski.pdf">paper</a> <span
class="citation" data-cites="kiselyovSKISemantically2018">(<a
href="#ref-kiselyovSKISemantically2018"
role="doc-biblioref">2018</a>)</span> on getting this down to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>,
with some memoisation. There’s also a blog post <span class="citation"
data-cites="lynnBenLynnOnline2018">(<a href="#ref-lynnBenLynnOnline2018"
role="doc-biblioref">Lynn 2018</a>)</span>, describing how to get that
conversion without memoisation in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>
time, and an online implementation <a
href="https://crypto.stanford.edu/~blynn/lambda/logski.html">here</a>.</p>
<h1 id="conclusion">Conclusion</h1>
<p>That’s all for this post! I’ll probably write more about combinators
in the future: they’re an extremely interesting subject, and a lot of
fun as puzzles to mess around with. One thing that I haven’t mentioned
is the connection between combinators and concatenative languages: it
turns out that these two things are pretty much the same thing! Maybe
I’ll look at it in a future post.</p>
<hr />
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-graunkeIntroductionCombinatorCompilers2016"
class="csl-entry" role="listitem">
Graunke, David. 2016. <span>“An <span>Introduction</span> to
<span>Combinator Compilers</span> and <span>Graph Reduction
Machines</span>.”</span> <span>St. Louis</span>. <a
href="https://www.youtube.com/watch?v=GawiQQCn3bk">https://www.youtube.com/watch?v=GawiQQCn3bk</a>.
</div>
<div id="ref-kiselyovSKISemantically2018" class="csl-entry"
role="listitem">
Kiselyov, Oleg. 2018.
<span>“<span><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>λ</mi><annotation encoding="application/x-tex">\lambda</annotation></semantics></math></span>
to <span>SKI</span>, <span>Semantically</span>.”</span> In
<em>Functional and <span>Logic Programming</span></em>, ed by. John P.
Gallagher and Martin Sulzmann, 33–50. Lecture <span>Notes</span> in
<span>Computer Science</span>. <span>Cham</span>: <span>Springer
International Publishing</span>. doi:<a
href="https://doi.org/10.1007/978-3-319-90686-7_3">10.1007/978-3-319-90686-7_3</a>.
<a
href="http://okmij.org/ftp/tagless-final/ski.pdf">http://okmij.org/ftp/tagless-final/ski.pdf</a>.
</div>
<div id="ref-kmettCombinatorsRevisited2018" class="csl-entry"
role="listitem">
Kmett, Edward. 2018. <span>“Combinators <span>Revisited</span>.”</span>
<span>Wesley Conference Centre, Sydney, Australia</span>. <a
href="https://yowconference.com/talks/edward-kmett/yow-lambda-jam-2018/combinators-revisited-5919">https://yowconference.com/talks/edward-kmett/yow-lambda-jam-2018/combinators-revisited-5919</a>.
</div>
<div id="ref-lynnBenLynnOnline2018" class="csl-entry" role="listitem">
Lynn, Ben. 2018. <span>“Ben <span>Lynn</span>’s <span>Online
Garbage</span>: <span>Lambda</span> the
<span>Penultimate</span>.”</span> <em>Ben Lynn’s Online Garbage</em>. <a
href="https://benlynn.blogspot.com/2018/11/lambda-penultimate_16.html">https://benlynn.blogspot.com/2018/11/lambda-penultimate_16.html</a>.
</div>
<div id="ref-wildenhainTuringCompletenessMS2017" class="csl-entry"
role="listitem">
Wildenhain, Tom. 2017. <span>“On the <span>Turing Completeness</span> of
<span>MS PowerPoint</span>.”</span> <a
href="http://www.andrew.cmu.edu/user/twildenh/PowerPointTM/Paper.pdf">http://www.andrew.cmu.edu/user/twildenh/PowerPointTM/Paper.pdf</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>If you want to look up these combinators elsewhere, this
is the only one you won’t be able to find: it’s much less common than
<code>K</code>, and where I have found it people just call it
<code>K</code>, so I had to pick a different letter to distinguish it<a
href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Sat, 17 Oct 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-10-17-ski.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Some More List Algorithms</title>
    <link>https://doisinkidney.com/posts/2020-08-22-some-more-list-algorithms.html</link>
    <description><![CDATA[<div class="info">
    Posted on August 22, 2020
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>It’s been a while since I last wrote a post (I’ve been busy with my
Master’s thesis, which is nearly done), so I thought I would quickly
throw out some fun snippets of Haskell I had reason to write over the
past couple of weeks.</p>
<h1 id="zipping-with-folds">Zipping With Folds</h1>
<p>For some reason, until recently I had been under the impression that
it was impossible to fuse zips efficiently. In other words, I thought
that <code>zip</code> was like <code>tail</code>, in that if it was
implemented using only <code>foldr</code> it would result in an
asymptotic slowdown (<code>tail</code> is normally
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>,
implemented as a fold it’s
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>).</p>
<p>Well, it seems like this is not the case. The old zip-folding code I
had looks to me now to be the correct complexity: it’s related to <a
href="http://okmij.org/ftp/Streams.html#zip-folds">How To Zip Folds</a>,
by Oleg Kiselyov (although I’m using a different version of the function
which can be found <a
href="https://mail.haskell.org/pipermail/haskell/2005-October/016693.html">on
the mailing list</a>). The relevant code is as follows:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Zip</span> a b <span class="ot">=</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Zip</span> {<span class="ot"> runZip ::</span> a <span class="ot">-&gt;</span> (<span class="dt">Zip</span> a b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b }</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs ys <span class="ot">=</span> <span class="fu">foldr</span> xf xb xs (<span class="dt">Zip</span> (<span class="fu">foldr</span> yf yb ys))</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    xf x xk yk <span class="ot">=</span> runZip yk x xk</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    xb _ <span class="ot">=</span> []</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    yf y yk x xk <span class="ot">=</span> (x,y) <span class="op">:</span> xk (<span class="dt">Zip</span> yk)</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    yb _ _ <span class="ot">=</span> []</span></code></pre></div>
<p>There are apparently <a
href="https://hackage.haskell.org/package/base-4.14.0.0/docs/src/GHC.List.html#zip">reasons</a>
for why the Prelude’s <code>zip</code> isn’t allowed to fuse both of its
arguments: I don’t fully understand them, however. (in particular the
linked page says that the fused zip would have different strictness
behaviour, but the version I have above seems to function properly).</p>
<p>This version of zip leads to some more fun solutions to folding
puzzles, like <a
href="https://old.reddit.com/r/haskell/comments/f3z18s/zipping_from_the_end_of_a_list/">this
one</a>:</p>
<blockquote>
<p>Write a function that is equivalent to:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>zipFromEnd xs ys <span class="ot">=</span> <span class="fu">reverse</span> (<span class="fu">zip</span> (<span class="fu">reverse</span> xs) (<span class="fu">reverse</span> ys))</span></code></pre></div>
<p>Without creating any intermediate lists.</p>
</blockquote>
<p>The desired function is interesting in that, instead of lining up
lists according to their first elements, it aligns them according to the
<em>ends</em>.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> zipFromEnd [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>] <span class="st">&quot;abc&quot;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">1</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">2</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">3</span>,<span class="ch">&#39;c&#39;</span>)]</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> zipFromEnd [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>] <span class="st">&quot;abcd&quot;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">1</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">2</span>,<span class="ch">&#39;c&#39;</span>),(<span class="dv">3</span>,<span class="ch">&#39;d&#39;</span>)]</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> zipFromEnd [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>] <span class="st">&quot;abc&quot;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">2</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">3</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">4</span>,<span class="ch">&#39;c&#39;</span>)]</span></code></pre></div>
<p>The solution here is just to use <code>foldl</code>, and we get the
following:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipFromEnd ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>zipFromEnd xs ys <span class="ot">=</span> <span class="fu">foldl</span> xf xb xs (<span class="dt">Zip</span> (<span class="fu">foldl</span> yf yb ys)) []</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    xf xk x yk <span class="ot">=</span> runZip yk x xk</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    xb _ zs <span class="ot">=</span> zs</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    yf yk y x xk zs <span class="ot">=</span> xk (<span class="dt">Zip</span> yk) ((x,y) <span class="op">:</span> zs)</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    yb _ _ zs <span class="ot">=</span> zs</span></code></pre></div>
<p>Another function which is a little interesting is the “zip longest”
function:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipLongest ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>zipLongest c xs ys <span class="ot">=</span> <span class="fu">foldr</span> xf xb xs (<span class="dt">Zip</span> (<span class="fu">foldr</span> yf yb ys))</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    xf x xk yk <span class="ot">=</span> runZip yk (<span class="dt">Just</span> x) xk</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    xb zs <span class="ot">=</span> runZip zs <span class="dt">Nothing</span> xb</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    yf y yk <span class="dt">Nothing</span>  xk <span class="ot">=</span>     y <span class="op">:</span> xk (<span class="dt">Zip</span> yk)</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    yf y yk (<span class="dt">Just</span> x) xk <span class="ot">=</span> c x y <span class="op">:</span> xk (<span class="dt">Zip</span> yk)</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    yb <span class="dt">Nothing</span>  _  <span class="ot">=</span> []</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    yb (<span class="dt">Just</span> x) zs <span class="ot">=</span> x <span class="op">:</span> zs (<span class="dt">Zip</span> yb)</span></code></pre></div>
<p>Finally, all of these functions rely on the <code>Zip</code> type,
which is <em>not</em> strictly positive. This means that we can’t use it
in Agda, and it’s tricky to reason about: I wonder what it is about
functions for deforestation that tends to lead to non-strictly-positive
datatypes.</p>
<h1 id="lexicographic-permutations">Lexicographic Permutations</h1>
<p>The next puzzle I was interested in was finding the next
lexicographic permutation of some string. In other words, given some
string
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>s</mi><annotation encoding="application/x-tex">s</annotation></semantics></math>,
you need to find another string
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>t</mi><annotation encoding="application/x-tex">t</annotation></semantics></math>
that is a permutation of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>s</mi><annotation encoding="application/x-tex">s</annotation></semantics></math>
such that
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mo>&lt;</mo><mi>t</mi></mrow><annotation encoding="application/x-tex">s &lt; t</annotation></semantics></math>,
and that there is no string
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>u</mi><annotation encoding="application/x-tex">u</annotation></semantics></math>
that is a permutation of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>s</mi><annotation encoding="application/x-tex">s</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>s</mi><mo>&lt;</mo><mi>u</mi><mo>&lt;</mo><mi>t</mi></mrow><annotation encoding="application/x-tex">s &lt; u &lt; t</annotation></semantics></math>.
The <a
href="https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order">Wikipedia
article on the topic</a> is excellent (and clear), but again the
algorithm is described in extremely imperative terms:</p>
<blockquote>
<ol>
<li>Find the largest index k such that a[k] &lt; a[k + 1]. If no such
index exists, the permutation is the last permutation.</li>
<li>Find the largest index l greater than k such that a[k] &lt;
a[l].</li>
<li>Swap the value of a[k] with that of a[l].</li>
<li>Reverse the sequence from a[k + 1] up to and including the final
element a[n].</li>
</ol>
</blockquote>
<p>The challenge here is to write this algorithm without doing any
indexing: indexing is expensive on Haskell lists, and regardless it is
cleaner to express it without.</p>
<p>I managed to work out the following:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">nextLexPerm ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> [a]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>nextLexPerm []     <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>nextLexPerm (x<span class="op">:</span>xs) <span class="ot">=</span> go1 x xs</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    go1 _ []     <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    go1 i (j<span class="op">:</span>xs) <span class="ot">=</span> <span class="fu">maybe</span> (go2 i j [] xs) (<span class="dt">Just</span> <span class="op">.</span> (i<span class="op">:</span>)) (go1 j xs)</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    go2 i j xs ys</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> j <span class="op">&lt;=</span> i    <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Just</span> (fromMaybe (j <span class="op">:</span> <span class="fu">foldl</span> (<span class="fu">flip</span> (<span class="op">:</span>)) (i<span class="op">:</span>xs) ys) (go3 i (j<span class="op">:</span>xs) ys))</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>    go3 _ _  []     <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>    go3 i xs (j<span class="op">:</span>ys) <span class="ot">=</span> go2 i j xs ys</span></code></pre></div>
<h1 id="circular-sorting">Circular Sorting</h1>
<p>This comes from the <a
href="http://rosettacode.org/wiki/Sorting_Algorithms/Circle_Sort">Rosetta
Code problem Circle Sort</a>. This is a strange little sorting
algorithm, where basically you compare elements on opposite sides of an
array, swapping them as needed. The example given is the following:</p>
<pre><code>6 7 8 9 2 5 3 4 1</code></pre>
<p>First we compare (and swap) <code>6</code> and <code>1</code>, and
then <code>7</code> and <code>4</code>, and so on, until we reach the
middle. At this point we split the array in two and perform the
procedure on each half. After doing this once it is not the case that
the array is definitely sorted: you may have to repeat the procedure
several (but finitely many) times, until no swaps are performed.</p>
<p>I have absolutely no idea what the practical application for such an
odd algorithm would be, but it seemed like an interesting challenge to
try implement it in a functional style (i.e. without indices or
mutation).</p>
<p>The first thing we have to do is fold the list in half, so we pair up
the right items. We’ve actually seen an algorithm to do this <a
href="2019-05-08-list-manipulation-tricks.html">before</a>: it’s often
called the “tortoise and the hare”, and our previous use was to check if
a list was a palindrome. Here’s how we implement it:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">halve ::</span> [a] <span class="ot">-&gt;</span> [(a,a)]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>halve xs <span class="ot">=</span> <span class="fu">snd</span> (go xs xs)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    go (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> f y (go ys zs)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    go (_<span class="op">:</span>ys) [_]      <span class="ot">=</span> (ys,[])</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    go ys     []       <span class="ot">=</span> (ys,[])</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    f x (y<span class="op">:</span>ys,zs) <span class="ot">=</span> (ys, (x,y) <span class="op">:</span> zs)</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> halve [<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">2</span>,<span class="dv">5</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">1</span>]</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">6</span>,<span class="dv">1</span>),(<span class="dv">7</span>,<span class="dv">4</span>),(<span class="dv">8</span>,<span class="dv">3</span>),(<span class="dv">9</span>,<span class="dv">5</span>)]</span></code></pre></div>
<p>Notice that the <code>2</code> in the very middle of the list is
missing from the output: I’ll describe how to handle that element later
on. In the above piece of code, that <code>2</code> actually gets bound
to the underscore (in <code>(_:ys)</code>) in the second clause of
<code>go</code>.</p>
<p>Next we need to do the actual swapping: this is actually pretty
straightforward, if we think of the algorithm functionally, rather than
imperatively. Instead of swapping things in place, we are building up
both halves of the new list, so the “swap” operation should simply
decide which list each item goes into.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">halve ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> ([a],[a])</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>halve xs <span class="ot">=</span> tl (go xs xs)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    tl (_,lte,gt) <span class="ot">=</span> (lte,gt)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    go (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> swap y (go ys zs)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    go (_<span class="op">:</span>ys) [_]      <span class="ot">=</span> (ys,[],[])</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>    go ys     []       <span class="ot">=</span> (ys,[],[])</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>    swap x (y<span class="op">:</span>ys,lte,gt)</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> (ys, x <span class="op">:</span> lte, y <span class="op">:</span> gt)</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (ys, y <span class="op">:</span> lte, x <span class="op">:</span> gt)</span></code></pre></div>
<p>At this point we can also see what to do with the middle item: we’ll
put it in the higher or lower list, depending on a comparison with the
element it’s next to.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">halve ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> ([a],[a])</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>halve xs <span class="ot">=</span> tl (go xs xs)</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    tl (_,lte,gt) <span class="ot">=</span> (lte,gt)</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    go (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> swap y (go ys zs)</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    go ys     []       <span class="ot">=</span> (ys,[],[])</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>    go (y<span class="op">:</span>ys) [_]      <span class="ot">=</span> (ys,[y <span class="op">|</span> e],[y <span class="op">|</span> <span class="fu">not</span> e])</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> e <span class="ot">=</span> y <span class="op">&lt;=</span> <span class="fu">head</span> ys</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>    swap x (y<span class="op">:</span>ys,lte,gt)</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> (ys, x <span class="op">:</span> lte, y <span class="op">:</span> gt)</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (ys, y <span class="op">:</span> lte, x <span class="op">:</span> gt)</span></code></pre></div>
<p>Next, we can use this as a helper function in the overall recursive
function.</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">circleSort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>circleSort [] <span class="ot">=</span> []</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>circleSort [x] <span class="ot">=</span> [x]</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>circleSort xs <span class="ot">=</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> (lte,gt) <span class="ot">=</span> halve xs</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span> circleSort lte <span class="op">++</span> circleSort (<span class="fu">reverse</span> gt)</span></code></pre></div>
<p>This function isn’t correct (yet). As we mentioned already, we need
to run the circle sort procedure multiple times until no swaps occur. We
can add in the tracking of swaps like so:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">circleSort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>circleSort xs <span class="ot">=</span> <span class="kw">if</span> swapped <span class="kw">then</span> circleSort ks <span class="kw">else</span> ks</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    (swapped,ks) <span class="ot">=</span> go xs</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    go []  <span class="ot">=</span> (<span class="dt">False</span>, [])</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>    go [x] <span class="ot">=</span> (<span class="dt">False</span>, [x])</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>    go xs  <span class="ot">=</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> (s,_,lte,gt) <span class="ot">=</span> halve xs xs</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>          (sl,lte&#39;) <span class="ot">=</span> go lte</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>          (sg,gt&#39; ) <span class="ot">=</span> go (<span class="fu">reverse</span> gt)</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">in</span> (s <span class="op">||</span> sl <span class="op">||</span> sg, lte&#39; <span class="op">++</span> gt&#39;)</span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a>    halve (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> swap y (halve ys zs)</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>    halve ys     []       <span class="ot">=</span> (<span class="dt">False</span>,ys,[],[])</span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>    halve (y<span class="op">:</span>ys) [_]      <span class="ot">=</span> (<span class="dt">False</span>,ys,[y <span class="op">|</span> e],[y <span class="op">|</span> <span class="fu">not</span> e])</span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> e <span class="ot">=</span> y <span class="op">&lt;=</span> <span class="fu">head</span> ys</span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a>    swap x (s,y<span class="op">:</span>ys,lte,gt)</span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> (s   ,ys, x <span class="op">:</span> lte, y <span class="op">:</span> gt)</span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (<span class="dt">True</span>,ys, y <span class="op">:</span> lte, x <span class="op">:</span> gt)</span></code></pre></div>
<p>So at this point we actually have a working implementation of the
function, which avoids indices as intended. It has some problems still,
though. First, we call <code>++</code>, when we could be using
difference lists. Here’s the solution to that:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">circleSort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>circleSort xs <span class="ot">=</span> <span class="kw">if</span> swapped <span class="kw">then</span> circleSort ks <span class="kw">else</span> ks</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    (swapped,ks) <span class="ot">=</span> go xs []</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    go []  zs <span class="ot">=</span> (<span class="dt">False</span>, zs)</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    go [x] zs <span class="ot">=</span> (<span class="dt">False</span>, x<span class="op">:</span>zs)</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>    go xs  zs <span class="ot">=</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> (s,_,lte,gt) <span class="ot">=</span> halve xs xs</span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>          (sl,lte&#39;) <span class="ot">=</span> go lte gt&#39;</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>          (sg,gt&#39; ) <span class="ot">=</span> go (<span class="fu">reverse</span> gt) zs</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">in</span> (s <span class="op">||</span> sl <span class="op">||</span> sg, lte&#39;)</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>    halve (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> swap y (halve ys zs)</span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a>    halve ys     []       <span class="ot">=</span> (<span class="dt">False</span>,ys,[],[])</span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a>    halve (y<span class="op">:</span>ys) [_]      <span class="ot">=</span> (<span class="dt">False</span>,ys,[y <span class="op">|</span> e],[y <span class="op">|</span> <span class="fu">not</span> e])</span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> e <span class="ot">=</span> y <span class="op">&lt;=</span> <span class="fu">head</span> ys</span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a>    swap x (s,y<span class="op">:</span>ys,lte,gt)</span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> (s   ,ys, x <span class="op">:</span> lte, y <span class="op">:</span> gt)</span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (<span class="dt">True</span>,ys, y <span class="op">:</span> lte, x <span class="op">:</span> gt)</span></code></pre></div>
<p>Next we can actually rewrite the <code>go</code> function to allow
for a certain amount of tail recursion (kind of):</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">circleSort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>circleSort xs <span class="ot">=</span> <span class="kw">if</span> swapped <span class="kw">then</span> circleSort ks <span class="kw">else</span> ks</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    (swapped,ks) <span class="ot">=</span> go xs (<span class="dt">False</span>,[])</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    go []  (s,ks) <span class="ot">=</span> (s,ks)</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    go [x] (s,ks) <span class="ot">=</span> (s,x<span class="op">:</span>ks)</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    go xs  (s,ks) <span class="ot">=</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> (s&#39;,_,ls,rs) <span class="ot">=</span> halve s xs xs</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>      <span class="kw">in</span> go ls (go (<span class="fu">reverse</span> rs) (s&#39;,ks))</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>    halve s (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> swap y (halve s ys zs)</span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>    halve s ys     []       <span class="ot">=</span> (s,ys,[],[])</span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a>    halve s (y<span class="op">:</span>ys) [_]      <span class="ot">=</span> (s,ys,[y <span class="op">|</span> e],[y <span class="op">|</span> <span class="fu">not</span> e])</span>
<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> e <span class="ot">=</span> y <span class="op">&lt;=</span> <span class="fu">head</span> ys</span>
<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a>    swap x (s,y<span class="op">:</span>ys,ls,rs)</span>
<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> (   s,ys,x<span class="op">:</span>ls,y<span class="op">:</span>rs)</span>
<span id="cb14-19"><a href="#cb14-19" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (<span class="dt">True</span>,ys,y<span class="op">:</span>ls,x<span class="op">:</span>rs)</span></code></pre></div>
<p>Next, we call <code>reverse</code>: but we can avoid the reverse by
passing a parameter which tells us which direction we’re walking down
the list. Since the swapping logic is symmetric, we’re able to just
invert some of the functions. It is a little tricky, though:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">circleSort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>circleSort xs <span class="ot">=</span> <span class="kw">if</span> swapped <span class="kw">then</span> circleSort ks <span class="kw">else</span> ks</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    (swapped,ks) <span class="ot">=</span> go <span class="dt">False</span> xs (<span class="dt">False</span>,[])</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    go d []  (s,ks) <span class="ot">=</span> (s,ks)</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    go d [x] (s,ks) <span class="ot">=</span> (s,x<span class="op">:</span>ks)</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>    go d xs  (s,ks) <span class="ot">=</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">let</span> (s&#39;,_,ls,rs) <span class="ot">=</span> halve d s xs xs</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>      <span class="kw">in</span> go <span class="dt">False</span> ls (go <span class="dt">True</span> rs (s&#39;,ks))</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>    halve d s (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> swap d y (halve d s ys zs)</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>    halve d s ys     []       <span class="ot">=</span> (s,ys,[],[])</span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>    halve d s (y<span class="op">:</span>ys) [_]      <span class="ot">=</span> (s,ys,[y <span class="op">|</span> e],[y <span class="op">|</span> <span class="fu">not</span> e])</span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> e <span class="ot">=</span> y <span class="op">&lt;=</span> <span class="fu">head</span> ys</span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>    swap d x (s,y<span class="op">:</span>ys,ls,rs)</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> bool (<span class="op">&lt;=</span>) (<span class="op">&lt;</span>) d x y <span class="ot">=</span> (    d <span class="op">||</span> s,ys,x<span class="op">:</span>ls,y<span class="op">:</span>rs)</span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span>           <span class="ot">=</span> (<span class="fu">not</span> d <span class="op">||</span> s,ys,y<span class="op">:</span>ls,x<span class="op">:</span>rs)</span></code></pre></div>
<p>So there it is! The one-pass, purely functional implementation of
circle sort. Very possibly the most useless piece of code I’ve ever
written.</p>
]]></description>
    <pubDate>Sat, 22 Aug 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-08-22-some-more-list-algorithms.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Presentation on Purely Functional Data Structures</title>
    <link>https://doisinkidney.com/posts/2020-05-19-purely-functional-data-structures-slides.html</link>
    <description><![CDATA[<div class="info">
    Posted on May 19, 2020
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>A week or so ago I gave a presentation on purely functional data
structures as part of an interview<a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"><sup>1</sup></a>. Here are the
slides:</p>
<p><a
href="../pdfs/purely-functional-data-structures-slides.pdf">https://doisinkidney.com/pdfs/purely-functional-data-structures-slides.pdf</a></p>
<p>The presentation is meant to be about 45 minutes long, and it’s aimed
at end of first year computer science students who have done some
Haskell and know a little bit about pointers.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>The interview went well, by the way! All going well with
my master’s I’ll be starting a PhD in Imperial in <a
href="http://zenzike.com/">Nicolas Wu</a>’s group this October.<a
href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Tue, 19 May 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-05-19-purely-functional-data-structures-slides.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>More Random Access Lists</title>
    <link>https://doisinkidney.com/posts/2020-05-02-more-random-access-lists.html</link>
    <description><![CDATA[<div class="info">
    Posted on May  2, 2020
</div>
<div class="info">
    
        Part 2 of a <a href="/series/Random%20Access%20Lists.html">2-part series on Random Access Lists</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<details>
<summary>
Imports and Pragmas
</summary>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DataKinds              #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE PolyKinds              #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE GADTs                  #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeFamilyDependencies #-}</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE ConstraintKinds        #-}</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeOperators          #-}</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE UndecidableInstances   #-}</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE RankNTypes             #-}</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE MultiParamTypeClasses  #-}</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleInstances      #-}</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleContexts       #-}</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE AllowAmbiguousTypes    #-}</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeApplications       #-}</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE ScopedTypeVariables    #-}</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -Wall -fno-warn-unticked-promoted-constructors #-}</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Post</span> <span class="kw">where</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Kind</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> (lookup)</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">GHC.TypeLits</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Lens</span> <span class="kw">hiding</span> (<span class="dt">Cons</span>, index)</span></code></pre></div>
</details>
<h1 id="numerical-representations">Numerical Representations</h1>
<p>One of the common techniques for building purely functional data
structures is to base the structure on some numerical representation
<span class="citation" data-cites="hinze_numerical_1998">(<a
href="#ref-hinze_numerical_1998" role="doc-biblioref">Hinze
1998</a>)</span>. Most recently, I read <span class="citation"
data-cites="swierstraHeterogeneousBinaryRandomaccess2020">Swierstra (<a
href="#ref-swierstraHeterogeneousBinaryRandomaccess2020"
role="doc-biblioref">2020</a>)</span>, where the binary numbers were
used to implement a heterogeneous random-access list (effectively a
generic tuple).</p>
<p>I’m going to look today at using the zeroless binary system to
implement a similar structure, and see what the differences are.</p>
<h1 id="zeroless-binary">Zeroless Binary</h1>
<p>I have talked about this representation before, so I won’t go into it
in huge depth, but put simply the zeroless binary system represents a
binary number as a string of <code>1</code>s and <code>2</code>s
(i.e. no zeroes). The vast majority of the normal binary operations
(addition, multiplication, etc.) can be implemented with the same broad
efficiency, but this system has one key advantage in that every single
number is uniquely represented. Since we’re going to use these numbers
to index our data types, this is actually extremely useful.</p>
<p>Before we get started, we’ll first define the peculiar type of lists
we’re going to use.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Plus</span> a <span class="ot">=</span> a <span class="op">:-</span> <span class="dt">Star</span> a</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Star</span> a</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Some</span> (<span class="dt">Plus</span> a)</span></code></pre></div>
<p><code>Star a</code> is isomorphic to <code>[a]</code>, so we’ve not
lost any expressive power or anything like that. The usefulness of this
definition is that we have a non-empty list type built in to our list
type, so we don’t have to do conversion back and forth which can be
cumbersome.</p>
<p>Next on to the number itself:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Bit</span> <span class="ot">=</span> <span class="dt">B1</span> <span class="op">|</span> <span class="dt">B2</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Inc</span> (<span class="ot">xs ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) <span class="ot">=</span> (<span class="ot">ys ::</span> <span class="dt">Plus</span> <span class="dt">Bit</span>) <span class="op">|</span> ys <span class="ot">-&gt;</span> xs <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Inc</span> <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">B1</span> <span class="op">:-</span> <span class="dt">Nil</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Inc</span> (<span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> xs)) <span class="ot">=</span> <span class="dt">B2</span> <span class="op">:-</span> xs</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Inc</span> (<span class="dt">Some</span> (<span class="dt">B2</span> <span class="op">:-</span> xs)) <span class="ot">=</span> <span class="dt">B1</span> <span class="op">:-</span> <span class="dt">Some</span> (<span class="dt">Inc</span> xs)</span></code></pre></div>
<p>We’re straight into the type-level operations here, and there’s an
interesting bit of syntax worth pointing out before we move on.
<code>ys -&gt; xs</code> is a type family dependency: it means that we
can uniquely determine <code>xs</code> given <code>ys</code>. This is
very handy for type inference and so on, and is perhaps the main benefit
of the zeroless binary numbers.</p>
<h1 id="a-braun-tree">A Braun Tree</h1>
<p>Next, we’ll build a tree indexed by these numbers. Now that we’re
jumping in to indexing, we’ll need some singletons. Here’s my preferred
way to do them:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">The</span> k <span class="ot">=</span> (<span class="ot">s ::</span> k <span class="ot">-&gt;</span> <span class="dt">Type</span>) <span class="op">|</span> s <span class="ot">-&gt;</span> k</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Known</span> (<span class="ot">x ::</span> a) <span class="kw">where</span><span class="ot"> sing ::</span> <span class="dt">The</span> a x</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SBit</span> b <span class="kw">where</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">SB1</span><span class="ot"> ::</span> <span class="dt">SBit</span> <span class="dt">B1</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">SB2</span><span class="ot"> ::</span> <span class="dt">SBit</span> <span class="dt">B2</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> <span class="dt">The</span> <span class="dt">Bit</span> <span class="ot">=</span> <span class="dt">SBit</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Known</span> <span class="dt">B1</span> <span class="kw">where</span> sing <span class="ot">=</span> <span class="dt">SB1</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Known</span> <span class="dt">B2</span> <span class="kw">where</span> sing <span class="ot">=</span> <span class="dt">SB2</span></span></code></pre></div>
<p>The type family defines the singleton GADTs themselves. The class
<code>Known</code> is for automatically generating singleton values.</p>
<p>On to the tree. We’re actually going to build a <em>Braun</em> tree
here, as they are actually particularly clean to implement on the type
level.</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Carry</span> (<span class="ot">x ::</span> <span class="dt">Bit</span>) (<span class="ot">xs ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>)<span class="ot"> ::</span> <span class="dt">Star</span> <span class="dt">Bit</span> <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Carry</span> <span class="dt">B1</span> xs <span class="ot">=</span> xs</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Carry</span> <span class="dt">B2</span> xs <span class="ot">=</span> <span class="dt">Some</span> (<span class="dt">Inc</span> xs)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> (<span class="ot">xs ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) a <span class="kw">where</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Leaf</span><span class="ot">   ::</span> <span class="dt">Tree</span> <span class="dt">Nil</span> a</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Branch</span><span class="ot"> ::</span> <span class="dt">Forest</span> xs a <span class="ot">-&gt;</span> <span class="dt">Tree</span> (<span class="dt">Some</span> xs) a</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Forest</span> (<span class="ot">xs ::</span> <span class="dt">Plus</span> <span class="dt">Bit</span>) a <span class="kw">where</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Root</span><span class="ot"> ::</span> a</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Bit</span> x</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Tree</span> (<span class="dt">Carry</span> x xs) a</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Tree</span> xs a</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Forest</span> (x <span class="op">:-</span> xs) a</span></code></pre></div>
<p>We first have a type family which increments a binary number if its
first argument is <code>B2</code>: this will maintain the Braun tree’s
invariant.</p>
<p>Next, we have the tree definition itself, which is split into two
mutual definitions, in much the same way as the <code>Star</code> and
<code>Plus</code> lists previously. Next, to <code>cons</code> something
onto the tree:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Cons</span> (<span class="ot">x ::</span> a) (<span class="ot">xs ::</span> <span class="dt">Tree</span> ns a) <span class="ot">=</span> (<span class="ot">ys ::</span> <span class="dt">Forest</span> (<span class="dt">Inc</span> ns) a) <span class="op">|</span> ys <span class="ot">-&gt;</span> x xs <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Cons</span> x <span class="dt">Leaf</span> <span class="ot">=</span> <span class="dt">Root</span> x <span class="dt">SB1</span> <span class="dt">Leaf</span> <span class="dt">Leaf</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Cons</span> x (<span class="dt">Branch</span> (<span class="dt">Root</span> y <span class="dt">SB1</span> ls rs)) <span class="ot">=</span> <span class="dt">Root</span> x <span class="dt">SB2</span> (<span class="dt">Branch</span> (<span class="dt">Cons</span> y rs)) ls</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Cons</span> x (<span class="dt">Branch</span> (<span class="dt">Root</span> y <span class="dt">SB2</span> ls rs)) <span class="ot">=</span> <span class="dt">Root</span> x <span class="dt">SB1</span> (<span class="dt">Branch</span> (<span class="dt">Cons</span> y rs)) ls</span></code></pre></div>
<p>You’ll notice that we can again annotate this type family with
injectivity.</p>
<h1 id="a-heterogeneous-tree">A Heterogeneous Tree</h1>
<p>So far all we have is a size-indexed tree. We want a
<em>heterogeneous</em> tree, meaning that we must next construct a tree
<em>indexed</em> by the previous tree. In order to do this, we’ll first
need singletons on the type level:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Sing</span> (<span class="ot">x ::</span> a) <span class="ot">=</span> (<span class="ot">y ::</span> <span class="dt">The</span> a x) <span class="op">|</span> y <span class="ot">-&gt;</span> x</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> <span class="dt">Sing</span> <span class="dt">B1</span> <span class="ot">=</span> <span class="dt">SB1</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> <span class="dt">Sing</span> <span class="dt">B2</span> <span class="ot">=</span> <span class="dt">SB2</span></span></code></pre></div>
<p>This kind of nonsense we’re doing here is precisely the kind of thing
obsolesced by dependent types, by the way. If you’re already doing
type-level heavy stuff (as we are here) the extra power afforded by full
dependent types often means that hacky special cases just turn into
standard functions, greatly simplifying things like the above type
families.</p>
<p>But anyway, back to the tree:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">HTree</span> (<span class="ot">xs ::</span> <span class="dt">Tree</span> ns <span class="dt">Type</span>) <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HLeaf</span><span class="ot"> ::</span> <span class="dt">HTree</span> <span class="dt">Leaf</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HNode</span><span class="ot"> ::</span> x</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="op">!</span>(<span class="dt">The</span> <span class="dt">Bit</span> b)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="op">!</span>(<span class="dt">HTree</span> ls)</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="op">!</span>(<span class="dt">HTree</span> rs)</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">HTree</span> (<span class="dt">Branch</span> (<span class="dt">Root</span> x (<span class="dt">Sing</span> b) ls rs))</span></code></pre></div>
<p>And we can <code>cons</code> on an element in much the same way we
did with the homogeneous tree:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">&lt;:</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;:) ::</span> x <span class="ot">-&gt;</span> <span class="dt">HTree</span> xs <span class="ot">-&gt;</span> <span class="dt">HTree</span> (<span class="dt">Branch</span> (<span class="dt">Cons</span> x xs))</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;:</span> <span class="dt">HLeaf</span> <span class="ot">=</span> <span class="dt">HNode</span> x <span class="dt">SB1</span> <span class="dt">HLeaf</span> <span class="dt">HLeaf</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;:</span> <span class="dt">HNode</span> y <span class="dt">SB1</span> yl yr <span class="ot">=</span> <span class="dt">HNode</span> x <span class="dt">SB2</span> (y <span class="op">&lt;:</span> yr) yl</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;:</span> <span class="dt">HNode</span> y <span class="dt">SB2</span> yl yr <span class="ot">=</span> <span class="dt">HNode</span> x <span class="dt">SB1</span> (y <span class="op">&lt;:</span> yr) yl</span></code></pre></div>
<h1 id="indexing">Indexing</h1>
<p>The real use of this data structure is quick <em>indexing</em>. As
with the previous functions, we will first need to construct the
type-level version of what we want to do.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Lookup</span> (<span class="ot">i ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) (<span class="ot">xs ::</span> <span class="dt">Tree</span> sz a)<span class="ot"> ::</span> a <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lookup</span> <span class="dt">Nil</span>              (<span class="dt">Branch</span> (<span class="dt">Root</span> x _ _  _)) <span class="ot">=</span> x</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lookup</span> (<span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> i)) (<span class="dt">Branch</span> (<span class="dt">Root</span> _ _ ls _)) <span class="ot">=</span> <span class="dt">Lookup</span> i ls</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lookup</span> (<span class="dt">Some</span> (<span class="dt">B2</span> <span class="op">:-</span> i)) (<span class="dt">Branch</span> (<span class="dt">Root</span> _ _ _ rs)) <span class="ot">=</span> <span class="dt">Lookup</span> i rs</span></code></pre></div>
<p>While this function is partial, the value-level one should not be: it
should be provably in-bounds for lookups. As a result we’ll need a
slightly complex type to represent the indices:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Position</span> (<span class="ot">xs ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) (<span class="ot">ys ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) <span class="kw">where</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">P0</span><span class="ot"> ::</span> <span class="dt">Position</span> <span class="dt">Nil</span> (<span class="dt">Some</span> ys)</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">P1</span><span class="ot"> ::</span> <span class="op">!</span>(<span class="dt">Position</span> xs (<span class="dt">Carry</span> y ys)) <span class="ot">-&gt;</span> <span class="dt">Position</span> (<span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> xs)) (<span class="dt">Some</span> (y <span class="op">:-</span> ys))</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">P2</span><span class="ot"> ::</span> <span class="op">!</span>(<span class="dt">Position</span> xs ys) <span class="ot">-&gt;</span> <span class="dt">Position</span> (<span class="dt">Some</span> (<span class="dt">B2</span>  <span class="op">:-</span> xs)) (<span class="dt">Some</span> (y <span class="op">:-</span> ys))</span></code></pre></div>
<p>A value of type <code>Position xs ys</code> is actually a proof that
<code>xs</code> is smaller than <code>ys</code>, but we’re using it here
just as a pointer to an entry in the tree. Here’s the actual lookup
function itself.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> <span class="kw">forall</span> is (<span class="ot">ts ::</span> <span class="dt">Tree</span> sz <span class="dt">Type</span>)<span class="op">.</span> <span class="dt">Position</span> is sz <span class="ot">-&gt;</span> <span class="dt">HTree</span> ts <span class="ot">-&gt;</span> <span class="dt">Lookup</span> is ts</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span> <span class="dt">P0</span>     (<span class="dt">HNode</span> x _ _  _) <span class="ot">=</span> x</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span> (<span class="dt">P1</span> i) (<span class="dt">HNode</span> _ _ ls _) <span class="ot">=</span> <span class="fu">lookup</span> i ls</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span> (<span class="dt">P2</span> i) (<span class="dt">HNode</span> _ _ _ rs) <span class="ot">=</span> <span class="fu">lookup</span> i rs</span></code></pre></div>
<p>Just having pointers isn’t much use: we also need a way to build
them. The key function here is <code>push</code>: this increments the
index pointed to by one.</p>
<details>
<summary>
Singletons for lists
</summary>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">::-</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SPlus</span> xs <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (::-) ::</span> <span class="dt">The</span> a x <span class="ot">-&gt;</span> <span class="dt">The</span> (<span class="dt">Star</span> a) xs <span class="ot">-&gt;</span> <span class="dt">SPlus</span> (x <span class="op">:-</span> xs)</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SStar</span> xs <span class="kw">where</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nily</span><span class="ot"> ::</span> <span class="dt">SStar</span> <span class="dt">Nil</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Somy</span><span class="ot"> ::</span> <span class="dt">The</span> (<span class="dt">Plus</span> a) xs <span class="ot">-&gt;</span> <span class="dt">SStar</span> (<span class="dt">Some</span> xs)</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> <span class="dt">The</span> (<span class="dt">Plus</span> a) <span class="ot">=</span> <span class="dt">SPlus</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> <span class="dt">The</span> (<span class="dt">Star</span> a) <span class="ot">=</span> <span class="dt">SStar</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Known</span> <span class="dt">Nil</span> <span class="kw">where</span> sing <span class="ot">=</span> <span class="dt">Nily</span></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Known</span> xs <span class="ot">=&gt;</span> <span class="dt">Known</span> (<span class="dt">Some</span> xs) <span class="kw">where</span> sing <span class="ot">=</span> <span class="dt">Somy</span> sing</span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Known</span> x, <span class="dt">Known</span> xs) <span class="ot">=&gt;</span> <span class="dt">Known</span> (x <span class="op">:-</span> xs) <span class="kw">where</span> sing <span class="ot">=</span> sing <span class="op">::-</span> sing</span></code></pre></div>
</details>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">push ::</span> <span class="dt">Known</span> ys <span class="ot">=&gt;</span> <span class="dt">Position</span> xs ys <span class="ot">-&gt;</span> <span class="dt">Position</span> (<span class="dt">Some</span> (<span class="dt">Inc</span> xs)) (<span class="dt">Some</span> (<span class="dt">Inc</span> ys))</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>push p <span class="ot">=</span> go p sing</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">Position</span> xs ys <span class="ot">-&gt;</span> <span class="dt">The</span> (<span class="dt">Star</span> <span class="dt">Bit</span>) ys <span class="ot">-&gt;</span> <span class="dt">Position</span> (<span class="dt">Some</span> (<span class="dt">Inc</span> xs)) (<span class="dt">Some</span> (<span class="dt">Inc</span> ys))</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    go <span class="dt">P0</span>     (<span class="dt">Somy</span> (<span class="dt">SB1</span> <span class="op">::-</span> _ )) <span class="ot">=</span> <span class="dt">P1</span> <span class="dt">P0</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    go <span class="dt">P0</span>     (<span class="dt">Somy</span> (<span class="dt">SB2</span> <span class="op">::-</span> _ )) <span class="ot">=</span> <span class="dt">P1</span> <span class="dt">P0</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">P2</span> i) (<span class="dt">Somy</span> (<span class="dt">SB1</span> <span class="op">::-</span> ys)) <span class="ot">=</span> <span class="dt">P1</span> (go i ys)</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">P2</span> i) (<span class="dt">Somy</span> (<span class="dt">SB2</span> <span class="op">::-</span> ys)) <span class="ot">=</span> <span class="dt">P1</span> (go i ys)</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">P1</span> i) (<span class="dt">Somy</span> (<span class="dt">SB1</span> <span class="op">::-</span> _ )) <span class="ot">=</span> <span class="dt">P2</span> i</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">P1</span> i) (<span class="dt">Somy</span> (<span class="dt">SB2</span> <span class="op">::-</span> _ )) <span class="ot">=</span> <span class="dt">P2</span> i</span></code></pre></div>
<h1 id="type-level-lists-for-a-nicer-interface">Type-Level Lists for A
Nicer Interface</h1>
<p>Everything above is pretty much all you need for many use cases, but
it’s pretty ugly stuff. To actually use this thing as a generic tuple
we’ll need a lot of quality-of-life improvements.</p>
<p>First of all, we should use type-level lists to indicate the tuple
itself:</p>
<details>
<summary>
Type families for building a tree from a list.
</summary>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Length</span> (<span class="ot">xs ::</span> [a])<span class="ot"> ::</span> <span class="dt">Star</span> <span class="dt">Bit</span> <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Length</span> &#39;[] <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Length</span> (_ <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">Some</span> (<span class="dt">Inc</span> (<span class="dt">Length</span> xs))</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">FromList</span> (<span class="ot">xs ::</span> [a]) <span class="ot">=</span> (<span class="ot">ys ::</span> <span class="dt">Tree</span> (<span class="dt">Length</span> xs) a) <span class="op">|</span> ys <span class="ot">-&gt;</span> xs <span class="kw">where</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FromList</span> &#39;[] <span class="ot">=</span> <span class="dt">Leaf</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FromList</span> (x <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">Branch</span> (<span class="dt">Cons</span> x (<span class="dt">FromList</span> xs))</span></code></pre></div>
</details>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Tuple</span> (<span class="ot">xs ::</span> [<span class="dt">Type</span>]) <span class="ot">=</span> (<span class="ot">ys ::</span> <span class="dt">Type</span>) <span class="op">|</span> ys <span class="ot">-&gt;</span> xs <span class="kw">where</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Tuple</span> xs <span class="ot">=</span> <span class="dt">HTree</span> (<span class="dt">FromList</span> xs)</span></code></pre></div>
<p>Because the type family here is injective, we won’t get any of the
usual weird errors when we use the type <code
class="sourceCode haskell"><span class="dt">Tuple</span> [<span class="dt">Bool</span>,<span class="dt">String</span>]</code>
or whatever: passing that around will function almost exactly the same
as passing around the tree representation itself directly.</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">example ::</span> <span class="dt">Tuple</span> [<span class="dt">Bool</span>,<span class="dt">String</span>,<span class="dt">Int</span>,(),<span class="dt">String</span>]</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>example <span class="ot">=</span> <span class="dt">True</span> <span class="op">&lt;:</span> <span class="st">&quot;True&quot;</span> <span class="op">&lt;:</span> <span class="dv">1</span> <span class="op">&lt;:</span> () <span class="op">&lt;:</span> <span class="st">&quot;T&quot;</span> <span class="op">&lt;:</span> <span class="dt">HLeaf</span></span></code></pre></div>
<h1 id="folding">Folding</h1>
<p>We can fold over the tree itself (using the Braun tree folding
algorithm from a previous post) if every element in the tree conforms to
some class. Using this we can generate a nice string representation of
the tree.</p>
<details>
<summary>
Implementation of folding over tree and <code>Show</code> instance.
</summary>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">All</span> (<span class="ot">c ::</span> a <span class="ot">-&gt;</span> <span class="dt">Constraint</span>) (<span class="ot">xs ::</span> <span class="dt">Tree</span> ns a)<span class="ot"> ::</span> <span class="dt">Constraint</span> <span class="kw">where</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">All</span> c <span class="dt">Leaf</span> <span class="ot">=</span> ()</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">All</span> c (<span class="dt">Branch</span> (<span class="dt">Root</span> x _ ls rs)) <span class="ot">=</span> (c x, <span class="dt">All</span> c ls, <span class="dt">All</span> c rs)</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q2</span> a</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Q2</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> unQ2 ::</span> (<span class="dt">Q2</span> a <span class="ot">-&gt;</span> <span class="dt">Q2</span> a) <span class="ot">-&gt;</span> (<span class="dt">Q2</span> a <span class="ot">-&gt;</span> <span class="dt">Q2</span> a) <span class="ot">-&gt;</span> a</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a><span class="ot">foldrTree ::</span> <span class="kw">forall</span> c xs b<span class="op">.</span> <span class="dt">All</span> c xs <span class="ot">=&gt;</span> (<span class="kw">forall</span> x<span class="op">.</span> c x <span class="ot">=&gt;</span> x <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">HTree</span> xs <span class="ot">-&gt;</span> b</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>foldrTree g&#39; n&#39; t <span class="ot">=</span> unQ2 (f <span class="op">@</span>c g&#39; n&#39; t b) <span class="fu">id</span> <span class="fu">id</span></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> <span class="kw">forall</span> c&#39; ys b&#39;<span class="op">.</span> <span class="dt">All</span> c&#39; ys <span class="ot">=&gt;</span> (<span class="kw">forall</span> x<span class="op">.</span> c&#39; x <span class="ot">=&gt;</span> x <span class="ot">-&gt;</span> b&#39; <span class="ot">-&gt;</span> b&#39;) <span class="ot">-&gt;</span> b&#39; <span class="ot">-&gt;</span> <span class="dt">HTree</span> ys <span class="ot">-&gt;</span> <span class="dt">Q2</span> b&#39; <span class="ot">-&gt;</span> <span class="dt">Q2</span> b&#39;</span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>    f g n (<span class="dt">HNode</span> x _ l r) xs <span class="ot">=</span> <span class="dt">Q2</span> (\ls rs <span class="ot">-&gt;</span> g x (unQ2 xs (ls <span class="op">.</span> f <span class="op">@</span>c&#39; g n l) (rs <span class="op">.</span> f <span class="op">@</span>c&#39; g n r)))</span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>    f _ n <span class="dt">HLeaf</span>           _  <span class="ot">=</span> <span class="dt">Q2</span> (\_  _  <span class="ot">-&gt;</span> n)</span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> <span class="dt">Q2</span> (\ls rs <span class="ot">-&gt;</span> unQ2 (ls (rs b)) <span class="fu">id</span> <span class="fu">id</span>)</span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">All</span> <span class="dt">Show</span> xs <span class="ot">=&gt;</span> <span class="dt">Show</span> (<span class="dt">HTree</span> xs) <span class="kw">where</span></span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a>  <span class="fu">showsPrec</span> _ tr <span class="ot">=</span> <span class="fu">showChar</span> <span class="ch">&#39;(&#39;</span> <span class="op">.</span> go (foldrTree <span class="op">@</span><span class="dt">Show</span> (\x xs <span class="ot">-&gt;</span> <span class="fu">shows</span> x <span class="op">:</span> xs) [] tr)</span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a><span class="ot">      go ::</span> [<span class="dt">ShowS</span>] <span class="ot">-&gt;</span> <span class="dt">ShowS</span></span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a>      go []     <span class="ot">=</span> <span class="fu">showChar</span> <span class="ch">&#39;)&#39;</span></span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a>      go (x<span class="op">:</span>xs) <span class="ot">=</span> x <span class="op">.</span> <span class="fu">foldr</span> (\y ys <span class="ot">-&gt;</span> <span class="fu">showChar</span> <span class="ch">&#39;,&#39;</span> <span class="op">.</span> y <span class="op">.</span> ys)  (<span class="fu">showChar</span> <span class="ch">&#39;)&#39;</span>) xs</span></code></pre></div>
</details>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> example</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>(<span class="dt">True</span>,<span class="st">&quot;True&quot;</span>,<span class="dv">1</span>,(),<span class="st">&quot;T&quot;</span>)</span></code></pre></div>
<h1 id="using-a-different-approach-for-building-indices">Using a
Different Approach For Building Indices</h1>
<p>The approach used in <span class="citation"
data-cites="swierstraHeterogeneousBinaryRandomaccess2020">Swierstra (<a
href="#ref-swierstraHeterogeneousBinaryRandomaccess2020"
role="doc-biblioref">2020</a>)</span> had a specific goal in mind: using
the heterogeneous list to implement a lookup table for evaluating lambda
calculus. As such, efficiently being able to “increment” an index was
vital.</p>
<p>If we wanted to use the type as a generic tuple, though, we would
have no such requirement. Instead, we might expect all accesses to be
resolved and inlined at compile-time <span class="citation"
data-cites="martinezJustItCompiling2013">(as in <a
href="#ref-martinezJustItCompiling2013" role="doc-biblioref">Martinez,
Viera, and Pardo 2013</a>)</span>. We also would want a nice syntax for
accessing parts of the tuple.</p>
<p>We can accomplish all of this with some type classes, as it happens.
If we replace pattern-matching on data types with typeclass resolution
we can be all but guaranteed that the function calls and so on will be
inlined entirely at compile-time (we also would need to add INLINE
pragmas to every instance, which I haven’t done here for readability’s
sake). The main class we’ll use is the following:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (<span class="ot">xs ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) <span class="op">&lt;</span> (<span class="ot">ys ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) <span class="kw">where</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  pull ::</span> <span class="kw">forall</span> (<span class="ot">t ::</span> <span class="dt">Tree</span> ys <span class="dt">Type</span>)<span class="op">.</span> <span class="dt">HTree</span> t <span class="ot">-&gt;</span> <span class="dt">Lookup</span> xs t</span></code></pre></div>
<details>
<summary>
Interface for building indices.
</summary>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Nil</span> <span class="op">&lt;</span> <span class="dt">Some</span> ys <span class="kw">where</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  pull (<span class="dt">HNode</span> x _ _ _) <span class="ot">=</span> x</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> xs <span class="op">&lt;</span> ys <span class="ot">=&gt;</span> <span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> xs) <span class="op">&lt;</span> <span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> ys) <span class="kw">where</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>  pull (<span class="dt">HNode</span> _ _ ls _) <span class="ot">=</span> pull <span class="op">@</span>xs ls</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> xs <span class="op">&lt;</span> <span class="dt">Some</span> (<span class="dt">Inc</span> ys) <span class="ot">=&gt;</span> <span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> xs) <span class="op">&lt;</span> <span class="dt">Some</span> (<span class="dt">B2</span> <span class="op">:-</span> ys) <span class="kw">where</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>  pull (<span class="dt">HNode</span> _ _ ls _) <span class="ot">=</span> pull <span class="op">@</span>xs ls</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> xs <span class="op">&lt;</span> ys <span class="ot">=&gt;</span> <span class="dt">Some</span> (<span class="dt">B2</span> <span class="op">:-</span> xs) <span class="op">&lt;</span> <span class="dt">Some</span> (y <span class="op">:-</span> ys) <span class="kw">where</span></span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a>  pull (<span class="dt">HNode</span> _ _ _ rs) <span class="ot">=</span> pull <span class="op">@</span>xs rs</span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">TypeError</span> (<span class="dt">Text</span> <span class="st">&quot;Index out of range&quot;</span>) <span class="ot">=&gt;</span> xs <span class="op">&lt;</span> <span class="dt">Nil</span> <span class="kw">where</span></span>
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a>  pull <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;unreachable&quot;</span></span>
<span id="cb21-15"><a href="#cb21-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-16"><a href="#cb21-16" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Peano</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Peano</span></span>
<span id="cb21-17"><a href="#cb21-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-18"><a href="#cb21-18" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">FromPeano</span> (<span class="ot">n ::</span> <span class="dt">Peano</span>) <span class="ot">=</span> (<span class="ot">m ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) <span class="op">|</span> m <span class="ot">-&gt;</span> n <span class="kw">where</span></span>
<span id="cb21-19"><a href="#cb21-19" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FromPeano</span> <span class="dt">Z</span>     <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb21-20"><a href="#cb21-20" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FromPeano</span> (<span class="dt">S</span> n) <span class="ot">=</span> <span class="dt">Some</span> (<span class="dt">Inc</span> (<span class="dt">FromPeano</span> n))</span>
<span id="cb21-21"><a href="#cb21-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-22"><a href="#cb21-22" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">FromLit</span> (<span class="ot">n ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Peano</span> <span class="kw">where</span></span>
<span id="cb21-23"><a href="#cb21-23" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FromLit</span> <span class="dv">0</span> <span class="ot">=</span> <span class="dt">Z</span></span>
<span id="cb21-24"><a href="#cb21-24" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FromLit</span> n <span class="ot">=</span> <span class="dt">S</span> (<span class="dt">FromLit</span> (n <span class="op">-</span> <span class="dv">1</span>))</span>
<span id="cb21-25"><a href="#cb21-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-26"><a href="#cb21-26" aria-hidden="true" tabindex="-1"></a><span class="ot">get ::</span> <span class="kw">forall</span> n xs (<span class="ot">t ::</span> <span class="dt">Tree</span> xs <span class="dt">Type</span>)<span class="op">.</span> <span class="dt">FromPeano</span> (<span class="dt">FromLit</span> n) <span class="op">&lt;</span> xs</span>
<span id="cb21-27"><a href="#cb21-27" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">HTree</span> t <span class="ot">-&gt;</span> <span class="dt">Lookup</span> (<span class="dt">FromPeano</span> (<span class="dt">FromLit</span> n)) t</span>
<span id="cb21-28"><a href="#cb21-28" aria-hidden="true" tabindex="-1"></a>get <span class="ot">=</span> pull <span class="op">@</span>(<span class="dt">FromPeano</span> (<span class="dt">FromLit</span> n))</span></code></pre></div>
</details>
<p>Some other details out of the way we get the following nice
interface:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> get <span class="op">@</span><span class="dv">4</span> example</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;T&quot;</span></span></code></pre></div>
<p>You even get a type error for out-of-range indices:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> get <span class="op">@</span><span class="dv">7</span> example</span></code></pre></div>
<pre><code>    • Index out of range
    • In the expression: get @7 example</code></pre>
<p>Or we could even add a lens interface:</p>
<details>
<summary>
Implementation of Lenses for the Tuple
</summary>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Replace</span> (<span class="ot">i ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) (<span class="ot">x ::</span> a) (<span class="ot">xs ::</span> <span class="dt">Tree</span> sz a)<span class="ot"> ::</span> <span class="dt">Tree</span> sz a <span class="kw">where</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Replace</span> <span class="dt">Nil</span>              x (<span class="dt">Branch</span> (<span class="dt">Root</span> _ b ls rs)) <span class="ot">=</span> <span class="dt">Branch</span> (<span class="dt">Root</span> x b ls rs)</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Replace</span> (<span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> i)) x (<span class="dt">Branch</span> (<span class="dt">Root</span> y b ls rs)) <span class="ot">=</span> <span class="dt">Branch</span> (<span class="dt">Root</span> y b (<span class="dt">Replace</span> i x ls) rs)</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Replace</span> (<span class="dt">Some</span> (<span class="dt">B2</span> <span class="op">:-</span> i)) x (<span class="dt">Branch</span> (<span class="dt">Root</span> y b ls rs)) <span class="ot">=</span> <span class="dt">Branch</span> (<span class="dt">Root</span> y b ls (<span class="dt">Replace</span> i x rs))</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (<span class="ot">xs ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) <span class="op">&lt;!</span> (<span class="ot">ys ::</span> <span class="dt">Star</span> <span class="dt">Bit</span>) <span class="kw">where</span></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a><span class="ot">  index ::</span> <span class="kw">forall</span> (<span class="ot">t ::</span> <span class="dt">Tree</span> ys <span class="dt">Type</span>) b<span class="op">.</span> <span class="dt">Lens</span> (<span class="dt">HTree</span> t) (<span class="dt">HTree</span> (<span class="dt">Replace</span> xs b t)) (<span class="dt">Lookup</span> xs t) b</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Nil</span> <span class="op">&lt;!</span> <span class="dt">Some</span> ys <span class="kw">where</span></span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">index</span> f (<span class="dt">HNode</span> x b ls rs) <span class="ot">=</span> <span class="fu">fmap</span> (\x&#39; <span class="ot">-&gt;</span> <span class="dt">HNode</span> x&#39; b ls rs) (f x)</span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> xs <span class="op">&lt;!</span> ys <span class="ot">=&gt;</span> <span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> xs) <span class="op">&lt;!</span> <span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> ys) <span class="kw">where</span></span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">index</span> f (<span class="dt">HNode</span> x b ls rs) <span class="ot">=</span> <span class="fu">fmap</span> (\ls&#39; <span class="ot">-&gt;</span> <span class="dt">HNode</span> x b ls&#39; rs) (<span class="fu">index</span> <span class="op">@</span>xs f ls)</span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> xs <span class="op">&lt;!</span> <span class="dt">Some</span> (<span class="dt">Inc</span> ys) <span class="ot">=&gt;</span> <span class="dt">Some</span> (<span class="dt">B1</span> <span class="op">:-</span> xs) <span class="op">&lt;!</span> <span class="dt">Some</span> (<span class="dt">B2</span> <span class="op">:-</span> ys) <span class="kw">where</span></span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a>  <span class="fu">index</span> f (<span class="dt">HNode</span> x b ls rs) <span class="ot">=</span> <span class="fu">fmap</span> (\ls&#39; <span class="ot">-&gt;</span> <span class="dt">HNode</span> x b ls&#39; rs) (<span class="fu">index</span> <span class="op">@</span>xs f ls)</span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-18"><a href="#cb25-18" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> xs <span class="op">&lt;!</span> ys <span class="ot">=&gt;</span> <span class="dt">Some</span> (<span class="dt">B2</span> <span class="op">:-</span> xs) <span class="op">&lt;!</span> <span class="dt">Some</span> (y <span class="op">:-</span> ys) <span class="kw">where</span></span>
<span id="cb25-19"><a href="#cb25-19" aria-hidden="true" tabindex="-1"></a>  <span class="fu">index</span> f (<span class="dt">HNode</span> x b ls rs) <span class="ot">=</span> <span class="fu">fmap</span> (\rs&#39; <span class="ot">-&gt;</span> <span class="dt">HNode</span> x b ls rs&#39;) (<span class="fu">index</span> <span class="op">@</span>xs f rs)</span>
<span id="cb25-20"><a href="#cb25-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-21"><a href="#cb25-21" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">TypeError</span> (<span class="dt">Text</span> <span class="st">&quot;Index out of range&quot;</span>) <span class="ot">=&gt;</span> xs <span class="op">&lt;!</span> <span class="dt">Nil</span> <span class="kw">where</span></span>
<span id="cb25-22"><a href="#cb25-22" aria-hidden="true" tabindex="-1"></a>  <span class="fu">index</span> <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;unreachable&quot;</span></span>
<span id="cb25-23"><a href="#cb25-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-24"><a href="#cb25-24" aria-hidden="true" tabindex="-1"></a><span class="ot">ind ::</span> <span class="kw">forall</span> n xs (<span class="ot">t ::</span> <span class="dt">Tree</span> xs <span class="dt">Type</span>) a<span class="op">.</span> <span class="dt">FromPeano</span> (<span class="dt">FromLit</span> n) <span class="op">&lt;!</span> xs</span>
<span id="cb25-25"><a href="#cb25-25" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Lens</span> (<span class="dt">HTree</span> t) (<span class="dt">HTree</span> (<span class="dt">Replace</span> (<span class="dt">FromPeano</span> (<span class="dt">FromLit</span> n)) a t)) (<span class="dt">Lookup</span> (<span class="dt">FromPeano</span> (<span class="dt">FromLit</span> n)) t) a</span>
<span id="cb25-26"><a href="#cb25-26" aria-hidden="true" tabindex="-1"></a>ind <span class="ot">=</span> <span class="fu">index</span> <span class="op">@</span>(<span class="dt">FromPeano</span> (<span class="dt">FromLit</span> n))</span></code></pre></div>
</details>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> over (ind <span class="op">@</span><span class="dv">1</span>) <span class="fu">length</span> example</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>(<span class="dt">True</span>,<span class="dv">4</span>,<span class="dv">1</span>,(),<span class="st">&quot;T&quot;</span>)</span></code></pre></div>
<hr />
<h1 id="as-a-nested-datatype">As a Nested Datatype</h1>
<p>The approach I’ve taken here is actually a little unusual: in both
<span class="citation" data-cites="hinze_numerical_1998">Hinze (<a
href="#ref-hinze_numerical_1998" role="doc-biblioref">1998</a>)</span>
and <span class="citation"
data-cites="swierstraHeterogeneousBinaryRandomaccess2020">Swierstra (<a
href="#ref-swierstraHeterogeneousBinaryRandomaccess2020"
role="doc-biblioref">2020</a>)</span> the tree is defined as a
<em>nested</em> data type. Let’s take a look at that approach, while
also switching to Agda.</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">:</span> <span class="dt">Set</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">=</span> List Bool</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> 1ᵇ <span class="ot">=</span> false</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> 2ᵇ <span class="ot">=</span> true</span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> When <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> Bool <span class="ot">→</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>  O⟨⟩ <span class="ot">:</span> When A false</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a>  I⟨<span class="ot">_</span>⟩ <span class="ot">:</span> A <span class="ot">→</span> When A true</span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">4</span> <span class="ot">_</span>×2</span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> <span class="ot">_</span>×2 <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb27-13"><a href="#cb27-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>,<span class="ot">_</span></span>
<span id="cb27-14"><a href="#cb27-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb27-15"><a href="#cb27-15" aria-hidden="true" tabindex="-1"></a>    fst snd <span class="ot">:</span> A</span>
<span id="cb27-16"><a href="#cb27-16" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> <span class="ot">_</span>×2</span>
<span id="cb27-17"><a href="#cb27-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-18"><a href="#cb27-18" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> ⟨<span class="ot">_</span>⟩+<span class="ot">_</span>+2×<span class="ot">_</span></span>
<span id="cb27-19"><a href="#cb27-19" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Array <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> 𝔹 <span class="ot">→</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb27-20"><a href="#cb27-20" aria-hidden="true" tabindex="-1"></a>  O <span class="ot">:</span> Array A []</span>
<span id="cb27-21"><a href="#cb27-21" aria-hidden="true" tabindex="-1"></a>  ⟨<span class="ot">_</span>⟩+<span class="ot">_</span>+2×<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n ns<span class="ot">}</span> <span class="ot">→</span> A <span class="ot">→</span> When A n <span class="ot">→</span> Array <span class="ot">(</span>A ×2<span class="ot">)</span> ns <span class="ot">→</span> Array A <span class="ot">(</span>n ∷ ns<span class="ot">)</span></span></code></pre></div>
<p>The cons function here is really no more complex than the previous
cons:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">:</span> 𝔹 <span class="ot">→</span> List Bool</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>inc [] <span class="ot">=</span> 1ᵇ ∷ []</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">(</span>1ᵇ ∷ xs<span class="ot">)</span> <span class="ot">=</span> 2ᵇ ∷ xs</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">(</span>2ᵇ ∷ xs<span class="ot">)</span> <span class="ot">=</span> 1ᵇ ∷ inc xs</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>cons <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>ns<span class="ot">}</span> <span class="ot">→</span> A <span class="ot">→</span> Array A ns <span class="ot">→</span> Array A <span class="ot">(</span>inc ns<span class="ot">)</span></span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>cons x O <span class="ot">=</span> ⟨ x ⟩+ O⟨⟩ +2× O</span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a>cons x₁ <span class="ot">(</span>⟨ x₂ ⟩+ O⟨⟩ +2× xs<span class="ot">)</span> <span class="ot">=</span> ⟨ x₁ ⟩+ I⟨ x₂ ⟩ +2× xs</span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>cons x₁ <span class="ot">(</span>⟨ x₂ ⟩+ I⟨ x₃ ⟩ +2× xs<span class="ot">)</span> <span class="ot">=</span> ⟨ x₁ ⟩+ O⟨⟩ +2× cons <span class="ot">(</span>x₂ , x₃<span class="ot">)</span> xs</span></code></pre></div>
<p>But what I’m really interested in, again, is <em>indexing</em>. In
particular, I’m interested in using an actual binary number to index
into this structure, rather than the weird GADT we had to use in
Haskell. One of the advantages of using full dependent types is that we
can write functions like the following:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>lookup <span class="ot">:</span> <span class="ot">∀</span> is <span class="ot">→</span> Array A xs <span class="ot">→</span> is &lt; xs <span class="ot">→</span> A</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>lookup <span class="ot">=</span> <span class="ot">{!!}</span></span></code></pre></div>
<p>In other words, we can pass the proof term separately. This can help
performance a little, but mainly it’s nice to use the actual number type
one intended to use along with all of the functions we might use on that
term.</p>
<p>So let’s get writing! The first thing to define is the proof of
<code>&lt;</code>. I’m going to define it in terms of a boolean function
on the bits themselves, i.e.:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;ᴮ<span class="ot">_</span> <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹 <span class="ot">→</span> Bool</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;ᴮ<span class="ot">_</span> <span class="ot">=</span> <span class="ot">{!!}</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>T <span class="ot">:</span> Bool <span class="ot">→</span> <span class="dt">Set</span></span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>T true   <span class="ot">=</span> ⊤</span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>T false  <span class="ot">=</span> ⊥</span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;<span class="ot">_</span> <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹 <span class="ot">→</span> <span class="dt">Set</span></span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>x &lt; y <span class="ot">=</span> T <span class="ot">(</span>x &lt;ᴮ y<span class="ot">)</span></span></code></pre></div>
<p>This will mean the proofs themselves are easy to pass around without
modification. In fact, we can go further and have the compiler
<em>definitionally</em> understand that the proof of
<code>x &lt; y</code> is proof irrelevant, with Agda’s <a
href="https://agda.readthedocs.io/en/v2.6.1/language/prop.html"><code>Prop</code></a>.</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> ⊤ <span class="ot">:</span> <span class="dt">Prop</span> <span class="kw">where</span> <span class="kw">constructor</span> tt</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span>   ⊥ <span class="ot">:</span> <span class="dt">Prop</span> <span class="kw">where</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>T <span class="ot">:</span> Bool <span class="ot">→</span> <span class="dt">Prop</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>T true   <span class="ot">=</span> ⊤</span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>T false  <span class="ot">=</span> ⊥</span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;<span class="ot">_</span> <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹 <span class="ot">→</span> <span class="dt">Prop</span></span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>x &lt; y <span class="ot">=</span> T <span class="ot">(</span>x &lt;ᴮ y<span class="ot">)</span></span></code></pre></div>
<p>Next, the functions which compute the actual comparison.</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&amp;<span class="ot">_</span>≲ᵇ<span class="ot">_</span> <span class="ot">:</span> Bool <span class="ot">→</span> Bool <span class="ot">→</span> Bool <span class="ot">→</span> Bool</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>s &amp; false ≲ᵇ y <span class="ot">=</span> s or  y</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>s &amp; true  ≲ᵇ y <span class="ot">=</span> s and y</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&amp;<span class="ot">_</span>≲ᴮ<span class="ot">_</span> <span class="ot">:</span> Bool <span class="ot">→</span> 𝔹 <span class="ot">→</span> 𝔹 <span class="ot">→</span> Bool</span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>s &amp; []       ≲ᴮ []       <span class="ot">=</span> s</span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>s &amp; []       ≲ᴮ <span class="ot">(</span>y ∷ ys<span class="ot">)</span> <span class="ot">=</span> true</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>s &amp; <span class="ot">(</span>x ∷ xs<span class="ot">)</span> ≲ᴮ []       <span class="ot">=</span> false</span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>s &amp; <span class="ot">(</span>x ∷ xs<span class="ot">)</span> ≲ᴮ <span class="ot">(</span>y ∷ ys<span class="ot">)</span> <span class="ot">=</span> <span class="ot">(</span>s &amp; x ≲ᵇ y<span class="ot">)</span> &amp; xs ≲ᴮ ys</span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;ᴮ<span class="ot">_</span> <span class="ot">_</span>≤ᴮ<span class="ot">_</span> <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹 <span class="ot">→</span> Bool</span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;ᴮ<span class="ot">_</span> <span class="ot">=</span> false &amp;<span class="ot">_</span>≲ᴮ<span class="ot">_</span></span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>≤ᴮ<span class="ot">_</span> <span class="ot">=</span> true  &amp;<span class="ot">_</span>≲ᴮ<span class="ot">_</span></span></code></pre></div>
<p>These functions combine the definitions of <code>≤</code> and
<code>&lt;</code>, and do them both at once. We pass whether the
comparison is non-strict or not as the first parameter: this is worth
doing since both <code>&lt;</code> and <code>≤</code> can be defined in
terms of each other:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(</span>1ᵇ ∷ xs<span class="ot">)</span> &lt; <span class="ot">(</span>2ᵇ ∷ ys<span class="ot">)</span> <span class="ot">=</span> xs ≤ ys</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a><span class="ot">(</span>2ᵇ ∷ xs<span class="ot">)</span> ≤ <span class="ot">(</span>1ᵇ ∷ ys<span class="ot">)</span> <span class="ot">=</span> xs &lt; ys</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span></span></code></pre></div>
<p>Finally the function itself:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>sel-bit <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>b<span class="ot">}</span> <span class="ot">→</span> When A b <span class="ot">→</span> A ×2 <span class="ot">→</span> A</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>sel-bit <span class="ot">{</span>b <span class="ot">=</span> 1ᵇ<span class="ot">}</span> <span class="ot">_</span> <span class="ot">=</span> snd</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>sel-bit <span class="ot">{</span>b <span class="ot">=</span> 2ᵇ<span class="ot">}</span> <span class="ot">_</span> <span class="ot">=</span> fst</span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a><span class="kw">mutual</span></span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a>  index <span class="ot">:</span> <span class="ot">∀</span> xs <span class="ot">{</span>ys<span class="ot">}</span> <span class="ot">→</span> Array A ys <span class="ot">→</span> xs &lt; ys <span class="ot">→</span> A</span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a>  index []        <span class="ot">(</span>⟨ x ⟩+ <span class="ot">_</span> +2× <span class="ot">_</span> <span class="ot">)</span> p <span class="ot">=</span> x</span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a>  index <span class="ot">(</span>1ᵇ ∷ is<span class="ot">)</span> <span class="ot">(</span>⟨ <span class="ot">_</span> ⟩+ x +2× xs<span class="ot">)</span> p <span class="ot">=</span> index₂ is x xs p</span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a>  index <span class="ot">(</span>2ᵇ ∷ is<span class="ot">)</span> <span class="ot">(</span>⟨ <span class="ot">_</span> ⟩+ x +2× xs<span class="ot">)</span> p <span class="ot">=</span> sel-bit x <span class="ot">(</span>index is xs p<span class="ot">)</span></span>
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-11"><a href="#cb34-11" aria-hidden="true" tabindex="-1"></a>  index₂ <span class="ot">:</span> <span class="ot">∀</span> xs <span class="ot">{</span>y ys<span class="ot">}</span> <span class="ot">→</span> When A y <span class="ot">→</span> Array <span class="ot">(</span>A ×2<span class="ot">)</span> ys <span class="ot">→</span> 1ᵇ ∷ xs &lt; y ∷ ys <span class="ot">→</span> A</span>
<span id="cb34-12"><a href="#cb34-12" aria-hidden="true" tabindex="-1"></a>  index₂ is       O⟨⟩    xs p <span class="ot">=</span> fst <span class="ot">(</span>index  is xs p<span class="ot">)</span></span>
<span id="cb34-13"><a href="#cb34-13" aria-hidden="true" tabindex="-1"></a>  index₂ []       I⟨ x ⟩ xs p <span class="ot">=</span> x</span>
<span id="cb34-14"><a href="#cb34-14" aria-hidden="true" tabindex="-1"></a>  index₂ <span class="ot">(</span>i ∷ is<span class="ot">)</span> I⟨ <span class="ot">_</span> ⟩ xs p <span class="ot">=</span> snd <span class="ot">(</span>index₃ i is xs p<span class="ot">)</span></span>
<span id="cb34-15"><a href="#cb34-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-16"><a href="#cb34-16" aria-hidden="true" tabindex="-1"></a>  index₃ <span class="ot">:</span> <span class="ot">∀</span> x xs <span class="ot">{</span>ys<span class="ot">}</span> <span class="ot">→</span> Array A ys <span class="ot">→</span> x ∷ xs ≤ ys <span class="ot">→</span> A</span>
<span id="cb34-17"><a href="#cb34-17" aria-hidden="true" tabindex="-1"></a>  index₃ 2ᵇ is       <span class="ot">(</span>⟨ <span class="ot">_</span> ⟩+ x +2× xs<span class="ot">)</span> p <span class="ot">=</span> index₂ is x xs p</span>
<span id="cb34-18"><a href="#cb34-18" aria-hidden="true" tabindex="-1"></a>  index₃ 1ᵇ []       <span class="ot">(</span>⟨ x ⟩+ <span class="ot">_</span> +2× <span class="ot">_</span> <span class="ot">)</span> p <span class="ot">=</span> x</span>
<span id="cb34-19"><a href="#cb34-19" aria-hidden="true" tabindex="-1"></a>  index₃ 1ᵇ <span class="ot">(</span>i ∷ is<span class="ot">)</span> <span class="ot">(</span>⟨ <span class="ot">_</span> ⟩+ x +2× xs<span class="ot">)</span> p <span class="ot">=</span> sel-bit x <span class="ot">(</span>index₃ i is xs p<span class="ot">)</span></span></code></pre></div>
<hr />
<h1 id="conclusion">Conclusion</h1>
<p>I think Braun trees are a fascinating data structure with lots of
interesting aspects. In practice they tend to be much slower than other
comparable structures, but they’re extremely simple and have many
properties which make them particularly well-suited to type-level
programming.</p>
<hr />
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-hinze_numerical_1998" class="csl-entry" role="listitem">
Hinze, Ralf. 1998. <em>Numerical <span>Representations</span> as
<span>Higher</span>-<span>Order Nested Datatypes</span></em>.
<span>Institut f<span>ü</span>r Informatik III, Universit<span>ä</span>t
Bonn</span>.
</div>
<div id="ref-martinezJustItCompiling2013" class="csl-entry"
role="listitem">
Martinez, Bruno, Marcos Viera, and Alberto Pardo. 2013. <span>“Just do
it while compiling!: Fast extensible records in haskell.”</span> In
<em>Proceedings of the <span>ACM SIGPLAN</span> 2013 workshop on
<span>Partial</span> evaluation and program manipulation -
<span>PEPM</span> ’13</em>, 77. <span>Rome, Italy</span>: <span>ACM
Press</span>. doi:<a
href="https://doi.org/10.1145/2426890.2426908">10.1145/2426890.2426908</a>.
</div>
<div id="ref-swierstraHeterogeneousBinaryRandomaccess2020"
class="csl-entry" role="listitem">
Swierstra, Wouter. 2020. <span>“Heterogeneous binary random-access
lists.”</span> <em>Journal of Functional Programming</em> 30: e10.
doi:<a
href="https://doi.org/10.1017/S0956796820000064">10.1017/S0956796820000064</a>.
</div>
</div>
]]></description>
    <pubDate>Sat, 02 May 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-05-02-more-random-access-lists.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Another Breadth-First Traversal</title>
    <link>https://doisinkidney.com/posts/2020-02-20-final-bft.html</link>
    <description><![CDATA[<div class="info">
    Posted on February 20, 2020
</div>
<div class="info">
    
        Part 9 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>This post will be quite light on details: I’m trying to gather up all
of the material in this series to be a chapter in my Master’s thesis, so
I’m going to leave the heavy-duty explanations and theory for that. Once
finished I will probably do a short write up on this blog.</p>
<p>That said, the reason I’m writing this post is that in writing my
thesis I figured out a nice way to solve the problem I first wrote about
in <a
href="2018-06-03-breadth-first-traversals-in-too-much-detail.html">this</a>
post. I won’t restate it in its entirety, but basically we’re looking
for a function with the following signature:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span></code></pre></div>
<p>Seasoned Haskellers will recognise it as a “traversal”. However, this
shouldn’t be an ordinary traversal: that, after all, can be derived
automatically by the compiler these days. Instead, the Applicative
effects should be evaluated in <em>breadth-first</em> order. To put it
another way, if we have a function which lists the elements of a tree in
breadth-first order:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfs ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span></code></pre></div>
<p>Then we should have the following identity:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>bft (\x <span class="ot">-&gt;</span> ([x], x)) t <span class="ot">=</span> (bfs t, t)</span></code></pre></div>
<p>Using the writer Applicative with the list monoid here as a way to
talk about ordering of effects.</p>
<p>There are many solutions to the puzzle <span class="citation"
data-cites="gibbons_breadth-first_2015 easterly_functions_2019">(see <a
href="#ref-gibbons_breadth-first_2015" role="doc-biblioref">Gibbons
2015</a>; or <a href="#ref-easterly_functions_2019"
role="doc-biblioref">Easterly 2019</a>, or any of the posts in this
series)</span>, but I had found them mostly unsatisfying. They basically
relied on enumerating the tree in breadth-first order, running the
traversal on the intermediate list, and then rebuilding the tree. It has
the correct time complexity and so on, but it would be nice to deforest
the intermediate structure a little bit more.</p>
<p>Anyways, the function I finally managed to get is the following:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>bft f (x <span class="op">:&amp;</span> xs) <span class="ot">=</span> liftA2 (<span class="op">:&amp;</span>) (f x) (bftF f xs)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="ot">bftF ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> [<span class="dt">Tree</span> a] <span class="ot">-&gt;</span> f [<span class="dt">Tree</span> b]</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>bftF t <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">head</span> <span class="op">.</span> <span class="fu">foldr</span> (<span class="op">&lt;*&gt;</span>) (<span class="fu">pure</span> []) <span class="op">.</span> <span class="fu">foldr</span> f [<span class="fu">pure</span> ([]<span class="op">:</span>)]</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&amp;</span> xs) (q <span class="op">:</span> qs) <span class="ot">=</span> liftA2 c (t x) q <span class="op">:</span> <span class="fu">foldr</span> f (p qs) xs</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    p []     <span class="ot">=</span> [<span class="fu">pure</span> ([]<span class="op">:</span>)]</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    p (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="fu">fmap</span> (([]<span class="op">:</span>)<span class="op">.</span>) x <span class="op">:</span> xs</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>    c x k (xs <span class="op">:</span> ks) <span class="ot">=</span> ((x <span class="op">:&amp;</span> xs) <span class="op">:</span> y) <span class="op">:</span> ys</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> (y <span class="op">:</span> ys) <span class="ot">=</span> k ks</span></code></pre></div>
<p>The <code
class="sourceCode haskell"><span class="dt">Tree</span></code> is
defined like so:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> a <span class="op">:&amp;</span> [<span class="dt">Tree</span> a]</span></code></pre></div>
<p>It has all the right properties (complexity, etc.), and if you stick
tildes before every irrefutable pattern-match it is also maximally
lazy.</p>
<hr />
<p>As a bonus, here’s another small function I looked at for my thesis.
It performs a topological sort of a graph.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Graph</span> a <span class="ot">=</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ot">topoSort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Graph</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>topoSort g <span class="ot">=</span> <span class="fu">fst</span> <span class="op">.</span> <span class="fu">foldr</span> f ([], ∅)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    f x (xs,s)</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x ∈ s <span class="ot">=</span> (xs,s)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x ∉ s <span class="ot">=</span> first (x<span class="op">:</span>) (<span class="fu">foldr</span> f (xs, {x} ∪ s) (g x))</span></code></pre></div>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-easterly_functions_2019" class="csl-entry" role="listitem">
Easterly, Noah. 2019. <span>“Functions and newtype wrappers for
traversing <span>Trees</span>: Rampion/tree-traversals.”</span> <a
href="https://github.com/rampion/tree-traversals">https://github.com/rampion/tree-traversals</a>.
</div>
<div id="ref-gibbons_breadth-first_2015" class="csl-entry"
role="listitem">
Gibbons, Jeremy. 2015. <span>“Breadth-<span>First
Traversal</span>.”</span> <em>Patterns in Functional Programming</em>.
<a
href="https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/">https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/</a>.
</div>
</div>
]]></description>
    <pubDate>Thu, 20 Feb 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-02-20-final-bft.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Typing TABA</title>
    <link>https://doisinkidney.com/posts/2020-02-15-taba.html</link>
    <description><![CDATA[<div class="info">
    Posted on February 15, 2020
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Just a short one again today!</p>
<p>There’s an <a
href="https://www.youtube.com/watch?v=u_OsUlwkmBQ">excellent talk</a> by
Kenneth Foner at Compose from 2016 which goes through a paper by <span
class="citation" data-cites="danvy_there_2005">Danvy and Goldberg (<a
href="#ref-danvy_there_2005" role="doc-biblioref">2005</a>)</span>
called “There and Back Again” (or TABA). You should watch the talk and
read the paper if you’re in any way excited by the weird and wonderful
algorithms we use in functional languages to do simple things like
reversing a list.</p>
<p>The function focused on in the paper is one which does the
following:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipRev ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>zipRev xs ys <span class="ot">=</span> <span class="fu">zip</span> xs (<span class="fu">reverse</span> ys)</span></code></pre></div>
<p>But does it in one pass, <em>without</em> reversing the second list.
It uses a not-insignificant bit of cleverness to do it, but you can
actually arrive at the same solution in a pretty straightforward way by
aggressively converting everything you can to a fold. The result is the
following:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipRev ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>zipRev xs ys <span class="ot">=</span> <span class="fu">foldl</span> f b ys xs</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    b _ <span class="ot">=</span> []</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    f k y (x<span class="op">:</span>xs) <span class="ot">=</span> (x,y) <span class="op">:</span> k xs</span></code></pre></div>
<p>I have written a little more on this function and the general
technique <a
href="2019-05-08-list-manipulation-tricks.html#there-and-back-again">before</a>.</p>
<p>The talk goes through the same stuff, but takes a turn then to
proving the function total: our version above won’t work correctly if
the lists don’t have the same length, so it would be nice to provide
that guarantee in the types somehow. Directly translating the version
from the TABA paper into one which uses length-indexed vectors will
require some nasty, expensive proofs, though, which end up making the
whole function quadratic. The solution in the talk is to call out to an
external solver which gives some extremely slick proofs (and a very nice
interface). However, yesterday I realised you needn’t use a solver at
all: you can type the Haskell version just fine, and you don’t even need
the fanciest of type-level features.</p>
<p>As ever, the solution is another fold. To demonstrate this rather
short solution, we’ll first need the regular toolbox of types:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Nat</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Nat</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Vec</span> (<span class="ot">a ::</span> <span class="dt">Type</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>) <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span><span class="ot"> ::</span> <span class="dt">Vec</span> a <span class="dt">Z</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:-) ::</span> a <span class="ot">-&gt;</span> <span class="dt">Vec</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> a (<span class="dt">S</span> n)</span></code></pre></div>
<p>And now we will write a length-indexed left fold on this vector. The
key trick here is that the type passed in the recursive call changes, by
composition:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> (<span class="op">:.:</span>) (<span class="ot">f ::</span> b <span class="ot">-&gt;</span> <span class="dt">Type</span>) (<span class="ot">g ::</span> a <span class="ot">-&gt;</span> b) (<span class="ot">x ::</span> a) <span class="ot">=</span> <span class="dt">Comp</span> {<span class="ot"> unComp ::</span> f (g x) }</span></code></pre></div>
<p>Safe coercions will let us use the above type safely without a
performance hit, resulting in the following linear-time function:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldlVec ::</span> <span class="kw">forall</span> a b n<span class="op">.</span> (<span class="kw">forall</span> m<span class="op">.</span> a <span class="ot">-&gt;</span> b m <span class="ot">-&gt;</span> b (<span class="dt">S</span> m)) <span class="ot">-&gt;</span> b <span class="dt">Z</span> <span class="ot">-&gt;</span> <span class="dt">Vec</span> a n <span class="ot">-&gt;</span> b n</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>foldlVec f b <span class="dt">Nil</span> <span class="ot">=</span> b</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>foldlVec f b (x <span class="op">:-</span> xs) <span class="ot">=</span> unComp (foldlVec (c f) (<span class="dt">Comp</span> (f x b)) xs)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ot">    c ::</span> (a <span class="ot">-&gt;</span> b (<span class="dt">S</span> m) <span class="ot">-&gt;</span> b (<span class="dt">S</span> (<span class="dt">S</span> m))) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> (b <span class="op">:.:</span> <span class="dt">S</span>) m <span class="ot">-&gt;</span> (b <span class="op">:.:</span> <span class="dt">S</span>) (<span class="dt">S</span> m))</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    c <span class="ot">=</span> coerce</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE c #-}</span></span></code></pre></div>
<p>We can use this function to write vector reverse:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">reverseVec ::</span> <span class="dt">Vec</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> a n</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>reverseVec <span class="ot">=</span> foldlVec (<span class="op">:-</span>) <span class="dt">Nil</span></span></code></pre></div>
<p>Now, to write the reversing zip, we need another newtype to put the
parameter in the right place, but it is straightforward other than
that.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">VecCont</span> a b n <span class="ot">=</span> <span class="dt">VecCont</span> {<span class="ot"> runVecCont ::</span> <span class="dt">Vec</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> (a,b) n }</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ot">revZip ::</span> <span class="dt">Vec</span> a n <span class="ot">-&gt;</span> <span class="dt">Vec</span> b n <span class="ot">-&gt;</span> <span class="dt">Vec</span> (a,b) n</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>revZip <span class="ot">=</span> <span class="fu">flip</span> <span class="op">$</span> runVecCont <span class="op">.</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  foldlVec</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>      (\y k <span class="ot">-&gt;</span> <span class="dt">VecCont</span> (\(x <span class="op">:-</span> xs) <span class="ot">-&gt;</span> (x,y) <span class="op">:-</span> runVecCont k xs))</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>      (<span class="dt">VecCont</span> (<span class="fu">const</span> <span class="dt">Nil</span>))</span></code></pre></div>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-danvy_there_2005" class="csl-entry" role="listitem">
Danvy, Olivier, and Mayer Goldberg. 2005. <span>“There and <span>Back
Again</span>.”</span> <em>Fundamenta Informaticae</em> 66 (4)
(December): 397–413. <a
href="https://cs.au.dk/~danvy/DSc/08_danvy-goldberg_fi-2005.pdf">https://cs.au.dk/~danvy/DSc/08_danvy-goldberg_fi-2005.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Sat, 15 Feb 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-02-15-taba.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Terminating Tricky Traversals</title>
    <link>https://doisinkidney.com/posts/2020-01-29-terminating-tricky-traversals.html</link>
    <description><![CDATA[<div class="info">
    Posted on January 29, 2020
</div>
<div class="info">
    
        Part 8 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>, <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<details>
<summary>
Imports
</summary>
<pre class="Agda"><a id="192" class="Symbol">{-#</a> <a id="196" class="Keyword">OPTIONS</a> <a id="204" class="Pragma">--cubical</a> <a id="214" class="Pragma">--sized-types</a> <a id="228" class="Symbol">#-}</a>

<a id="233" class="Keyword">module</a> <a id="240" href="" class="Module">Post</a> <a id="245" class="Keyword">where</a>

<a id="252" class="Keyword">open</a> <a id="257" class="Keyword">import</a> <a id="264" href="../code/terminating-tricky-traversals/Post.Prelude.html" class="Module">../code/terminating-tricky-traversals/Post.Prelude</a>
</pre>
</details>
<p>Just a short one today. I’m going to look at a couple of algorithms
for breadth-first traversals with complex termination proofs.</p>
<h1 id="breadth-first-graph-traversal">Breadth-First Graph
Traversal</h1>
<p>In a previous post I talked about breadth-first traversals over
graphs, and the difficulties that cycles cause. Graphs are especially
tricky to work with in a purely functional language, because so many of
the basic algorithms are described in explicitly mutating terms
(i.e. “mark off a node as you see it”), with no obvious immutable
translation. The following is the last algorithm I came up with:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>bfs g r <span class="ot">=</span> <span class="fu">takeWhile</span> (<span class="fu">not</span><span class="op">.</span><span class="fu">null</span>) (<span class="fu">map</span> <span class="fu">fst</span> (fix (f r <span class="op">.</span> push)))</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    push xs <span class="ot">=</span> ([],Set.empty) <span class="op">:</span> [ ([],seen) <span class="op">|</span> (_,seen) <span class="ot">&lt;-</span> xs ]</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    f x q<span class="op">@</span>((l,s)<span class="op">:</span>qs)</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> Set.member x s <span class="ot">=</span> q</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (x<span class="op">:</span>l, Set.insert x s) <span class="op">:</span> <span class="fu">foldr</span> f qs (g x)</span></code></pre></div>
<p>As difficult as it is to work with graphs in a pure functional
language, it’s even <em>more</em> difficult to work in a <em>total</em>
language, like Agda. Looking at the above function, there are several
bits that we can see right off the bat won’t translate over easily.
Let’s start with <code>fix</code>.</p>
<p>We shouldn’t expect to be able to write <code>fix</code> in Agda
as-is. Just look at its Haskell implementation:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fix ::</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>fix f <span class="ot">=</span> f (fix f)</span></code></pre></div>
<p>It’s obviously non total!</p>
<p>(this is actually a non-memoizing version of <code>fix</code>, which
is different from the <a
href="https://stackoverflow.com/questions/37366222/why-is-this-version-of-fix-more-efficient-in-haskell/37366374">usual
one</a>)</p>
<p>We can write a function <em>like</em> <code>fix</code>, though, using
coinduction and sized types.</p>
<pre class="Agda"><a id="1890" class="Keyword">record</a> <a id="Thunk"></a><a id="1897" href="#1897" class="Record">Thunk</a> <a id="1903" class="Symbol">(</a><a id="1904" href="#1904" class="Bound">A</a> <a id="1906" class="Symbol">:</a> <a id="1908" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#179" class="Postulate">Size</a> <a id="1913" class="Symbol">→</a> <a id="1915" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="1920" href="../code/terminating-tricky-traversals/Post.Prelude.html#221" class="Generalizable">a</a><a id="1921" class="Symbol">)</a> <a id="1923" class="Symbol">(</a><a id="1924" href="#1924" class="Bound">i</a> <a id="1926" class="Symbol">:</a> <a id="1928" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#179" class="Postulate">Size</a><a id="1932" class="Symbol">)</a> <a id="1934" class="Symbol">:</a> <a id="1936" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="1941" href="#1920" class="Bound">a</a> <a id="1943" class="Keyword">where</a>
  <a id="1951" class="Keyword">coinductive</a>
  <a id="1965" class="Keyword">field</a> <a id="Thunk.force"></a><a id="1971" href="#1971" class="Field">force</a> <a id="1977" class="Symbol">:</a> <a id="1979" class="Symbol">∀</a> <a id="1981" class="Symbol">{</a><a id="1982" href="#1982" class="Bound">j</a> <a id="1984" class="Symbol">:</a> <a id="1986" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#211" class="Postulate Operator">Size&lt;</a> <a id="1992" href="#1924" class="Bound">i</a><a id="1993" class="Symbol">}</a> <a id="1995" class="Symbol">→</a> <a id="1997" href="#1904" class="Bound">A</a> <a id="1999" href="#1982" class="Bound">j</a>
<a id="2001" class="Keyword">open</a> <a id="2006" href="#1897" class="Module">Thunk</a> <a id="2012" class="Keyword">public</a>

<a id="fix"></a><a id="2020" href="#2020" class="Function">fix</a> <a id="2024" class="Symbol">:</a> <a id="2026" class="Symbol">(</a><a id="2027" href="#2027" class="Bound">A</a> <a id="2029" class="Symbol">:</a> <a id="2031" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#179" class="Postulate">Size</a> <a id="2036" class="Symbol">→</a> <a id="2038" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="2043" href="../code/terminating-tricky-traversals/Post.Prelude.html#221" class="Generalizable">a</a><a id="2044" class="Symbol">)</a> <a id="2046" class="Symbol">→</a> <a id="2048" class="Symbol">(∀</a> <a id="2051" class="Symbol">{</a><a id="2052" href="#2052" class="Bound">i</a><a id="2053" class="Symbol">}</a> <a id="2055" class="Symbol">→</a> <a id="2057" href="#1897" class="Record">Thunk</a> <a id="2063" href="#2027" class="Bound">A</a> <a id="2065" href="#2052" class="Bound">i</a> <a id="2067" class="Symbol">→</a> <a id="2069" href="#2027" class="Bound">A</a> <a id="2071" href="#2052" class="Bound">i</a><a id="2072" class="Symbol">)</a> <a id="2074" class="Symbol">→</a> <a id="2076" class="Symbol">∀</a> <a id="2078" class="Symbol">{</a><a id="2079" href="#2079" class="Bound">j</a><a id="2080" class="Symbol">}</a> <a id="2082" class="Symbol">→</a> <a id="2084" href="#2027" class="Bound">A</a> <a id="2086" href="#2079" class="Bound">j</a>
<a id="2088" href="#2020" class="Function">fix</a> <a id="2092" href="#2092" class="Bound">A</a> <a id="2094" href="#2094" class="Bound">f</a> <a id="2096" class="Symbol">=</a> <a id="2098" href="#2094" class="Bound">f</a> <a id="2100" class="Symbol">λ</a> <a id="2102" class="Keyword">where</a> <a id="2108" class="Symbol">.</a><a id="2109" href="#1971" class="Field">force</a> <a id="2115" class="Symbol">→</a> <a id="2117" href="#2020" class="Function">fix</a> <a id="2121" href="#2092" class="Bound">A</a> <a id="2123" href="#2094" class="Bound">f</a>
</pre>
<p>Coinductive types are the dual to inductive types. Totality-wise, a
coinductive type must be “productive”; i.e. a coinductive list can be
infinitely long, but it must be provably able to evaluate to a
constructor (cons or nil) in finite time.</p>
<p>Sized types also help us out here: they’re quite subtle, and a little
finicky to use occasionally, but they are invaluable when it comes to
proving termination or productivity of complex (especially higher-order)
functions. The canonical example is mapping over the following tree
type:</p>
<pre class="Agda"><a id="2670" class="Keyword">module</a> <a id="NonTerminating"></a><a id="2677" href="#2677" class="Module">NonTerminating</a> <a id="2692" class="Keyword">where</a>
  <a id="2700" class="Keyword">data</a> <a id="NonTerminating.Tree"></a><a id="2705" href="#2705" class="Datatype">Tree</a> <a id="2710" class="Symbol">(</a><a id="2711" href="#2711" class="Bound">A</a> <a id="2713" class="Symbol">:</a> <a id="2715" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="2720" href="../code/terminating-tricky-traversals/Post.Prelude.html#221" class="Generalizable">a</a><a id="2721" class="Symbol">)</a> <a id="2723" class="Symbol">:</a> <a id="2725" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="2730" href="#2720" class="Bound">a</a> <a id="2732" class="Keyword">where</a>
    <a id="NonTerminating.Tree._&amp;_"></a><a id="2742" href="#2742" class="InductiveConstructor Operator">_&amp;_</a> <a id="2746" class="Symbol">:</a> <a id="2748" href="#2711" class="Bound">A</a> <a id="2750" class="Symbol">→</a> <a id="2752" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="2757" class="Symbol">(</a><a id="2758" href="#2705" class="Datatype">Tree</a> <a id="2763" href="#2711" class="Bound">A</a><a id="2764" class="Symbol">)</a> <a id="2766" class="Symbol">→</a> <a id="2768" href="#2705" class="Datatype">Tree</a> <a id="2773" href="#2711" class="Bound">A</a>

  <a id="2778" class="Symbol">{-#</a> <a id="2782" class="Keyword">TERMINATING</a> <a id="2794" class="Symbol">#-}</a>
  <a id="NonTerminating.mapTree"></a><a id="2800" href="#2800" class="Function">mapTree</a> <a id="2808" class="Symbol">:</a> <a id="2810" class="Symbol">(</a><a id="2811" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="2813" class="Symbol">→</a> <a id="2815" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a><a id="2816" class="Symbol">)</a> <a id="2818" class="Symbol">→</a> <a id="2820" href="#2705" class="Datatype">Tree</a> <a id="2825" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="2827" class="Symbol">→</a> <a id="2829" href="#2705" class="Datatype">Tree</a> <a id="2834" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a>
  <a id="2838" href="#2800" class="Function">mapTree</a> <a id="2846" href="#2846" class="Bound">f</a> <a id="2848" class="Symbol">(</a><a id="2849" href="#2849" class="Bound">x</a> <a id="2851" href="#2742" class="InductiveConstructor Operator">&amp;</a> <a id="2853" href="#2853" class="Bound">xs</a><a id="2855" class="Symbol">)</a> <a id="2857" class="Symbol">=</a> <a id="2859" href="#2846" class="Bound">f</a> <a id="2861" href="#2849" class="Bound">x</a> <a id="2863" href="#2742" class="InductiveConstructor Operator">&amp;</a> <a id="2865" href="../code/terminating-tricky-traversals/Post.Prelude.html#678" class="Function">map</a> <a id="2869" class="Symbol">(</a><a id="2870" href="#2800" class="Function">mapTree</a> <a id="2878" href="#2846" class="Bound">f</a><a id="2879" class="Symbol">)</a> <a id="2881" href="#2853" class="Bound">xs</a>
</pre>
<p>The compiler can’t tell that the recursive call in the
<code>mapTree</code> function will only be called on subnodes of the
argument: it can’t tell that it’s structurally recursive, in other
words. Annoyingly, we can fix the problem by inlining
<code>map</code>.</p>
<pre class="Agda">  <a id="3141" class="Keyword">mutual</a>
    <a id="NonTerminating.mapTree′"></a><a id="3152" href="#3152" class="Function">mapTree′</a> <a id="3161" class="Symbol">:</a> <a id="3163" class="Symbol">(</a><a id="3164" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="3166" class="Symbol">→</a> <a id="3168" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a><a id="3169" class="Symbol">)</a> <a id="3171" class="Symbol">→</a> <a id="3173" href="#2705" class="Datatype">Tree</a> <a id="3178" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="3180" class="Symbol">→</a> <a id="3182" href="#2705" class="Datatype">Tree</a> <a id="3187" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a>
    <a id="3193" href="#3152" class="Function">mapTree′</a> <a id="3202" href="#3202" class="Bound">f</a> <a id="3204" class="Symbol">(</a><a id="3205" href="#3205" class="Bound">x</a> <a id="3207" href="#2742" class="InductiveConstructor Operator">&amp;</a> <a id="3209" href="#3209" class="Bound">xs</a><a id="3211" class="Symbol">)</a> <a id="3213" class="Symbol">=</a> <a id="3215" href="#3202" class="Bound">f</a> <a id="3217" href="#3205" class="Bound">x</a> <a id="3219" href="#2742" class="InductiveConstructor Operator">&amp;</a> <a id="3221" href="#3241" class="Function">mapForest</a> <a id="3231" href="#3202" class="Bound">f</a> <a id="3233" href="#3209" class="Bound">xs</a>

    <a id="NonTerminating.mapForest"></a><a id="3241" href="#3241" class="Function">mapForest</a> <a id="3251" class="Symbol">:</a> <a id="3253" class="Symbol">(</a><a id="3254" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="3256" class="Symbol">→</a> <a id="3258" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a><a id="3259" class="Symbol">)</a> <a id="3261" class="Symbol">→</a> <a id="3263" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="3268" class="Symbol">(</a><a id="3269" href="#2705" class="Datatype">Tree</a> <a id="3274" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a><a id="3275" class="Symbol">)</a> <a id="3277" class="Symbol">→</a> <a id="3279" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="3284" class="Symbol">(</a><a id="3285" href="#2705" class="Datatype">Tree</a> <a id="3290" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a><a id="3291" class="Symbol">)</a>
    <a id="3297" href="#3241" class="Function">mapForest</a> <a id="3307" href="#3307" class="Bound">f</a> <a id="3309" href="../code/terminating-tricky-traversals/Post.Prelude.html#542" class="InductiveConstructor">[]</a> <a id="3312" class="Symbol">=</a> <a id="3314" href="../code/terminating-tricky-traversals/Post.Prelude.html#542" class="InductiveConstructor">[]</a>
    <a id="3321" href="#3241" class="Function">mapForest</a> <a id="3331" href="#3331" class="Bound">f</a> <a id="3333" class="Symbol">(</a><a id="3334" href="#3334" class="Bound">x</a> <a id="3336" href="../code/terminating-tricky-traversals/Post.Prelude.html#556" class="InductiveConstructor Operator">∷</a> <a id="3338" href="#3338" class="Bound">xs</a><a id="3340" class="Symbol">)</a> <a id="3342" class="Symbol">=</a> <a id="3344" href="#3152" class="Function">mapTree′</a> <a id="3353" href="#3331" class="Bound">f</a> <a id="3355" href="#3334" class="Bound">x</a> <a id="3357" href="../code/terminating-tricky-traversals/Post.Prelude.html#556" class="InductiveConstructor Operator">∷</a> <a id="3359" href="#3241" class="Function">mapForest</a> <a id="3369" href="#3331" class="Bound">f</a> <a id="3371" href="#3338" class="Bound">xs</a>
</pre>
<p>The other solution is to give the tree a size parameter. This way,
all subnodes of a given tree will have smaller sizes, which will give
the compiler a finite descending chain condition it can use to prove
termination.</p>
<pre class="Agda"><a id="3606" class="Keyword">data</a> <a id="Tree"></a><a id="3611" href="#3611" class="Datatype">Tree</a> <a id="3616" class="Symbol">(</a><a id="3617" href="#3617" class="Bound">A</a> <a id="3619" class="Symbol">:</a> <a id="3621" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="3626" href="../code/terminating-tricky-traversals/Post.Prelude.html#221" class="Generalizable">a</a><a id="3627" class="Symbol">)</a> <a id="3629" class="Symbol">(</a><a id="3630" href="#3630" class="Bound">i</a> <a id="3632" class="Symbol">:</a> <a id="3634" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#179" class="Postulate">Size</a><a id="3638" class="Symbol">)</a> <a id="3640" class="Symbol">:</a> <a id="3642" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="3647" href="#3626" class="Bound">a</a> <a id="3649" class="Keyword">where</a>
  <a id="Tree._&amp;_"></a><a id="3657" href="#3657" class="InductiveConstructor Operator">_&amp;_</a> <a id="3661" class="Symbol">:</a> <a id="3663" href="#3617" class="Bound">A</a> <a id="3665" class="Symbol">→</a> <a id="3667" class="Symbol">∀</a> <a id="3669" class="Symbol">{</a><a id="3670" href="#3670" class="Bound">j</a> <a id="3672" class="Symbol">:</a> <a id="3674" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#211" class="Postulate Operator">Size&lt;</a> <a id="3680" href="#3630" class="Bound">i</a><a id="3681" class="Symbol">}</a> <a id="3683" class="Symbol">→</a> <a id="3685" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="3690" class="Symbol">(</a><a id="3691" href="#3611" class="Datatype">Tree</a> <a id="3696" href="#3617" class="Bound">A</a> <a id="3698" href="#3670" class="Bound">j</a><a id="3699" class="Symbol">)</a> <a id="3701" class="Symbol">→</a> <a id="3703" href="#3611" class="Datatype">Tree</a> <a id="3708" href="#3617" class="Bound">A</a> <a id="3710" href="#3630" class="Bound">i</a>

<a id="mapTree"></a><a id="3713" href="#3713" class="Function">mapTree</a> <a id="3721" class="Symbol">:</a> <a id="3723" class="Symbol">(</a><a id="3724" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="3726" class="Symbol">→</a> <a id="3728" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a><a id="3729" class="Symbol">)</a> <a id="3731" class="Symbol">→</a> <a id="3733" href="#3611" class="Datatype">Tree</a> <a id="3738" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="3740" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a> <a id="3742" class="Symbol">→</a> <a id="3744" href="#3611" class="Datatype">Tree</a> <a id="3749" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a> <a id="3751" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a>
<a id="3753" href="#3713" class="Function">mapTree</a> <a id="3761" href="#3761" class="Bound">f</a> <a id="3763" class="Symbol">(</a><a id="3764" href="#3764" class="Bound">x</a> <a id="3766" href="#3657" class="InductiveConstructor Operator">&amp;</a> <a id="3768" href="#3768" class="Bound">xs</a><a id="3770" class="Symbol">)</a> <a id="3772" class="Symbol">=</a> <a id="3774" href="#3761" class="Bound">f</a> <a id="3776" href="#3764" class="Bound">x</a> <a id="3778" href="#3657" class="InductiveConstructor Operator">&amp;</a> <a id="3780" href="../code/terminating-tricky-traversals/Post.Prelude.html#678" class="Function">map</a> <a id="3784" class="Symbol">(</a><a id="3785" href="#3713" class="Function">mapTree</a> <a id="3793" href="#3761" class="Bound">f</a><a id="3794" class="Symbol">)</a> <a id="3796" href="#3768" class="Bound">xs</a>
</pre>
<p>So how do we use this stuff in our graph traversal? Well first we’ll
need a coinductive Stream type:</p>
<pre class="Agda"><a id="3914" class="Keyword">record</a> <a id="Stream"></a><a id="3921" href="#3921" class="Record">Stream</a> <a id="3928" class="Symbol">(</a><a id="3929" href="#3929" class="Bound">A</a> <a id="3931" class="Symbol">:</a> <a id="3933" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="3938" href="../code/terminating-tricky-traversals/Post.Prelude.html#221" class="Generalizable">a</a><a id="3939" class="Symbol">)</a> <a id="3941" class="Symbol">(</a><a id="3942" href="#3942" class="Bound">i</a> <a id="3944" class="Symbol">:</a> <a id="3946" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#179" class="Postulate">Size</a><a id="3950" class="Symbol">)</a> <a id="3952" class="Symbol">:</a> <a id="3954" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="3959" href="#3938" class="Bound">a</a> <a id="3961" class="Keyword">where</a>
  <a id="3969" class="Keyword">coinductive</a>
  <a id="3983" class="Keyword">field</a>
    <a id="Stream.head"></a><a id="3993" href="#3993" class="Field">head</a> <a id="3998" class="Symbol">:</a> <a id="4000" href="#3929" class="Bound">A</a>
    <a id="Stream.tail"></a><a id="4006" href="#4006" class="Field">tail</a> <a id="4011" class="Symbol">:</a> <a id="4013" class="Symbol">∀</a> <a id="4015" class="Symbol">{</a><a id="4016" href="#4016" class="Bound">j</a> <a id="4018" class="Symbol">:</a> <a id="4020" href="../code/terminating-tricky-traversals/Agda.Builtin.Size.html#211" class="Postulate Operator">Size&lt;</a> <a id="4026" href="#3942" class="Bound">i</a><a id="4027" class="Symbol">}</a> <a id="4029" class="Symbol">→</a> <a id="4031" href="#3921" class="Record">Stream</a> <a id="4038" href="#3929" class="Bound">A</a> <a id="4040" href="#4016" class="Bound">j</a>
<a id="4042" class="Keyword">open</a> <a id="4047" href="#3921" class="Module">Stream</a> <a id="4054" class="Keyword">public</a>

<a id="smap"></a><a id="4062" href="#4062" class="Function">smap</a> <a id="4067" class="Symbol">:</a> <a id="4069" class="Symbol">(</a><a id="4070" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="4072" class="Symbol">→</a> <a id="4074" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a><a id="4075" class="Symbol">)</a> <a id="4077" class="Symbol">→</a> <a id="4079" href="#3921" class="Record">Stream</a> <a id="4086" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="4088" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a> <a id="4090" class="Symbol">→</a> <a id="4092" href="#3921" class="Record">Stream</a> <a id="4099" href="../code/terminating-tricky-traversals/Post.Prelude.html#250" class="Generalizable">B</a> <a id="4101" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a>
<a id="4103" href="#4062" class="Function">smap</a> <a id="4108" href="#4108" class="Bound">f</a> <a id="4110" href="#4110" class="Bound">xs</a> <a id="4113" class="Symbol">.</a><a id="4114" href="#3993" class="Field">head</a> <a id="4119" class="Symbol">=</a> <a id="4121" href="#4108" class="Bound">f</a> <a id="4123" class="Symbol">(</a><a id="4124" href="#4110" class="Bound">xs</a> <a id="4127" class="Symbol">.</a><a id="4128" href="#3993" class="Field">head</a><a id="4132" class="Symbol">)</a>
<a id="4134" href="#4062" class="Function">smap</a> <a id="4139" href="#4139" class="Bound">f</a> <a id="4141" href="#4141" class="Bound">xs</a> <a id="4144" class="Symbol">.</a><a id="4145" href="#4006" class="Field">tail</a> <a id="4150" class="Symbol">=</a> <a id="4152" href="#4062" class="Function">smap</a> <a id="4157" href="#4139" class="Bound">f</a> <a id="4159" class="Symbol">(</a><a id="4160" href="#4141" class="Bound">xs</a> <a id="4163" class="Symbol">.</a><a id="4164" href="#4006" class="Field">tail</a><a id="4168" class="Symbol">)</a>
</pre>
<p>And then we can use it to write our breadth-first traversal.</p>
<pre class="Agda"><a id="bfs"></a><a id="4245" href="#4245" class="Function">bfs</a> <a id="4249" class="Symbol">:</a> <a id="4251" class="Symbol">⦃</a> <a id="4253" href="#4253" class="Bound">_</a> <a id="4255" class="Symbol">:</a> <a id="4257" href="../code/terminating-tricky-traversals/Post.Prelude.html#2916" class="Record">IsDiscrete</a> <a id="4268" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="4270" class="Symbol">⦄</a> <a id="4272" class="Symbol">→</a> <a id="4274" class="Symbol">(</a><a id="4275" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="4277" class="Symbol">→</a> <a id="4279" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="4284" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a><a id="4285" class="Symbol">)</a> <a id="4287" class="Symbol">→</a> <a id="4289" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="4291" class="Symbol">→</a> <a id="4293" href="#3921" class="Record">Stream</a> <a id="4300" class="Symbol">(</a><a id="4301" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="4306" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a><a id="4307" class="Symbol">)</a> <a id="4309" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a>
<a id="4311" href="#4245" class="Function">bfs</a> <a id="4315" href="#4315" class="Bound">g</a> <a id="4317" href="#4317" class="Bound">r</a> <a id="4319" class="Symbol">=</a> <a id="4321" href="#4062" class="Function">smap</a> <a id="4326" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="4330" class="Symbol">(</a><a id="4331" href="#2020" class="Function">fix</a> <a id="4335" class="Symbol">(</a><a id="4336" href="#3921" class="Record">Stream</a> <a id="4343" class="Symbol">_)</a> <a id="4346" class="Symbol">(</a><a id="4347" href="#4490" class="Function">f</a> <a id="4349" href="#4317" class="Bound">r</a> <a id="4351" href="../code/terminating-tricky-traversals/Post.Prelude.html#434" class="Function Operator">∘</a> <a id="4353" href="#4370" class="Function">push</a><a id="4357" class="Symbol">))</a>
  <a id="4362" class="Keyword">where</a>
  <a id="4370" href="#4370" class="Function">push</a> <a id="4375" class="Symbol">:</a> <a id="4377" href="#1897" class="Record">Thunk</a> <a id="4383" class="Symbol">(</a><a id="4384" href="#3921" class="Record">Stream</a> <a id="4391" class="Symbol">_)</a> <a id="4394" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a> <a id="4396" class="Symbol">→</a> <a id="4398" href="#3921" class="Record">Stream</a> <a id="4405" class="Symbol">_</a> <a id="4407" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a>
  <a id="4411" href="#4370" class="Function">push</a> <a id="4416" href="#4416" class="Bound">xs</a> <a id="4419" class="Symbol">.</a><a id="4420" href="#3993" class="Field">head</a> <a id="4425" class="Symbol">=</a> <a id="4427" class="Symbol">(</a><a id="4428" href="../code/terminating-tricky-traversals/Post.Prelude.html#542" class="InductiveConstructor">[]</a> <a id="4431" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="4433" href="../code/terminating-tricky-traversals/Post.Prelude.html#542" class="InductiveConstructor">[]</a><a id="4435" class="Symbol">)</a>
  <a id="4439" href="#4370" class="Function">push</a> <a id="4444" href="#4444" class="Bound">xs</a> <a id="4447" class="Symbol">.</a><a id="4448" href="#4006" class="Field">tail</a> <a id="4453" class="Symbol">=</a> <a id="4455" href="#4062" class="Function">smap</a> <a id="4460" class="Symbol">(</a><a id="4461" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">_,_</a> <a id="4465" href="../code/terminating-tricky-traversals/Post.Prelude.html#542" class="InductiveConstructor">[]</a> <a id="4468" href="../code/terminating-tricky-traversals/Post.Prelude.html#434" class="Function Operator">∘</a> <a id="4470" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#237" class="Field">snd</a><a id="4473" class="Symbol">)</a> <a id="4475" class="Symbol">(</a><a id="4476" href="#4444" class="Bound">xs</a> <a id="4479" class="Symbol">.</a><a id="4480" href="#1971" class="Field">force</a><a id="4485" class="Symbol">)</a>

  <a id="4490" href="#4490" class="Function">f</a> <a id="4492" class="Symbol">:</a> <a id="4494" class="Symbol">_</a> <a id="4496" class="Symbol">→</a> <a id="4498" href="#3921" class="Record">Stream</a> <a id="4505" class="Symbol">_</a> <a id="4507" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a> <a id="4509" class="Symbol">→</a> <a id="4511" href="#3921" class="Record">Stream</a> <a id="4518" class="Symbol">_</a> <a id="4520" href="../code/terminating-tricky-traversals/Post.Prelude.html#276" class="Generalizable">i</a>
  <a id="4524" href="#4490" class="Function">f</a> <a id="4526" href="#4526" class="Bound">x</a> <a id="4528" href="#4528" class="Bound">qs</a> <a id="4531" class="Keyword">with</a> <a id="4536" class="Symbol">(</a><a id="4537" href="#4526" class="Bound">x</a> <a id="4539" href="../code/terminating-tricky-traversals/Post.Prelude.html#3012" class="Function Operator">∈?</a> <a id="4542" href="#4528" class="Bound">qs</a> <a id="4545" class="Symbol">.</a><a id="4546" href="#3993" class="Field">head</a> <a id="4551" class="Symbol">.</a><a id="4552" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#237" class="Field">snd</a><a id="4555" class="Symbol">)</a> <a id="4557" class="Symbol">.</a><a id="4558" href="../code/terminating-tricky-traversals/Post.Prelude.html#1059" class="Field">does</a>
  <a id="4565" class="Symbol">...</a> <a id="4569" class="Symbol">|</a> <a id="4571" href="../code/terminating-tricky-traversals/Agda.Builtin.Bool.html#160" class="InductiveConstructor">true</a> <a id="4576" class="Symbol">=</a> <a id="4578" class="Bound">qs</a>
  <a id="4583" class="Symbol">...</a> <a id="4587" class="Symbol">|</a> <a id="4589" href="../code/terminating-tricky-traversals/Agda.Builtin.Bool.html#154" class="InductiveConstructor">false</a> <a id="4595" class="Symbol">=</a> <a id="4597" class="Symbol">λ</a> <a id="4599" class="Keyword">where</a> <a id="4605" class="Symbol">.</a><a id="4606" href="#3993" class="Field">head</a> <a id="4611" class="Symbol">→</a> <a id="4613" class="Symbol">(</a><a id="4614" class="Bound">x</a> <a id="4616" href="../code/terminating-tricky-traversals/Post.Prelude.html#556" class="InductiveConstructor Operator">∷</a> <a id="4618" class="Bound">qs</a> <a id="4621" class="Symbol">.</a><a id="4622" href="#3993" class="Field">head</a> <a id="4627" class="Symbol">.</a><a id="4628" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="4632" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="4634" class="Bound">x</a> <a id="4636" href="../code/terminating-tricky-traversals/Post.Prelude.html#556" class="InductiveConstructor Operator">∷</a> <a id="4638" class="Bound">qs</a> <a id="4641" class="Symbol">.</a><a id="4642" href="#3993" class="Field">head</a> <a id="4647" class="Symbol">.</a><a id="4648" href="../code/terminating-tricky-traversals/Agda.Builtin.Sigma.html#237" class="Field">snd</a><a id="4651" class="Symbol">)</a>
                        <a id="4677" class="Symbol">.</a><a id="4678" href="#4006" class="Field">tail</a> <a id="4683" class="Symbol">→</a> <a id="4685" href="../code/terminating-tricky-traversals/Post.Prelude.html#583" class="Function">foldr</a> <a id="4691" href="#4490" class="Function">f</a> <a id="4693" class="Symbol">(</a><a id="4694" class="Bound">qs</a> <a id="4697" class="Symbol">.</a><a id="4698" href="#4006" class="Field">tail</a><a id="4702" class="Symbol">)</a> <a id="4704" class="Symbol">(</a><a id="4705" href="#4315" class="Bound">g</a> <a id="4707" class="Bound">x</a><a id="4708" class="Symbol">)</a>
</pre>
<p>How do we convert this to a list of lists? Well, for this condition
we would actually need to prove that there are only finitely many
elements in the graph. We could actually use <a
href="https://arxiv.org/abs/1604.01186">Noetherian finiteness</a> for
this: though I have a working implementation, I’m still figuring out how
to clean this up, so I will leave it for another post.</p>
<h1 id="traversing-a-braun-tree">Traversing a Braun Tree</h1>
<p>A recent paper <span class="citation" data-cites="NipkowS-CPP20">(<a
href="#ref-NipkowS-CPP20" role="doc-biblioref">Nipkow and Sewell
2020</a>)</span> provided Coq proofs for some algorithms on Braun trees
<span class="citation" data-cites="okasakiThreeAlgorithmsBraun1997">(<a
href="#ref-okasakiThreeAlgorithmsBraun1997" role="doc-biblioref">Okasaki
1997</a>)</span>, which prompted me to take a look at them again. This
time, I came up with an interesting linear-time <code>toList</code>
function, which relies on the following peculiar type:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q2</span> a</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Q2</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> unQ2 ::</span> (<span class="dt">Q2</span> a <span class="ot">-&gt;</span> <span class="dt">Q2</span> a) <span class="ot">-&gt;</span> (<span class="dt">Q2</span> a <span class="ot">-&gt;</span> <span class="dt">Q2</span> a) <span class="ot">-&gt;</span> a</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>Even after coming up with the type myself, I still can’t really make
heads nor tails of it. If I squint, it starts to look like some bizarre
church-encoded binary number (but I have to <em>really</em> squint). It
certainly seems related to corecursive queues <span class="citation"
data-cites="smith_lloyd_2009">(<a href="#ref-smith_lloyd_2009"
role="doc-biblioref">Smith 2009</a>)</span>.</p>
<p>Anyway, we can use the type to write the following lovely
<code>toList</code> function on a Braun tree.</p>
<p><span id="toListImpl"></p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toList ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>toList t <span class="ot">=</span> unQ2 (f t b) <span class="fu">id</span> <span class="fu">id</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x l r) xs <span class="ot">=</span> <span class="dt">Q2</span> (\ls rs <span class="ot">-&gt;</span> x <span class="op">:</span> unQ2 xs (ls <span class="op">.</span> f l) (rs <span class="op">.</span> f r))</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">Leaf</span>         xs <span class="ot">=</span> <span class="dt">Q2</span> (\_  _  <span class="ot">-&gt;</span> [])</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> <span class="dt">Q2</span> (\ls rs <span class="ot">-&gt;</span> unQ2 (ls (rs b)) <span class="fu">id</span> <span class="fu">id</span>)</span></code></pre></div>
<p></span></p>
<p>So can we convert it to Agda?</p>
<p>Not really! As it turns out, this function is even more difficult to
implement than one might expect. We can’t even <em>write</em> the
<code>Q2</code> type in Agda without getting in trouble.</p>
<pre class="Agda"><a id="6242" class="Symbol">{-#</a> <a id="6246" class="Keyword">NO_POSITIVITY_CHECK</a> <a id="6266" class="Symbol">#-}</a>
<a id="6270" class="Keyword">record</a> <a id="Q2"></a><a id="6277" href="#6277" class="Record">Q2</a> <a id="6280" class="Symbol">(</a><a id="6281" href="#6281" class="Bound">A</a> <a id="6283" class="Symbol">:</a> <a id="6285" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="6290" href="../code/terminating-tricky-traversals/Post.Prelude.html#221" class="Generalizable">a</a><a id="6291" class="Symbol">)</a> <a id="6293" class="Symbol">:</a> <a id="6295" href="../code/terminating-tricky-traversals/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="6300" href="#6290" class="Bound">a</a> <a id="6302" class="Keyword">where</a>
  <a id="6310" class="Keyword">inductive</a>
  <a id="6322" class="Keyword">field</a>
    <a id="Q2.q2"></a><a id="6332" href="#6332" class="Field">q2</a> <a id="6335" class="Symbol">:</a> <a id="6337" class="Symbol">(</a><a id="6338" href="#6277" class="Record">Q2</a> <a id="6341" href="#6281" class="Bound">A</a> <a id="6343" class="Symbol">→</a> <a id="6345" href="#6277" class="Record">Q2</a> <a id="6348" href="#6281" class="Bound">A</a><a id="6349" class="Symbol">)</a> <a id="6351" class="Symbol">→</a>
         <a id="6362" class="Symbol">(</a><a id="6363" href="#6277" class="Record">Q2</a> <a id="6366" href="#6281" class="Bound">A</a> <a id="6368" class="Symbol">→</a> <a id="6370" href="#6277" class="Record">Q2</a> <a id="6373" href="#6281" class="Bound">A</a><a id="6374" class="Symbol">)</a> <a id="6376" class="Symbol">→</a>
         <a id="6387" href="#6281" class="Bound">A</a>
<a id="6389" class="Keyword">open</a> <a id="6394" href="#6277" class="Module">Q2</a>
</pre>
<p><code>Q2</code> isn’t strictly positive, unfortunately.</p>
<pre class="Agda"><a id="6456" class="Symbol">{-#</a> <a id="6460" class="Keyword">TERMINATING</a> <a id="6472" class="Symbol">#-}</a>
<a id="toList"></a><a id="6476" href="#6476" class="Function">toList</a> <a id="6483" class="Symbol">:</a> <a id="6485" href="../code/terminating-tricky-traversals/Post.Prelude.html#4077" class="Datatype">Braun</a> <a id="6491" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="6493" class="Symbol">→</a> <a id="6495" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="6500" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a>
<a id="6502" href="#6476" class="Function">toList</a> <a id="6509" href="#6509" class="Bound">t</a> <a id="6511" class="Symbol">=</a> <a id="6513" href="#6587" class="Function">f</a> <a id="6515" href="#6509" class="Bound">t</a> <a id="6517" href="#6539" class="Function">n</a> <a id="6519" class="Symbol">.</a><a id="6520" href="#6332" class="Field">q2</a> <a id="6523" href="../code/terminating-tricky-traversals/Post.Prelude.html#3105" class="Function">id</a> <a id="6526" href="../code/terminating-tricky-traversals/Post.Prelude.html#3105" class="Function">id</a>
  <a id="6531" class="Keyword">where</a>
  <a id="6539" href="#6539" class="Function">n</a> <a id="6541" class="Symbol">:</a> <a id="6543" href="#6277" class="Record">Q2</a> <a id="6546" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a>
  <a id="6550" href="#6539" class="Function">n</a> <a id="6552" class="Symbol">.</a><a id="6553" href="#6332" class="Field">q2</a> <a id="6556" href="#6556" class="Bound">ls</a> <a id="6559" href="#6559" class="Bound">rs</a> <a id="6562" class="Symbol">=</a> <a id="6564" href="#6556" class="Bound">ls</a> <a id="6567" class="Symbol">(</a><a id="6568" href="#6559" class="Bound">rs</a> <a id="6571" href="#6539" class="Function">n</a><a id="6572" class="Symbol">)</a> <a id="6574" class="Symbol">.</a><a id="6575" href="#6332" class="Field">q2</a> <a id="6578" href="../code/terminating-tricky-traversals/Post.Prelude.html#3105" class="Function">id</a> <a id="6581" href="../code/terminating-tricky-traversals/Post.Prelude.html#3105" class="Function">id</a>

  <a id="6587" href="#6587" class="Function">f</a> <a id="6589" class="Symbol">:</a> <a id="6591" href="../code/terminating-tricky-traversals/Post.Prelude.html#4077" class="Datatype">Braun</a> <a id="6597" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a> <a id="6599" class="Symbol">→</a> <a id="6601" href="#6277" class="Record">Q2</a> <a id="6604" class="Symbol">(</a><a id="6605" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="6610" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a><a id="6611" class="Symbol">)</a> <a id="6613" class="Symbol">→</a> <a id="6615" href="#6277" class="Record">Q2</a> <a id="6618" class="Symbol">(</a><a id="6619" href="../code/terminating-tricky-traversals/Post.Prelude.html#507" class="Datatype">List</a> <a id="6624" href="../code/terminating-tricky-traversals/Post.Prelude.html#237" class="Generalizable">A</a><a id="6625" class="Symbol">)</a>
  <a id="6629" href="#6587" class="Function">f</a> <a id="6631" href="../code/terminating-tricky-traversals/Post.Prelude.html#4113" class="InductiveConstructor">leaf</a>         <a id="6644" href="#6644" class="Bound">xs</a> <a id="6647" class="Symbol">.</a><a id="6648" href="#6332" class="Field">q2</a> <a id="6651" href="#6651" class="Bound">ls</a> <a id="6654" href="#6654" class="Bound">rs</a> <a id="6657" class="Symbol">=</a> <a id="6659" href="../code/terminating-tricky-traversals/Post.Prelude.html#542" class="InductiveConstructor">[]</a>
  <a id="6664" href="#6587" class="Function">f</a> <a id="6666" class="Symbol">(</a><a id="6667" href="../code/terminating-tricky-traversals/Post.Prelude.html#4130" class="InductiveConstructor">node</a> <a id="6672" href="#6672" class="Bound">x</a> <a id="6674" href="#6674" class="Bound">l</a> <a id="6676" href="#6676" class="Bound">r</a><a id="6677" class="Symbol">)</a> <a id="6679" href="#6679" class="Bound">xs</a> <a id="6682" class="Symbol">.</a><a id="6683" href="#6332" class="Field">q2</a> <a id="6686" href="#6686" class="Bound">ls</a> <a id="6689" href="#6689" class="Bound">rs</a> <a id="6692" class="Symbol">=</a> <a id="6694" href="#6672" class="Bound">x</a> <a id="6696" href="../code/terminating-tricky-traversals/Post.Prelude.html#556" class="InductiveConstructor Operator">∷</a> <a id="6698" href="#6679" class="Bound">xs</a> <a id="6701" class="Symbol">.</a><a id="6702" href="#6332" class="Field">q2</a> <a id="6705" class="Symbol">(</a><a id="6706" href="#6686" class="Bound">ls</a> <a id="6709" href="../code/terminating-tricky-traversals/Post.Prelude.html#434" class="Function Operator">∘</a> <a id="6711" href="#6587" class="Function">f</a> <a id="6713" href="#6674" class="Bound">l</a><a id="6714" class="Symbol">)</a> <a id="6716" class="Symbol">(</a><a id="6717" href="#6689" class="Bound">rs</a> <a id="6720" href="../code/terminating-tricky-traversals/Post.Prelude.html#434" class="Function Operator">∘</a> <a id="6722" href="#6587" class="Function">f</a> <a id="6724" href="#6676" class="Bound">r</a><a id="6725" class="Symbol">)</a>
</pre>
<p>Apparently this problem of strict positivity for breadth-first
traversals has come up before: <span class="citation"
data-cites="bergerMartinHofmannCase2019">Berger, Matthes, and Setzer (<a
href="#ref-bergerMartinHofmannCase2019"
role="doc-biblioref">2019</a>)</span>; <span class="citation"
data-cites="hofmannNonStrictlyPositive1993">Hofmann (<a
href="#ref-hofmannNonStrictlyPositive1993"
role="doc-biblioref">1993</a>)</span>.</p>
<h1 id="waitwhere-did-q2-come-from">Wait—Where did Q2 Come From?</h1>
<p>Update 31/01/2020</p>
<p>Daniel Peebles (<a
href="https://twitter.com/copumpkin">@copumpkin</a> on twitter) replied
to my tweet about this post with the following:</p>
<blockquote>
<p>Interesting! Curious <em>how</em> you came up with that weird type at
the end. It doesn’t exactly feel like the first thing one might reach
for and it would be interesting to see some writing on the thought
process that led to it</p>
<p><a
href="https://twitter.com/copumpkin/status/1222681927854936065">Dan P
(@copumpkin), Jan 30, 2020.</a></p>
</blockquote>
<p>So that’s what I’m going to add here!</p>
<p>Let’s take the Braun tree of the numbers 1 to 15:</p>
<pre><code>     ┌8
   ┌4┤
   │ └12
 ┌2┤
 │ │ ┌10
 │ └6┤
 │   └14
1┤
 │   ┌9
 │ ┌5┤
 │ │ └13
 └3┤
   │ ┌11
   └7┤
     └15</code></pre>
<p>Doing a normal breadth-first traversal for the first two levels is
fine (1, 2, 3): it starts to fall apart at the third level (4, 6, 5, 7).
Here’s the way we should traverse it: “all of the left branches, and
then all of the right branches”. So, we will have a queue of trees. We
take the root element of each tree in the queue, and emit it, and then
we add all of the <em>left</em> children of the trees in the queue to
one queue, and then all the <em>right</em> children to another, and then
concatenate them into a new queue and we start again. We can stop
whenever we hit an empty tree because of the structure of the Braun
tree. Here’s an ascii diagram to show what’s going on:</p>
<pre><code>     ┌8   |     ┌8    |     ┌8     |       8
   ┌4┤    |   ┌4┤     |    4┤      |
   │ └12  |   │ └12   |     └12    |       9
 ┌2┤      |  2┤       |            |
 │ │ ┌10  |   │ ┌10   |     ┌9     |       10
 │ └6┤    |   └6┤     |    5┤      |
 │   └14  |     └14   |     └13    |       11
1┤       --&gt;        -----&gt;      --------&gt;
 │   ┌9   |     ┌9    |     ┌10    |       12
 │ ┌5┤    |   ┌5┤     |    6┤      |
 │ │ └13  |   │ └13   |     └14    |       13
 └3┤      |  3┤       |            |
   │ ┌11  |   │ ┌11   |     ┌11    |       14
   └7┤    |   └7┤     |    7┤      |
     └15  |     └15   |     └15    |       15

         1,         2, 3,       4, 5, 6, 7,   8, 9, 10, 11, 12, 13, 14, 15</code></pre>
<p>If we want to do this in Haskell, we have a number of options for how
we would represent queues: as ever, though, I much prefer to use vanilla
lists and time the reversals so that they stay linear. Here’s what that
looks like:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toList ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>toList t <span class="ot">=</span> f t b [] []</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x l r) xs ls rs <span class="ot">=</span> x <span class="op">:</span> xs (l <span class="op">:</span> ls) (r <span class="op">:</span> rs)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">Leaf</span>         _ _  _  <span class="ot">=</span> []</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    b ls rs <span class="ot">=</span> <span class="fu">foldr</span> f b (<span class="fu">reverse</span> ls <span class="op">++</span> <span class="fu">reverse</span> rs) [] []</span></code></pre></div>
<p>Any place we see a <code>foldr</code> being run after a reverse or a
concatenation, we know that we can remove a pass (in actual fact rewrite
rules will likely do this automatically for us).</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toList ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>toList t <span class="ot">=</span> f b t [] []</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x l r) xs ls rs <span class="ot">=</span> x <span class="op">:</span> xs (l <span class="op">:</span> ls) (r <span class="op">:</span> rs)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">Leaf</span>         _  _  _  <span class="ot">=</span> []</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    b ls rs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">flip</span> f) (<span class="fu">foldl</span> (<span class="fu">flip</span> f) b rs) ls [] []</span></code></pre></div>
<p>Finally, since we’re building up the lists with <code>:</code> (in a
linear way, i.e. we will not use the intermediate queues more than
once), and we’re immediately consuming them with a fold, we can deforest
the intermediate list, replacing every <code>:</code> with
<code>f</code> (actually, it’s a little more tricky than that, since we
replace the <code>:</code> with the <em>reversed</em> version of
<code>f</code>, i.e. the one you would pass to <code>foldr</code> if you
wanted it to act like <code>foldl</code>. This trick is explained in
more detail in <a href="2019-05-08-list-manipulation-tricks.html">this
post</a>).</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toList ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>toList t <span class="ot">=</span> f t b <span class="fu">id</span> <span class="fu">id</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x l r) xs ls rs <span class="ot">=</span> x <span class="op">:</span> xs (ls <span class="op">.</span> f l) (rs <span class="op">.</span> f r)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">Leaf</span>         _ _ _ <span class="ot">=</span> []</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    b ls rs <span class="ot">=</span> ls (rs b) <span class="fu">id</span> <span class="fu">id</span></span></code></pre></div>
<p>Once you do that, however, you run into the “cannot construct the
infinite type” error. To be precise:</p>
<blockquote>
<pre><code>• Occurs check: cannot construct the infinite type:
    a3 ~ (a3 -&gt; c0) -&gt; (a3 -&gt; c1) -&gt; [a2]</code></pre>
</blockquote>
<p>And this gives us the template for our newtype! It requires some
trial and error, but you can see where some of the recursive calls are,
and what you eventually get is the following:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q2</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Q2</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> unQ2 ::</span> (<span class="dt">Q2</span> a <span class="ot">-&gt;</span> <span class="dt">Q2</span> a) <span class="ot">-&gt;</span> (<span class="dt">Q2</span> a <span class="ot">-&gt;</span> <span class="dt">Q2</span> a) <span class="ot">-&gt;</span> [a]</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>(You can remove the list type constructor at the end, I did as I
thought it made it slightly more general). And from there we get back to
<a href="#toListImpl">the <code>toList</code> function</a>.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-bergerMartinHofmannCase2019" class="csl-entry"
role="listitem">
Berger, Ulrich, Ralph Matthes, and Anton Setzer. 2019. <span>“Martin
<span>Hofmann</span>’s <span>Case</span> for
<span>Non</span>-<span>Strictly Positive Data Types</span>.”</span> In
<em>24th international conference on types for proofs and programs
(<span>TYPES</span> 2018)</em>, ed by. Peter Dybjer, José Espírito
Santo, and Luís Pinto, 130:22. Leibniz international proceedings in
informatics (<span>LIPIcs</span>). <span>Dagstuhl, Germany</span>:
<span>Schloss DagstuhlLeibniz-Zentrum fuer Informatik</span>. doi:<a
href="https://doi.org/10.4230/LIPIcs.TYPES.2018.1">10.4230/LIPIcs.TYPES.2018.1</a>.
<a
href="http://drops.dagstuhl.de/opus/volltexte/2019/11405">http://drops.dagstuhl.de/opus/volltexte/2019/11405</a>.
</div>
<div id="ref-hofmannNonStrictlyPositive1993" class="csl-entry"
role="listitem">
Hofmann, Martin. 1993. <span>“Non <span>Strictly Positive
Datatypes</span> in <span>System F</span>.”</span> <a
href="https://www.seas.upenn.edu/~sweirich/types/archive/1993/msg00027.html">https://www.seas.upenn.edu/~sweirich/types/archive/1993/msg00027.html</a>.
</div>
<div id="ref-NipkowS-CPP20" class="csl-entry" role="listitem">
Nipkow, Tobias, and Thomas Sewell. 2020. <span>“Proof pearl:
<span>Braun</span> trees.”</span> In <em>Certified programs and proofs,
<span>CPP</span> 2020</em>, ed by. J. Blanchette and C. Hritcu, –.
<span>ACM</span>. <a
href="http://www21.in.tum.de/~nipkow/pubs/cpp20.html">http://www21.in.tum.de/~nipkow/pubs/cpp20.html</a>.
</div>
<div id="ref-okasakiThreeAlgorithmsBraun1997" class="csl-entry"
role="listitem">
Okasaki, Chris. 1997. <span>“Three <span>Algorithms</span> on
<span>Braun Trees</span>.”</span> <em>Journal of Functional
Programming</em> 7 (6) (November): 661–666. doi:<a
href="https://doi.org/10.1017/S0956796897002876">10.1017/S0956796897002876</a>.
<a
href="https://www.eecs.northwestern.edu/~robby/courses/395-495-2013-fall/three-algorithms-on-braun-trees.pdf">https://www.eecs.northwestern.edu/~robby/courses/395-495-2013-fall/three-algorithms-on-braun-trees.pdf</a>.
</div>
<div id="ref-smith_lloyd_2009" class="csl-entry" role="listitem">
Smith, Leon P. 2009. <span>“Lloyd <span>Allison</span>’s
<span>Corecursive Queues</span>: <span>Why Continuations
Matter</span>.”</span> <em>The Monad.Reader</em> 14 (14) (July): 28. <a
href="https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf">https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Wed, 29 Jan 2020 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2020-01-29-terminating-tricky-traversals.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Lazy Constructive Numbers and the Stern-Brocot Tree</title>
    <link>https://doisinkidney.com/posts/2019-12-14-stern-brocot.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 14, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>In dependently typed languages, it’s often important to figure out a
good “low-level” representation for some concept. Here’s a common
low-level representation of the natural numbers:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Nat</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Nat</span></span></code></pre></div>
<p>For “real” applications, of course, these numbers are offensively
inefficient, in terms of both space and time. But that’s not what I’m
after here: I’m looking for a type which best describes the essence of
the natural numbers, and that can be used to prove and think about them.
In that sense, this representation is second to none: it’s basically the
simplest possible type which <em>can</em> represent the naturals.</p>
<p>Let’s nail down that idea a little better. What do we mean when a
type is a “good” representation for some concept?</p>
<ul>
<li><p>There should be no redundancy. The type for the natural numbers
above has this property: every natural number as one (and only one)
canonical representative in <code>Nat</code>. Compare that to the
following possible representation for the integers:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Int</span> <span class="ot">=</span> <span class="dt">Neg</span> <span class="dt">Nat</span> <span class="op">|</span> <span class="dt">Pos</span> <span class="dt">Nat</span></span></code></pre></div>
<p>There are two ways to represent <code>0</code> here: as
<code>Pos Z</code> or <code>Neg Z</code>.</p>
<p>Of course, you can quotient out the redundancy in Cubical Agda, or
normalise on construction every time, but either of these workarounds
gets your representation a demerit.</p></li>
<li><p>Operations should be definable simply and directly on the
representation. Points docked for converting to and from some
non-normalised form.</p></li>
<li><p>That conversion, however, can exist, and ideally should exist, in
some fundamental way. You should be able to establish an efficient
isomorphism with other representations of the same concept.</p></li>
<li><p>Properties about the type should correspond to intuitive
properties about the representation. For <code>Nat</code> above, this
means things like order: the usual order on the natural numbers again
has a straightforward analogue on <code>Nat</code>.</p></li>
</ul>
<p>With that laundry list of requirements, it’s no wonder that it’s
often tricky to figure out the “right” type for a concept.</p>
<p>In this post, I’m going to talk about a type for the rational
numbers, and I’m going to try satisfy those requirements as best I
can.</p>
<h1 id="the-rationals-as-a-pair-of-numbers">The Rationals as a Pair of
Numbers</h1>
<p>Our first attempt at representing the rationals might use a
fraction:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Frac</span> <span class="ot">=</span> <span class="dt">Integer</span> <span class="op">:/</span> <span class="dt">Integer</span></span></code></pre></div>
<p>This obviously fails the redundancy property. The fractions
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>2</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{2}</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>2</mn><mn>4</mn></mfrac><annotation encoding="application/x-tex">\frac{2}{4}</annotation></semantics></math>
represent the same number, but have different underlying values.</p>
<p>So the type isn’t suitable as a potential representation for the
rationals. That’s not to say that this type is useless: far from it!
Indeed, Haskell’s <a
href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-Ratio.html">Data.Ratio</a>
uses something quite like this to implement rationals.</p>
<p>If you’re going to deal with redundant elements, there are two broad
ways to deal with it. Data.Ratio’s approach is to normalise on
construction, and only export a constructor which does this. This gives
you a pretty good guarantee that there won’t be any unreduced fractions
lying around in your program. Agda’s standard library also uses an
approach like this, although the fact that the numerator and denominator
are coprime is statically verified by way of a proof carried in the
type.</p>
<p>The other way to deal with redundancy is by quotient. In Haskell,
that kind of means doing the following:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Eq</span> <span class="dt">Frac</span> <span class="kw">where</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  (x <span class="op">:/</span> xd) <span class="op">==</span> (y <span class="op">:/</span> yd) <span class="ot">=</span> (x <span class="op">*</span> yd) <span class="op">==</span> (y <span class="op">*</span> xd)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> <span class="dt">Frac</span> <span class="kw">where</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">compare</span> (x <span class="op">:/</span> xd) (y <span class="op">:/</span> yd) <span class="ot">=</span> <span class="fu">compare</span> (x <span class="op">*</span> yd) (y <span class="op">*</span> xd)</span></code></pre></div>
<p>We don’t have real quotient types in Haskell, but this gets the idea
across: we haven’t normalised our representation internally, but as far
as anyone <em>using</em> the type is concerned, they shouldn’t be able
to tell the difference between
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>2</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{2}</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>2</mn><mn>4</mn></mfrac><annotation encoding="application/x-tex">\frac{2}{4}</annotation></semantics></math>.</p>
<p>The <code>Num</code> instance is pretty much just a restating of the
axioms for fractions.</p>
<details>
<summary>
<code>Num</code> instance for <code>Frac</code>.
</summary>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Frac</span> <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fromInteger</span> n <span class="ot">=</span> n <span class="op">:/</span> <span class="dv">1</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  (x <span class="op">:/</span> xd) <span class="op">*</span> (y <span class="op">:/</span> yd) <span class="ot">=</span> (x <span class="op">*</span> y) <span class="op">:/</span> (xd <span class="op">*</span> yd)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  (x <span class="op">:/</span> xd) <span class="op">+</span> (y <span class="op">:/</span> yd) <span class="ot">=</span> (x <span class="op">*</span> yd <span class="op">+</span> y <span class="op">*</span> xd) <span class="op">:/</span> (xd <span class="op">*</span> yd)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">signum</span> (n <span class="op">:/</span> d) <span class="ot">=</span> <span class="fu">signum</span> (n <span class="op">*</span> d) <span class="op">:/</span> <span class="dv">1</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">abs</span> n <span class="ot">=</span> <span class="fu">signum</span> n <span class="op">*</span> n</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>  (x <span class="op">:/</span> xd) <span class="op">-</span> (y <span class="op">:/</span> yd) <span class="ot">=</span> (x <span class="op">*</span> yd <span class="op">-</span> y <span class="op">*</span> xd) <span class="op">:/</span> (xd <span class="op">*</span> yd)</span></code></pre></div>
</details>
<p>Cubical Agda, of course, <em>does</em> have real quotient types.
There, the <code>Eq</code> instance becomes a path constructor.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ℚ <span class="ot">:</span> Type₀ <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>÷<span class="ot">_</span> <span class="ot">:</span> <span class="ot">(</span>n d <span class="ot">:</span> ℕ<span class="ot">)</span> <span class="ot">→</span> ℚ</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  reduce <span class="ot">:</span> <span class="ot">∀</span> xⁿ xᵈ yⁿ yᵈ <span class="ot">→</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>           xⁿ ℕ* yᵈ ≡ yⁿ ℕ* xᵈ <span class="ot">→</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>           xⁿ ÷ xᵈ ≡ yⁿ ÷ yᵈ</span></code></pre></div>
<p>But we’ll leave the Agda stuff for another post.</p>
<h1 id="the-rationals-as-a-trace-of-euclids-algorithm">The Rationals as
a Trace of Euclid’s Algorithm</h1>
<p>Now we get to the cool stuff. To reduce a fraction, we usually do
something like getting the greatest common divisor of each operand. One
nice way to do that is to use Euclid’s algorithm:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">gcd</span><span class="ot"> ::</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="fu">gcd</span> n m <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> n m <span class="kw">of</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">EQ</span> <span class="ot">-&gt;</span> n</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> n (m <span class="op">-</span> n)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> (n <span class="op">-</span> m) m</span></code></pre></div>
<p>Let’s run that function on three different inputs:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>2</mn><mn>3</mn></mfrac><annotation encoding="application/x-tex">\frac{2}{3}</annotation></semantics></math>,
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>4</mn><mn>6</mn></mfrac><annotation encoding="application/x-tex">\frac{4}{6}</annotation></semantics></math>,
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>5</mn><mn>6</mn></mfrac><annotation encoding="application/x-tex">\frac{5}{6}</annotation></semantics></math>.</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">gcd</span> <span class="dv">2</span> <span class="dv">3</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">2</span> <span class="dv">3</span> <span class="kw">of</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> <span class="dv">2</span> (<span class="dv">3</span> <span class="op">-</span> <span class="dv">2</span>) <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">2</span> <span class="dv">1</span> <span class="kw">of</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> (<span class="dv">2</span> <span class="op">-</span> <span class="dv">1</span>) <span class="dv">1</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">1</span> <span class="dv">1</span> <span class="kw">of</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>      <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dv">1</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="fu">gcd</span> <span class="dv">4</span> <span class="dv">6</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">4</span> <span class="dv">6</span> <span class="kw">of</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> <span class="dv">4</span> (<span class="dv">6</span> <span class="op">-</span> <span class="dv">4</span>) <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">4</span> <span class="dv">2</span> <span class="kw">of</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> (<span class="dv">4</span> <span class="op">-</span> <span class="dv">2</span>) <span class="dv">2</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">2</span> <span class="dv">2</span> <span class="kw">of</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>      <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dv">2</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="fu">gcd</span> <span class="dv">5</span> <span class="dv">6</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">5</span> <span class="dv">6</span> <span class="kw">of</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> <span class="dv">5</span> (<span class="dv">6</span> <span class="op">-</span> <span class="dv">5</span>) <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">5</span> <span class="dv">1</span> <span class="kw">of</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>    <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> (<span class="dv">5</span> <span class="op">-</span> <span class="dv">1</span>) <span class="dv">1</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">4</span> <span class="dv">1</span> <span class="kw">of</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>      <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> (<span class="dv">4</span> <span class="op">-</span> <span class="dv">1</span>) <span class="dv">1</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">3</span> <span class="dv">1</span> <span class="kw">of</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>        <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> (<span class="dv">3</span> <span class="op">-</span> <span class="dv">1</span>) <span class="dv">1</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">2</span> <span class="dv">1</span> <span class="kw">of</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>          <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="fu">gcd</span> (<span class="dv">2</span> <span class="op">-</span> <span class="dv">1</span>) <span class="dv">1</span> <span class="ot">=&gt;</span> <span class="kw">case</span> <span class="fu">compare</span> <span class="dv">1</span> <span class="dv">1</span> <span class="kw">of</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>            <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dv">1</span></span></code></pre></div>
<p>Those all return the right things, but that’s not what’s interesting
here: look at the chain of comparison results. For the two fractions
which are equivalent, their <em>chains</em> are equal.</p>
<p>This turns out to hold in general. Every rational number can be
(uniquely!) represented as a list of bits, where each bit is a
comparison result from Euclid’s algorithm.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Bit</span> <span class="ot">=</span> <span class="dt">O</span> <span class="op">|</span> <span class="dt">I</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Rational</span> <span class="ot">=</span> [<span class="dt">Bit</span>]</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="fu">abs</span><span class="ot"> ::</span> <span class="dt">Frac</span> <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="fu">abs</span> <span class="ot">=</span> unfoldr f</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>    f (n <span class="op">:/</span> d) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> n d <span class="kw">of</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>      <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>      <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="dt">O</span>, n <span class="op">:/</span> (d <span class="op">-</span> n))</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>      <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="dt">I</span>, (n <span class="op">-</span> d) <span class="op">:/</span> d)</span></code></pre></div>
<p>And since we used <code>unfoldr</code>, it’s easy to reverse the
algorithm to convert from the representation to a pair of numbers.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">rep ::</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> <span class="dt">Frac</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>rep <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="dv">1</span> <span class="op">:/</span> <span class="dv">1</span>)</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">I</span> (n <span class="op">:/</span> d) <span class="ot">=</span> (n <span class="op">+</span> d) <span class="op">:/</span> d</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">O</span> (n <span class="op">:/</span> d) <span class="ot">=</span> n <span class="op">:/</span> (n <span class="op">+</span> d)</span></code></pre></div>
<p>Now <code>abs . rep</code> is the identity function, and
<code>rep . abs</code> reduces a fraction! We have identified an
isomorphism between our type (a list of bits) and the rational
numbers!</p>
<p>Well, between the positive rational numbers. Not to worry: we can add
a sign before it. And, because our type doesn’t actually include 0, we
don’t get the duplicate 0 problems we did with <code>Int</code>.</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Q</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Neg</span> <span class="dt">Rational</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Zero</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Pos</span> <span class="dt">Rational</span></span></code></pre></div>
<p>We can also define some operations on the type, by converting back
and forth.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Rational</span> <span class="kw">where</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fromInteger</span> n <span class="ot">=</span> <span class="fu">abs</span> (n <span class="op">:/</span> <span class="dv">1</span>)</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">+</span> ys <span class="ot">=</span> <span class="fu">abs</span> (rep xs <span class="op">+</span> rep ys)</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">*</span> ys <span class="ot">=</span> <span class="fu">abs</span> (rep xs <span class="op">*</span> rep ys)</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">-</span> ys <span class="ot">=</span> <span class="fu">abs</span> (rep xs <span class="op">-</span> rep ys)</span></code></pre></div>
<h1 id="rationals-as-a-path-into-the-stern-brocot-tree">Rationals as a
Path into The Stern-Brocot Tree</h1>
<p>So we have a construction that has our desired property of
canonicity. Even better, there’s a reasonably efficient algorithm to
convert to and from it! Our next task will be examining the
representation itself, and seeing what information we can get from
it.</p>
<p>To do so we’ll turn to the subject of the title of this post: the <a
href="https://en.wikipedia.org/wiki/Stern%E2%80%93Brocot_tree">Stern-Brocot
tree</a>.</p>
<figure>
<img
src="https://upload.wikimedia.org/wikipedia/commons/3/37/SternBrocotTree.svg"
alt="The Stern-Brocot Tree. By Aaron Rotenberg, CC BY-SA 3.0, from Wikimedia Commons." />
<figcaption aria-hidden="true">The Stern-Brocot Tree. By Aaron
Rotenberg, CC BY-SA 3.0, from Wikimedia Commons.</figcaption>
</figure>
<p>This tree, pictured above, has some incredible properties:</p>
<ul>
<li>It contains every rational number (in reduced form) exactly
once.</li>
<li>It is a binary search tree.</li>
</ul>
<p>Both of these properties make it an excellent candidate for basing a
representation on. As it turns out, that’s what we already did! Our list
of bits above is precisely a path into the Stern-Brocot tree, where
every <code>O</code> is a left turn and every <code>I</code> right.</p>
<h1 id="incrementalising">Incrementalising</h1>
<p>The most important fact we’ve gleaned so far from the Stern-Brocot
tree is that our representation is lexicographically ordered. While that
may not seem like much, it turns our list of bits into a
progressively-narrowing interval, which generates more and more accurate
estimates of the true value. When we see a <code>O</code> at the head of
the list, we know that the result must be smaller than <code>1</code>;
what follows will tell us on what side of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>2</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{2}</annotation></semantics></math>
the answer lies, and so on.</p>
<p>This turns out to be quite a useful property: we often don’t need
<em>exact</em> precision for some calculation, but rather some
approximate answer. It’s even rarer still that we know exactly how much
precision we need for a given expression (which is what floating point
demands). Usually, the precision we need changes quite dynamically. If a
particular number plays a more influential role in some expression, for
instance, its precision is more important than the others!</p>
<p>By producing a lazy list of bits, however, we can allow the
<em>consumer</em> to specify the precision they need, by demanding those
bits as they go along. (In the literature, this kind of thing is
referred to as “lazy exact arithmetic”, and it’s quite fascinating. The
representation presented here, however, is not very suitable for any
real computation: it’s incredibly slow. There is a paper on the topic:
<span class="citation" data-cites="niquiExactArithmeticStern2007">Niqui
(<a href="#ref-niquiExactArithmeticStern2007"
role="doc-biblioref">2007</a>)</span>, which examines the Stern-Brocot
numbers in Coq).</p>
<p>In proofs, the benefit is even more pronounced: finding out that a
number is in a given range by just inspecting the first element of the
list gives an excellent recursion strategy. We can do case analysis on:
“what if it’s 1”, “what if it’s less than 1”, and “what if it’s greater
than 1”, which is quite intuitive.</p>
<p>There’s one problem: our evaluation function is defined as a
<code>foldr</code>, and forces the accumulator at every step. We will
need to figure out another evaluator which folds from the left.</p>
<h1 id="intervals">Intervals</h1>
<p>So let’s look more at the “interval” interpretation of the
Stern-Brocot tree. The first interval is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="true" form="prefix">(</mo><mfrac><mn>0</mn><mn>1</mn></mfrac><mo>,</mo><mfrac><mn>1</mn><mn>0</mn></mfrac><mo stretchy="true" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\left(\frac{0}{1},\frac{1}{0}\right)</annotation></semantics></math>:
neither of these values are actually members of the type, which is why
we’re not breaking any major rules with the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>0</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{0}</annotation></semantics></math>.
To move left (to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>2</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{2}</annotation></semantics></math>
in the diagram), we need to use a peculiar operation called “child’s
addition”, often denoted with a
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>⊕</mi><annotation encoding="application/x-tex">\oplus</annotation></semantics></math>.</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mfrac><mi>a</mi><mi>b</mi></mfrac><mo>⊕</mo><mfrac><mi>c</mi><mi>d</mi></mfrac><mo>=</mo><mfrac><mrow><mi>a</mi><mo>+</mo><mi>c</mi></mrow><mrow><mi>b</mi><mo>+</mo><mi>d</mi></mrow></mfrac></mrow><annotation encoding="application/x-tex"> \frac{a}{b} \oplus \frac{c}{d} = \frac{a+c}{b+d} </annotation></semantics></math></p>
<p>The name comes from the fact that it’s a very common mistaken
definition of addition on fractions.</p>
<p>Right, next steps: to move <em>left</em> in an interval, we do the
following:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">left</mtext><mrow><mo stretchy="true" form="prefix">(</mo><mrow><mi>𝑙</mi><mi>𝑏</mi></mrow><mo>,</mo><mrow><mi>𝑢</mi><mi>𝑏</mi></mrow><mo stretchy="true" form="postfix">)</mo></mrow><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mrow><mi>𝑙</mi><mi>𝑏</mi></mrow><mo>,</mo><mrow><mi>𝑙</mi><mi>𝑏</mi></mrow><mo>⊕</mo><mrow><mi>𝑢</mi><mi>𝑏</mi></mrow><mo stretchy="true" form="postfix">)</mo></mrow></mrow><annotation encoding="application/x-tex"> \text{left} \left(\mathit{lb},\mathit{ub} \right) = \left( \mathit{lb}, \mathit{lb} \oplus \mathit{ub} \right) </annotation></semantics></math></p>
<p>In other words, we narrow the right-hand-side of the interval. To
move right is the opposite:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">right</mtext><mrow><mo stretchy="true" form="prefix">(</mo><mrow><mi>𝑙</mi><mi>𝑏</mi></mrow><mo>,</mo><mrow><mi>𝑢</mi><mi>𝑏</mi></mrow><mo stretchy="true" form="postfix">)</mo></mrow><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mrow><mi>𝑙</mi><mi>𝑏</mi></mrow><mo>⊕</mo><mrow><mi>𝑢</mi><mi>𝑏</mi></mrow><mo>,</mo><mrow><mi>𝑢</mi><mi>𝑏</mi></mrow><mo stretchy="true" form="postfix">)</mo></mrow></mrow><annotation encoding="application/x-tex"> \text{right} \left(\mathit{lb},\mathit{ub} \right) = \left( \mathit{lb}
\oplus \mathit{ub} , \mathit{ub} \right) </annotation></semantics></math></p>
<p>And finally, when we hit the end of the sequence, we take the
<em>mediant</em> value.</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">mediant</mtext><mrow><mo stretchy="true" form="prefix">(</mo><mrow><mi>𝑙</mi><mi>𝑏</mi></mrow><mo>,</mo><mrow><mi>𝑢</mi><mi>𝑏</mi></mrow><mo stretchy="true" form="postfix">)</mo></mrow><mo>=</mo><mrow><mi>𝑙</mi><mi>𝑏</mi></mrow><mo>⊕</mo><mrow><mi>𝑟</mi><mi>𝑏</mi></mrow></mrow><annotation encoding="application/x-tex"> \text{mediant}\left(\mathit{lb} , \mathit{ub}\right) = \mathit{lb} \oplus
\mathit{rb} </annotation></semantics></math></p>
<p>From this, we get a straightforward left fold which can compute our
fraction.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>infix <span class="dv">6</span> <span class="op">:-:</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Interval</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> (<span class="op">:-:</span>)</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> lb ::</span> <span class="dt">Frac</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> ub ::</span> <span class="dt">Frac</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a><span class="ot">mediant ::</span> <span class="dt">Interval</span> <span class="ot">-&gt;</span> <span class="dt">Frac</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>mediant (b <span class="op">:/</span> d <span class="op">:-:</span> a <span class="op">:/</span> c) <span class="ot">=</span> (a<span class="op">+</span>b) <span class="op">:/</span> (c<span class="op">+</span>d)</span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>left,<span class="ot"> right ::</span> <span class="dt">Interval</span> <span class="ot">-&gt;</span> <span class="dt">Interval</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>left  x <span class="ot">=</span> lb x <span class="op">:-:</span> mediant x</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>right x <span class="ot">=</span> mediant x <span class="op">:-:</span> ub x</span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a><span class="ot">rep&#39; ::</span> [<span class="dt">Bit</span>] <span class="ot">-&gt;</span> <span class="dt">Frac</span></span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a>rep&#39; <span class="ot">=</span> mediant <span class="op">.</span> <span class="fu">foldl</span> f ((<span class="dv">0</span> <span class="op">:/</span> <span class="dv">1</span>) <span class="op">:-:</span> (<span class="dv">1</span> <span class="op">:/</span> <span class="dv">0</span>))</span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>    f a <span class="dt">I</span> <span class="ot">=</span> right a</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a>    f a <span class="dt">O</span> <span class="ot">=</span> left a</span></code></pre></div>
<h1 id="monoids-and-matrices">Monoids and Matrices</h1>
<p>Before diving in and using this new evaluator to incrementalise our
functions, let’s take a look at what’s going on behind the scenes of the
“interval narrowing” idea.</p>
<p>It turns out that the “interval” is really a
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mo>×</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">2\times2</annotation></semantics></math>
square matrix in disguise (albeit a little reordered).</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mo stretchy="true" form="prefix">(</mo><mfrac><mi>a</mi><mi>b</mi></mfrac><mo>,</mo><mfrac><mi>c</mi><mi>d</mi></mfrac><mo stretchy="true" form="postfix">)</mo></mrow><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mtable><mtr><mtd columnalign="center" style="text-align: center"><mi>c</mi></mtd><mtd columnalign="center" style="text-align: center"><mi>a</mi></mtd></mtr><mtr><mtd columnalign="center" style="text-align: center"><mi>d</mi></mtd><mtd columnalign="center" style="text-align: center"><mi>b</mi></mtd></mtr></mtable><mo stretchy="true" form="postfix">)</mo></mrow></mrow><annotation encoding="application/x-tex"> \left( \frac{a}{b} , \frac{c}{d} \right) =
\left(
\begin{matrix}
  c &amp; a \\
  d &amp; b
\end{matrix}
\right)
</annotation></semantics></math></p>
<p>Seen in this way, the beginning
interval—<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="true" form="prefix">(</mo><mfrac><mn>0</mn><mn>1</mn></mfrac><mo>,</mo><mfrac><mn>1</mn><mn>0</mn></mfrac><mo stretchy="true" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\left(\frac{0}{1} ,
\frac{1}{0}\right)</annotation></semantics></math>—is actually the
identity matrix. Also, the two values in the second row of the tree
correspond to special matrices which we will refer to as
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>L</mi><annotation encoding="application/x-tex">L</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>R</mi><annotation encoding="application/x-tex">R</annotation></semantics></math>.</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>L</mi><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mtable><mtr><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd></mtr><mtr><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd></mtr></mtable><mo stretchy="true" form="postfix">)</mo></mrow><mspace width="0.278em"></mspace><mi>R</mi><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mtable><mtr><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd></mtr><mtr><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd></mtr></mtable><mo stretchy="true" form="postfix">)</mo></mrow></mrow><annotation encoding="application/x-tex"> L =
\left(
\begin{matrix}
  1 &amp; 0 \\
  1 &amp; 1
\end{matrix}
\right) \;
R =
\left(
\begin{matrix}
  1 &amp; 1 \\
  0 &amp; 1
\end{matrix}
\right)
</annotation></semantics></math></p>
<p>It turns out that the left and right functions we defined earlier
correspond to multiplication by these matrices.</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">left</mtext><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo stretchy="false" form="postfix">)</mo><mo>=</mo><mi>x</mi><mi>L</mi></mrow><annotation encoding="application/x-tex"> \text{left}(x) = xL </annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">right</mtext><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo stretchy="false" form="postfix">)</mo><mo>=</mo><mi>x</mi><mi>R</mi></mrow><annotation encoding="application/x-tex"> \text{right}(x) = xR </annotation></semantics></math></p>
<p>Since matrix multiplication is associative, what we have here is a
monoid. <code>mempty</code> is the open interval at the beginning, and
<code>mappend</code> is matrix multiplication. This is the property that
lets us incrementalise the whole thing, by the way: associativity allows
us to decide when to start and stop the calculation.</p>
<h1 id="incrementalising-1">Incrementalising!</h1>
<p>We now have all the parts we need. First, we will write an evaluator
that returns increasingly precise intervals. Our friend
<code>scanl</code> fits the requirement precisely.</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">approximate ::</span> [<span class="dt">Bit</span>] <span class="ot">-&gt;</span> [<span class="dt">Interval</span>]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>approximate <span class="ot">=</span> <span class="fu">scanl</span> f <span class="fu">mempty</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    f i <span class="dt">I</span> <span class="ot">=</span> right i</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    f i <span class="dt">O</span> <span class="ot">=</span> left  i</span></code></pre></div>
<p>Next, we will need to combine two of these lists with some operation
on fractions.</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">interleave ::</span> (<span class="dt">Frac</span> <span class="ot">-&gt;</span> <span class="dt">Frac</span> <span class="ot">-&gt;</span> <span class="dt">Frac</span>)</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> [<span class="dt">Interval</span>]</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> [<span class="dt">Interval</span>]</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> [<span class="dt">Interval</span>]</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>interleave (<span class="op">*</span>) [xi] ys <span class="ot">=</span> <span class="fu">map</span> (\y <span class="ot">-&gt;</span> x <span class="op">*</span> lb y <span class="op">:-:</span> x <span class="op">*</span> ub y) ys</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span> x <span class="ot">=</span> mediant xi</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>interleave (<span class="op">*</span>) (x<span class="op">:</span>xs) ys<span class="op">@</span>(y<span class="op">:</span>_) <span class="ot">=</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  (((<span class="op">*</span>) <span class="ot">`on`</span> lb) x y <span class="op">:-:</span> ((<span class="op">*</span>) <span class="ot">`on`</span> ub) x y) <span class="op">:</span> interleave (<span class="op">*</span>) ys xs</span></code></pre></div>
<p>The operation must respect orders in the proper way for this to be
valid.</p>
<p>This pops one bit from each list in turn: one of the many possible
optimisations would be to pull more information from the more
informative value, in some clever way.</p>
<p>Finally, we have a function which incrementally runs some binary
operator lazily on a list of bits.</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">quad ::</span> (<span class="dt">Frac</span> <span class="ot">-&gt;</span> <span class="dt">Frac</span> <span class="ot">-&gt;</span> <span class="dt">Frac</span>)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> [<span class="dt">Bit</span>]</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> [<span class="dt">Bit</span>]</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> [<span class="dt">Bit</span>]</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>quad (<span class="op">*</span>) xs ys <span class="ot">=</span> <span class="fu">foldr</span> f (unfoldr p) zs <span class="fu">mempty</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>    zs <span class="ot">=</span> (interleave (<span class="op">*</span>) <span class="ot">`on`</span> approximate) xs ys</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>    f x xs c</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> mediant c <span class="op">&lt;</span> lb x <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> f x xs (right c)</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> mediant c <span class="op">&gt;</span> ub x <span class="ot">=</span> <span class="dt">O</span> <span class="op">:</span> f x xs (left  c)</span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> xs c</span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>    t <span class="ot">=</span> mediant (<span class="fu">last</span> zs)</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>    p c <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> (mediant c) t <span class="kw">of</span></span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>      <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="dt">I</span>, right c)</span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a>      <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="dt">O</span>, left  c)</span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a>      <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span></code></pre></div>
<p>The function only ever inspects the next bit when it absolutely needs
to.</p>
<p>The helper function <code>f</code> here is the “incremental” version.
<code>p</code> takes over when the precision of the input is
exhausted.</p>
<p>We can use this to write an addition function (with some added
special cases to speed things up).</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> [<span class="dt">Bit</span>] <span class="ot">-&gt;</span> [<span class="dt">Bit</span>] <span class="ot">-&gt;</span> [<span class="dt">Bit</span>]</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>add [] ys <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> ys</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>add xs [] <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> xs</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>add (<span class="dt">I</span><span class="op">:</span>xs) ys <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> add xs ys</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>add xs (<span class="dt">I</span><span class="op">:</span>ys) <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> add xs ys</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>add xs ys <span class="ot">=</span> quad (<span class="op">+</span>) xs ys</span></code></pre></div>
<p>We (could) also try and optimise the times we look for a new bit.
Above we have noticed every case where one of the rationals is preceded
by a whole part. After you encounter two <code>O</code>s, in addition if
the two strings are inverses of each other the result will be 1.
i.e. <code>OOIOOI</code> + <code>OIOIIO</code> =
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>1</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{1}</annotation></semantics></math>.
We could try and spot this, only testing with comparison of the mediant
when the bits are the same. You’ve doubtless spotted some other possible
optimisations: I have yet to look into them!</p>
<h1 id="inverting-functions">Inverting Functions</h1>
<p>One of the other applications of lazy rationals is that they can
begin to <em>look</em> like the real numbers. For instance, the
<code>p</code> helper function above is basically defined extensionally.
Instead of stating the value of the number, we give a function which
tells us when we’ve made something too big or too small (which sounds an
awful lot like a Dedekind cut to my ears). Here’s a function which
<em>inverts</em> a given function on fractions, for instance.</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">inv ::</span> (<span class="dt">Frac</span> <span class="ot">-&gt;</span> <span class="dt">Frac</span>) <span class="ot">-&gt;</span> [<span class="dt">Bit</span>] <span class="ot">-&gt;</span> [<span class="dt">Bit</span>]</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>inv o n <span class="ot">=</span> unfoldr f <span class="fu">mempty</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    t <span class="ot">=</span> fromQ n</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>    f c <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> (o (mediant c)) t <span class="kw">of</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>      <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="dt">I</span>, right c)</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>      <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="dt">O</span>, left  c)</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>      <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span></code></pre></div>
<p>Of course, the function has to satisfy all kinds of extra properties
that I haven’t really thought a lot about yet, but no matter. We can use
it to invert a squaring function:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sqrt</span><span class="ot"> ::</span> [<span class="dt">Bit</span>] <span class="ot">-&gt;</span> [<span class="dt">Bit</span>]</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sqrt</span> <span class="ot">=</span> inv (\x <span class="ot">-&gt;</span> x <span class="op">*</span> x)</span></code></pre></div>
<p>And we can use <em>this</em> to get successive approximations to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msqrt><mn>2</mn></msqrt><annotation encoding="application/x-tex">\sqrt{2}</annotation></semantics></math>!</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>root2Approx</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="fu">map</span> (toDouble <span class="op">.</span> mediant) (approximate (<span class="fu">sqrt</span> (<span class="fu">abs</span> (<span class="dv">2</span> <span class="op">:/</span> <span class="dv">1</span>))))</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">mapM_</span> <span class="fu">print</span> root2Approx</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a><span class="fl">1.0</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a><span class="fl">2.0</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a><span class="fl">1.5</span></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a><span class="fl">1.3333333333333333</span></span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a><span class="fl">1.4</span></span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a><span class="fl">1.4285714285714286</span></span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a><span class="fl">1.4166666666666667</span></span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a><span class="fl">1.411764705882353</span></span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a><span class="fl">1.4137931034482758</span></span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a><span class="fl">1.4146341463414633</span></span>
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a><span class="op">...</span></span></code></pre></div>
<h1 id="conclusions-and-related-work">Conclusions and Related Work</h1>
<p>Using the Stern-Brocot tree to represent the rationals was formalised
in Coq in <span class="citation"
data-cites="bertotSimpleCanonicalRepresentation2003">Bertot (<a
href="#ref-bertotSimpleCanonicalRepresentation2003"
role="doc-biblioref">2003</a>)</span>. The corresponding lazy operations
are formalised in <a
href="https://github.com/coq-community/qarith-stern-brocot">QArith</a>.
Its theory and implementation is described in <span class="citation"
data-cites="niquiExactArithmeticStern2007">Niqui (<a
href="#ref-niquiExactArithmeticStern2007"
role="doc-biblioref">2007</a>)</span>. Unfortunately, I found most of
the algorithms impenetrably complex, so I can’t really judge how they
compare to the ones I have here.</p>
<p>I mentioned that one of the reasons you might want lazy rational
arithmetic is that it can help with certain proofs. While this is true,
in general the two main reasons people reach for lazy arithmetic is
efficiency and as a way to get to the real numbers.</p>
<p>From the perspective of efficiency, the Stern-Brocot tree is probably
a bad idea. You may have noticed that the right branch of the tree
contains all the whole numbers: this means that the whole part is
encoded in unary. Beyond that, we generally have to convert to some
fraction in order to do any calculation, which is massively
expensive.</p>
<p>The problem is that bits in the same position in different numbers
don’t necessarily correspond to the same quantities. In base 10, for
instance, the numbers 561 and 1024 have values in the “ones” position of
1 and 4, respectively. We can work with those two values independent of
the rest of the number, which can lead to quicker algorithms.</p>
<p>Looking at the Stern-Brocot encoding, the numbers
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>2</mn><mn>3</mn></mfrac><annotation encoding="application/x-tex">\frac{2}{3}</annotation></semantics></math>
and 3 are represented by <code>OI</code> and <code>II</code>,
respectively. That second <code>I</code> in each, despite being in the
same position, corresponds to <em>different values</em>:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>3</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{3}</annotation></semantics></math>
in the first, and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>3</mn><mn>2</mn></mfrac><annotation encoding="application/x-tex">\frac{3}{2}</annotation></semantics></math>
in the second.</p>
<p>Solutions to both of these problems necessitate losing the one-to-one
property of the representation. We could improve the size of the
representation of terms by having our
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>L</mi><annotation encoding="application/x-tex">L</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>R</mi><annotation encoding="application/x-tex">R</annotation></semantics></math>
matrices be the following <span class="citation"
data-cites="kurkaExactRealArithmetic2014">(<a
href="#ref-kurkaExactRealArithmetic2014" role="doc-biblioref">Kůrka
2014</a>)</span>:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>L</mi><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mtable><mtr><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd></mtr><mtr><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>2</mn></mtd></mtr></mtable><mo stretchy="true" form="postfix">)</mo></mrow><mspace width="0.278em"></mspace><mi>R</mi><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mtable><mtr><mtd columnalign="center" style="text-align: center"><mn>2</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd></mtr><mtr><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd></mtr></mtable><mo stretchy="true" form="postfix">)</mo></mrow></mrow><annotation encoding="application/x-tex"> L = \left(
\begin{matrix}
  1 &amp; 0 \\
  1 &amp; 2
\end{matrix}
\right) \;
 R = \left(
\begin{matrix}
  2 &amp; 1 \\
  0 &amp; 1
\end{matrix}
\right) </annotation></semantics></math></p>
<p>But now there will be gaps in the tree. This basically means we’ll
have to use infinite repeating bits to represent terms like
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>2</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{2}</annotation></semantics></math>.</p>
<p>We could solve the other problem by throwing out the Stern-Brocot
tree entirely and using a more traditional positional number system.
Again, this introduces redundancy: in order to represent some fraction
which doesn’t divide properly into the base of the number system you
have to use repeating decimals.</p>
<p>The second reason for lazy rational arithmetic is that it can be a
crucial component in building a constructive interpretation of the real
numbers. This in particular is an area of real excitement at the moment:
HoTT has opened up some interesting avenues that weren’t possible before
for constructing the reals <span class="citation"
data-cites="bauerRealNumbersHomotopy2016">(<a
href="#ref-bauerRealNumbersHomotopy2016" role="doc-biblioref">Bauer
2016</a>)</span>.</p>
<p>In a future post, I might present a formalisation of these numbers in
Agda. I also intend to look at the dyadic numbers.</p>
<p>Update 26/12/2019: thanks Anton Felix Lorenzen and Joseph C. Sible
for spotting some mistakes in this post.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-bauerRealNumbersHomotopy2016" class="csl-entry"
role="listitem">
Bauer, Andrej. 2016. <span>“The real numbers in homotopy type
theory.”</span> <span>Faro, Portugal</span>. <a
href="http://math.andrej.com/wp-content/uploads/2016/06/hott-reals-cca2016.pdf">http://math.andrej.com/wp-content/uploads/2016/06/hott-reals-cca2016.pdf</a>.
</div>
<div id="ref-bertotSimpleCanonicalRepresentation2003" class="csl-entry"
role="listitem">
Bertot, Yves. 2003. <span>“A simple canonical representation of rational
numbers.”</span> <em>Electronic Notes in Theoretical Computer
Science</em> 85 (7). Mathematics, <span>Logic</span> and
<span>Computation</span> (<span>Satellite Event</span> of
<span>ICALP</span> 2003) (September): 1–16. doi:<a
href="https://doi.org/10.1016/S1571-0661(04)80754-0">10.1016/S1571-0661(04)80754-0</a>.
<a
href="http://www.sciencedirect.com/science/article/pii/S1571066104807540">http://www.sciencedirect.com/science/article/pii/S1571066104807540</a>.
</div>
<div id="ref-kurkaExactRealArithmetic2014" class="csl-entry"
role="listitem">
Kůrka, Petr. 2014. <span>“Exact real arithmetic for interval number
systems.”</span> <em>Theoretical Computer Science</em> 542 (July):
32–43. doi:<a
href="https://doi.org/10.1016/j.tcs.2014.04.030">10.1016/j.tcs.2014.04.030</a>.
<a
href="http://www.sciencedirect.com/science/article/pii/S0304397514003351">http://www.sciencedirect.com/science/article/pii/S0304397514003351</a>.
</div>
<div id="ref-niquiExactArithmeticStern2007" class="csl-entry"
role="listitem">
Niqui, Milad. 2007. <span>“Exact arithmetic on the <span>Stern</span>
tree.”</span> <em>Journal of Discrete Algorithms</em> 5 (2). 2004
<span>Symposium</span> on <span>String Processing</span> and
<span>Information Retrieval</span> (June): 356–379. doi:<a
href="https://doi.org/10.1016/j.jda.2005.03.007">10.1016/j.jda.2005.03.007</a>.
<a
href="http://www.sciencedirect.com/science/article/pii/S1570866706000311">http://www.sciencedirect.com/science/article/pii/S1570866706000311</a>.
</div>
</div>
]]></description>
    <pubDate>Sat, 14 Dec 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-12-14-stern-brocot.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Small Proof that Fin is Injective</title>
    <link>https://doisinkidney.com/posts/2019-11-15-small-proof-fin-inj.html</link>
    <description><![CDATA[<div class="info">
    Posted on November 15, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<details>
<summary>
Imports etc.
</summary>
<pre class="Agda"><a id="115" class="Symbol">{-#</a> <a id="119" class="Keyword">OPTIONS</a> <a id="127" class="Pragma">--safe</a> <a id="134" class="Pragma">--without-K</a> <a id="146" class="Symbol">#-}</a>

<a id="151" class="Keyword">module</a> <a id="158" href="" class="Module">Post</a> <a id="163" class="Keyword">where</a>

<a id="170" class="Keyword">open</a> <a id="175" class="Keyword">import</a> <a id="182" href="../code/fininj/Data.Fin.html" class="Module">Data.Fin</a>                              <a id="220" class="Keyword">using</a> <a id="226" class="Symbol">(</a><a id="227" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a><a id="230" class="Symbol">;</a> <a id="232" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a><a id="235" class="Symbol">;</a> <a id="237" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a><a id="241" class="Symbol">;</a> <a id="243" href="../code/fininj/Data.Fin.Properties.html#1997" class="../code/fininj/Function Operator">_≟_</a><a id="246" class="Symbol">)</a>
<a id="248" class="Keyword">open</a> <a id="253" class="Keyword">import</a> <a id="260" href="../code/fininj/Data.Nat.html" class="Module">Data.Nat</a>                              <a id="298" class="Keyword">using</a> <a id="304" class="Symbol">(</a><a id="305" href="../code/fininj/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a><a id="306" class="Symbol">;</a> <a id="308" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="311" class="Symbol">;</a> <a id="313" href="../code/fininj/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a><a id="317" class="Symbol">;</a> <a id="319" href="../code/fininj/Agda.Builtin.Nat.html#298" class="Primitive Operator">_+_</a><a id="322" class="Symbol">;</a> <a id="324" href="../code/fininj/Data.Nat.Base.html#3697" class="../code/fininj/Function">compare</a><a id="331" class="Symbol">;</a> <a id="333" href="../code/fininj/Data.Nat.Base.html#3620" class="InductiveConstructor">equal</a><a id="338" class="Symbol">;</a> <a id="340" href="../code/fininj/Data.Nat.Base.html#3653" class="InductiveConstructor">greater</a><a id="347" class="Symbol">;</a> <a id="349" href="../code/fininj/Data.Nat.Base.html#3575" class="InductiveConstructor">less</a><a id="353" class="Symbol">)</a>
<a id="355" class="Keyword">open</a> <a id="360" class="Keyword">import</a> <a id="367" href="../code/fininj/Data.Nat.Properties.html" class="Module">Data.Nat.Properties</a>                   <a id="405" class="Keyword">using</a> <a id="411" class="Symbol">(</a><a id="412" href="../code/fininj/Data.Nat.Properties.html#12828" class="../code/fininj/Function">+-comm</a><a id="418" class="Symbol">)</a>
<a id="420" class="Keyword">open</a> <a id="425" class="Keyword">import</a> <a id="432" href="../code/fininj/Data.Bool.html" class="Module">Data.Bool</a>                             <a id="470" class="Keyword">using</a> <a id="476" class="Symbol">(</a><a id="477" href="../code/fininj/Data.Bool.Base.html#932" class="../code/fininj/Function">not</a><a id="480" class="Symbol">;</a> <a id="482" href="../code/fininj/Data.Bool.Base.html#1451" class="../code/fininj/Function">T</a><a id="483" class="Symbol">)</a>
<a id="485" class="Keyword">open</a> <a id="490" class="Keyword">import</a> <a id="497" href="../code/fininj/Relation.Nullary.html" class="Module">Relation.Nullary</a>                      <a id="535" class="Keyword">using</a> <a id="541" class="Symbol">(</a><a id="542" href="../code/fininj/Relation.Nullary.html#1645">yes</a><a id="545" class="Symbol">;</a> <a id="547" href="../code/fininj/Relation.Nullary.html#1682">no</a><a id="549" class="Symbol">;</a> <a id="551" href="../code/fininj/Relation.Nullary.html#1578" class="Field">does</a><a id="555" class="Symbol">;</a> <a id="557" href="../code/fininj/Relation.Nullary.html#653" class="../code/fininj/Function Operator">¬_</a><a id="559" class="Symbol">)</a>
<a id="561" class="Keyword">open</a> <a id="566" class="Keyword">import</a> <a id="573" href="../code/fininj/Data.Product.html" class="Module">Data.Product</a>                          <a id="611" class="Keyword">using</a> <a id="617" class="Symbol">(</a><a id="618" href="../code/fininj/Agda.Builtin.Sigma.html#139" class="Record">Σ</a><a id="619" class="Symbol">;</a> <a id="621" href="../code/fininj/Data.Product.html#916" class="../code/fininj/Function">Σ-syntax</a><a id="629" class="Symbol">;</a> <a id="631" href="../code/fininj/Agda.Builtin.Sigma.html#225" class="Field">proj₁</a><a id="636" class="Symbol">;</a> <a id="638" href="../code/fininj/Agda.Builtin.Sigma.html#237" class="Field">proj₂</a><a id="643" class="Symbol">;</a> <a id="645" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">_,_</a><a id="648" class="Symbol">)</a>
<a id="650" class="Keyword">open</a> <a id="655" class="Keyword">import</a> <a id="662" href="../code/fininj/Data.Unit.html" class="Module">Data.Unit</a>                             <a id="700" class="Keyword">using</a> <a id="706" class="Symbol">(</a><a id="707" href="../code/fininj/Agda.Builtin.Unit.html#174" class="InductiveConstructor">tt</a><a id="709" class="Symbol">;</a> <a id="711" href="../code/fininj/Agda.Builtin.Unit.html#137" class="Record">⊤</a><a id="712" class="Symbol">)</a>
<a id="714" class="Keyword">open</a> <a id="719" class="Keyword">import</a> <a id="726" href="../code/fininj/Function.html" class="Module">Function</a>                              <a id="764" class="Keyword">using</a> <a id="770" class="Symbol">(</a><a id="771" href="../code/fininj/Function.Base.html#992" class="../code/fininj/Function Operator">_∘_</a><a id="774" class="Symbol">;</a> <a id="776" href="../code/fininj/Function.Base.html#615" class="../code/fininj/Function">id</a><a id="778" class="Symbol">;</a> <a id="780" href="../code/fininj/Function.Base.html#3828" class="../code/fininj/Function Operator">_⟨_⟩_</a><a id="785" class="Symbol">)</a>
<a id="787" class="Keyword">open</a> <a id="792" class="Keyword">import</a> <a id="799" href="../code/fininj/Relation.Binary.PropositionalEquality.html" class="Module">Relation.Binary.PropositionalEquality</a> <a id="837" class="Keyword">using</a> <a id="843" class="Symbol">(</a><a id="844" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#1076" class="../code/fininj/Function">subst</a><a id="849" class="Symbol">;</a> <a id="851" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#1025" class="../code/fininj/Function">trans</a><a id="856" class="Symbol">;</a> <a id="858" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#1131" class="../code/fininj/Function">cong</a><a id="862" class="Symbol">;</a> <a id="864" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#980" class="../code/fininj/Function">sym</a><a id="867" class="Symbol">;</a> <a id="869" href="../code/fininj/Agda.Builtin.Equality.html#125" class="Datatype Operator">_≡_</a><a id="872" class="Symbol">;</a> <a id="874" href="../code/fininj/Agda.Builtin.Equality.html#182" class="InductiveConstructor">refl</a><a id="878" class="Symbol">;</a> <a id="880" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#840" class="../code/fininj/Function Operator">_≢_</a><a id="883" class="Symbol">)</a>
<a id="885" class="Keyword">open</a> <a id="890" class="Keyword">import</a> <a id="897" href="../code/fininj/Data.Empty.html" class="Module">Data.Empty</a>                            <a id="935" class="Keyword">using</a> <a id="941" class="Symbol">(</a><a id="942" href="../code/fininj/Data.Empty.html#275" class="../code/fininj/Function">⊥-elim</a><a id="948" class="Symbol">;</a> <a id="950" href="../code/fininj/Data.Empty.html#260" class="Datatype">⊥</a><a id="951" class="Symbol">)</a>

<a id="954" class="Keyword">variable</a> <a id="963" href="#963" class="Generalizable">n</a> <a id="965" href="#965" class="Generalizable">m</a> <a id="967" class="Symbol">:</a> <a id="969" href="../code/fininj/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
</pre>
</details>
<p>Here’s a puzzle: can you prove that <code>Fin</code> is injective?
That’s the type constructor, by the way, not the type itself. Here’s the
type of the proof we want:</p>
<pre class="Agda"><a id="Goal"></a><a id="1153" href="#1153" class="../code/fininj/Function">Goal</a> <a id="1158" class="Symbol">:</a> <a id="1160" class="PrimitiveType">Set₁</a>
<a id="1165" href="#1153" class="../code/fininj/Function">Goal</a> <a id="1170" class="Symbol">=</a> <a id="1172" class="Symbol">∀</a> <a id="1174" class="Symbol">{</a><a id="1175" href="#1175" class="Bound">n</a> <a id="1177" href="#1177" class="Bound">m</a><a id="1178" class="Symbol">}</a> <a id="1180" class="Symbol">→</a> <a id="1182" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="1186" href="#1175" class="Bound">n</a> <a id="1188" href="../code/fininj/Agda.Builtin.Equality.html#125" class="Datatype Operator">≡</a> <a id="1190" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="1194" href="#1177" class="Bound">m</a> <a id="1196" class="Symbol">→</a> <a id="1198" href="#1175" class="Bound">n</a> <a id="1200" href="../code/fininj/Agda.Builtin.Equality.html#125" class="Datatype Operator">≡</a> <a id="1202" href="#1177" class="Bound">m</a>
</pre>
<p>I’m going to present a proof of this lemma that has a couple
interesting features. You should try it yourself before reading on,
though: it’s difficult, but great practice for understanding Agda’s type
system.</p>
<p>First off, I should say that it’s not really a “new” proof: it’s
basically <a
href="https://github.com/AndrasKovacs/misc-stuff/blob/db1b6f8699870ba25986c5408f1dddbded663b7c/agda/FinInj.agda">Andras
Kovac’s proof</a>, with one key change. That proof, as well as this one,
goes <code>--without-K</code>: because I actually use this proof in some
work I’m doing in Cubical Agda at the moment, this was non optional. It
does make things significantly harder, and disallows nice tricks like
the <a
href="https://github.com/effectfully/random-stuff/blob/8907dda8cbba29073e6c9720e9b05f47be864440/Fin-injective.agda">ones
used by effectfully</a>.</p>
<h1 id="computational-inequalities">Computational Inequalities</h1>
<p>The trick we’re going to use comes courtesy of <a
href="https://personal.cis.strath.ac.uk/james.wood.100/blog/html/VecMat.html">James
Wood</a>. The central idea is the following type:</p>
<pre class="Agda"><a id="_≢ᶠ_"></a><a id="2239" href="#2239" class="../code/fininj/Function Operator">_≢ᶠ_</a> <a id="2244" class="Symbol">:</a> <a id="2246" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="2250" href="#963" class="Generalizable">n</a> <a id="2252" class="Symbol">→</a> <a id="2254" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="2258" href="#963" class="Generalizable">n</a> <a id="2260" class="Symbol">→</a> <a id="2262" class="PrimitiveType">Set</a>
<a id="2266" href="#2266" class="Bound">x</a> <a id="2268" href="#2239" class="../code/fininj/Function Operator">≢ᶠ</a> <a id="2271" href="#2271" class="Bound">y</a> <a id="2273" class="Symbol">=</a> <a id="2275" href="../code/fininj/Data.Bool.Base.html#1451" class="../code/fininj/Function">T</a> <a id="2277" class="Symbol">(</a><a id="2278" href="../code/fininj/Data.Bool.Base.html#932" class="../code/fininj/Function">not</a> <a id="2282" class="Symbol">(</a><a id="2283" href="../code/fininj/Relation.Nullary.html#1578" class="Field">does</a> <a id="2288" class="Symbol">(</a><a id="2289" href="#2266" class="Bound">x</a> <a id="2291" href="../code/fininj/Data.Fin.Properties.html#1997" class="../code/fininj/Function Operator">≟</a> <a id="2293" href="#2271" class="Bound">y</a><a id="2294" class="Symbol">)))</a>
</pre>
<p>This proof of inequality of <code>Fin</code>s is different from the
usual definition, which might be something like:</p>
<pre class="Agda"><a id="_≢ᶠ′_"></a><a id="2418" href="#2418" class="../code/fininj/Function Operator">_≢ᶠ′_</a> <a id="2424" class="Symbol">:</a> <a id="2426" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="2430" href="#963" class="Generalizable">n</a> <a id="2432" class="Symbol">→</a> <a id="2434" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="2438" href="#963" class="Generalizable">n</a> <a id="2440" class="Symbol">→</a> <a id="2442" class="PrimitiveType">Set</a>
<a id="2446" href="#2446" class="Bound">x</a> <a id="2448" href="#2418" class="../code/fininj/Function Operator">≢ᶠ′</a> <a id="2452" href="#2452" class="Bound">y</a> <a id="2454" class="Symbol">=</a> <a id="2456" href="#2446" class="Bound">x</a> <a id="2458" href="../code/fininj/Agda.Builtin.Equality.html#125" class="Datatype Operator">≡</a> <a id="2460" href="#2452" class="Bound">y</a> <a id="2462" class="Symbol">→</a> <a id="2464" href="../code/fininj/Data.Empty.html#260" class="Datatype">⊥</a>
</pre>
<p>Our definition is based on the decidable equality of two
<code>Fin</code>s. It also uses the standard library’s new
<code>Dec</code> type. Basically, we get better computation behaviour
from our definition. It behaves as if it were defined like so:</p>
<pre class="Agda"><a id="_≢ᶠ″_"></a><a id="2707" href="#2707" class="../code/fininj/Function Operator">_≢ᶠ″_</a> <a id="2713" class="Symbol">:</a> <a id="2715" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="2719" href="#963" class="Generalizable">n</a> <a id="2721" class="Symbol">→</a> <a id="2723" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="2727" href="#963" class="Generalizable">n</a> <a id="2729" class="Symbol">→</a> <a id="2731" class="PrimitiveType">Set</a>
<a id="2735" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>  <a id="2741" href="#2707" class="../code/fininj/Function Operator">≢ᶠ″</a> <a id="2745" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>  <a id="2751" class="Symbol">=</a> <a id="2753" href="../code/fininj/Data.Empty.html#260" class="Datatype">⊥</a>
<a id="2755" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>  <a id="2761" href="#2707" class="../code/fininj/Function Operator">≢ᶠ″</a> <a id="2765" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="2769" href="#2769" class="Bound">y</a> <a id="2771" class="Symbol">=</a> <a id="2773" href="../code/fininj/Agda.Builtin.Unit.html#137" class="Record">⊤</a>
<a id="2775" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="2779" href="#2779" class="Bound">x</a> <a id="2781" href="#2707" class="../code/fininj/Function Operator">≢ᶠ″</a> <a id="2785" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>  <a id="2791" class="Symbol">=</a> <a id="2793" href="../code/fininj/Agda.Builtin.Unit.html#137" class="Record">⊤</a>
<a id="2795" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="2799" href="#2799" class="Bound">x</a> <a id="2801" href="#2707" class="../code/fininj/Function Operator">≢ᶠ″</a> <a id="2805" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="2809" href="#2809" class="Bound">y</a> <a id="2811" class="Symbol">=</a> <a id="2813" href="#2799" class="Bound">x</a> <a id="2815" href="#2707" class="../code/fininj/Function Operator">≢ᶠ″</a> <a id="2819" href="#2809" class="Bound">y</a>
</pre>
<p>The benefit of this, in contrast to <code>_≢ᶠ′_</code>, is that each
case becomes a definitional equality we don’t have to prove. Compare the
two following proofs of congruence under <code>suc</code>:</p>
<pre class="Agda"><a id="cong-suc″"></a><a id="3014" href="#3014" class="../code/fininj/Function">cong-suc″</a> <a id="3024" class="Symbol">:</a> <a id="3026" class="Symbol">∀</a> <a id="3028" class="Symbol">{</a><a id="3029" href="#3029" class="Bound">x</a> <a id="3031" href="#3031" class="Bound">y</a> <a id="3033" class="Symbol">:</a> <a id="3035" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3039" href="#963" class="Generalizable">n</a><a id="3040" class="Symbol">}</a> <a id="3042" class="Symbol">→</a> <a id="3044" href="#3029" class="Bound">x</a> <a id="3046" href="#2707" class="../code/fininj/Function Operator">≢ᶠ″</a> <a id="3050" href="#3031" class="Bound">y</a> <a id="3052" class="Symbol">→</a> <a id="3054" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3058" href="#3029" class="Bound">x</a> <a id="3060" href="#2707" class="../code/fininj/Function Operator">≢ᶠ″</a> <a id="3064" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3068" href="#3031" class="Bound">y</a>
<a id="3070" href="#3014" class="../code/fininj/Function">cong-suc″</a> <a id="3080" href="#3080" class="Bound">p</a> <a id="3082" class="Symbol">=</a> <a id="3084" href="#3080" class="Bound">p</a>

<a id="cong-suc′"></a><a id="3087" href="#3087" class="../code/fininj/Function">cong-suc′</a> <a id="3097" class="Symbol">:</a> <a id="3099" class="Symbol">∀</a> <a id="3101" class="Symbol">{</a><a id="3102" href="#3102" class="Bound">x</a> <a id="3104" href="#3104" class="Bound">y</a> <a id="3106" class="Symbol">:</a> <a id="3108" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3112" href="#963" class="Generalizable">n</a><a id="3113" class="Symbol">}</a> <a id="3115" class="Symbol">→</a> <a id="3117" href="#3102" class="Bound">x</a> <a id="3119" href="#2418" class="../code/fininj/Function Operator">≢ᶠ′</a> <a id="3123" href="#3104" class="Bound">y</a> <a id="3125" class="Symbol">→</a> <a id="3127" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3131" href="#3102" class="Bound">x</a> <a id="3133" href="#2418" class="../code/fininj/Function Operator">≢ᶠ′</a> <a id="3137" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3141" href="#3104" class="Bound">y</a>
<a id="3143" href="#3087" class="../code/fininj/Function">cong-suc′</a> <a id="3153" class="Symbol">{</a><a id="3154" class="Argument">n</a> <a id="3156" class="Symbol">=</a> <a id="3158" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="3162" href="#3162" class="Bound">n</a><a id="3163" class="Symbol">}</a> <a id="3165" href="#3165" class="Bound">p</a> <a id="3167" href="#3167" class="Bound">q</a> <a id="3169" class="Symbol">=</a> <a id="3171" href="#3165" class="Bound">p</a> <a id="3173" class="Symbol">(</a><a id="3174" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#1131" class="../code/fininj/Function">cong</a> <a id="3179" href="#3198" class="../code/fininj/Function">fpred</a> <a id="3185" href="#3167" class="Bound">q</a><a id="3186" class="Symbol">)</a>
  <a id="3190" class="Keyword">where</a>
  <a id="3198" href="#3198" class="../code/fininj/Function">fpred</a> <a id="3204" class="Symbol">:</a> <a id="3206" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3210" class="Symbol">(</a><a id="3211" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="3215" class="Symbol">(</a><a id="3216" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="3220" href="#3162" class="Bound">n</a><a id="3221" class="Symbol">))</a> <a id="3224" class="Symbol">→</a> <a id="3226" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3230" class="Symbol">(</a><a id="3231" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="3235" href="#3162" class="Bound">n</a><a id="3236" class="Symbol">)</a>
  <a id="3240" href="#3198" class="../code/fininj/Function">fpred</a> <a id="3246" class="Symbol">(</a><a id="3247" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3251" href="#3251" class="Bound">x</a><a id="3252" class="Symbol">)</a> <a id="3254" class="Symbol">=</a> <a id="3256" href="#3251" class="Bound">x</a>
  <a id="3260" href="#3198" class="../code/fininj/Function">fpred</a> <a id="3266" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a> <a id="3271" class="Symbol">=</a> <a id="3273" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>
</pre>
<h1 id="the-proof">The Proof</h1>
<p>First, we will describe an “injection” for functions from
<code>Fin</code>s to <code>Fin</code>s.</p>
<pre class="Agda"><a id="_F↣_"></a><a id="3381" href="#3381" class="../code/fininj/Function Operator">_F↣_</a> <a id="3386" class="Symbol">:</a> <a id="3388" href="../code/fininj/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="3390" class="Symbol">→</a> <a id="3392" href="../code/fininj/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="3394" class="Symbol">→</a> <a id="3396" class="PrimitiveType">Set</a>
<a id="3400" href="#3400" class="Bound">n</a> <a id="3402" href="#3381" class="../code/fininj/Function Operator">F↣</a> <a id="3405" href="#3405" class="Bound">m</a> <a id="3407" class="Symbol">=</a> <a id="3409" href="../code/fininj/Data.Product.html#916" class="../code/fininj/Function">Σ[</a> <a id="3412" href="#3412" class="Bound">f</a> <a id="3414" href="../code/fininj/Data.Product.html#916" class="../code/fininj/Function">∈</a> <a id="3416" class="Symbol">(</a><a id="3417" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3421" href="#3400" class="Bound">n</a> <a id="3423" class="Symbol">→</a> <a id="3425" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3429" href="#3405" class="Bound">m</a><a id="3430" class="Symbol">)</a> <a id="3432" href="../code/fininj/Data.Product.html#916" class="../code/fininj/Function">]</a> <a id="3434" class="Symbol">∀</a> <a id="3436" class="Symbol">{</a><a id="3437" href="#3437" class="Bound">x</a> <a id="3439" href="#3439" class="Bound">y</a><a id="3440" class="Symbol">}</a> <a id="3442" class="Symbol">→</a> <a id="3444" href="#3437" class="Bound">x</a> <a id="3446" href="#2239" class="../code/fininj/Function Operator">≢ᶠ</a> <a id="3449" href="#3439" class="Bound">y</a> <a id="3451" class="Symbol">→</a> <a id="3453" href="#3412" class="Bound">f</a> <a id="3455" href="#3437" class="Bound">x</a> <a id="3457" href="#2239" class="../code/fininj/Function Operator">≢ᶠ</a> <a id="3460" href="#3412" class="Bound">f</a> <a id="3462" href="#3439" class="Bound">y</a>
</pre>
<p>We’re using the negated from of injectivity here, which is usually
avoided in constructive settings. It actually works a little better for
us here, though. Since we’re working in the domain of <code>Fin</code>s,
and since our proof is prop-valued, it’s almost like we’re working in
classical logic.</p>
<p>Next, we have the workhorse of the proof, the <code>shrink</code>
lemma:</p>
<pre class="Agda"><a id="shift"></a><a id="3829" href="#3829" class="../code/fininj/Function">shift</a> <a id="3835" class="Symbol">:</a> <a id="3837" class="Symbol">(</a><a id="3838" href="#3838" class="Bound">x</a> <a id="3840" href="#3840" class="Bound">y</a> <a id="3842" class="Symbol">:</a> <a id="3844" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3848" class="Symbol">(</a><a id="3849" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="3853" href="#963" class="Generalizable">n</a><a id="3854" class="Symbol">))</a> <a id="3857" class="Symbol">→</a> <a id="3859" href="#3838" class="Bound">x</a> <a id="3861" href="#2239" class="../code/fininj/Function Operator">≢ᶠ</a> <a id="3864" href="#3840" class="Bound">y</a> <a id="3866" class="Symbol">→</a> <a id="3868" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="3872" href="#963" class="Generalizable">n</a>
<a id="3874" href="#3829" class="../code/fininj/Function">shift</a>         <a id="3888" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>    <a id="3896" class="Symbol">(</a><a id="3897" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3901" href="#3901" class="Bound">y</a><a id="3902" class="Symbol">)</a> <a id="3904" href="#3904" class="Bound">x≢y</a> <a id="3908" class="Symbol">=</a> <a id="3910" href="#3901" class="Bound">y</a>
<a id="3912" href="#3829" class="../code/fininj/Function">shift</a> <a id="3918" class="Symbol">{</a><a id="3919" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="3923" class="Symbol">_}</a> <a id="3926" class="Symbol">(</a><a id="3927" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3931" href="#3931" class="Bound">x</a><a id="3932" class="Symbol">)</a> <a id="3934" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>    <a id="3942" href="#3942" class="Bound">x≢y</a> <a id="3946" class="Symbol">=</a> <a id="3948" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>
<a id="3953" href="#3829" class="../code/fininj/Function">shift</a> <a id="3959" class="Symbol">{</a><a id="3960" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="3964" class="Symbol">_}</a> <a id="3967" class="Symbol">(</a><a id="3968" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3972" href="#3972" class="Bound">x</a><a id="3973" class="Symbol">)</a> <a id="3975" class="Symbol">(</a><a id="3976" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3980" href="#3980" class="Bound">y</a><a id="3981" class="Symbol">)</a> <a id="3983" href="#3983" class="Bound">x≢y</a> <a id="3987" class="Symbol">=</a> <a id="3989" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="3993" class="Symbol">(</a><a id="3994" href="#3829" class="../code/fininj/Function">shift</a> <a id="4000" href="#3972" class="Bound">x</a> <a id="4002" href="#3980" class="Bound">y</a> <a id="4004" href="#3983" class="Bound">x≢y</a><a id="4007" class="Symbol">)</a>

<a id="shift-inj"></a><a id="4010" href="#4010" class="../code/fininj/Function">shift-inj</a> <a id="4020" class="Symbol">:</a> <a id="4022" class="Symbol">∀</a> <a id="4024" class="Symbol">(</a><a id="4025" href="#4025" class="Bound">x</a> <a id="4027" href="#4027" class="Bound">y</a> <a id="4029" href="#4029" class="Bound">z</a> <a id="4031" class="Symbol">:</a> <a id="4033" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="4037" class="Symbol">(</a><a id="4038" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4042" href="#963" class="Generalizable">n</a><a id="4043" class="Symbol">))</a> <a id="4046" href="#4046" class="Bound">y≢x</a> <a id="4050" href="#4050" class="Bound">z≢x</a> <a id="4054" class="Symbol">→</a> <a id="4056" href="#4027" class="Bound">y</a> <a id="4058" href="#2239" class="../code/fininj/Function Operator">≢ᶠ</a> <a id="4061" href="#4029" class="Bound">z</a> <a id="4063" class="Symbol">→</a> <a id="4065" href="#3829" class="../code/fininj/Function">shift</a> <a id="4071" href="#4025" class="Bound">x</a> <a id="4073" href="#4027" class="Bound">y</a> <a id="4075" href="#4046" class="Bound">y≢x</a> <a id="4079" href="#2239" class="../code/fininj/Function Operator">≢ᶠ</a> <a id="4082" href="#3829" class="../code/fininj/Function">shift</a> <a id="4088" href="#4025" class="Bound">x</a> <a id="4090" href="#4029" class="Bound">z</a> <a id="4092" href="#4050" class="Bound">z≢x</a>
<a id="4096" href="#4010" class="../code/fininj/Function">shift-inj</a>         <a id="4114" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>    <a id="4122" class="Symbol">(</a><a id="4123" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4127" href="#4127" class="Bound">y</a><a id="4128" class="Symbol">)</a> <a id="4130" class="Symbol">(</a><a id="4131" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4135" href="#4135" class="Bound">z</a><a id="4136" class="Symbol">)</a> <a id="4138" href="#4138" class="Bound">y≢x</a> <a id="4142" href="#4142" class="Bound">z≢x</a> <a id="4146" href="#4146" class="Bound">neq</a> <a id="4150" class="Symbol">=</a> <a id="4152" href="#4146" class="Bound">neq</a>
<a id="4156" href="#4010" class="../code/fininj/Function">shift-inj</a> <a id="4166" class="Symbol">{</a><a id="4167" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4171" class="Symbol">_}</a> <a id="4174" class="Symbol">(</a><a id="4175" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4179" href="#4179" class="Bound">x</a><a id="4180" class="Symbol">)</a> <a id="4182" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>    <a id="4190" class="Symbol">(</a><a id="4191" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4195" href="#4195" class="Bound">z</a><a id="4196" class="Symbol">)</a> <a id="4198" href="#4198" class="Bound">y≢x</a> <a id="4202" href="#4202" class="Bound">z≢x</a> <a id="4206" href="#4206" class="Bound">neq</a> <a id="4210" class="Symbol">=</a> <a id="4212" href="../code/fininj/Agda.Builtin.Unit.html#174" class="InductiveConstructor">tt</a>
<a id="4215" href="#4010" class="../code/fininj/Function">shift-inj</a> <a id="4225" class="Symbol">{</a><a id="4226" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4230" class="Symbol">_}</a> <a id="4233" class="Symbol">(</a><a id="4234" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4238" href="#4238" class="Bound">x</a><a id="4239" class="Symbol">)</a> <a id="4241" class="Symbol">(</a><a id="4242" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4246" href="#4246" class="Bound">y</a><a id="4247" class="Symbol">)</a> <a id="4249" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>    <a id="4257" href="#4257" class="Bound">y≢x</a> <a id="4261" href="#4261" class="Bound">z≢x</a> <a id="4265" href="#4265" class="Bound">neq</a> <a id="4269" class="Symbol">=</a> <a id="4271" href="../code/fininj/Agda.Builtin.Unit.html#174" class="InductiveConstructor">tt</a>
<a id="4274" href="#4010" class="../code/fininj/Function">shift-inj</a> <a id="4284" class="Symbol">{</a><a id="4285" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4289" class="Symbol">_}</a> <a id="4292" class="Symbol">(</a><a id="4293" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4297" href="#4297" class="Bound">x</a><a id="4298" class="Symbol">)</a> <a id="4300" class="Symbol">(</a><a id="4301" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4305" href="#4305" class="Bound">y</a><a id="4306" class="Symbol">)</a> <a id="4308" class="Symbol">(</a><a id="4309" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4313" href="#4313" class="Bound">z</a><a id="4314" class="Symbol">)</a> <a id="4316" href="#4316" class="Bound">y≢x</a> <a id="4320" href="#4320" class="Bound">z≢x</a> <a id="4324" href="#4324" class="Bound">neq</a> <a id="4328" class="Symbol">=</a> <a id="4330" href="#4010" class="../code/fininj/Function">shift-inj</a> <a id="4340" href="#4297" class="Bound">x</a> <a id="4342" href="#4305" class="Bound">y</a> <a id="4344" href="#4313" class="Bound">z</a> <a id="4346" href="#4316" class="Bound">y≢x</a> <a id="4350" href="#4320" class="Bound">z≢x</a> <a id="4354" href="#4324" class="Bound">neq</a>

<a id="shrink"></a><a id="4359" href="#4359" class="../code/fininj/Function">shrink</a> <a id="4366" class="Symbol">:</a> <a id="4368" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4372" href="#963" class="Generalizable">n</a> <a id="4374" href="#3381" class="../code/fininj/Function Operator">F↣</a> <a id="4377" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4381" href="#965" class="Generalizable">m</a> <a id="4383" class="Symbol">→</a> <a id="4385" href="#963" class="Generalizable">n</a> <a id="4387" href="#3381" class="../code/fininj/Function Operator">F↣</a> <a id="4390" href="#965" class="Generalizable">m</a>
<a id="4392" href="#4359" class="../code/fininj/Function">shrink</a> <a id="4399" class="Symbol">(</a><a id="4400" href="#4400" class="Bound">f</a> <a id="4402" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="4404" href="#4404" class="Bound">inj</a><a id="4407" class="Symbol">)</a> <a id="4409" class="Symbol">.</a><a id="4410" href="../code/fininj/Agda.Builtin.Sigma.html#225" class="Field">proj₁</a> <a id="4416" href="#4416" class="Bound">x</a> <a id="4418" class="Symbol">=</a> <a id="4420" href="#3829" class="../code/fininj/Function">shift</a> <a id="4426" class="Symbol">(</a><a id="4427" href="#4400" class="Bound">f</a> <a id="4429" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a><a id="4433" class="Symbol">)</a> <a id="4435" class="Symbol">(</a><a id="4436" href="#4400" class="Bound">f</a> <a id="4438" class="Symbol">(</a><a id="4439" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4443" href="#4416" class="Bound">x</a><a id="4444" class="Symbol">))</a> <a id="4447" class="Symbol">(</a><a id="4448" href="#4404" class="Bound">inj</a> <a id="4452" href="../code/fininj/Agda.Builtin.Unit.html#174" class="InductiveConstructor">tt</a><a id="4454" class="Symbol">)</a>
<a id="4456" href="#4359" class="../code/fininj/Function">shrink</a> <a id="4463" class="Symbol">(</a><a id="4464" href="#4464" class="Bound">f</a> <a id="4466" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="4468" href="#4468" class="Bound">inj</a><a id="4471" class="Symbol">)</a> <a id="4473" class="Symbol">.</a><a id="4474" href="../code/fininj/Agda.Builtin.Sigma.html#237" class="Field">proj₂</a> <a id="4480" href="#4480" class="Bound">p</a> <a id="4482" class="Symbol">=</a> <a id="4484" href="#4010" class="../code/fininj/Function">shift-inj</a> <a id="4494" class="Symbol">(</a><a id="4495" href="#4464" class="Bound">f</a> <a id="4497" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a><a id="4501" class="Symbol">)</a> <a id="4503" class="Symbol">(</a><a id="4504" href="#4464" class="Bound">f</a> <a id="4506" class="Symbol">(</a><a id="4507" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4511" class="Symbol">_))</a> <a id="4515" class="Symbol">(</a><a id="4516" href="#4464" class="Bound">f</a> <a id="4518" class="Symbol">(</a><a id="4519" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="4523" class="Symbol">_))</a> <a id="4527" class="Symbol">(</a><a id="4528" href="#4468" class="Bound">inj</a> <a id="4532" href="../code/fininj/Agda.Builtin.Unit.html#174" class="InductiveConstructor">tt</a><a id="4534" class="Symbol">)</a> <a id="4536" class="Symbol">(</a><a id="4537" href="#4468" class="Bound">inj</a> <a id="4541" href="../code/fininj/Agda.Builtin.Unit.html#174" class="InductiveConstructor">tt</a><a id="4543" class="Symbol">)</a> <a id="4545" class="Symbol">(</a><a id="4546" href="#4468" class="Bound">inj</a> <a id="4550" href="#4480" class="Bound">p</a><a id="4551" class="Symbol">)</a>
</pre>
<p>This will give us the inductive step for the overall proof. Notice
the absence of any <code>cong</code>s or the like: the computation
behaviour of <code>≢ᶠ</code> saves us on that particular front. Also we
don’t have to use <code>⊥-elim</code> at any point: again, because of
the computation behaviour of <code>≢ᶠ</code>, Agda knows that certain
cases are unreachable, so we don’t even have to define them.</p>
<p>Next, we derive the proof that a <code>Fin</code> cannot inject into
a smaller <code>Fin</code>.</p>
<pre class="Agda"><a id="¬plus-inj"></a><a id="5006" href="#5006" class="../code/fininj/Function">¬plus-inj</a> <a id="5016" class="Symbol">:</a> <a id="5018" class="Symbol">∀</a> <a id="5020" href="#5020" class="Bound">n</a> <a id="5022" href="#5022" class="Bound">m</a> <a id="5024" class="Symbol">→</a> <a id="5026" href="../code/fininj/Relation.Nullary.html#653" class="../code/fininj/Function Operator">¬</a> <a id="5028" class="Symbol">(</a><a id="5029" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="5033" class="Symbol">(</a><a id="5034" href="#5020" class="Bound">n</a> <a id="5036" href="../code/fininj/Agda.Builtin.Nat.html#298" class="Primitive Operator">+</a> <a id="5038" href="#5022" class="Bound">m</a><a id="5039" class="Symbol">)</a> <a id="5041" href="#3381" class="../code/fininj/Function Operator">F↣</a> <a id="5044" href="#5022" class="Bound">m</a><a id="5045" class="Symbol">)</a>
<a id="5047" href="#5006" class="../code/fininj/Function">¬plus-inj</a> <a id="5057" href="../code/fininj/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>    <a id="5065" class="Symbol">(</a><a id="5066" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="5070" href="#5070" class="Bound">m</a><a id="5071" class="Symbol">)</a> <a id="5073" href="#5073" class="Bound">inj</a>       <a id="5083" class="Symbol">=</a> <a id="5085" href="#5006" class="../code/fininj/Function">¬plus-inj</a> <a id="5095" href="../code/fininj/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="5100" href="#5070" class="Bound">m</a> <a id="5102" class="Symbol">(</a><a id="5103" href="#4359" class="../code/fininj/Function">shrink</a> <a id="5110" href="#5073" class="Bound">inj</a><a id="5113" class="Symbol">)</a>
<a id="5115" href="#5006" class="../code/fininj/Function">¬plus-inj</a> <a id="5125" class="Symbol">(</a><a id="5126" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="5130" href="#5130" class="Bound">n</a><a id="5131" class="Symbol">)</a> <a id="5133" href="#5133" class="Bound">m</a>       <a id="5141" class="Symbol">(</a><a id="5142" href="#5142" class="Bound">f</a> <a id="5144" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="5146" href="#5146" class="Bound">inj</a><a id="5149" class="Symbol">)</a> <a id="5151" class="Symbol">=</a> <a id="5153" href="#5006" class="../code/fininj/Function">¬plus-inj</a> <a id="5163" href="#5130" class="Bound">n</a> <a id="5165" href="#5133" class="Bound">m</a> <a id="5167" class="Symbol">(</a><a id="5168" href="#5142" class="Bound">f</a> <a id="5170" href="../code/fininj/Function.Base.html#992" class="../code/fininj/Function Operator">∘</a> <a id="5172" href="../code/fininj/Data.Fin.Base.html#1114" class="InductiveConstructor">suc</a> <a id="5176" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="5178" href="#5146" class="Bound">inj</a><a id="5181" class="Symbol">)</a>
<a id="5183" href="#5006" class="../code/fininj/Function">¬plus-inj</a> <a id="5193" href="../code/fininj/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>    <a id="5201" href="../code/fininj/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>    <a id="5209" class="Symbol">(</a><a id="5210" href="#5210" class="Bound">f</a> <a id="5212" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="5214" class="Symbol">_)</a> <a id="5217" class="Keyword">with</a> <a id="5222" href="#5210" class="Bound">f</a> <a id="5224" href="../code/fininj/Data.Fin.Base.html#1083" class="InductiveConstructor">zero</a>
<a id="5229" class="Symbol">...</a> <a id="5233" class="Symbol">|</a> <a id="5235" class="Symbol">()</a>
</pre>
<p>That’s actually the bulk of the proof done: the rest is Lego, joining
up the pieces and types. First, we give the normal definition of
injectivity:</p>
<pre class="Agda"><a id="Injective"></a><a id="5400" href="#5400" class="../code/fininj/Function">Injective</a> <a id="5410" class="Symbol">:</a> <a id="5412" class="Symbol">∀</a> <a id="5414" class="Symbol">{</a><a id="5415" href="#5415" class="Bound">a</a> <a id="5417" href="#5417" class="Bound">b</a><a id="5418" class="Symbol">}</a> <a id="5420" class="Symbol">{</a><a id="5421" href="#5421" class="Bound">A</a> <a id="5423" class="Symbol">:</a> <a id="5425" class="PrimitiveType">Set</a> <a id="5429" href="#5415" class="Bound">a</a><a id="5430" class="Symbol">}</a> <a id="5432" class="Symbol">{</a><a id="5433" href="#5433" class="Bound">B</a> <a id="5435" class="Symbol">:</a> <a id="5437" class="PrimitiveType">Set</a> <a id="5441" href="#5417" class="Bound">b</a><a id="5442" class="Symbol">}</a> <a id="5444" class="Symbol">→</a> <a id="5446" class="Symbol">(</a><a id="5447" href="#5421" class="Bound">A</a> <a id="5449" class="Symbol">→</a> <a id="5451" href="#5433" class="Bound">B</a><a id="5452" class="Symbol">)</a> <a id="5454" class="Symbol">→</a> <a id="5456" class="PrimitiveType">Set</a> <a id="5460" class="Symbol">_</a>
<a id="5462" href="#5400" class="../code/fininj/Function">Injective</a> <a id="5472" href="#5472" class="Bound">f</a> <a id="5474" class="Symbol">=</a> <a id="5476" class="Symbol">∀</a> <a id="5478" class="Symbol">{</a><a id="5479" href="#5479" class="Bound">x</a> <a id="5481" href="#5481" class="Bound">y</a><a id="5482" class="Symbol">}</a> <a id="5484" class="Symbol">→</a> <a id="5486" href="#5472" class="Bound">f</a> <a id="5488" href="#5479" class="Bound">x</a> <a id="5490" href="../code/fininj/Agda.Builtin.Equality.html#125" class="Datatype Operator">≡</a> <a id="5492" href="#5472" class="Bound">f</a> <a id="5494" href="#5481" class="Bound">y</a> <a id="5496" class="Symbol">→</a> <a id="5498" href="#5479" class="Bound">x</a> <a id="5500" href="../code/fininj/Agda.Builtin.Equality.html#125" class="Datatype Operator">≡</a> <a id="5502" href="#5481" class="Bound">y</a>

<a id="_↣_"></a><a id="5505" href="#5505" class="../code/fininj/Function Operator">_↣_</a> <a id="5509" class="Symbol">:</a> <a id="5511" class="Symbol">∀</a> <a id="5513" class="Symbol">{</a><a id="5514" href="#5514" class="Bound">a</a> <a id="5516" href="#5516" class="Bound">b</a><a id="5517" class="Symbol">}</a> <a id="5519" class="Symbol">→</a> <a id="5521" class="PrimitiveType">Set</a> <a id="5525" href="#5514" class="Bound">a</a> <a id="5527" class="Symbol">→</a> <a id="5529" class="PrimitiveType">Set</a> <a id="5533" href="#5516" class="Bound">b</a> <a id="5535" class="Symbol">→</a> <a id="5537" class="PrimitiveType">Set</a> <a id="5541" class="Symbol">_</a>
<a id="5543" href="#5543" class="Bound">A</a> <a id="5545" href="#5505" class="../code/fininj/Function Operator">↣</a> <a id="5547" href="#5547" class="Bound">B</a> <a id="5549" class="Symbol">=</a> <a id="5551" href="../code/fininj/Agda.Builtin.Sigma.html#139" class="Record">Σ</a> <a id="5553" class="Symbol">(</a><a id="5554" href="#5543" class="Bound">A</a> <a id="5556" class="Symbol">→</a> <a id="5558" href="#5547" class="Bound">B</a><a id="5559" class="Symbol">)</a> <a id="5561" href="#5400" class="../code/fininj/Function">Injective</a>
</pre>
<p>Then we convert from one to the other:</p>
<pre class="Agda"><a id="toFin-inj"></a><a id="5624" href="#5624" class="../code/fininj/Function">toFin-inj</a> <a id="5634" class="Symbol">:</a> <a id="5636" class="Symbol">(</a><a id="5637" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="5641" href="#963" class="Generalizable">n</a> <a id="5643" href="#5505" class="../code/fininj/Function Operator">↣</a> <a id="5645" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="5649" href="#965" class="Generalizable">m</a><a id="5650" class="Symbol">)</a> <a id="5652" class="Symbol">→</a> <a id="5654" href="#963" class="Generalizable">n</a> <a id="5656" href="#3381" class="../code/fininj/Function Operator">F↣</a> <a id="5659" href="#965" class="Generalizable">m</a>
<a id="5661" href="#5624" class="../code/fininj/Function">toFin-inj</a> <a id="5671" href="#5671" class="Bound">f</a> <a id="5673" class="Symbol">.</a><a id="5674" href="../code/fininj/Agda.Builtin.Sigma.html#225" class="Field">proj₁</a> <a id="5680" class="Symbol">=</a> <a id="5682" href="#5671" class="Bound">f</a> <a id="5684" class="Symbol">.</a><a id="5685" href="../code/fininj/Agda.Builtin.Sigma.html#225" class="Field">proj₁</a>
<a id="5691" href="#5624" class="../code/fininj/Function">toFin-inj</a> <a id="5701" class="Symbol">(</a><a id="5702" href="#5702" class="Bound">f</a> <a id="5704" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="5706" href="#5706" class="Bound">inj</a><a id="5709" class="Symbol">)</a> <a id="5711" class="Symbol">.</a><a id="5712" href="../code/fininj/Agda.Builtin.Sigma.html#237" class="Field">proj₂</a> <a id="5718" class="Symbol">{</a><a id="5719" href="#5719" class="Bound">x</a><a id="5720" class="Symbol">}</a> <a id="5722" class="Symbol">{</a><a id="5723" href="#5723" class="Bound">y</a><a id="5724" class="Symbol">}</a> <a id="5726" href="#5726" class="Bound">x≢ᶠy</a> <a id="5731" class="Keyword">with</a> <a id="5736" href="#5719" class="Bound">x</a> <a id="5738" href="../code/fininj/Data.Fin.Properties.html#1997" class="../code/fininj/Function Operator">≟</a> <a id="5740" href="#5723" class="Bound">y</a> <a id="5742" class="Symbol">|</a> <a id="5744" href="#5702" class="Bound">f</a> <a id="5746" href="#5719" class="Bound">x</a> <a id="5748" href="../code/fininj/Data.Fin.Properties.html#1997" class="../code/fininj/Function Operator">≟</a> <a id="5750" href="#5702" class="Bound">f</a> <a id="5752" href="#5723" class="Bound">y</a>
<a id="5754" class="Symbol">...</a> <a id="5758" class="Symbol">|</a> <a id="5760" href="../code/fininj/Relation.Nullary.html#1682" class="InductiveConstructor">no</a> <a id="5763" href="#5763" class="Bound">¬p</a> <a id="5766" class="Symbol">|</a> <a id="5768" href="../code/fininj/Relation.Nullary.html#1645" class="InductiveConstructor">yes</a> <a id="5772" href="#5772" class="Bound">p</a> <a id="5774" class="Symbol">=</a> <a id="5776" href="#5763" class="Bound">¬p</a> <a id="5779" class="Symbol">(</a><a id="5780" class="Bound">inj</a> <a id="5784" href="#5772" class="Bound">p</a><a id="5785" class="Symbol">)</a>
<a id="5787" class="Symbol">...</a> <a id="5791" class="Symbol">|</a> <a id="5793" href="../code/fininj/Relation.Nullary.html#1682" class="InductiveConstructor">no</a> <a id="5796" class="Symbol">_</a>  <a id="5799" class="Symbol">|</a> <a id="5801" href="../code/fininj/Relation.Nullary.html#1682" class="InductiveConstructor">no</a> <a id="5804" class="Symbol">_</a>  <a id="5807" class="Symbol">=</a> <a id="5809" href="../code/fininj/Agda.Builtin.Unit.html#174" class="InductiveConstructor">tt</a>
</pre>
<p>And finally we have our proof:</p>
<pre class="Agda"><a id="n≢sn+m"></a><a id="5857" href="#5857" class="../code/fininj/Function">n≢sn+m</a> <a id="5864" class="Symbol">:</a> <a id="5866" class="Symbol">∀</a> <a id="5868" href="#5868" class="Bound">n</a> <a id="5870" href="#5870" class="Bound">m</a> <a id="5872" class="Symbol">→</a> <a id="5874" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="5878" href="#5868" class="Bound">n</a> <a id="5880" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#840" class="../code/fininj/Function Operator">≢</a> <a id="5882" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="5886" class="Symbol">(</a><a id="5887" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="5891" class="Symbol">(</a><a id="5892" href="#5868" class="Bound">n</a> <a id="5894" href="../code/fininj/Agda.Builtin.Nat.html#298" class="Primitive Operator">+</a> <a id="5896" href="#5870" class="Bound">m</a><a id="5897" class="Symbol">))</a>
<a id="5900" href="#5857" class="../code/fininj/Function">n≢sn+m</a> <a id="5907" href="#5907" class="Bound">n</a> <a id="5909" href="#5909" class="Bound">m</a> <a id="5911" href="#5911" class="Bound">n≡m</a> <a id="5915" class="Symbol">=</a>
  <a id="5919" href="#5006" class="../code/fininj/Function">¬plus-inj</a> <a id="5929" href="#5909" class="Bound">m</a> <a id="5931" href="#5907" class="Bound">n</a> <a id="5933" class="Symbol">(</a><a id="5934" href="#5624" class="../code/fininj/Function">toFin-inj</a> <a id="5944" class="Symbol">(</a><a id="5945" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#1076" class="../code/fininj/Function">subst</a> <a id="5951" class="Symbol">(</a><a id="5952" href="#5505" class="../code/fininj/Function Operator">_↣</a> <a id="5955" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="5959" href="#5907" class="Bound">n</a><a id="5960" class="Symbol">)</a>
                             <a id="5991" class="Symbol">(</a><a id="5992" href="#5911" class="Bound">n≡m</a> <a id="5996" href="../code/fininj/Function.Base.html#3828" class="../code/fininj/Function Operator">⟨</a> <a id="5998" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#1025" class="../code/fininj/Function">trans</a> <a id="6004" href="../code/fininj/Function.Base.html#3828" class="../code/fininj/Function Operator">⟩</a> <a id="6006" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#1131" class="../code/fininj/Function">cong</a> <a id="6011" class="Symbol">(</a><a id="6012" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a> <a id="6016" href="../code/fininj/Function.Base.html#992" class="../code/fininj/Function Operator">∘</a> <a id="6018" href="../code/fininj/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="6021" class="Symbol">)</a> <a id="6023" class="Symbol">(</a><a id="6024" href="../code/fininj/Data.Nat.Properties.html#12828" class="../code/fininj/Function">+-comm</a> <a id="6031" href="#5907" class="Bound">n</a> <a id="6033" href="#5909" class="Bound">m</a><a id="6034" class="Symbol">))</a>
                             <a id="6066" class="Symbol">(</a><a id="6067" href="../code/fininj/Function.Base.html#615" class="../code/fininj/Function">id</a> <a id="6070" href="../code/fininj/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="6072" href="../code/fininj/Function.Base.html#615" class="../code/fininj/Function">id</a><a id="6074" class="Symbol">)))</a>

<a id="Fin-inj"></a><a id="6079" href="#6079" class="../code/fininj/Function">Fin-inj</a> <a id="6087" class="Symbol">:</a> <a id="6089" href="#5400" class="../code/fininj/Function">Injective</a> <a id="6099" href="../code/fininj/Data.Fin.Base.html#1061" class="Datatype">Fin</a>
<a id="6103" href="#6079" class="../code/fininj/Function">Fin-inj</a> <a id="6111" class="Symbol">{</a><a id="6112" href="#6112" class="Bound">n</a><a id="6113" class="Symbol">}</a> <a id="6115" class="Symbol">{</a><a id="6116" href="#6116" class="Bound">m</a><a id="6117" class="Symbol">}</a> <a id="6119" href="#6119" class="Bound">n≡m</a> <a id="6123" class="Keyword">with</a> <a id="6128" href="../code/fininj/Data.Nat.Base.html#3697" class="../code/fininj/Function">compare</a> <a id="6136" href="#6112" class="Bound">n</a> <a id="6138" href="#6116" class="Bound">m</a>
<a id="6140" class="Symbol">...</a> <a id="6144" class="Symbol">|</a> <a id="6146" href="../code/fininj/Data.Nat.Base.html#3620" class="InductiveConstructor">equal</a> <a id="6152" class="Symbol">_</a> <a id="6154" class="Symbol">=</a> <a id="6156" href="../code/fininj/Agda.Builtin.Equality.html#182" class="InductiveConstructor">refl</a>
<a id="6161" class="Symbol">...</a> <a id="6165" class="Symbol">|</a> <a id="6167" href="../code/fininj/Data.Nat.Base.html#3575" class="InductiveConstructor">less</a>    <a id="6175" class="Bound">n</a> <a id="6177" href="#6177" class="Bound">k</a> <a id="6179" class="Symbol">=</a> <a id="6181" href="../code/fininj/Data.Empty.html#275" class="../code/fininj/Function">⊥-elim</a> <a id="6188" class="Symbol">(</a><a id="6189" href="#5857" class="../code/fininj/Function">n≢sn+m</a> <a id="6196" class="Bound">n</a> <a id="6198" href="#6177" class="Bound">k</a> <a id="6200" class="Bound">n≡m</a><a id="6203" class="Symbol">)</a>
<a id="6205" class="Symbol">...</a> <a id="6209" class="Symbol">|</a> <a id="6211" href="../code/fininj/Data.Nat.Base.html#3653" class="InductiveConstructor">greater</a> <a id="6219" class="Bound">m</a> <a id="6221" href="#6221" class="Bound">k</a> <a id="6223" class="Symbol">=</a> <a id="6225" href="../code/fininj/Data.Empty.html#275" class="../code/fininj/Function">⊥-elim</a> <a id="6232" class="Symbol">(</a><a id="6233" href="#5857" class="../code/fininj/Function">n≢sn+m</a> <a id="6240" class="Bound">m</a> <a id="6242" href="#6221" class="Bound">k</a> <a id="6244" class="Symbol">(</a><a id="6245" href="../code/fininj/Relation.Binary.PropositionalEquality.Core.html#980" class="../code/fininj/Function">sym</a> <a id="6249" class="Bound">n≡m</a><a id="6252" class="Symbol">))</a>

<a id="6256" href="#6256" class="../code/fininj/Function">_</a> <a id="6258" class="Symbol">:</a> <a id="6260" href="#1153" class="../code/fininj/Function">Goal</a>
<a id="6265" class="Symbol">_</a> <a id="6267" class="Symbol">=</a> <a id="6269" href="#6079" class="../code/fininj/Function">Fin-inj</a>
</pre>
<p>All in all, the proof is about 36 lines, which is pretty short for
what it does.</p>
]]></description>
    <pubDate>Fri, 15 Nov 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-11-15-small-proof-fin-inj.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>How to do Binary Random-Access Lists Simply</title>
    <link>https://doisinkidney.com/posts/2019-11-02-how-to-binary-random-access-list.html</link>
    <description><![CDATA[<div class="info">
    Posted on November  2, 2019
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Random%20Access%20Lists.html">2-part series on Random Access Lists</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>“Heterogeneous Random-Access Lists” by Wouter Swierstra <span
class="citation"
data-cites="swierstraHeterogeneousRandomaccessLists2019">(<a
href="#ref-swierstraHeterogeneousRandomaccessLists2019"
role="doc-biblioref">2019</a>)</span> describes how to write a simple
binary random-access list <span class="citation"
data-cites="okasakiPurelyFunctionalRandomaccess1995">(<a
href="#ref-okasakiPurelyFunctionalRandomaccess1995"
role="doc-biblioref">Okasaki 1995</a>)</span> to use as a heterogeneous
tuple. If you haven’t tried to implement the data structure described in
the paper before, you might not realise the just how <em>elegant</em>
the implementation is. The truth is that arriving at the definitions
presented is difficult: behind every simple function is a litany of
complex and ugly alternatives that had to be tried and discarded first
before settling on the final answer.</p>
<p>In this post I want to go through a very similar structure, with
special focus on the “wrong turns” in implementation which can lead to
headache.</p>
<!--
<pre class="Agda"><a id="768" class="Symbol">{-#</a> <a id="772" class="Keyword">OPTIONS</a> <a id="780" class="Pragma">--cubical</a> <a id="790" class="Pragma">--safe</a> <a id="797" class="Symbol">#-}</a>

<a id="802" class="Keyword">open</a> <a id="807" class="Keyword">import</a> <a id="814" href="../code/binary/Prelude.html" class="Module">Prelude</a>

<a id="823" class="Keyword">variable</a>
  <a id="834" href="#834" class="Generalizable">t</a> <a id="836" class="Symbol">:</a> <a id="838" href="../code/binary/Agda.Primitive.html#408" class="Postulate">Level</a>
  <a id="846" href="#846" class="Generalizable">T</a> <a id="848" class="Symbol">:</a> <a id="850" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="852" class="Symbol">→</a> <a id="854" class="PrimitiveType">Set</a> <a id="858" href="#834" class="Generalizable">t</a>
  <a id="862" href="#862" class="Generalizable">p</a> <a id="864" class="Symbol">:</a> <a id="866" href="../code/binary/Agda.Primitive.html#408" class="Postulate">Level</a>
  <a id="874" href="#874" class="Generalizable">P</a> <a id="876" class="Symbol">:</a> <a id="878" class="PrimitiveType">Set</a> <a id="882" href="#862" class="Generalizable">p</a>
</pre>-->
<h1 id="two-proofs-on-ℕ-and-how-to-avoid-them">Two Proofs on ℕ, and How
to Avoid Them</h1>
<p>Here are a couple of important identities on ℕ:</p>
<pre class="Agda"><a id="+0"></a><a id="992" href="#992" class="Function">+0</a> <a id="995" class="Symbol">:</a> <a id="997" class="Symbol">∀</a> <a id="999" href="#999" class="Bound">n</a> <a id="1001" class="Symbol">→</a> <a id="1003" href="#999" class="Bound">n</a> <a id="1005" href="../code/binary/Agda.Builtin.Nat.html#298" class="Primitive Operator">+</a> <a id="1007" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="1012" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="1014" href="#999" class="Bound">n</a>
<a id="1016" href="#992" class="Function">+0</a> <a id="1019" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>    <a id="1027" class="Symbol">=</a> <a id="1029" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="1034" href="#992" class="Function">+0</a> <a id="1037" class="Symbol">(</a><a id="1038" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="1042" href="#1042" class="Bound">n</a><a id="1043" class="Symbol">)</a> <a id="1045" class="Symbol">=</a> <a id="1047" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="1052" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="1056" class="Symbol">(</a><a id="1057" href="#992" class="Function">+0</a> <a id="1060" href="#1042" class="Bound">n</a><a id="1061" class="Symbol">)</a>

<a id="+-suc"></a><a id="1064" href="#1064" class="Function">+-suc</a> <a id="1070" class="Symbol">:</a> <a id="1072" class="Symbol">∀</a> <a id="1074" href="#1074" class="Bound">n</a> <a id="1076" href="#1076" class="Bound">m</a> <a id="1078" class="Symbol">→</a> <a id="1080" href="#1074" class="Bound">n</a> <a id="1082" href="../code/binary/Agda.Builtin.Nat.html#298" class="Primitive Operator">+</a> <a id="1084" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="1088" href="#1076" class="Bound">m</a> <a id="1090" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="1092" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="1096" href="#1074" class="Bound">n</a> <a id="1098" href="../code/binary/Agda.Builtin.Nat.html#298" class="Primitive Operator">+</a> <a id="1100" href="#1076" class="Bound">m</a>
<a id="1102" href="#1064" class="Function">+-suc</a> <a id="1108" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>    <a id="1116" href="#1116" class="Bound">m</a> <a id="1118" class="Symbol">=</a> <a id="1120" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="1125" href="#1064" class="Function">+-suc</a> <a id="1131" class="Symbol">(</a><a id="1132" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="1136" href="#1136" class="Bound">n</a><a id="1137" class="Symbol">)</a> <a id="1139" href="#1139" class="Bound">m</a> <a id="1141" class="Symbol">=</a> <a id="1143" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="1148" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="1152" class="Symbol">(</a><a id="1153" href="#1064" class="Function">+-suc</a> <a id="1159" href="#1136" class="Bound">n</a> <a id="1161" href="#1139" class="Bound">m</a><a id="1162" class="Symbol">)</a>
</pre>
<p>These two show up all the time as proof obligations from the compiler
(i.e. “couldn’t match type <code>n + suc m</code> with
<code>suc n + m</code>”). The solution is obvious, right?
<code>subst</code> in one of the proofs above and you’re on your way.
Wait! There might be a better way.</p>
<p>We’re going to look at reversing a vector as an example. We have a
normal-looking length-indexed vector:</p>
<pre class="Agda"><a id="1539" class="Keyword">infixr</a> <a id="1546" class="Number">5</a> <a id="1548" href="#7886" class="InductiveConstructor Operator">_∷_</a>
<a id="1552" class="Keyword">data</a> <a id="Vec"></a><a id="1557" href="#1557" class="Datatype">Vec</a> <a id="1561" class="Symbol">(</a><a id="1562" href="#1562" class="Bound">A</a> <a id="1564" class="Symbol">:</a> <a id="1566" class="PrimitiveType">Set</a> <a id="1570" href="../code/binary/Prelude.html#454" class="Generalizable">a</a><a id="1571" class="Symbol">)</a> <a id="1573" class="Symbol">:</a> <a id="1575" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="1577" class="Symbol">→</a> <a id="1579" class="PrimitiveType">Set</a> <a id="1583" href="#1570" class="Bound">a</a> <a id="1585" class="Keyword">where</a>
  <a id="Vec.[]"></a><a id="1593" href="#1593" class="InductiveConstructor">[]</a> <a id="1596" class="Symbol">:</a> <a id="1598" href="#1557" class="Datatype">Vec</a> <a id="1602" href="#1562" class="Bound">A</a> <a id="1604" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>
  <a id="Vec._∷_"></a><a id="1611" href="#1611" class="InductiveConstructor Operator">_∷_</a> <a id="1615" class="Symbol">:</a> <a id="1617" href="#1562" class="Bound">A</a> <a id="1619" class="Symbol">→</a> <a id="1621" href="#1557" class="Datatype">Vec</a> <a id="1625" href="#1562" class="Bound">A</a> <a id="1627" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="1629" class="Symbol">→</a> <a id="1631" href="#1557" class="Datatype">Vec</a> <a id="1635" href="#1562" class="Bound">A</a> <a id="1637" class="Symbol">(</a><a id="1638" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="1642" href="../code/binary/Prelude.html#506" class="Generalizable">n</a><a id="1643" class="Symbol">)</a>
</pre>
<p>Reversing a list is easy: we do it the standard way, in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
time, with an accumulator:</p>
<pre class="Agda"><a id="list-reverse"></a><a id="1759" href="#1759" class="Function">list-reverse</a> <a id="1772" class="Symbol">:</a> <a id="1774" href="../code/binary/Prelude.html#760" class="Datatype">List</a> <a id="1779" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="1781" class="Symbol">→</a> <a id="1783" href="../code/binary/Prelude.html#760" class="Datatype">List</a> <a id="1788" href="../code/binary/Prelude.html#470" class="Generalizable">A</a>
<a id="1790" href="#1759" class="Function">list-reverse</a> <a id="1803" class="Symbol">=</a> <a id="1805" href="#1821" class="Function">go</a> <a id="1808" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a>
  <a id="1813" class="Keyword">where</a>
  <a id="1821" href="#1821" class="Function">go</a> <a id="1824" class="Symbol">:</a> <a id="1826" href="../code/binary/Prelude.html#760" class="Datatype">List</a> <a id="1831" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="1833" class="Symbol">→</a> <a id="1835" href="../code/binary/Prelude.html#760" class="Datatype">List</a> <a id="1840" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="1842" class="Symbol">→</a> <a id="1844" href="../code/binary/Prelude.html#760" class="Datatype">List</a> <a id="1849" href="../code/binary/Prelude.html#470" class="Generalizable">A</a>
  <a id="1853" href="#1821" class="Function">go</a> <a id="1856" href="#1856" class="Bound">acc</a> <a id="1860" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a> <a id="1863" class="Symbol">=</a> <a id="1865" href="#1856" class="Bound">acc</a>
  <a id="1871" href="#1821" class="Function">go</a> <a id="1874" href="#1874" class="Bound">acc</a> <a id="1878" class="Symbol">(</a><a id="1879" href="#1879" class="Bound">x</a> <a id="1881" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="1883" href="#1883" class="Bound">xs</a><a id="1885" class="Symbol">)</a> <a id="1887" class="Symbol">=</a> <a id="1889" href="#1821" class="Function">go</a> <a id="1892" class="Symbol">(</a><a id="1893" href="#1879" class="Bound">x</a> <a id="1895" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="1897" href="#1874" class="Bound">acc</a><a id="1900" class="Symbol">)</a> <a id="1902" href="#1883" class="Bound">xs</a>
</pre>
<p>Transferring over to a vector and we see our friends
<code>+-suc</code> and <code>+0</code>.</p>
<pre class="Agda"><a id="vec-reverse₁"></a><a id="1990" href="#1990" class="Function">vec-reverse₁</a> <a id="2003" class="Symbol">:</a> <a id="2005" href="#1557" class="Datatype">Vec</a> <a id="2009" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2011" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="2013" class="Symbol">→</a> <a id="2015" href="#1557" class="Datatype">Vec</a> <a id="2019" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2021" href="../code/binary/Prelude.html#506" class="Generalizable">n</a>
<a id="2023" href="#1990" class="Function">vec-reverse₁</a> <a id="2036" href="#2036" class="Bound">xs</a> <a id="2039" class="Symbol">=</a> <a id="2041" href="../code/binary/Cubical.Foundations.Prelude.html#4264" class="Function">subst</a> <a id="2047" class="Symbol">(</a><a id="2048" href="#1557" class="Datatype">Vec</a> <a id="2052" class="Symbol">_)</a> <a id="2055" class="Symbol">(</a><a id="2056" href="#992" class="Function">+0</a> <a id="2059" class="Symbol">_)</a> <a id="2062" class="Symbol">(</a><a id="2063" href="#2083" class="Function">go</a> <a id="2066" href="#1593" class="InductiveConstructor">[]</a> <a id="2069" href="#2036" class="Bound">xs</a><a id="2071" class="Symbol">)</a>
  <a id="2075" class="Keyword">where</a>
  <a id="2083" href="#2083" class="Function">go</a> <a id="2086" class="Symbol">:</a> <a id="2088" href="#1557" class="Datatype">Vec</a> <a id="2092" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2094" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="2096" class="Symbol">→</a> <a id="2098" href="#1557" class="Datatype">Vec</a> <a id="2102" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2104" href="../code/binary/Prelude.html#508" class="Generalizable">m</a> <a id="2106" class="Symbol">→</a> <a id="2108" href="#1557" class="Datatype">Vec</a> <a id="2112" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2114" class="Symbol">(</a><a id="2115" href="../code/binary/Prelude.html#508" class="Generalizable">m</a> <a id="2117" href="../code/binary/Agda.Builtin.Nat.html#298" class="Primitive Operator">+</a> <a id="2119" href="../code/binary/Prelude.html#506" class="Generalizable">n</a><a id="2120" class="Symbol">)</a>
  <a id="2124" href="#2083" class="Function">go</a> <a id="2127" href="#2127" class="Bound">acc</a> <a id="2131" href="#1593" class="InductiveConstructor">[]</a> <a id="2134" class="Symbol">=</a> <a id="2136" href="#2127" class="Bound">acc</a>
  <a id="2142" href="#2083" class="Function">go</a> <a id="2145" href="#2145" class="Bound">acc</a> <a id="2149" class="Symbol">(</a><a id="2150" href="#2150" class="Bound">x</a> <a id="2152" href="#1611" class="InductiveConstructor Operator">∷</a> <a id="2154" href="#2154" class="Bound">xs</a><a id="2156" class="Symbol">)</a> <a id="2158" class="Symbol">=</a> <a id="2160" href="../code/binary/Cubical.Foundations.Prelude.html#4264" class="Function">subst</a> <a id="2166" class="Symbol">(</a><a id="2167" href="#1557" class="Datatype">Vec</a> <a id="2171" class="Symbol">_)</a> <a id="2174" class="Symbol">(</a><a id="2175" href="#1064" class="Function">+-suc</a> <a id="2181" class="Symbol">_</a> <a id="2183" class="Symbol">_)</a> <a id="2186" class="Symbol">(</a><a id="2187" href="#2083" class="Function">go</a> <a id="2190" class="Symbol">(</a><a id="2191" href="#2150" class="Bound">x</a> <a id="2193" href="#1611" class="InductiveConstructor Operator">∷</a> <a id="2195" href="#2145" class="Bound">acc</a><a id="2198" class="Symbol">)</a> <a id="2200" href="#2154" class="Bound">xs</a><a id="2202" class="Symbol">)</a>
</pre>
<p>The solution, as with so many things, is to use a fold instead of
explicit recursion. Folds on vectors are a little more aggressively
typed than those on lists:</p>
<pre class="Agda"><a id="vec-foldr"></a><a id="2378" href="#2378" class="Function">vec-foldr</a> <a id="2388" class="Symbol">:</a> <a id="2390" class="Symbol">(</a><a id="2391" href="#2391" class="Bound">B</a> <a id="2393" class="Symbol">:</a> <a id="2395" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="2397" class="Symbol">→</a> <a id="2399" href="../code/binary/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="2404" href="../code/binary/Prelude.html#456" class="Generalizable">b</a><a id="2405" class="Symbol">)</a>
          <a id="2417" class="Symbol">→</a> <a id="2419" class="Symbol">(∀</a> <a id="2422" class="Symbol">{</a><a id="2423" href="#2423" class="Bound">n</a><a id="2424" class="Symbol">}</a> <a id="2426" class="Symbol">→</a> <a id="2428" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2430" class="Symbol">→</a> <a id="2432" href="#2391" class="Bound">B</a> <a id="2434" href="#2423" class="Bound">n</a> <a id="2436" class="Symbol">→</a> <a id="2438" href="#2391" class="Bound">B</a> <a id="2440" class="Symbol">(</a><a id="2441" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="2445" href="#2423" class="Bound">n</a><a id="2446" class="Symbol">))</a>
          <a id="2459" class="Symbol">→</a> <a id="2461" href="#2391" class="Bound">B</a> <a id="2463" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>
          <a id="2478" class="Symbol">→</a> <a id="2480" href="#1557" class="Datatype">Vec</a> <a id="2484" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2486" href="../code/binary/Prelude.html#506" class="Generalizable">n</a>
          <a id="2498" class="Symbol">→</a> <a id="2500" href="#2391" class="Bound">B</a> <a id="2502" href="../code/binary/Prelude.html#506" class="Generalizable">n</a>
<a id="2504" href="#2378" class="Function">vec-foldr</a> <a id="2514" href="#2514" class="Bound">B</a> <a id="2516" href="#2516" class="Bound">f</a> <a id="2518" href="#2518" class="Bound">b</a> <a id="2520" href="#1593" class="InductiveConstructor">[]</a> <a id="2523" class="Symbol">=</a> <a id="2525" href="#2518" class="Bound">b</a>
<a id="2527" href="#2378" class="Function">vec-foldr</a> <a id="2537" href="#2537" class="Bound">B</a> <a id="2539" href="#2539" class="Bound">f</a> <a id="2541" href="#2541" class="Bound">b</a> <a id="2543" class="Symbol">(</a><a id="2544" href="#2544" class="Bound">x</a> <a id="2546" href="#1611" class="InductiveConstructor Operator">∷</a> <a id="2548" href="#2548" class="Bound">xs</a><a id="2550" class="Symbol">)</a> <a id="2552" class="Symbol">=</a> <a id="2554" href="#2539" class="Bound">f</a> <a id="2556" href="#2544" class="Bound">x</a> <a id="2558" class="Symbol">(</a><a id="2559" href="#2378" class="Function">vec-foldr</a> <a id="2569" href="#2537" class="Bound">B</a> <a id="2571" href="#2539" class="Bound">f</a> <a id="2573" href="#2541" class="Bound">b</a> <a id="2575" href="#2548" class="Bound">xs</a><a id="2577" class="Symbol">)</a>
</pre>
<p>We allow the output type to be indexed by the list of the vector.
This is a good thing, bear in mind: we need that extra information to
properly type <code>reverse</code>.</p>
<p>For reverse, unfortunately, we need a <em>left</em>-leaning fold,
which is a little trickier to implement than <code>vec-foldr</code>.</p>
<pre class="Agda"><a id="vec-foldl"></a><a id="2872" href="#2872" class="Function">vec-foldl</a> <a id="2882" class="Symbol">:</a> <a id="2884" class="Symbol">(</a><a id="2885" href="#2885" class="Bound">B</a> <a id="2887" class="Symbol">:</a> <a id="2889" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="2891" class="Symbol">→</a> <a id="2893" class="PrimitiveType">Set</a> <a id="2897" href="../code/binary/Prelude.html#456" class="Generalizable">b</a><a id="2898" class="Symbol">)</a>
          <a id="2910" class="Symbol">→</a> <a id="2912" class="Symbol">(∀</a> <a id="2915" class="Symbol">{</a><a id="2916" href="#2916" class="Bound">n</a><a id="2917" class="Symbol">}</a> <a id="2919" class="Symbol">→</a> <a id="2921" href="#2885" class="Bound">B</a> <a id="2923" href="#2916" class="Bound">n</a> <a id="2925" class="Symbol">→</a> <a id="2927" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2929" class="Symbol">→</a> <a id="2931" href="#2885" class="Bound">B</a> <a id="2933" class="Symbol">(</a><a id="2934" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="2938" href="#2916" class="Bound">n</a><a id="2939" class="Symbol">))</a>
          <a id="2952" class="Symbol">→</a> <a id="2954" href="#2885" class="Bound">B</a> <a id="2956" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>
          <a id="2971" class="Symbol">→</a> <a id="2973" href="#1557" class="Datatype">Vec</a> <a id="2977" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="2979" href="../code/binary/Prelude.html#506" class="Generalizable">n</a>
          <a id="2991" class="Symbol">→</a> <a id="2993" href="#2885" class="Bound">B</a> <a id="2995" href="../code/binary/Prelude.html#506" class="Generalizable">n</a>
<a id="2997" href="#2872" class="Function">vec-foldl</a> <a id="3007" href="#3007" class="Bound">B</a> <a id="3009" href="#3009" class="Bound">f</a> <a id="3011" href="#3011" class="Bound">b</a> <a id="3013" href="#1593" class="InductiveConstructor">[]</a> <a id="3016" class="Symbol">=</a> <a id="3018" href="#3011" class="Bound">b</a>
<a id="3020" href="#2872" class="Function">vec-foldl</a> <a id="3030" href="#3030" class="Bound">B</a> <a id="3032" href="#3032" class="Bound">f</a> <a id="3034" href="#3034" class="Bound">b</a> <a id="3036" class="Symbol">(</a><a id="3037" href="#3037" class="Bound">x</a> <a id="3039" href="#1611" class="InductiveConstructor Operator">∷</a> <a id="3041" href="#3041" class="Bound">xs</a><a id="3043" class="Symbol">)</a> <a id="3045" class="Symbol">=</a> <a id="3047" href="#2872" class="Function">vec-foldl</a> <a id="3057" class="Symbol">(</a><a id="3058" href="#3030" class="Bound">B</a> <a id="3060" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="3062" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="3065" class="Symbol">)</a> <a id="3067" href="#3032" class="Bound">f</a> <a id="3069" class="Symbol">(</a><a id="3070" href="#3032" class="Bound">f</a> <a id="3072" href="#3034" class="Bound">b</a> <a id="3074" href="#3037" class="Bound">x</a><a id="3075" class="Symbol">)</a> <a id="3077" href="#3041" class="Bound">xs</a>
</pre>
<p>With this we can finally <code>reverse</code>.</p>
<pre class="Agda"><a id="vec-reverse"></a><a id="3130" href="#3130" class="Function">vec-reverse</a> <a id="3142" class="Symbol">:</a> <a id="3144" href="#1557" class="Datatype">Vec</a> <a id="3148" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="3150" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="3152" class="Symbol">→</a> <a id="3154" href="#1557" class="Datatype">Vec</a> <a id="3158" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="3160" href="../code/binary/Prelude.html#506" class="Generalizable">n</a>
<a id="3162" href="#3130" class="Function">vec-reverse</a> <a id="3174" class="Symbol">=</a> <a id="3176" href="#2872" class="Function">vec-foldl</a> <a id="3186" class="Symbol">(</a><a id="3187" href="#1557" class="Datatype">Vec</a> <a id="3191" class="Symbol">_)</a> <a id="3194" class="Symbol">(λ</a> <a id="3197" href="#3197" class="Bound">xs</a> <a id="3200" href="#3200" class="Bound">x</a> <a id="3202" class="Symbol">→</a> <a id="3204" href="#3200" class="Bound">x</a> <a id="3206" href="#1611" class="InductiveConstructor Operator">∷</a> <a id="3208" href="#3197" class="Bound">xs</a><a id="3210" class="Symbol">)</a> <a id="3212" href="#1593" class="InductiveConstructor">[]</a>
</pre>
<p>The real trick in this function is that the type of the return value
changes as we fold. If you think about it, it’s the same optimisation
that we make for the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
reverse on lists: the <code>B</code> type above is the “difference list”
in types, allowing us to append on to the end without
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>
proofs.</p>
<p>As an aside, this same trick can let us type the convolve-TABA <span
class="citation"
data-cites="danvyThereBackAgain2005 fonerThereBackAgain2016">(<a
href="#ref-danvyThereBackAgain2005" role="doc-biblioref">Danvy and
Goldberg 2005</a>; <a href="#ref-fonerThereBackAgain2016"
role="doc-biblioref">Foner 2016</a>)</span> function quite simply:</p>
<pre class="Agda"><a id="convolve"></a><a id="3636" href="#3636" class="Function">convolve</a> <a id="3645" class="Symbol">:</a> <a id="3647" href="#1557" class="Datatype">Vec</a> <a id="3651" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="3653" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="3655" class="Symbol">→</a> <a id="3657" href="#1557" class="Datatype">Vec</a> <a id="3661" href="../code/binary/Prelude.html#482" class="Generalizable">B</a> <a id="3663" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="3665" class="Symbol">→</a> <a id="3667" href="#1557" class="Datatype">Vec</a> <a id="3671" class="Symbol">(</a><a id="3672" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="3674" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="3676" href="../code/binary/Prelude.html#482" class="Generalizable">B</a><a id="3677" class="Symbol">)</a> <a id="3679" href="../code/binary/Prelude.html#506" class="Generalizable">n</a>
<a id="3681" href="#3636" class="Function">convolve</a> <a id="3690" class="Symbol">=</a>
  <a id="3694" href="#2872" class="Function">vec-foldl</a>
    <a id="3708" class="Symbol">(λ</a> <a id="3711" href="#3711" class="Bound">n</a> <a id="3713" class="Symbol">→</a> <a id="3715" href="#1557" class="Datatype">Vec</a> <a id="3719" class="Symbol">_</a> <a id="3721" href="#3711" class="Bound">n</a> <a id="3723" class="Symbol">→</a> <a id="3725" href="#1557" class="Datatype">Vec</a> <a id="3729" class="Symbol">_</a> <a id="3731" href="#3711" class="Bound">n</a><a id="3732" class="Symbol">)</a>
    <a id="3738" class="Symbol">(λ</a> <a id="3741" class="Symbol">{</a> <a id="3743" href="#3743" class="Bound">k</a> <a id="3745" href="#3745" class="Bound">x</a> <a id="3747" class="Symbol">(</a><a id="3748" href="#3748" class="Bound">y</a> <a id="3750" href="#1611" class="InductiveConstructor Operator">∷</a> <a id="3752" href="#3752" class="Bound">ys</a><a id="3754" class="Symbol">)</a> <a id="3756" class="Symbol">→</a> <a id="3758" class="Symbol">(</a><a id="3759" href="#3745" class="Bound">x</a> <a id="3761" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="3763" href="#3748" class="Bound">y</a><a id="3764" class="Symbol">)</a> <a id="3766" href="#1611" class="InductiveConstructor Operator">∷</a> <a id="3768" href="#3743" class="Bound">k</a> <a id="3770" href="#3752" class="Bound">ys</a><a id="3772" class="Symbol">})</a>
    <a id="3779" class="Symbol">(λ</a> <a id="3782" href="#3782" class="Bound">_</a> <a id="3784" class="Symbol">→</a> <a id="3786" href="#1593" class="InductiveConstructor">[]</a><a id="3788" class="Symbol">)</a>
</pre>
<h1 id="binary-numbers">Binary Numbers</h1>
<p>Binary numbers come up a lot in dependently-typed programming
languages: they offer an alternative representation of ℕ that’s
tolerably efficient (well, depending on who’s doing the tolerating). In
contrast to the Peano numbers, though, there are a huge number of ways
to implement them.</p>
<p>I’m going to recommend one particular implementation over the others,
but before I do I want to define a function on ℕ:</p>
<pre class="Agda"><a id="2*"></a><a id="4231" href="#4231" class="Function">2*</a> <a id="4234" class="Symbol">:</a> <a id="4236" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="4238" class="Symbol">→</a> <a id="4240" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
<a id="4242" href="#4231" class="Function">2*</a> <a id="4245" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="4250" class="Symbol">=</a> <a id="4252" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>
<a id="4257" href="#4231" class="Function">2*</a> <a id="4260" class="Symbol">(</a><a id="4261" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4265" href="#4265" class="Bound">n</a><a id="4266" class="Symbol">)</a> <a id="4268" class="Symbol">=</a> <a id="4270" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4274" class="Symbol">(</a><a id="4275" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="4279" class="Symbol">(</a><a id="4280" href="#4231" class="Function">2*</a> <a id="4283" href="#4265" class="Bound">n</a><a id="4284" class="Symbol">))</a>
</pre>
<p>In all of the implementations of binary numbers we’ll need a function
like this. It is absolutely crucial that it is defined in the way above:
the other obvious definition (<code>2* n = n + n</code>) is a nightmare
for proofs.</p>
<p>Right, now on to some actual binary numbers. The obvious way (a list
of bits) is insufficient, as it allows multiple representations of the
same number (because of the trailing zeroes). Picking a more clever
implementation is tricky, though. One way splits it into two types:</p>
<pre class="Agda"><a id="4794" class="Keyword">module</a> <a id="OneTerminated"></a><a id="4801" href="#4801" class="Module">OneTerminated</a> <a id="4815" class="Keyword">where</a>
  <a id="4823" class="Keyword">infixl</a> <a id="4830" class="Number">5</a> <a id="4832" href="#4893" class="InductiveConstructor Operator">_0ᵇ</a> <a id="4836" href="#4897" class="InductiveConstructor Operator">_1ᵇ</a>
  <a id="4842" class="Keyword">infixr</a> <a id="4849" class="Number">4</a> <a id="4851" href="#4949" class="InductiveConstructor Operator">𝕓_</a>

  <a id="4857" class="Keyword">data</a> <a id="OneTerminated.𝔹⁺"></a><a id="4862" href="#4862" class="Datatype">𝔹⁺</a> <a id="4865" class="Symbol">:</a> <a id="4867" class="PrimitiveType">Set</a> <a id="4871" class="Keyword">where</a>
    <a id="OneTerminated.𝔹⁺.1ᵇ"></a><a id="4881" href="#4881" class="InductiveConstructor">1ᵇ</a> <a id="4884" class="Symbol">:</a> <a id="4886" href="#4862" class="Datatype">𝔹⁺</a>
    <a id="OneTerminated.𝔹⁺._0ᵇ"></a><a id="4893" href="#4893" class="InductiveConstructor Operator">_0ᵇ</a> <a id="OneTerminated.𝔹⁺._1ᵇ"></a><a id="4897" href="#4897" class="InductiveConstructor Operator">_1ᵇ</a> <a id="4901" class="Symbol">:</a> <a id="4903" href="#4862" class="Datatype">𝔹⁺</a> <a id="4906" class="Symbol">→</a> <a id="4908" href="#4862" class="Datatype">𝔹⁺</a>

  <a id="4914" class="Keyword">data</a> <a id="OneTerminated.𝔹"></a><a id="4919" href="#4919" class="Datatype">𝔹</a> <a id="4921" class="Symbol">:</a> <a id="4923" class="PrimitiveType">Set</a> <a id="4927" class="Keyword">where</a>
    <a id="OneTerminated.𝔹.𝕓0ᵇ"></a><a id="4937" href="#4937" class="InductiveConstructor">𝕓0ᵇ</a> <a id="4941" class="Symbol">:</a> <a id="4943" href="#4919" class="Datatype">𝔹</a>
    <a id="OneTerminated.𝔹.𝕓_"></a><a id="4949" href="#4949" class="InductiveConstructor Operator">𝕓_</a> <a id="4952" class="Symbol">:</a> <a id="4954" href="#4862" class="Datatype">𝔹⁺</a> <a id="4957" class="Symbol">→</a> <a id="4959" href="#4919" class="Datatype">𝔹</a>
</pre>
<p>𝔹⁺ is the strictly positive natural numbers (i.e. the naturals
starting from 1). 𝔹 adds a zero to that set. This removes the
possibility for trailing zeroes, thereby making this representation
unique for every natural number.</p>
<details>
<summary>
Evaluation is pretty standard
</summary>
<pre class="Agda">  <a id="OneTerminated.⟦_⇓⟧⁺"></a><a id="5262" href="#5262" class="Function Operator">⟦_⇓⟧⁺</a> <a id="5268" class="Symbol">:</a> <a id="5270" href="#4862" class="Datatype">𝔹⁺</a> <a id="5273" class="Symbol">→</a> <a id="5275" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
  <a id="5279" href="#5262" class="Function Operator">⟦</a> <a id="5281" href="#4881" class="InductiveConstructor">1ᵇ</a>   <a id="5286" href="#5262" class="Function Operator">⇓⟧⁺</a> <a id="5290" class="Symbol">=</a> <a id="5292" class="Number">1</a>
  <a id="5296" href="#5262" class="Function Operator">⟦</a> <a id="5298" href="#5298" class="Bound">x</a> <a id="5300" href="#4893" class="InductiveConstructor Operator">0ᵇ</a> <a id="5303" href="#5262" class="Function Operator">⇓⟧⁺</a> <a id="5307" class="Symbol">=</a>      <a id="5314" href="#4231" class="Function">2*</a> <a id="5317" href="#5262" class="Function Operator">⟦</a> <a id="5319" href="#5298" class="Bound">x</a> <a id="5321" href="#5262" class="Function Operator">⇓⟧⁺</a>
  <a id="5327" href="#5262" class="Function Operator">⟦</a> <a id="5329" href="#5329" class="Bound">x</a> <a id="5331" href="#4897" class="InductiveConstructor Operator">1ᵇ</a> <a id="5334" href="#5262" class="Function Operator">⇓⟧⁺</a> <a id="5338" class="Symbol">=</a> <a id="5340" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="5344" class="Symbol">(</a><a id="5345" href="#4231" class="Function">2*</a> <a id="5348" href="#5262" class="Function Operator">⟦</a> <a id="5350" href="#5329" class="Bound">x</a> <a id="5352" href="#5262" class="Function Operator">⇓⟧⁺</a><a id="5355" class="Symbol">)</a>

  <a id="OneTerminated.⟦_⇓⟧"></a><a id="5360" href="#5360" class="Function Operator">⟦_⇓⟧</a> <a id="5365" class="Symbol">:</a> <a id="5367" href="#4919" class="Datatype">𝔹</a> <a id="5369" class="Symbol">→</a> <a id="5371" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
  <a id="5375" href="#5360" class="Function Operator">⟦</a> <a id="5377" href="#4937" class="InductiveConstructor">𝕓0ᵇ</a>  <a id="5382" href="#5360" class="Function Operator">⇓⟧</a> <a id="5385" class="Symbol">=</a> <a id="5387" class="Number">0</a>
  <a id="5391" href="#5360" class="Function Operator">⟦</a> <a id="5393" href="#4949" class="InductiveConstructor Operator">𝕓</a> <a id="5395" href="#5395" class="Bound">x</a>  <a id="5398" href="#5360" class="Function Operator">⇓⟧</a> <a id="5401" class="Symbol">=</a> <a id="5403" href="#5262" class="Function Operator">⟦</a> <a id="5405" href="#5395" class="Bound">x</a> <a id="5407" href="#5262" class="Function Operator">⇓⟧⁺</a>
</pre>
</details>
<p>The odd syntax lets us write binary numbers in the natural way:</p>
<pre class="Agda">  <a id="5503" href="#5503" class="Function">_</a> <a id="5505" class="Symbol">:</a> <a id="5507" href="#5360" class="Function Operator">⟦</a> <a id="5509" href="#4949" class="InductiveConstructor Operator">𝕓</a> <a id="5511" href="#4881" class="InductiveConstructor">1ᵇ</a> <a id="5514" href="#4893" class="InductiveConstructor Operator">0ᵇ</a> <a id="5517" href="#4897" class="InductiveConstructor Operator">1ᵇ</a> <a id="5520" href="#5360" class="Function Operator">⇓⟧</a> <a id="5523" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="5525" class="Number">5</a>
  <a id="5529" class="Symbol">_</a> <a id="5531" class="Symbol">=</a> <a id="5533" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>

  <a id="5541" href="#5541" class="Function">_</a> <a id="5543" class="Symbol">:</a> <a id="5545" href="#5360" class="Function Operator">⟦</a> <a id="5547" href="#4949" class="InductiveConstructor Operator">𝕓</a> <a id="5549" href="#4881" class="InductiveConstructor">1ᵇ</a> <a id="5552" href="#4893" class="InductiveConstructor Operator">0ᵇ</a> <a id="5555" href="#4893" class="InductiveConstructor Operator">0ᵇ</a> <a id="5558" href="#4897" class="InductiveConstructor Operator">1ᵇ</a> <a id="5561" href="#5360" class="Function Operator">⇓⟧</a> <a id="5564" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="5566" class="Number">9</a>
  <a id="5570" class="Symbol">_</a> <a id="5572" class="Symbol">=</a> <a id="5574" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
</pre>
<p>I would actually recommend this representation for most use-cases,
especially when you’re using binary numbers “as binary numbers”, rather
than as an abstract type for faster computation.</p>
<p>Another clever representation is one I wrote about before: the
“gapless” representation. This is far too much trouble for what it’s
worth.</p>
<p>Finally, my favourite representation at the moment is
<em>zeroless</em>. It has a unique representation for each number, just
like the two above, but it is still a list of bits. The difference is
that the bits here are 1 and 2, not 0 and 1. I like to reuse types in
combination with pattern synonyms (rather than defining new types), as
it can often make parallels between different functions clearer.</p>
<pre class="Agda"><a id="Bit"></a><a id="6317" href="#6317" class="Function">Bit</a> <a id="6321" class="Symbol">:</a> <a id="6323" class="PrimitiveType">Set</a>
<a id="6327" href="#6317" class="Function">Bit</a> <a id="6331" class="Symbol">=</a> <a id="6333" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a>

<a id="6339" class="Keyword">pattern</a> <a id="1ᵇ"></a><a id="6347" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="6350" class="Symbol">=</a> <a id="6352" href="../code/binary/Prelude.html#1388" class="InductiveConstructor">false</a>
<a id="6358" class="Keyword">pattern</a> <a id="2ᵇ"></a><a id="6366" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="6369" class="Symbol">=</a> <a id="6371" href="../code/binary/Prelude.html#1403" class="InductiveConstructor">true</a>

<a id="𝔹"></a><a id="6377" href="#6377" class="Function">𝔹</a> <a id="6379" class="Symbol">:</a> <a id="6381" class="PrimitiveType">Set</a>
<a id="6385" href="#6377" class="Function">𝔹</a> <a id="6387" class="Symbol">=</a> <a id="6389" href="../code/binary/Prelude.html#760" class="Datatype">List</a> <a id="6394" href="#6317" class="Function">Bit</a>
</pre>
<!--
<pre class="Agda"><a id="6416" class="Keyword">variable</a>
  <a id="6427" href="#6427" class="Generalizable">d</a> <a id="6429" class="Symbol">:</a> <a id="6431" href="#6317" class="Function">Bit</a>
  <a id="6437" href="#6437" class="Generalizable">ds</a> <a id="6440" class="Symbol">:</a> <a id="6442" href="#6377" class="Function">𝔹</a>
</pre>-->
<p>Functions like <code>inc</code> are not difficult to implement:</p>
<pre class="Agda"><a id="inc"></a><a id="6515" href="#6515" class="Function">inc</a> <a id="6519" class="Symbol">:</a> <a id="6521" href="#6377" class="Function">𝔹</a> <a id="6523" class="Symbol">→</a> <a id="6525" href="#6377" class="Function">𝔹</a>
<a id="6527" href="#6515" class="Function">inc</a> <a id="6531" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a> <a id="6534" class="Symbol">=</a> <a id="6536" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="6539" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="6541" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a>
<a id="6544" href="#6515" class="Function">inc</a> <a id="6548" class="Symbol">(</a><a id="6549" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="6552" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="6554" href="#6554" class="Bound">xs</a><a id="6556" class="Symbol">)</a> <a id="6558" class="Symbol">=</a> <a id="6560" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="6563" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="6565" href="#6554" class="Bound">xs</a>
<a id="6568" href="#6515" class="Function">inc</a> <a id="6572" class="Symbol">(</a><a id="6573" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="6576" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="6578" href="#6578" class="Bound">xs</a><a id="6580" class="Symbol">)</a> <a id="6582" class="Symbol">=</a> <a id="6584" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="6587" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="6589" href="#6515" class="Function">inc</a> <a id="6593" href="#6578" class="Bound">xs</a>
</pre>
<p>And evaluation:</p>
<pre class="Agda"><a id="_∷⇓_"></a><a id="6626" href="#6626" class="Function Operator">_∷⇓_</a> <a id="6631" class="Symbol">:</a> <a id="6633" href="#6317" class="Function">Bit</a> <a id="6637" class="Symbol">→</a> <a id="6639" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="6641" class="Symbol">→</a> <a id="6643" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
<a id="6645" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="6648" href="#6626" class="Function Operator">∷⇓</a> <a id="6651" href="#6651" class="Bound">xs</a> <a id="6654" class="Symbol">=</a>      <a id="6661" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="6665" class="Symbol">(</a><a id="6666" href="#4231" class="Function">2*</a> <a id="6669" href="#6651" class="Bound">xs</a><a id="6671" class="Symbol">)</a>
<a id="6673" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="6676" href="#6626" class="Function Operator">∷⇓</a> <a id="6679" href="#6679" class="Bound">xs</a> <a id="6682" class="Symbol">=</a> <a id="6684" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="6688" class="Symbol">(</a><a id="6689" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="6693" class="Symbol">(</a><a id="6694" href="#4231" class="Function">2*</a> <a id="6697" href="#6679" class="Bound">xs</a><a id="6699" class="Symbol">))</a>

<a id="⟦_⇓⟧"></a><a id="6703" href="#6703" class="Function Operator">⟦_⇓⟧</a> <a id="6708" class="Symbol">:</a> <a id="6710" href="#6377" class="Function">𝔹</a> <a id="6712" class="Symbol">→</a> <a id="6714" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
<a id="6716" href="#6703" class="Function Operator">⟦_⇓⟧</a> <a id="6721" class="Symbol">=</a> <a id="6723" href="../code/binary/Prelude.html#834" class="Function">foldr</a> <a id="6729" href="#6626" class="Function Operator">_∷⇓_</a> <a id="6734" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>
</pre>
<p>Since we’re working in Cubical Agda, we might as well go on and prove
that 𝔹 is isomorphic to ℕ. I’ll include the proof here for completeness,
but it’s not relevant to the rest of the post (although it is very
short, as a consequence of the simple definitions).</p>
<details>
<summary>
Proof that 𝔹 and ℕ are isomorphic
</summary>
<pre class="Agda"><a id="⟦_⇑⟧"></a><a id="7079" href="#7079" class="Function Operator">⟦_⇑⟧</a> <a id="7084" class="Symbol">:</a> <a id="7086" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="7088" class="Symbol">→</a> <a id="7090" href="#6377" class="Function">𝔹</a>
<a id="7092" href="#7079" class="Function Operator">⟦</a> <a id="7094" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>  <a id="7100" href="#7079" class="Function Operator">⇑⟧</a> <a id="7103" class="Symbol">=</a> <a id="7105" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a>
<a id="7108" href="#7079" class="Function Operator">⟦</a> <a id="7110" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="7114" href="#7114" class="Bound">n</a> <a id="7116" href="#7079" class="Function Operator">⇑⟧</a> <a id="7119" class="Symbol">=</a> <a id="7121" href="#6515" class="Function">inc</a> <a id="7125" href="#7079" class="Function Operator">⟦</a> <a id="7127" href="#7114" class="Bound">n</a> <a id="7129" href="#7079" class="Function Operator">⇑⟧</a>

<a id="2*⇔1ᵇ∷"></a><a id="7133" href="#7133" class="Function">2*⇔1ᵇ∷</a> <a id="7140" class="Symbol">:</a> <a id="7142" class="Symbol">∀</a> <a id="7144" href="#7144" class="Bound">n</a> <a id="7146" class="Symbol">→</a> <a id="7148" href="#6515" class="Function">inc</a> <a id="7152" href="#7079" class="Function Operator">⟦</a> <a id="7154" href="#4231" class="Function">2*</a> <a id="7157" href="#7144" class="Bound">n</a> <a id="7159" href="#7079" class="Function Operator">⇑⟧</a> <a id="7162" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="7164" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="7167" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="7169" href="#7079" class="Function Operator">⟦</a> <a id="7171" href="#7144" class="Bound">n</a> <a id="7173" href="#7079" class="Function Operator">⇑⟧</a>
<a id="7176" href="#7133" class="Function">2*⇔1ᵇ∷</a> <a id="7183" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="7188" class="Symbol">=</a> <a id="7190" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="7195" href="#7133" class="Function">2*⇔1ᵇ∷</a> <a id="7202" class="Symbol">(</a><a id="7203" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="7207" href="#7207" class="Bound">n</a><a id="7208" class="Symbol">)</a> <a id="7210" class="Symbol">=</a> <a id="7212" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="7217" class="Symbol">(</a><a id="7218" href="#6515" class="Function">inc</a> <a id="7222" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="7224" href="#6515" class="Function">inc</a><a id="7227" class="Symbol">)</a> <a id="7229" class="Symbol">(</a><a id="7230" href="#7133" class="Function">2*⇔1ᵇ∷</a> <a id="7237" href="#7207" class="Bound">n</a><a id="7238" class="Symbol">)</a>

<a id="𝔹→ℕ→𝔹"></a><a id="7241" href="#7241" class="Function">𝔹→ℕ→𝔹</a> <a id="7247" class="Symbol">:</a> <a id="7249" class="Symbol">∀</a> <a id="7251" href="#7251" class="Bound">n</a> <a id="7253" class="Symbol">→</a> <a id="7255" href="#7079" class="Function Operator">⟦</a> <a id="7257" href="#6703" class="Function Operator">⟦</a> <a id="7259" href="#7251" class="Bound">n</a> <a id="7261" href="#6703" class="Function Operator">⇓⟧</a> <a id="7264" href="#7079" class="Function Operator">⇑⟧</a> <a id="7267" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="7269" href="#7251" class="Bound">n</a>
<a id="7271" href="#7241" class="Function">𝔹→ℕ→𝔹</a> <a id="7277" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a> <a id="7280" class="Symbol">=</a> <a id="7282" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="7287" href="#7241" class="Function">𝔹→ℕ→𝔹</a> <a id="7293" class="Symbol">(</a><a id="7294" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="7297" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="7299" href="#7299" class="Bound">xs</a><a id="7301" class="Symbol">)</a> <a id="7303" class="Symbol">=</a>           <a id="7315" href="#7133" class="Function">2*⇔1ᵇ∷</a> <a id="7322" href="#6703" class="Function Operator">⟦</a> <a id="7324" href="#7299" class="Bound">xs</a> <a id="7327" href="#6703" class="Function Operator">⇓⟧</a>  <a id="7331" href="../code/binary/Cubical.Foundations.Prelude.html#1705" class="Function Operator">;</a> <a id="7333" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="7338" class="Symbol">(</a><a id="7339" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="7342" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷_</a><a id="7344" class="Symbol">)</a> <a id="7346" class="Symbol">(</a><a id="7347" href="#7241" class="Function">𝔹→ℕ→𝔹</a> <a id="7353" href="#7299" class="Bound">xs</a><a id="7355" class="Symbol">)</a>
<a id="7357" href="#7241" class="Function">𝔹→ℕ→𝔹</a> <a id="7363" class="Symbol">(</a><a id="7364" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="7367" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="7369" href="#7369" class="Bound">xs</a><a id="7371" class="Symbol">)</a> <a id="7373" class="Symbol">=</a> <a id="7375" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="7380" href="#6515" class="Function">inc</a> <a id="7384" class="Symbol">(</a><a id="7385" href="#7133" class="Function">2*⇔1ᵇ∷</a> <a id="7392" href="#6703" class="Function Operator">⟦</a> <a id="7394" href="#7369" class="Bound">xs</a> <a id="7397" href="#6703" class="Function Operator">⇓⟧</a><a id="7399" class="Symbol">)</a> <a id="7401" href="../code/binary/Cubical.Foundations.Prelude.html#1705" class="Function Operator">;</a> <a id="7403" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="7408" class="Symbol">(</a><a id="7409" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="7412" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷_</a><a id="7414" class="Symbol">)</a> <a id="7416" class="Symbol">(</a><a id="7417" href="#7241" class="Function">𝔹→ℕ→𝔹</a> <a id="7423" href="#7369" class="Bound">xs</a><a id="7425" class="Symbol">)</a>

<a id="inc⇔suc"></a><a id="7428" href="#7428" class="Function">inc⇔suc</a> <a id="7436" class="Symbol">:</a> <a id="7438" class="Symbol">∀</a> <a id="7440" href="#7440" class="Bound">n</a> <a id="7442" class="Symbol">→</a> <a id="7444" href="#6703" class="Function Operator">⟦</a> <a id="7446" href="#6515" class="Function">inc</a> <a id="7450" href="#7440" class="Bound">n</a> <a id="7452" href="#6703" class="Function Operator">⇓⟧</a> <a id="7455" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="7457" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="7461" href="#6703" class="Function Operator">⟦</a> <a id="7463" href="#7440" class="Bound">n</a> <a id="7465" href="#6703" class="Function Operator">⇓⟧</a>
<a id="7468" href="#7428" class="Function">inc⇔suc</a> <a id="7476" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a> <a id="7479" class="Symbol">=</a> <a id="7481" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="7486" href="#7428" class="Function">inc⇔suc</a> <a id="7494" class="Symbol">(</a><a id="7495" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="7498" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="7500" href="#7500" class="Bound">xs</a><a id="7502" class="Symbol">)</a> <a id="7504" class="Symbol">=</a> <a id="7506" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="7511" href="#7428" class="Function">inc⇔suc</a> <a id="7519" class="Symbol">(</a><a id="7520" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="7523" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="7525" href="#7525" class="Bound">xs</a><a id="7527" class="Symbol">)</a> <a id="7529" class="Symbol">=</a> <a id="7531" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="7536" class="Symbol">(</a><a id="7537" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="7541" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="7543" href="#4231" class="Function">2*</a><a id="7545" class="Symbol">)</a> <a id="7547" class="Symbol">(</a><a id="7548" href="#7428" class="Function">inc⇔suc</a> <a id="7556" href="#7525" class="Bound">xs</a><a id="7558" class="Symbol">)</a>

<a id="ℕ→𝔹→ℕ"></a><a id="7561" href="#7561" class="Function">ℕ→𝔹→ℕ</a> <a id="7567" class="Symbol">:</a> <a id="7569" class="Symbol">∀</a> <a id="7571" href="#7571" class="Bound">n</a> <a id="7573" class="Symbol">→</a> <a id="7575" href="#6703" class="Function Operator">⟦</a> <a id="7577" href="#7079" class="Function Operator">⟦</a> <a id="7579" href="#7571" class="Bound">n</a> <a id="7581" href="#7079" class="Function Operator">⇑⟧</a> <a id="7584" href="#6703" class="Function Operator">⇓⟧</a> <a id="7587" href="../code/binary/Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="7589" href="#7571" class="Bound">n</a>
<a id="7591" href="#7561" class="Function">ℕ→𝔹→ℕ</a> <a id="7597" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>    <a id="7605" class="Symbol">=</a> <a id="7607" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="7612" href="#7561" class="Function">ℕ→𝔹→ℕ</a> <a id="7618" class="Symbol">(</a><a id="7619" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="7623" href="#7623" class="Bound">n</a><a id="7624" class="Symbol">)</a> <a id="7626" class="Symbol">=</a> <a id="7628" href="#7428" class="Function">inc⇔suc</a> <a id="7636" href="#7079" class="Function Operator">⟦</a> <a id="7638" href="#7623" class="Bound">n</a> <a id="7640" href="#7079" class="Function Operator">⇑⟧</a> <a id="7643" href="../code/binary/Cubical.Foundations.Prelude.html#1705" class="Function Operator">;</a> <a id="7645" href="../code/binary/Cubical.Foundations.Prelude.html#1057" class="Function">cong</a> <a id="7650" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="7654" class="Symbol">(</a><a id="7655" href="#7561" class="Function">ℕ→𝔹→ℕ</a> <a id="7661" href="#7623" class="Bound">n</a><a id="7662" class="Symbol">)</a>

<a id="𝔹⇔ℕ"></a><a id="7665" href="#7665" class="Function">𝔹⇔ℕ</a> <a id="7669" class="Symbol">:</a> <a id="7671" href="#6377" class="Function">𝔹</a> <a id="7673" href="../code/binary/Prelude.html#416" class="Function Operator">⇔</a> <a id="7675" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
<a id="7677" href="#7665" class="Function">𝔹⇔ℕ</a> <a id="7681" class="Symbol">=</a> <a id="7683" href="../code/binary/Cubical.Foundations.Isomorphism.html#710" class="InductiveConstructor">iso</a> <a id="7687" href="#6703" class="Function Operator">⟦_⇓⟧</a> <a id="7692" href="#7079" class="Function Operator">⟦_⇑⟧</a> <a id="7697" href="#7561" class="Function">ℕ→𝔹→ℕ</a> <a id="7703" href="#7241" class="Function">𝔹→ℕ→𝔹</a>
</pre>
</details>
<h1 id="binary-arrays">Binary Arrays</h1>
<p>Now on to the data structure. Here’s its type.</p>
<pre class="Agda"><a id="7799" class="Keyword">infixr</a> <a id="7806" class="Number">5</a> <a id="7808" href="#7956" class="InductiveConstructor Operator">_1∷_</a> <a id="7813" href="#7994" class="InductiveConstructor Operator">_2∷_</a>
<a id="7818" class="Keyword">data</a> <a id="Array"></a><a id="7823" href="#7823" class="Datatype">Array</a> <a id="7829" class="Symbol">(</a><a id="7830" href="#7830" class="Bound">T</a> <a id="7832" class="Symbol">:</a> <a id="7834" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="7836" class="Symbol">→</a> <a id="7838" href="../code/binary/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="7843" href="../code/binary/Prelude.html#454" class="Generalizable">a</a><a id="7844" class="Symbol">)</a> <a id="7846" class="Symbol">:</a> <a id="7848" href="#6377" class="Function">𝔹</a> <a id="7850" class="Symbol">→</a> <a id="7852" href="../code/binary/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="7857" href="#7843" class="Bound">a</a> <a id="7859" class="Keyword">where</a>
  <a id="Array.[]"></a><a id="7867" href="#7867" class="InductiveConstructor">[]</a>  <a id="7871" class="Symbol">:</a> <a id="7873" href="#7823" class="Datatype">Array</a> <a id="7879" href="#7830" class="Bound">T</a> <a id="7881" href="../code/binary/Prelude.html#793" class="InductiveConstructor">[]</a>
  <a id="Array._∷_"></a><a id="7886" href="#7886" class="InductiveConstructor Operator">_∷_</a> <a id="7890" class="Symbol">:</a> <a id="7892" href="#7830" class="Bound">T</a> <a id="7894" class="Symbol">(</a><a id="7895" href="../code/binary/Prelude.html#1416" class="Function">bool</a> <a id="7900" class="Number">0</a> <a id="7902" class="Number">1</a> <a id="7904" href="#6427" class="Generalizable">d</a><a id="7905" class="Symbol">)</a> <a id="7907" class="Symbol">→</a> <a id="7909" href="#7823" class="Datatype">Array</a> <a id="7915" class="Symbol">(</a><a id="7916" href="#7830" class="Bound">T</a> <a id="7918" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="7920" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="7923" class="Symbol">)</a> <a id="7925" href="#6437" class="Generalizable">ds</a> <a id="7928" class="Symbol">→</a> <a id="7930" href="#7823" class="Datatype">Array</a> <a id="7936" href="#7830" class="Bound">T</a> <a id="7938" class="Symbol">(</a><a id="7939" href="#6427" class="Generalizable">d</a> <a id="7941" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="7943" href="#6437" class="Generalizable">ds</a><a id="7945" class="Symbol">)</a>

<a id="7948" class="Keyword">pattern</a> <a id="_1∷_"></a><a id="7956" href="#7956" class="InductiveConstructor Operator">_1∷_</a> <a id="7961" href="#7981" class="Bound">x</a> <a id="7963" href="#7983" class="Bound">xs</a> <a id="7966" class="Symbol">=</a> <a id="7968" class="InductiveConstructor Operator">_∷_</a> <a id="7972" class="Symbol">{</a>d <a id="7975" class="Symbol">=</a> <a id="7977" href="#6347" class="InductiveConstructor">1ᵇ</a><a id="7979" class="Symbol">}</a> <a id="7981" href="#7981" class="Bound">x</a> <a id="7983" href="#7983" class="Bound">xs</a>
<a id="7986" class="Keyword">pattern</a> <a id="_2∷_"></a><a id="7994" href="#7994" class="InductiveConstructor Operator">_2∷_</a> <a id="7999" href="#8019" class="Bound">x</a> <a id="8001" href="#8021" class="Bound">xs</a> <a id="8004" class="Symbol">=</a> <a id="8006" class="InductiveConstructor Operator">_∷_</a> <a id="8010" class="Symbol">{</a>d <a id="8013" class="Symbol">=</a> <a id="8015" href="#6366" class="InductiveConstructor">2ᵇ</a><a id="8017" class="Symbol">}</a> <a id="8019" href="#8019" class="Bound">x</a> <a id="8021" href="#8021" class="Bound">xs</a>
</pre>
<p>So it is a list-like structure, which contains elements of type
<code>T</code>. <code>T</code> is the type of trees in the array: making
the array generic over the types of trees is a slight departure from the
norm. Usually, we would just use a perfect tree or something:</p>
<pre class="Agda"><a id="8288" class="Keyword">module</a> <a id="Prelim"></a><a id="8295" href="#8295" class="Module">Prelim</a> <a id="8302" class="Keyword">where</a>
  <a id="Prelim.Perfect"></a><a id="8310" href="#8310" class="Function">Perfect</a> <a id="8318" class="Symbol">:</a> <a id="8320" class="PrimitiveType">Set</a> <a id="8324" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="8326" class="Symbol">→</a> <a id="8328" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="8330" class="Symbol">→</a> <a id="8332" class="PrimitiveType">Set</a> <a id="8336" href="../code/binary/Prelude.html#454" class="Generalizable">a</a>
  <a id="8340" href="#8310" class="Function">Perfect</a> <a id="8348" href="#8348" class="Bound">A</a> <a id="8350" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="8355" class="Symbol">=</a> <a id="8357" href="#8348" class="Bound">A</a>
  <a id="8361" href="#8310" class="Function">Perfect</a> <a id="8369" href="#8369" class="Bound">A</a> <a id="8371" class="Symbol">(</a><a id="8372" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="8376" href="#8376" class="Bound">n</a><a id="8377" class="Symbol">)</a> <a id="8379" class="Symbol">=</a> <a id="8381" href="#8310" class="Function">Perfect</a> <a id="8389" class="Symbol">(</a><a id="8390" href="#8369" class="Bound">A</a> <a id="8392" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="8394" href="#8369" class="Bound">A</a><a id="8395" class="Symbol">)</a> <a id="8397" href="#8376" class="Bound">n</a>
</pre>
<p>By making the tree type a parameter, though, we actually
<em>simplify</em> some of the code for manipulating the tree. It’s
basically the same trick as the type-changing parameter in
<code>vec-foldl</code>.</p>
<p>As well as that, of course, we can use the array with more exotic
tree types. With binomial trees, for example, we get a binomial
heap:</p>
<pre class="Agda"><a id="8739" class="Keyword">mutual</a>
  <a id="8748" class="Keyword">data</a> <a id="BinomNode"></a><a id="8753" href="#8753" class="Datatype">BinomNode</a> <a id="8763" class="Symbol">(</a><a id="8764" href="#8764" class="Bound">A</a> <a id="8766" class="Symbol">:</a> <a id="8768" class="PrimitiveType">Set</a> <a id="8772" href="../code/binary/Prelude.html#454" class="Generalizable">a</a><a id="8773" class="Symbol">)</a> <a id="8775" class="Symbol">:</a> <a id="8777" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="8779" class="Symbol">→</a> <a id="8781" class="PrimitiveType">Set</a> <a id="8785" href="#8772" class="Bound">a</a> <a id="8787" class="Keyword">where</a>
    <a id="BinomNode.binom-leaf"></a><a id="8797" href="#8797" class="InductiveConstructor">binom-leaf</a>   <a id="8810" class="Symbol">:</a> <a id="8812" href="#8753" class="Datatype">BinomNode</a> <a id="8822" href="#8764" class="Bound">A</a> <a id="8824" class="Number">0</a>
    <a id="BinomNode.binom-branch"></a><a id="8830" href="#8830" class="InductiveConstructor">binom-branch</a> <a id="8843" class="Symbol">:</a> <a id="8845" href="#8899" class="Function">Binomial</a> <a id="8854" href="#8764" class="Bound">A</a> <a id="8856" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="8858" class="Symbol">→</a> <a id="8860" href="#8753" class="Datatype">BinomNode</a> <a id="8870" href="#8764" class="Bound">A</a> <a id="8872" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="8874" class="Symbol">→</a> <a id="8876" href="#8753" class="Datatype">BinomNode</a> <a id="8886" href="#8764" class="Bound">A</a> <a id="8888" class="Symbol">(</a><a id="8889" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="8893" href="../code/binary/Prelude.html#506" class="Generalizable">n</a><a id="8894" class="Symbol">)</a>

  <a id="Binomial"></a><a id="8899" href="#8899" class="Function">Binomial</a> <a id="8908" class="Symbol">:</a> <a id="8910" class="PrimitiveType">Set</a> <a id="8914" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="8916" class="Symbol">→</a> <a id="8918" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="8920" class="Symbol">→</a> <a id="8922" class="PrimitiveType">Set</a> <a id="8926" href="../code/binary/Prelude.html#454" class="Generalizable">a</a>
  <a id="8930" href="#8899" class="Function">Binomial</a> <a id="8939" href="#8939" class="Bound">A</a> <a id="8941" href="#8941" class="Bound">n</a> <a id="8943" class="Symbol">=</a> <a id="8945" href="#8939" class="Bound">A</a> <a id="8947" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="8949" href="#8753" class="Datatype">BinomNode</a> <a id="8959" href="#8939" class="Bound">A</a> <a id="8961" href="#8941" class="Bound">n</a>
</pre>
<p>But we’ll stick to the random-access lists for now.</p>
<h1 id="top-down-and-bottom-up-trees">Top-down and Bottom-up Trees</h1>
<p>The perfect trees above are actually a specific instance of a more
general data type: exponentiations of functors.</p>
<pre class="Agda"><a id="_^_"></a><a id="9177" href="#9177" class="Function Operator">_^_</a> <a id="9181" class="Symbol">:</a> <a id="9183" class="Symbol">(</a><a id="9184" class="PrimitiveType">Set</a> <a id="9188" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="9190" class="Symbol">→</a> <a id="9192" class="PrimitiveType">Set</a> <a id="9196" href="../code/binary/Prelude.html#454" class="Generalizable">a</a><a id="9197" class="Symbol">)</a> <a id="9199" class="Symbol">→</a> <a id="9201" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="9203" class="Symbol">→</a> <a id="9205" class="PrimitiveType">Set</a> <a id="9209" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="9211" class="Symbol">→</a> <a id="9213" class="PrimitiveType">Set</a> <a id="9217" href="../code/binary/Prelude.html#454" class="Generalizable">a</a>
<a id="9219" class="Symbol">(</a><a id="9220" href="#9220" class="Bound">F</a> <a id="9222" href="#9177" class="Function Operator">^</a> <a id="9224" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="9229" class="Symbol">)</a> <a id="9231" href="#9231" class="Bound">A</a> <a id="9233" class="Symbol">=</a> <a id="9235" href="#9231" class="Bound">A</a>
<a id="9237" class="Symbol">(</a><a id="9238" href="#9238" class="Bound">F</a> <a id="9240" href="#9177" class="Function Operator">^</a> <a id="9242" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="9246" href="#9246" class="Bound">n</a><a id="9247" class="Symbol">)</a> <a id="9249" href="#9249" class="Bound">A</a> <a id="9251" class="Symbol">=</a> <a id="9253" class="Symbol">(</a><a id="9254" href="#9238" class="Bound">F</a> <a id="9256" href="#9177" class="Function Operator">^</a> <a id="9258" href="#9246" class="Bound">n</a><a id="9259" class="Symbol">)</a> <a id="9261" class="Symbol">(</a><a id="9262" href="#9238" class="Bound">F</a> <a id="9264" href="#9249" class="Bound">A</a><a id="9265" class="Symbol">)</a>

<a id="Nest"></a><a id="9268" href="#9268" class="Function">Nest</a> <a id="9273" class="Symbol">:</a> <a id="9275" class="Symbol">(</a><a id="9276" class="PrimitiveType">Set</a> <a id="9280" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="9282" class="Symbol">→</a> <a id="9284" class="PrimitiveType">Set</a> <a id="9288" href="../code/binary/Prelude.html#454" class="Generalizable">a</a><a id="9289" class="Symbol">)</a> <a id="9291" class="Symbol">→</a> <a id="9293" class="PrimitiveType">Set</a> <a id="9297" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="9299" class="Symbol">→</a> <a id="9301" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="9303" class="Symbol">→</a> <a id="9305" class="PrimitiveType">Set</a> <a id="9309" href="../code/binary/Prelude.html#454" class="Generalizable">a</a>
<a id="9311" href="#9268" class="Function">Nest</a> <a id="9316" href="#9316" class="Bound">F</a> <a id="9318" href="#9318" class="Bound">A</a> <a id="9320" href="#9320" class="Bound">n</a> <a id="9322" class="Symbol">=</a> <a id="9324" class="Symbol">(</a><a id="9325" href="#9316" class="Bound">F</a> <a id="9327" href="#9177" class="Function Operator">^</a> <a id="9329" href="#9320" class="Bound">n</a><a id="9330" class="Symbol">)</a> <a id="9332" href="#9318" class="Bound">A</a>

<a id="Pair"></a><a id="9335" href="#9335" class="Function">Pair</a> <a id="9340" class="Symbol">:</a> <a id="9342" class="PrimitiveType">Set</a> <a id="9346" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="9348" class="Symbol">→</a> <a id="9350" class="PrimitiveType">Set</a> <a id="9354" href="../code/binary/Prelude.html#454" class="Generalizable">a</a>
<a id="9356" href="#9335" class="Function">Pair</a> <a id="9361" href="#9361" class="Bound">A</a> <a id="9363" class="Symbol">=</a> <a id="9365" href="#9361" class="Bound">A</a> <a id="9367" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="9369" href="#9361" class="Bound">A</a>

<a id="Perfect"></a><a id="9372" href="#9372" class="Function">Perfect</a> <a id="9380" class="Symbol">:</a> <a id="9382" class="PrimitiveType">Set</a> <a id="9386" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="9388" class="Symbol">→</a> <a id="9390" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="9392" class="Symbol">→</a> <a id="9394" class="PrimitiveType">Set</a> <a id="9398" href="../code/binary/Prelude.html#454" class="Generalizable">a</a>
<a id="9400" href="#9372" class="Function">Perfect</a> <a id="9408" class="Symbol">=</a> <a id="9410" href="#9268" class="Function">Nest</a> <a id="9415" href="#9335" class="Function">Pair</a>
</pre>
<!--

<pre class="Agda"><a id="9439" class="Keyword">variable</a>
  <a id="9450" href="#9450" class="Generalizable">F</a> <a id="9452" class="Symbol">:</a> <a id="9454" class="PrimitiveType">Set</a> <a id="9458" href="../code/binary/Prelude.html#454" class="Generalizable">a</a> <a id="9460" class="Symbol">→</a> <a id="9462" class="PrimitiveType">Set</a> <a id="9466" href="../code/binary/Prelude.html#454" class="Generalizable">a</a>
</pre>
-->
<p>It’s a nested datatype, built in a bottom-up way. This is in contrast
to, say, the binomial trees above, which are top-down.</p>
<h1 id="construction">Construction</h1>
<p>Our first function on the array is <code>cons</code>, which inserts
an element:</p>
<pre class="Agda"><a id="cons"></a><a id="9698" href="#9698" class="Function">cons</a> <a id="9703" class="Symbol">:</a> <a id="9705" class="Symbol">(∀</a> <a id="9708" href="#9708" class="Bound">n</a> <a id="9710" class="Symbol">→</a> <a id="9712" href="#846" class="Generalizable">T</a> <a id="9714" href="#9708" class="Bound">n</a> <a id="9716" class="Symbol">→</a> <a id="9718" href="#846" class="Generalizable">T</a> <a id="9720" href="#9708" class="Bound">n</a> <a id="9722" class="Symbol">→</a> <a id="9724" href="#846" class="Generalizable">T</a> <a id="9726" class="Symbol">(</a><a id="9727" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="9731" href="#9708" class="Bound">n</a><a id="9732" class="Symbol">))</a>
     <a id="9740" class="Symbol">→</a> <a id="9742" href="#846" class="Generalizable">T</a> <a id="9744" class="Number">0</a> <a id="9746" class="Symbol">→</a> <a id="9748" href="#7823" class="Datatype">Array</a> <a id="9754" href="#846" class="Generalizable">T</a> <a id="9756" href="#6437" class="Generalizable">ds</a> <a id="9759" class="Symbol">→</a> <a id="9761" href="#7823" class="Datatype">Array</a> <a id="9767" href="#846" class="Generalizable">T</a> <a id="9769" class="Symbol">(</a><a id="9770" href="#6515" class="Function">inc</a> <a id="9774" href="#6437" class="Generalizable">ds</a><a id="9776" class="Symbol">)</a>
<a id="9778" href="#9698" class="Function">cons</a> <a id="9783" href="#9783" class="Bound">branch</a> <a id="9790" href="#9790" class="Bound">x</a> <a id="9792" href="#7867" class="InductiveConstructor">[]</a> <a id="9795" class="Symbol">=</a> <a id="9797" href="#9790" class="Bound">x</a> <a id="9799" href="#7956" class="InductiveConstructor Operator">1∷</a> <a id="9802" href="#7867" class="InductiveConstructor">[]</a>
<a id="9805" href="#9698" class="Function">cons</a> <a id="9810" href="#9810" class="Bound">branch</a> <a id="9817" href="#9817" class="Bound">x</a> <a id="9819" class="Symbol">(</a><a id="9820" href="#9820" class="Bound">y</a> <a id="9822" href="#7956" class="InductiveConstructor Operator">1∷</a> <a id="9825" href="#9825" class="Bound">ys</a><a id="9827" class="Symbol">)</a> <a id="9829" class="Symbol">=</a> <a id="9831" href="#9810" class="Bound">branch</a> <a id="9838" class="Number">0</a> <a id="9840" href="#9817" class="Bound">x</a> <a id="9842" href="#9820" class="Bound">y</a> <a id="9844" href="#7994" class="InductiveConstructor Operator">2∷</a> <a id="9847" href="#9825" class="Bound">ys</a>
<a id="9850" href="#9698" class="Function">cons</a> <a id="9855" href="#9855" class="Bound">branch</a> <a id="9862" href="#9862" class="Bound">x</a> <a id="9864" class="Symbol">(</a><a id="9865" href="#9865" class="Bound">y</a> <a id="9867" href="#7994" class="InductiveConstructor Operator">2∷</a> <a id="9870" href="#9870" class="Bound">ys</a><a id="9872" class="Symbol">)</a> <a id="9874" class="Symbol">=</a> <a id="9876" href="#9862" class="Bound">x</a> <a id="9878" href="#7956" class="InductiveConstructor Operator">1∷</a> <a id="9881" href="#9698" class="Function">cons</a> <a id="9886" class="Symbol">(</a><a id="9887" href="#9855" class="Bound">branch</a> <a id="9894" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="9896" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="9899" class="Symbol">)</a> <a id="9901" href="#9865" class="Bound">y</a> <a id="9903" href="#9870" class="Bound">ys</a>
</pre>
<p>Since we’re generic over the type of trees, we need to pass in the
“branch” constructor (or function) for whatever tree type we end up
using. Here’s how we’d implement such a branch function for perfect
trees.</p>
<pre class="Agda"><a id="perf-branch"></a><a id="10130" href="#10130" class="Function">perf-branch</a> <a id="10142" class="Symbol">:</a> <a id="10144" class="Symbol">∀</a> <a id="10146" href="#10146" class="Bound">n</a> <a id="10148" class="Symbol">→</a> <a id="10150" href="#9372" class="Function">Perfect</a> <a id="10158" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="10160" href="#10146" class="Bound">n</a> <a id="10162" class="Symbol">→</a> <a id="10164" href="#9372" class="Function">Perfect</a> <a id="10172" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="10174" href="#10146" class="Bound">n</a> <a id="10176" class="Symbol">→</a> <a id="10178" href="#9372" class="Function">Perfect</a> <a id="10186" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="10188" class="Symbol">(</a><a id="10189" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="10193" href="#10146" class="Bound">n</a><a id="10194" class="Symbol">)</a>
<a id="10196" href="#10130" class="Function">perf-branch</a> <a id="10208" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="10213" class="Symbol">=</a> <a id="10215" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">_,_</a>
<a id="10219" href="#10130" class="Function">perf-branch</a> <a id="10231" class="Symbol">(</a><a id="10232" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="10236" href="#10236" class="Bound">n</a><a id="10237" class="Symbol">)</a> <a id="10239" class="Symbol">=</a> <a id="10241" href="#10130" class="Function">perf-branch</a> <a id="10253" href="#10236" class="Bound">n</a>
</pre>
<p>One issue here is that the <code>perf-branch</code> function probably
doesn’t optimise to the correct complexity, because the <code>n</code>
has to be scrutinised repeatedly. The alternative is to define a
<code>cons</code> for nested types, like so:</p>
<pre class="Agda"><a id="nest-cons"></a><a id="10487" href="#10487" class="Function">nest-cons</a> <a id="10497" class="Symbol">:</a> <a id="10499" class="Symbol">(∀</a> <a id="10502" class="Symbol">{</a><a id="10503" href="#10503" class="Bound">A</a><a id="10504" class="Symbol">}</a> <a id="10506" class="Symbol">→</a> <a id="10508" href="#10503" class="Bound">A</a> <a id="10510" class="Symbol">→</a> <a id="10512" href="#10503" class="Bound">A</a> <a id="10514" class="Symbol">→</a> <a id="10516" href="#9450" class="Generalizable">F</a> <a id="10518" href="#10503" class="Bound">A</a><a id="10519" class="Symbol">)</a> <a id="10521" class="Symbol">→</a> <a id="10523" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="10525" class="Symbol">→</a> <a id="10527" href="#7823" class="Datatype">Array</a> <a id="10533" class="Symbol">(</a><a id="10534" href="#9268" class="Function">Nest</a> <a id="10539" href="#9450" class="Generalizable">F</a> <a id="10541" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="10542" class="Symbol">)</a> <a id="10544" href="#6437" class="Generalizable">ds</a> <a id="10547" class="Symbol">→</a> <a id="10549" href="#7823" class="Datatype">Array</a> <a id="10555" class="Symbol">(</a><a id="10556" href="#9268" class="Function">Nest</a> <a id="10561" href="#9450" class="Generalizable">F</a> <a id="10563" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="10564" class="Symbol">)</a> <a id="10566" class="Symbol">(</a><a id="10567" href="#6515" class="Function">inc</a> <a id="10571" href="#6437" class="Generalizable">ds</a><a id="10573" class="Symbol">)</a>
<a id="10575" href="#10487" class="Function">nest-cons</a> <a id="10585" href="#10585" class="Bound Operator">_∙_</a> <a id="10589" href="#10589" class="Bound">x</a> <a id="10591" href="#7867" class="InductiveConstructor">[]</a> <a id="10594" class="Symbol">=</a> <a id="10596" href="#10589" class="Bound">x</a> <a id="10598" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="10600" href="#7867" class="InductiveConstructor">[]</a>
<a id="10603" href="#10487" class="Function">nest-cons</a> <a id="10613" href="#10613" class="Bound Operator">_∙_</a> <a id="10617" href="#10617" class="Bound">x</a> <a id="10619" class="Symbol">(</a><a id="10620" href="#10620" class="Bound">y</a> <a id="10622" href="#7956" class="InductiveConstructor Operator">1∷</a> <a id="10625" href="#10625" class="Bound">ys</a><a id="10627" class="Symbol">)</a> <a id="10629" class="Symbol">=</a> <a id="10631" class="Symbol">(</a><a id="10632" href="#10617" class="Bound">x</a> <a id="10634" href="#10613" class="Bound Operator">∙</a> <a id="10636" href="#10620" class="Bound">y</a><a id="10637" class="Symbol">)</a> <a id="10639" href="#7994" class="InductiveConstructor Operator">2∷</a> <a id="10642" href="#10625" class="Bound">ys</a>
<a id="10645" href="#10487" class="Function">nest-cons</a> <a id="10655" href="#10655" class="Bound Operator">_∙_</a> <a id="10659" href="#10659" class="Bound">x</a> <a id="10661" class="Symbol">(</a><a id="10662" href="#10662" class="Bound">y</a> <a id="10664" href="#7994" class="InductiveConstructor Operator">2∷</a> <a id="10667" href="#10667" class="Bound">ys</a><a id="10669" class="Symbol">)</a> <a id="10671" class="Symbol">=</a> <a id="10673" href="#10659" class="Bound">x</a> <a id="10675" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="10677" href="#10487" class="Function">nest-cons</a> <a id="10687" href="#10655" class="Bound Operator">_∙_</a> <a id="10691" href="#10662" class="Bound">y</a> <a id="10693" href="#10667" class="Bound">ys</a>

<a id="perf-cons"></a><a id="10697" href="#10697" class="Function">perf-cons</a> <a id="10707" class="Symbol">:</a> <a id="10709" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="10711" class="Symbol">→</a> <a id="10713" href="#7823" class="Datatype">Array</a> <a id="10719" class="Symbol">(</a><a id="10720" href="#9372" class="Function">Perfect</a> <a id="10728" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="10729" class="Symbol">)</a> <a id="10731" href="#6437" class="Generalizable">ds</a> <a id="10734" class="Symbol">→</a> <a id="10736" href="#7823" class="Datatype">Array</a> <a id="10742" class="Symbol">(</a><a id="10743" href="#9372" class="Function">Perfect</a> <a id="10751" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="10752" class="Symbol">)</a> <a id="10754" class="Symbol">(</a><a id="10755" href="#6515" class="Function">inc</a> <a id="10759" href="#6437" class="Generalizable">ds</a><a id="10761" class="Symbol">)</a>
<a id="10763" href="#10697" class="Function">perf-cons</a> <a id="10773" class="Symbol">=</a> <a id="10775" href="#10487" class="Function">nest-cons</a> <a id="10785" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">_,_</a>
</pre>
<h1 id="indexing">Indexing</h1>
<p>Again, we’re going to keep things general, allowing multiple index
types. For those index types we’ll need a type like <code>Fin</code> but
for binary numbers.</p>
<pre class="Agda"><a id="10964" class="Keyword">data</a> <a id="Fin𝔹"></a><a id="10969" href="#10969" class="Datatype">Fin𝔹</a> <a id="10974" class="Symbol">(</a><a id="10975" href="#10975" class="Bound">A</a> <a id="10977" class="Symbol">:</a> <a id="10979" class="PrimitiveType">Set</a> <a id="10983" href="../code/binary/Prelude.html#454" class="Generalizable">a</a><a id="10984" class="Symbol">)</a> <a id="10986" class="Symbol">:</a> <a id="10988" href="#6377" class="Function">𝔹</a> <a id="10990" class="Symbol">→</a> <a id="10992" href="../code/binary/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="10997" href="#10983" class="Bound">a</a> <a id="10999" class="Keyword">where</a>
  <a id="Fin𝔹.here₁"></a><a id="11007" href="#11007" class="InductiveConstructor">here₁</a> <a id="11013" class="Symbol">:</a>                       <a id="11037" href="#10969" class="Datatype">Fin𝔹</a> <a id="11042" href="#10975" class="Bound">A</a> <a id="11044" class="Symbol">(</a><a id="11045" href="#6347" class="InductiveConstructor">1ᵇ</a> <a id="11048" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="11050" href="#6437" class="Generalizable">ds</a><a id="11052" class="Symbol">)</a>
  <a id="Fin𝔹.here₂"></a><a id="11056" href="#11056" class="InductiveConstructor">here₂</a> <a id="11062" class="Symbol">:</a> <a id="11064" class="Symbol">(</a><a id="11065" href="#11065" class="Bound">i</a> <a id="11067" class="Symbol">:</a> <a id="11069" href="#10975" class="Bound">A</a><a id="11070" class="Symbol">)</a>             <a id="11084" class="Symbol">→</a> <a id="11086" href="#10969" class="Datatype">Fin𝔹</a> <a id="11091" href="#10975" class="Bound">A</a> <a id="11093" class="Symbol">(</a><a id="11094" href="#6366" class="InductiveConstructor">2ᵇ</a> <a id="11097" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="11099" href="#6437" class="Generalizable">ds</a><a id="11101" class="Symbol">)</a>
  <a id="Fin𝔹.there"></a><a id="11105" href="#11105" class="InductiveConstructor">there</a> <a id="11111" class="Symbol">:</a> <a id="11113" class="Symbol">(</a><a id="11114" href="#11114" class="Bound">i</a> <a id="11116" class="Symbol">:</a> <a id="11118" href="#10975" class="Bound">A</a><a id="11119" class="Symbol">)</a> <a id="11121" class="Symbol">→</a> <a id="11123" href="#10969" class="Datatype">Fin𝔹</a> <a id="11128" href="#10975" class="Bound">A</a> <a id="11130" href="#6437" class="Generalizable">ds</a> <a id="11133" class="Symbol">→</a> <a id="11135" href="#10969" class="Datatype">Fin𝔹</a> <a id="11140" href="#10975" class="Bound">A</a> <a id="11142" class="Symbol">(</a><a id="11143" href="#6427" class="Generalizable">d</a>  <a id="11146" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="11148" href="#6437" class="Generalizable">ds</a><a id="11150" class="Symbol">)</a>

<a id="lookup"></a><a id="11153" href="#11153" class="Function">lookup</a> <a id="11160" class="Symbol">:</a> <a id="11162" class="Symbol">(∀</a> <a id="11165" class="Symbol">{</a><a id="11166" href="#11166" class="Bound">n</a><a id="11167" class="Symbol">}</a> <a id="11169" class="Symbol">→</a> <a id="11171" href="#874" class="Generalizable">P</a> <a id="11173" class="Symbol">→</a> <a id="11175" href="#846" class="Generalizable">T</a> <a id="11177" class="Symbol">(</a><a id="11178" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="11182" href="#11166" class="Bound">n</a><a id="11183" class="Symbol">)</a> <a id="11185" class="Symbol">→</a> <a id="11187" href="#846" class="Generalizable">T</a> <a id="11189" href="#11166" class="Bound">n</a><a id="11190" class="Symbol">)</a>
       <a id="11199" class="Symbol">→</a> <a id="11201" href="#7823" class="Datatype">Array</a> <a id="11207" href="#846" class="Generalizable">T</a> <a id="11209" href="#6437" class="Generalizable">ds</a>
       <a id="11219" class="Symbol">→</a> <a id="11221" href="#10969" class="Datatype">Fin𝔹</a> <a id="11226" href="#874" class="Generalizable">P</a> <a id="11228" href="#6437" class="Generalizable">ds</a>
       <a id="11238" class="Symbol">→</a> <a id="11240" href="#846" class="Generalizable">T</a> <a id="11242" class="Number">0</a>
<a id="11244" href="#11153" class="Function">lookup</a> <a id="11251" href="#11251" class="Bound">ind</a> <a id="11255" class="Symbol">(</a><a id="11256" href="#11256" class="Bound">x</a> <a id="11258" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="11260" href="#11260" class="Bound">xs</a><a id="11262" class="Symbol">)</a> <a id="11264" href="#11007" class="InductiveConstructor">here₁</a> <a id="11270" class="Symbol">=</a> <a id="11272" href="#11256" class="Bound">x</a>
<a id="11274" href="#11153" class="Function">lookup</a> <a id="11281" href="#11281" class="Bound">ind</a> <a id="11285" class="Symbol">(</a><a id="11286" href="#11286" class="Bound">x</a> <a id="11288" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="11290" href="#11290" class="Bound">xs</a><a id="11292" class="Symbol">)</a> <a id="11294" class="Symbol">(</a><a id="11295" href="#11056" class="InductiveConstructor">here₂</a> <a id="11301" href="#11301" class="Bound">i</a><a id="11302" class="Symbol">)</a> <a id="11304" class="Symbol">=</a> <a id="11306" href="#11281" class="Bound">ind</a> <a id="11310" href="#11301" class="Bound">i</a> <a id="11312" href="#11286" class="Bound">x</a>
<a id="11314" href="#11153" class="Function">lookup</a> <a id="11321" href="#11321" class="Bound">ind</a> <a id="11325" class="Symbol">(</a><a id="11326" href="#11326" class="Bound">x</a> <a id="11328" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="11330" href="#11330" class="Bound">xs</a><a id="11332" class="Symbol">)</a> <a id="11334" class="Symbol">(</a><a id="11335" href="#11105" class="InductiveConstructor">there</a> <a id="11341" href="#11341" class="Bound">i</a> <a id="11343" href="#11343" class="Bound">is</a><a id="11345" class="Symbol">)</a> <a id="11347" class="Symbol">=</a> <a id="11349" href="#11321" class="Bound">ind</a> <a id="11353" href="#11341" class="Bound">i</a> <a id="11355" class="Symbol">(</a><a id="11356" href="#11153" class="Function">lookup</a> <a id="11363" href="#11321" class="Bound">ind</a> <a id="11367" href="#11330" class="Bound">xs</a> <a id="11370" href="#11343" class="Bound">is</a><a id="11372" class="Symbol">)</a>

<a id="nest-lookup"></a><a id="11375" href="#11375" class="Function">nest-lookup</a> <a id="11387" class="Symbol">:</a> <a id="11389" class="Symbol">(∀</a> <a id="11392" class="Symbol">{</a><a id="11393" href="#11393" class="Bound">A</a><a id="11394" class="Symbol">}</a> <a id="11396" class="Symbol">→</a> <a id="11398" href="#874" class="Generalizable">P</a> <a id="11400" class="Symbol">→</a> <a id="11402" href="#9450" class="Generalizable">F</a> <a id="11404" href="#11393" class="Bound">A</a> <a id="11406" class="Symbol">→</a> <a id="11408" href="#11393" class="Bound">A</a><a id="11409" class="Symbol">)</a>
            <a id="11423" class="Symbol">→</a> <a id="11425" href="#7823" class="Datatype">Array</a> <a id="11431" class="Symbol">(</a><a id="11432" href="#9268" class="Function">Nest</a> <a id="11437" href="#9450" class="Generalizable">F</a> <a id="11439" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="11440" class="Symbol">)</a> <a id="11442" href="#6437" class="Generalizable">ds</a>
            <a id="11457" class="Symbol">→</a> <a id="11459" href="#10969" class="Datatype">Fin𝔹</a> <a id="11464" href="#874" class="Generalizable">P</a> <a id="11466" href="#6437" class="Generalizable">ds</a>
            <a id="11481" class="Symbol">→</a> <a id="11483" href="../code/binary/Prelude.html#470" class="Generalizable">A</a>
<a id="11485" href="#11375" class="Function">nest-lookup</a> <a id="11497" href="#11497" class="Bound">ind</a> <a id="11501" class="Symbol">(</a><a id="11502" href="#11502" class="Bound">x</a> <a id="11504" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="11506" href="#11506" class="Bound">xs</a><a id="11508" class="Symbol">)</a> <a id="11510" href="#11007" class="InductiveConstructor">here₁</a> <a id="11516" class="Symbol">=</a> <a id="11518" href="#11502" class="Bound">x</a>
<a id="11520" href="#11375" class="Function">nest-lookup</a> <a id="11532" href="#11532" class="Bound">ind</a> <a id="11536" class="Symbol">(</a><a id="11537" href="#11537" class="Bound">x</a> <a id="11539" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="11541" href="#11541" class="Bound">xs</a><a id="11543" class="Symbol">)</a> <a id="11545" class="Symbol">(</a><a id="11546" href="#11056" class="InductiveConstructor">here₂</a> <a id="11552" href="#11552" class="Bound">i</a><a id="11553" class="Symbol">)</a> <a id="11555" class="Symbol">=</a> <a id="11557" href="#11532" class="Bound">ind</a> <a id="11561" href="#11552" class="Bound">i</a> <a id="11563" href="#11537" class="Bound">x</a>
<a id="11565" href="#11375" class="Function">nest-lookup</a> <a id="11577" href="#11577" class="Bound">ind</a> <a id="11581" class="Symbol">(</a><a id="11582" href="#11582" class="Bound">x</a> <a id="11584" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="11586" href="#11586" class="Bound">xs</a><a id="11588" class="Symbol">)</a> <a id="11590" class="Symbol">(</a><a id="11591" href="#11105" class="InductiveConstructor">there</a> <a id="11597" href="#11597" class="Bound">i</a> <a id="11599" href="#11599" class="Bound">is</a><a id="11601" class="Symbol">)</a> <a id="11603" class="Symbol">=</a> <a id="11605" href="#11577" class="Bound">ind</a> <a id="11609" href="#11597" class="Bound">i</a> <a id="11611" class="Symbol">(</a><a id="11612" href="#11375" class="Function">nest-lookup</a> <a id="11624" href="#11577" class="Bound">ind</a> <a id="11628" href="#11586" class="Bound">xs</a> <a id="11631" href="#11599" class="Bound">is</a><a id="11633" class="Symbol">)</a>
</pre>
<p>We’ll once more use perfect to show how these generic functions can
be concretised. For the index types into a perfect tree, we will use a
<code>Bool</code>.</p>
<pre class="Agda"><a id="perf-lookup"></a><a id="11797" href="#11797" class="Function">perf-lookup</a> <a id="11809" class="Symbol">:</a> <a id="11811" href="#7823" class="Datatype">Array</a> <a id="11817" class="Symbol">(</a><a id="11818" href="#9372" class="Function">Perfect</a> <a id="11826" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="11827" class="Symbol">)</a> <a id="11829" href="#6437" class="Generalizable">ds</a> <a id="11832" class="Symbol">→</a> <a id="11834" href="#10969" class="Datatype">Fin𝔹</a> <a id="11839" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a> <a id="11844" href="#6437" class="Generalizable">ds</a> <a id="11847" class="Symbol">→</a> <a id="11849" href="../code/binary/Prelude.html#470" class="Generalizable">A</a>
<a id="11851" href="#11797" class="Function">perf-lookup</a> <a id="11863" class="Symbol">=</a> <a id="11865" href="#11375" class="Function">nest-lookup</a> <a id="11877" class="Symbol">(</a><a id="11878" href="../code/binary/Prelude.html#1416" class="Function">bool</a> <a id="11883" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="11887" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a><a id="11890" class="Symbol">)</a>
</pre>
<h1 id="folding">Folding</h1>
<p>This next function is quite difficult to get right: a fold. We want
to consume the binary array into a unary, cons-list type thing.
Similarly to <code>foldl</code> on vectors, we will need to change the
return type as we fold, but we will <em>also</em> need to convert from
binary to unary, <em>as we fold</em>. The key ingredient is the
following function:</p>
<pre class="Agda"><a id="2^_*_"></a><a id="12250" href="#12250" class="Function Operator">2^_*_</a> <a id="12256" class="Symbol">:</a> <a id="12258" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="12260" class="Symbol">→</a> <a id="12262" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="12264" class="Symbol">→</a> <a id="12266" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
<a id="12268" href="#12250" class="Function Operator">2^</a> <a id="12271" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a>  <a id="12277" href="#12250" class="Function Operator">*</a> <a id="12279" href="#12279" class="Bound">n</a> <a id="12281" class="Symbol">=</a> <a id="12283" href="#12279" class="Bound">n</a>
<a id="12285" href="#12250" class="Function Operator">2^</a> <a id="12288" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="12292" href="#12292" class="Bound">m</a> <a id="12294" href="#12250" class="Function Operator">*</a> <a id="12296" href="#12296" class="Bound">n</a> <a id="12298" class="Symbol">=</a> <a id="12300" href="#4231" class="Function">2*</a> <a id="12303" class="Symbol">(</a><a id="12304" href="#12250" class="Function Operator">2^</a> <a id="12307" href="#12292" class="Bound">m</a> <a id="12309" href="#12250" class="Function Operator">*</a> <a id="12311" href="#12296" class="Bound">n</a><a id="12312" class="Symbol">)</a>
</pre>
<p>It will let us do the type-change-as-you-go trick from
<code>foldl</code>, but in a binary setting. Here’s
<code>foldr</code>:</p>
<pre class="Agda"><a id="array-foldr"></a><a id="12433" href="#12433" class="Function">array-foldr</a> <a id="12445" class="Symbol">:</a> <a id="12447" class="Symbol">(</a><a id="12448" href="#12448" class="Bound">B</a> <a id="12450" class="Symbol">:</a> <a id="12452" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="12454" class="Symbol">→</a> <a id="12456" href="../code/binary/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="12461" href="../code/binary/Prelude.html#456" class="Generalizable">b</a><a id="12462" class="Symbol">)</a>
            <a id="12476" class="Symbol">→</a> <a id="12478" class="Symbol">(∀</a> <a id="12481" href="#12481" class="Bound">n</a> <a id="12483" class="Symbol">{</a><a id="12484" href="#12484" class="Bound">m</a><a id="12485" class="Symbol">}</a> <a id="12487" class="Symbol">→</a> <a id="12489" href="#846" class="Generalizable">T</a> <a id="12491" href="#12481" class="Bound">n</a> <a id="12493" class="Symbol">→</a> <a id="12495" href="#12448" class="Bound">B</a> <a id="12497" class="Symbol">(</a><a id="12498" href="#12250" class="Function Operator">2^</a> <a id="12501" href="#12481" class="Bound">n</a> <a id="12503" href="#12250" class="Function Operator">*</a> <a id="12505" href="#12484" class="Bound">m</a><a id="12506" class="Symbol">)</a> <a id="12508" class="Symbol">→</a> <a id="12510" href="#12448" class="Bound">B</a> <a id="12512" class="Symbol">(</a><a id="12513" href="#12250" class="Function Operator">2^</a> <a id="12516" href="#12481" class="Bound">n</a> <a id="12518" href="#12250" class="Function Operator">*</a> <a id="12520" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="12524" href="#12484" class="Bound">m</a><a id="12525" class="Symbol">))</a>
            <a id="12540" class="Symbol">→</a> <a id="12542" href="#12448" class="Bound">B</a> <a id="12544" class="Number">0</a> <a id="12546" class="Symbol">→</a> <a id="12548" href="#7823" class="Datatype">Array</a> <a id="12554" href="#846" class="Generalizable">T</a> <a id="12556" href="#6437" class="Generalizable">ds</a> <a id="12559" class="Symbol">→</a> <a id="12561" href="#12448" class="Bound">B</a> <a id="12563" href="#6703" class="Function Operator">⟦</a> <a id="12565" href="#6437" class="Generalizable">ds</a> <a id="12568" href="#6703" class="Function Operator">⇓⟧</a>
<a id="12571" href="#12433" class="Function">array-foldr</a> <a id="12583" href="#12583" class="Bound">B</a> <a id="12585" href="#12585" class="Bound">c</a> <a id="12587" href="#12587" class="Bound">b</a> <a id="12589" href="#7867" class="InductiveConstructor">[]</a>        <a id="12599" class="Symbol">=</a> <a id="12601" href="#12587" class="Bound">b</a>
<a id="12603" href="#12433" class="Function">array-foldr</a> <a id="12615" href="#12615" class="Bound">B</a> <a id="12617" href="#12617" class="Bound">c</a> <a id="12619" href="#12619" class="Bound">b</a> <a id="12621" class="Symbol">(</a><a id="12622" href="#12622" class="Bound">x</a> <a id="12624" href="#7956" class="InductiveConstructor Operator">1∷</a> <a id="12627" href="#12627" class="Bound">xs</a><a id="12629" class="Symbol">)</a> <a id="12631" class="Symbol">=</a> <a id="12633" href="#12617" class="Bound">c</a> <a id="12635" class="Number">0</a> <a id="12637" href="#12622" class="Bound">x</a> <a id="12639" class="Symbol">(</a><a id="12640" href="#12433" class="Function">array-foldr</a> <a id="12652" class="Symbol">(</a><a id="12653" href="#12615" class="Bound">B</a> <a id="12655" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="12657" href="#4231" class="Function">2*</a><a id="12659" class="Symbol">)</a> <a id="12661" class="Symbol">(</a><a id="12662" href="#12617" class="Bound">c</a> <a id="12664" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="12666" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="12669" class="Symbol">)</a> <a id="12671" href="#12619" class="Bound">b</a> <a id="12673" href="#12627" class="Bound">xs</a><a id="12675" class="Symbol">)</a>
<a id="12677" href="#12433" class="Function">array-foldr</a> <a id="12689" href="#12689" class="Bound">B</a> <a id="12691" href="#12691" class="Bound">c</a> <a id="12693" href="#12693" class="Bound">b</a> <a id="12695" class="Symbol">(</a><a id="12696" href="#12696" class="Bound">x</a> <a id="12698" href="#7994" class="InductiveConstructor Operator">2∷</a> <a id="12701" href="#12701" class="Bound">xs</a><a id="12703" class="Symbol">)</a> <a id="12705" class="Symbol">=</a> <a id="12707" href="#12691" class="Bound">c</a> <a id="12709" class="Number">1</a> <a id="12711" href="#12696" class="Bound">x</a> <a id="12713" class="Symbol">(</a><a id="12714" href="#12433" class="Function">array-foldr</a> <a id="12726" class="Symbol">(</a><a id="12727" href="#12689" class="Bound">B</a> <a id="12729" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="12731" href="#4231" class="Function">2*</a><a id="12733" class="Symbol">)</a> <a id="12735" class="Symbol">(</a><a id="12736" href="#12691" class="Bound">c</a> <a id="12738" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="12740" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="12743" class="Symbol">)</a> <a id="12745" href="#12693" class="Bound">b</a> <a id="12747" href="#12701" class="Bound">xs</a><a id="12749" class="Symbol">)</a>
</pre>
<p>And, as you should expect, here’s how to use this in combination with
the perfect trees. Here we’ll build a binary random access list from a
vector, and convert back to a vector.</p>
<pre class="Agda"><a id="perf-foldr"></a><a id="12944" href="#12944" class="Function">perf-foldr</a> <a id="12955" class="Symbol">:</a> <a id="12957" class="Symbol">(</a><a id="12958" href="#12958" class="Bound">B</a> <a id="12960" class="Symbol">:</a> <a id="12962" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="12964" class="Symbol">→</a> <a id="12966" href="../code/binary/Cubical.Core.Primitives.html#957" class="Function">Type</a> <a id="12971" href="../code/binary/Prelude.html#456" class="Generalizable">b</a><a id="12972" class="Symbol">)</a>
           <a id="12985" class="Symbol">→</a> <a id="12987" class="Symbol">(∀</a> <a id="12990" class="Symbol">{</a><a id="12991" href="#12991" class="Bound">n</a><a id="12992" class="Symbol">}</a> <a id="12994" class="Symbol">→</a> <a id="12996" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="12998" class="Symbol">→</a> <a id="13000" href="#12958" class="Bound">B</a> <a id="13002" href="#12991" class="Bound">n</a> <a id="13004" class="Symbol">→</a> <a id="13006" href="#12958" class="Bound">B</a> <a id="13008" class="Symbol">(</a><a id="13009" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="13013" href="#12991" class="Bound">n</a><a id="13014" class="Symbol">))</a>
           <a id="13028" class="Symbol">→</a> <a id="13030" class="Symbol">∀</a> <a id="13032" href="#13032" class="Bound">n</a> <a id="13034" class="Symbol">{</a><a id="13035" href="#13035" class="Bound">m</a><a id="13036" class="Symbol">}</a>
           <a id="13049" class="Symbol">→</a> <a id="13051" href="#9372" class="Function">Perfect</a> <a id="13059" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="13061" href="#13032" class="Bound">n</a>
           <a id="13074" class="Symbol">→</a> <a id="13076" href="#12958" class="Bound">B</a> <a id="13078" class="Symbol">(</a><a id="13079" href="#12250" class="Function Operator">2^</a> <a id="13082" href="#13032" class="Bound">n</a> <a id="13084" href="#12250" class="Function Operator">*</a> <a id="13086" href="#13035" class="Bound">m</a><a id="13087" class="Symbol">)</a>
           <a id="13100" class="Symbol">→</a> <a id="13102" href="#12958" class="Bound">B</a> <a id="13104" class="Symbol">(</a><a id="13105" href="#12250" class="Function Operator">2^</a> <a id="13108" href="#13032" class="Bound">n</a> <a id="13110" href="#12250" class="Function Operator">*</a> <a id="13112" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="13116" href="#13035" class="Bound">m</a><a id="13117" class="Symbol">)</a>
<a id="13119" href="#12944" class="Function">perf-foldr</a> <a id="13130" href="#13130" class="Bound">B</a> <a id="13132" href="#13132" class="Bound">f</a> <a id="13134" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="13139" class="Symbol">=</a> <a id="13141" href="#13132" class="Bound">f</a>
<a id="13143" href="#12944" class="Function">perf-foldr</a> <a id="13154" href="#13154" class="Bound">B</a> <a id="13156" href="#13156" class="Bound">f</a> <a id="13158" class="Symbol">(</a><a id="13159" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="13163" href="#13163" class="Bound">n</a><a id="13164" class="Symbol">)</a> <a id="13166" class="Symbol">=</a>
  <a id="13170" href="#12944" class="Function">perf-foldr</a> <a id="13181" class="Symbol">(</a><a id="13182" href="#13154" class="Bound">B</a> <a id="13184" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="13186" href="#4231" class="Function">2*</a><a id="13188" class="Symbol">)</a> <a id="13190" class="Symbol">(λ</a> <a id="13193" class="Symbol">{</a> <a id="13195" class="Symbol">(</a><a id="13196" href="#13196" class="Bound">x</a> <a id="13198" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="13200" href="#13200" class="Bound">y</a><a id="13201" class="Symbol">)</a> <a id="13203" href="#13203" class="Bound">zs</a> <a id="13206" class="Symbol">→</a> <a id="13208" href="#13156" class="Bound">f</a> <a id="13210" href="#13196" class="Bound">x</a> <a id="13212" class="Symbol">(</a><a id="13213" href="#13156" class="Bound">f</a> <a id="13215" href="#13200" class="Bound">y</a> <a id="13217" href="#13203" class="Bound">zs</a><a id="13219" class="Symbol">)</a> <a id="13221" class="Symbol">})</a> <a id="13224" href="#13163" class="Bound">n</a>

<a id="toVec"></a><a id="13227" href="#13227" class="Function">toVec</a> <a id="13233" class="Symbol">:</a> <a id="13235" href="#7823" class="Datatype">Array</a> <a id="13241" class="Symbol">(</a><a id="13242" href="#9372" class="Function">Perfect</a> <a id="13250" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="13251" class="Symbol">)</a> <a id="13253" href="#6437" class="Generalizable">ds</a> <a id="13256" class="Symbol">→</a> <a id="13258" href="#1557" class="Datatype">Vec</a> <a id="13262" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="13264" href="#6703" class="Function Operator">⟦</a> <a id="13266" href="#6437" class="Generalizable">ds</a> <a id="13269" href="#6703" class="Function Operator">⇓⟧</a>
<a id="13272" href="#13227" class="Function">toVec</a> <a id="13278" class="Symbol">=</a> <a id="13280" href="#12433" class="Function">array-foldr</a> <a id="13292" class="Symbol">(</a><a id="13293" href="#1557" class="Datatype">Vec</a> <a id="13297" class="Symbol">_)</a> <a id="13300" class="Symbol">(</a><a id="13301" href="#12944" class="Function">perf-foldr</a> <a id="13312" class="Symbol">(</a><a id="13313" href="#1557" class="Datatype">Vec</a> <a id="13317" class="Symbol">_)</a> <a id="13320" href="#1611" class="InductiveConstructor Operator">_∷_</a><a id="13323" class="Symbol">)</a> <a id="13325" href="#1593" class="InductiveConstructor">[]</a>

<a id="fromVec"></a><a id="13329" href="#13329" class="Function">fromVec</a> <a id="13337" class="Symbol">:</a> <a id="13339" href="#1557" class="Datatype">Vec</a> <a id="13343" href="../code/binary/Prelude.html#470" class="Generalizable">A</a> <a id="13345" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="13347" class="Symbol">→</a> <a id="13349" href="#7823" class="Datatype">Array</a> <a id="13355" class="Symbol">(</a><a id="13356" href="#9372" class="Function">Perfect</a> <a id="13364" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="13365" class="Symbol">)</a> <a id="13367" href="#7079" class="Function Operator">⟦</a> <a id="13369" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="13371" href="#7079" class="Function Operator">⇑⟧</a>
<a id="13374" href="#13329" class="Function">fromVec</a> <a id="13382" class="Symbol">=</a> <a id="13384" href="#2378" class="Function">vec-foldr</a> <a id="13394" class="Symbol">(</a><a id="13395" href="#7823" class="Datatype">Array</a> <a id="13401" class="Symbol">(</a><a id="13402" href="#9372" class="Function">Perfect</a> <a id="13410" class="Symbol">_)</a> <a id="13413" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="13415" href="#7079" class="Function Operator">⟦_⇑⟧</a><a id="13419" class="Symbol">)</a> <a id="13421" href="#10697" class="Function">perf-cons</a> <a id="13431" href="#7867" class="InductiveConstructor">[]</a>
</pre>
<h1 id="lenses">Lenses</h1>
<p>That’s the end of the “simple” stuff! The binary random-access list
I’ve presented above is about as simple as I can get it.</p>
<p>In this section, I want to look at some more complex (and more fun)
things you can do with it. First: lenses.</p>
<p>Lenses aren’t super ergonomic in dependently-typed languages, but
they do come with some advantages. The lens laws are quite strong, for
instance, meaning that often by constructing programs using a lot of
lenses gives us certain properties “for free”. Here, for instance, we
can define the lenses for indexing.</p>
<pre class="Agda"><a id="14007" class="Keyword">open</a> <a id="14012" class="Keyword">import</a> <a id="14019" href="../code/binary/Lenses.html" class="Module">Lenses</a>
</pre>
<details>
<summary>
Lenses into the head and tail of an array
</summary>
<pre class="Agda"><a id="head"></a><a id="14111" href="#14111" class="Function">head</a> <a id="14116" class="Symbol">:</a> <a id="14118" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="14123" class="Symbol">(</a><a id="14124" href="#7823" class="Datatype">Array</a> <a id="14130" href="#846" class="Generalizable">T</a> <a id="14132" class="Symbol">(</a><a id="14133" href="#6427" class="Generalizable">d</a> <a id="14135" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="14137" href="#6437" class="Generalizable">ds</a><a id="14139" class="Symbol">))</a> <a id="14142" class="Symbol">(</a><a id="14143" href="#846" class="Generalizable">T</a> <a id="14145" class="Symbol">(</a><a id="14146" href="../code/binary/Prelude.html#1416" class="Function">bool</a> <a id="14151" class="Number">0</a> <a id="14153" class="Number">1</a> <a id="14155" href="#6427" class="Generalizable">d</a><a id="14156" class="Symbol">))</a>
<a id="14159" href="#14111" class="Function">head</a> <a id="14164" class="Symbol">.</a><a id="14165" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="14170" class="Symbol">(</a><a id="14171" href="#14171" class="Bound">x</a> <a id="14173" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14175" class="Symbol">_</a> <a id="14177" class="Symbol">)</a> <a id="14179" class="Symbol">.</a><a id="14180" href="../code/binary/Lenses.html#150" class="Field">get</a> <a id="14184" class="Symbol">=</a> <a id="14186" href="#14171" class="Bound">x</a>
<a id="14188" href="#14111" class="Function">head</a> <a id="14193" class="Symbol">.</a><a id="14194" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="14199" class="Symbol">(_</a> <a id="14202" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14204" href="#14204" class="Bound">xs</a><a id="14206" class="Symbol">)</a> <a id="14208" class="Symbol">.</a><a id="14209" href="../code/binary/Lenses.html#162" class="Field">set</a> <a id="14213" href="#14213" class="Bound">x</a> <a id="14215" class="Symbol">=</a> <a id="14217" href="#14213" class="Bound">x</a> <a id="14219" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14221" href="#14204" class="Bound">xs</a>
<a id="14224" href="#14111" class="Function">head</a> <a id="14229" class="Symbol">.</a><a id="14230" href="../code/binary/Lenses.html#293" class="Field">get-set</a> <a id="14238" class="Symbol">(_</a> <a id="14241" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14243" class="Symbol">_)</a> <a id="14246" class="Symbol">_</a> <a id="14248" class="Symbol">=</a> <a id="14250" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="14255" href="#14111" class="Function">head</a> <a id="14260" class="Symbol">.</a><a id="14261" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="14269" class="Symbol">(_</a> <a id="14272" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14274" class="Symbol">_)</a> <a id="14277" class="Symbol">=</a> <a id="14279" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="14284" href="#14111" class="Function">head</a> <a id="14289" class="Symbol">.</a><a id="14290" href="../code/binary/Lenses.html#395" class="Field">set-set</a> <a id="14298" class="Symbol">(_</a> <a id="14301" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14303" class="Symbol">_)</a> <a id="14306" class="Symbol">_</a> <a id="14308" class="Symbol">_</a> <a id="14310" class="Symbol">=</a> <a id="14312" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>

<a id="tail"></a><a id="14318" href="#14318" class="Function">tail</a> <a id="14323" class="Symbol">:</a> <a id="14325" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="14330" class="Symbol">(</a><a id="14331" href="#7823" class="Datatype">Array</a> <a id="14337" href="#846" class="Generalizable">T</a> <a id="14339" class="Symbol">(</a><a id="14340" href="#6427" class="Generalizable">d</a> <a id="14342" href="../code/binary/Prelude.html#807" class="InductiveConstructor Operator">∷</a> <a id="14344" href="#6437" class="Generalizable">ds</a><a id="14346" class="Symbol">))</a> <a id="14349" class="Symbol">(</a><a id="14350" href="#7823" class="Datatype">Array</a> <a id="14356" class="Symbol">(</a><a id="14357" href="#846" class="Generalizable">T</a> <a id="14359" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="14361" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="14364" class="Symbol">)</a> <a id="14366" href="#6437" class="Generalizable">ds</a><a id="14368" class="Symbol">)</a>
<a id="14370" href="#14318" class="Function">tail</a> <a id="14375" class="Symbol">.</a><a id="14376" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="14381" class="Symbol">(_</a> <a id="14384" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14386" href="#14386" class="Bound">xs</a><a id="14388" class="Symbol">)</a> <a id="14390" class="Symbol">.</a><a id="14391" href="../code/binary/Lenses.html#150" class="Field">get</a> <a id="14395" class="Symbol">=</a> <a id="14397" href="#14386" class="Bound">xs</a>
<a id="14400" href="#14318" class="Function">tail</a> <a id="14405" class="Symbol">.</a><a id="14406" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="14411" class="Symbol">(</a><a id="14412" href="#14412" class="Bound">x</a> <a id="14414" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14416" class="Symbol">_</a> <a id="14418" class="Symbol">)</a> <a id="14420" class="Symbol">.</a><a id="14421" href="../code/binary/Lenses.html#162" class="Field">set</a> <a id="14425" href="#14425" class="Bound">xs</a> <a id="14428" class="Symbol">=</a> <a id="14430" href="#14412" class="Bound">x</a> <a id="14432" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14434" href="#14425" class="Bound">xs</a>
<a id="14437" href="#14318" class="Function">tail</a> <a id="14442" class="Symbol">.</a><a id="14443" href="../code/binary/Lenses.html#293" class="Field">get-set</a> <a id="14451" class="Symbol">(_</a> <a id="14454" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14456" class="Symbol">_)</a> <a id="14459" class="Symbol">_</a> <a id="14461" class="Symbol">=</a> <a id="14463" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="14468" href="#14318" class="Function">tail</a> <a id="14473" class="Symbol">.</a><a id="14474" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="14482" class="Symbol">(_</a> <a id="14485" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14487" class="Symbol">_)</a> <a id="14490" class="Symbol">=</a> <a id="14492" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
<a id="14497" href="#14318" class="Function">tail</a> <a id="14502" class="Symbol">.</a><a id="14503" href="../code/binary/Lenses.html#395" class="Field">set-set</a> <a id="14511" class="Symbol">(_</a> <a id="14514" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="14516" class="Symbol">_)</a> <a id="14519" class="Symbol">_</a> <a id="14521" class="Symbol">_</a> <a id="14523" class="Symbol">=</a> <a id="14525" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
</pre>
</details>
<pre class="Agda"><a id="nest-lens"></a><a id="14555" href="#14555" class="Function">nest-lens</a> <a id="14565" class="Symbol">:</a> <a id="14567" class="Symbol">(∀</a> <a id="14570" class="Symbol">{</a><a id="14571" href="#14571" class="Bound">A</a><a id="14572" class="Symbol">}</a> <a id="14574" class="Symbol">→</a> <a id="14576" href="#874" class="Generalizable">P</a> <a id="14578" class="Symbol">→</a> <a id="14580" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="14585" class="Symbol">(</a><a id="14586" href="#9450" class="Generalizable">F</a> <a id="14588" href="#14571" class="Bound">A</a><a id="14589" class="Symbol">)</a> <a id="14591" href="#14571" class="Bound">A</a><a id="14592" class="Symbol">)</a>
          <a id="14604" class="Symbol">→</a> <a id="14606" href="#10969" class="Datatype">Fin𝔹</a> <a id="14611" href="#874" class="Generalizable">P</a> <a id="14613" href="#6437" class="Generalizable">ds</a>
          <a id="14626" class="Symbol">→</a> <a id="14628" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="14633" class="Symbol">(</a><a id="14634" href="#7823" class="Datatype">Array</a> <a id="14640" class="Symbol">(</a><a id="14641" href="#9268" class="Function">Nest</a> <a id="14646" href="#9450" class="Generalizable">F</a> <a id="14648" href="../code/binary/Prelude.html#470" class="Generalizable">A</a><a id="14649" class="Symbol">)</a> <a id="14651" href="#6437" class="Generalizable">ds</a><a id="14653" class="Symbol">)</a> <a id="14655" href="../code/binary/Prelude.html#470" class="Generalizable">A</a>
<a id="14657" href="#14555" class="Function">nest-lens</a> <a id="14667" href="#14667" class="Bound">ln</a> <a id="14670" href="#11007" class="InductiveConstructor">here₁</a>        <a id="14683" class="Symbol">=</a> <a id="14685" href="#14111" class="Function">head</a>
<a id="14690" href="#14555" class="Function">nest-lens</a> <a id="14700" href="#14700" class="Bound">ln</a> <a id="14703" class="Symbol">(</a><a id="14704" href="#11056" class="InductiveConstructor">here₂</a> <a id="14710" href="#14710" class="Bound">i</a><a id="14711" class="Symbol">)</a>    <a id="14716" class="Symbol">=</a> <a id="14718" href="#14111" class="Function">head</a> <a id="14723" href="../code/binary/Lenses.html#631" class="Function Operator">⋯</a> <a id="14725" href="#14700" class="Bound">ln</a> <a id="14728" href="#14710" class="Bound">i</a>
<a id="14730" href="#14555" class="Function">nest-lens</a> <a id="14740" href="#14740" class="Bound">ln</a> <a id="14743" class="Symbol">(</a><a id="14744" href="#11105" class="InductiveConstructor">there</a> <a id="14750" href="#14750" class="Bound">i</a> <a id="14752" href="#14752" class="Bound">is</a><a id="14754" class="Symbol">)</a> <a id="14756" class="Symbol">=</a> <a id="14758" href="#14318" class="Function">tail</a> <a id="14763" href="../code/binary/Lenses.html#631" class="Function Operator">⋯</a> <a id="14765" href="#14555" class="Function">nest-lens</a> <a id="14775" href="#14740" class="Bound">ln</a> <a id="14778" href="#14752" class="Bound">is</a> <a id="14781" href="../code/binary/Lenses.html#631" class="Function Operator">⋯</a> <a id="14783" href="#14740" class="Bound">ln</a> <a id="14786" href="#14750" class="Bound">i</a>
</pre>
<details>
<summary>
Top-down version
</summary>
<pre class="Agda"><a id="ind-lens"></a><a id="14848" href="#14848" class="Function">ind-lens</a> <a id="14857" class="Symbol">:</a> <a id="14859" class="Symbol">(∀</a> <a id="14862" class="Symbol">{</a><a id="14863" href="#14863" class="Bound">n</a><a id="14864" class="Symbol">}</a> <a id="14866" class="Symbol">→</a> <a id="14868" href="#874" class="Generalizable">P</a> <a id="14870" class="Symbol">→</a> <a id="14872" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="14877" class="Symbol">(</a><a id="14878" href="#846" class="Generalizable">T</a> <a id="14880" class="Symbol">(</a><a id="14881" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="14885" href="#14863" class="Bound">n</a><a id="14886" class="Symbol">))</a> <a id="14889" class="Symbol">(</a><a id="14890" href="#846" class="Generalizable">T</a> <a id="14892" href="#14863" class="Bound">n</a><a id="14893" class="Symbol">))</a>
         <a id="14905" class="Symbol">→</a> <a id="14907" href="#10969" class="Datatype">Fin𝔹</a> <a id="14912" href="#874" class="Generalizable">P</a> <a id="14914" href="#6437" class="Generalizable">ds</a>
         <a id="14926" class="Symbol">→</a> <a id="14928" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="14933" class="Symbol">(</a><a id="14934" href="#7823" class="Datatype">Array</a> <a id="14940" href="#846" class="Generalizable">T</a> <a id="14942" href="#6437" class="Generalizable">ds</a><a id="14944" class="Symbol">)</a> <a id="14946" class="Symbol">(</a><a id="14947" href="#846" class="Generalizable">T</a> <a id="14949" class="Number">0</a><a id="14950" class="Symbol">)</a>
<a id="14952" href="#14848" class="Function">ind-lens</a> <a id="14961" href="#14961" class="Bound">ln</a> <a id="14964" href="#11007" class="InductiveConstructor">here₁</a>        <a id="14977" class="Symbol">=</a> <a id="14979" href="#14111" class="Function">head</a>
<a id="14984" href="#14848" class="Function">ind-lens</a> <a id="14993" href="#14993" class="Bound">ln</a> <a id="14996" class="Symbol">(</a><a id="14997" href="#11056" class="InductiveConstructor">here₂</a> <a id="15003" href="#15003" class="Bound">i</a><a id="15004" class="Symbol">)</a>    <a id="15009" class="Symbol">=</a> <a id="15011" href="#14111" class="Function">head</a> <a id="15016" href="../code/binary/Lenses.html#631" class="Function Operator">⋯</a> <a id="15018" href="#14993" class="Bound">ln</a> <a id="15021" href="#15003" class="Bound">i</a>
<a id="15023" href="#14848" class="Function">ind-lens</a> <a id="15032" href="#15032" class="Bound">ln</a> <a id="15035" class="Symbol">(</a><a id="15036" href="#11105" class="InductiveConstructor">there</a> <a id="15042" href="#15042" class="Bound">i</a> <a id="15044" href="#15044" class="Bound">is</a><a id="15046" class="Symbol">)</a> <a id="15048" class="Symbol">=</a> <a id="15050" href="#14318" class="Function">tail</a> <a id="15055" href="../code/binary/Lenses.html#631" class="Function Operator">⋯</a> <a id="15057" href="#14848" class="Function">ind-lens</a> <a id="15066" href="#15032" class="Bound">ln</a> <a id="15069" href="#15044" class="Bound">is</a> <a id="15072" href="../code/binary/Lenses.html#631" class="Function Operator">⋯</a> <a id="15074" href="#15032" class="Bound">ln</a> <a id="15077" href="#15042" class="Bound">i</a>
</pre>
</details>
<h1 id="fenwick-trees">Fenwick Trees</h1>
<p>Finally, to demonstrate some of the versatility of this data
structure, we’re going to implement a tree based on a <em>Fenwick</em>
tree. This is a data structure for prefix sums: we can query the running
total at any point, and <em>update</em> the value at a given point, in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
time. We’re going to make it generic over a monoid:</p>
<pre class="Agda"><a id="15458" class="Keyword">module</a> <a id="15465" href="#15465" class="Module">_</a> <a id="15467" class="Symbol">{</a><a id="15468" href="#15468" class="Bound">ℓ</a><a id="15469" class="Symbol">}</a> <a id="15471" class="Symbol">(</a><a id="15472" href="#15472" class="Bound">mon</a> <a id="15476" class="Symbol">:</a> <a id="15478" href="../code/binary/Prelude.html#1125" class="Record">Monoid</a> <a id="15485" href="#15468" class="Bound">ℓ</a><a id="15486" class="Symbol">)</a> <a id="15488" class="Keyword">where</a>
  <a id="15496" class="Keyword">open</a> <a id="15501" href="../code/binary/Prelude.html#1125" class="Module">Monoid</a> <a id="15508" href="#15472" class="Bound">mon</a>

  <a id="15515" class="Keyword">record</a> <a id="15522" href="#15522" class="Record">Leaf</a> <a id="15527" class="Symbol">:</a> <a id="15529" class="PrimitiveType">Set</a> <a id="15533" href="#15468" class="Bound">ℓ</a> <a id="15535" class="Keyword">where</a>
    <a id="15545" class="Keyword">constructor</a> <a id="15557" href="#15557" class="InductiveConstructor">leaf</a>
    <a id="15566" class="Keyword">field</a> <a id="15572" href="#15572" class="Field">val</a> <a id="15576" class="Symbol">:</a> <a id="15578" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a>
  <a id="15582" class="Keyword">open</a> <a id="15587" href="#15522" class="Module">Leaf</a>

  <a id="15595" class="Keyword">mutual</a>
    <a id="15606" href="#15606" class="Function">SumNode</a> <a id="15614" class="Symbol">:</a> <a id="15616" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="15618" class="Symbol">→</a> <a id="15620" class="PrimitiveType">Set</a> <a id="15624" href="#15468" class="Bound">ℓ</a>
    <a id="15630" href="#15606" class="Function">SumNode</a> <a id="15638" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="15643" class="Symbol">=</a> <a id="15645" href="#15522" class="Record">Leaf</a>
    <a id="15654" href="#15606" class="Function">SumNode</a> <a id="15662" class="Symbol">(</a><a id="15663" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="15667" href="#15667" class="Bound">n</a><a id="15668" class="Symbol">)</a> <a id="15670" class="Symbol">=</a> <a id="15672" href="#15699" class="Function">Summary</a> <a id="15680" href="#15667" class="Bound">n</a> <a id="15682" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="15684" href="#15699" class="Function">Summary</a> <a id="15692" href="#15667" class="Bound">n</a>

    <a id="15699" href="#15699" class="Function">Summary</a> <a id="15707" class="Symbol">:</a> <a id="15709" href="../code/binary/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="15711" class="Symbol">→</a> <a id="15713" class="PrimitiveType">Set</a> <a id="15717" href="#15468" class="Bound">ℓ</a>
    <a id="15723" href="#15699" class="Function">Summary</a> <a id="15731" href="#15731" class="Bound">n</a> <a id="15733" class="Symbol">=</a> <a id="15735" href="../code/binary/Agda.Builtin.Sigma.html#139" class="Record">Σ</a> <a id="15737" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a> <a id="15739" class="Symbol">(</a><a id="15740" href="../code/binary/Cubical.Foundations.Equiv.html#801" class="Function">fiber</a> <a id="15746" class="Symbol">(</a><a id="15747" href="#15760" class="Function">cmb</a> <a id="15751" href="#15731" class="Bound">n</a><a id="15752" class="Symbol">))</a>

    <a id="15760" href="#15760" class="Function">cmb</a> <a id="15764" class="Symbol">:</a> <a id="15766" class="Symbol">∀</a> <a id="15768" href="#15768" class="Bound">n</a> <a id="15770" class="Symbol">→</a> <a id="15772" href="#15606" class="Function">SumNode</a> <a id="15780" href="#15768" class="Bound">n</a> <a id="15782" class="Symbol">→</a> <a id="15784" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a>
    <a id="15790" href="#15760" class="Function">cmb</a> <a id="15794" href="../code/binary/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a> <a id="15799" class="Symbol">=</a> <a id="15801" href="#15572" class="Field">val</a>
    <a id="15809" href="#15760" class="Function">cmb</a> <a id="15813" class="Symbol">(</a><a id="15814" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="15818" class="Symbol">_)</a> <a id="15821" class="Symbol">(</a><a id="15822" href="#15822" class="Bound">x</a> <a id="15824" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="15826" href="#15826" class="Bound">y</a><a id="15827" class="Symbol">)</a> <a id="15829" class="Symbol">=</a> <a id="15831" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="15835" href="#15822" class="Bound">x</a> <a id="15837" href="../code/binary/Prelude.html#1196" class="Field Operator">∙</a> <a id="15839" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="15843" href="#15826" class="Bound">y</a>

  <a id="15848" href="#15848" class="Function">Fenwick</a> <a id="15856" class="Symbol">:</a> <a id="15858" href="#6377" class="Function">𝔹</a> <a id="15860" class="Symbol">→</a>  <a id="15863" class="PrimitiveType">Set</a> <a id="15867" href="#15468" class="Bound">ℓ</a>
  <a id="15871" href="#15848" class="Function">Fenwick</a> <a id="15879" class="Symbol">=</a> <a id="15881" href="#7823" class="Datatype">Array</a> <a id="15887" href="#15699" class="Function">Summary</a>
</pre>
<p>So it’s an array of perfect trees, with each branch in the tree
containing a summary of its children. Constructing a tree is
straightforward:</p>
<pre class="Agda">  <a id="16052" href="#16052" class="Function">comb</a> <a id="16057" class="Symbol">:</a> <a id="16059" class="Symbol">∀</a> <a id="16061" href="#16061" class="Bound">n</a> <a id="16063" class="Symbol">→</a> <a id="16065" href="#15699" class="Function">Summary</a> <a id="16073" href="#16061" class="Bound">n</a> <a id="16075" class="Symbol">→</a> <a id="16077" href="#15699" class="Function">Summary</a> <a id="16085" href="#16061" class="Bound">n</a> <a id="16087" class="Symbol">→</a> <a id="16089" href="#15699" class="Function">Summary</a> <a id="16097" class="Symbol">(</a><a id="16098" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="16102" href="#16061" class="Bound">n</a><a id="16103" class="Symbol">)</a>
  <a id="16107" href="#16052" class="Function">comb</a> <a id="16112" href="#16112" class="Bound">n</a> <a id="16114" href="#16114" class="Bound">xs</a> <a id="16117" href="#16117" class="Bound">ys</a> <a id="16120" class="Symbol">=</a> <a id="16122" class="Symbol">_</a> <a id="16124" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16126" class="Symbol">(</a><a id="16127" href="#16114" class="Bound">xs</a> <a id="16130" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16132" href="#16117" class="Bound">ys</a><a id="16134" class="Symbol">)</a> <a id="16136" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16138" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>

  <a id="16146" href="#16146" class="Function">sing</a> <a id="16151" class="Symbol">:</a> <a id="16153" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a> <a id="16155" class="Symbol">→</a> <a id="16157" href="#15699" class="Function">Summary</a> <a id="16165" class="Number">0</a>
  <a id="16169" href="#16146" class="Function">sing</a> <a id="16174" href="#16174" class="Bound">x</a> <a id="16176" class="Symbol">=</a> <a id="16178" class="Symbol">_</a> <a id="16180" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16182" href="#15557" class="InductiveConstructor">leaf</a> <a id="16187" href="#16174" class="Bound">x</a> <a id="16189" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16191" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>

  <a id="16199" href="#16199" class="Function">fFromVec</a> <a id="16208" class="Symbol">:</a> <a id="16210" href="#1557" class="Datatype">Vec</a> <a id="16214" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a> <a id="16216" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="16218" class="Symbol">→</a> <a id="16220" href="#15848" class="Function">Fenwick</a> <a id="16228" href="#7079" class="Function Operator">⟦</a> <a id="16230" href="../code/binary/Prelude.html#506" class="Generalizable">n</a> <a id="16232" href="#7079" class="Function Operator">⇑⟧</a>
  <a id="16237" href="#16199" class="Function">fFromVec</a> <a id="16246" class="Symbol">=</a> <a id="16248" href="#2378" class="Function">vec-foldr</a> <a id="16258" class="Symbol">(</a><a id="16259" href="#15848" class="Function">Fenwick</a> <a id="16267" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="16269" href="#7079" class="Function Operator">⟦_⇑⟧</a><a id="16273" class="Symbol">)</a> <a id="16275" class="Symbol">(</a><a id="16276" href="#9698" class="Function">cons</a> <a id="16281" href="#16052" class="Function">comb</a> <a id="16286" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="16288" href="#16146" class="Function">sing</a><a id="16292" class="Symbol">)</a> <a id="16294" href="#7867" class="InductiveConstructor">[]</a>
</pre>
<p>Updating a particular point involves a good bit of boilerplate, but
isn’t too complex.</p>
<details>
<summary>
Lenses into a single level of the tree
</summary>
<pre class="Agda">  <a id="16469" href="#16469" class="Function">upd-lens</a> <a id="16478" class="Symbol">:</a> <a id="16480" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a> <a id="16485" class="Symbol">→</a> <a id="16487" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="16492" class="Symbol">(</a><a id="16493" href="#15699" class="Function">Summary</a> <a id="16501" class="Symbol">(</a><a id="16502" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="16506" href="../code/binary/Prelude.html#506" class="Generalizable">n</a><a id="16507" class="Symbol">))</a> <a id="16510" class="Symbol">(</a><a id="16511" href="#15699" class="Function">Summary</a> <a id="16519" href="../code/binary/Prelude.html#506" class="Generalizable">n</a><a id="16520" class="Symbol">)</a>
  <a id="16524" href="#16469" class="Function">upd-lens</a> <a id="16533" href="#16533" class="Bound">b</a> <a id="16535" class="Symbol">.</a><a id="16536" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="16541" class="Symbol">(_</a> <a id="16544" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16546" href="#16546" class="Bound">xs</a> <a id="16549" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16551" class="Symbol">_)</a> <a id="16554" class="Symbol">.</a><a id="16555" href="../code/binary/Lenses.html#150" class="Field">get</a> <a id="16559" class="Symbol">=</a> <a id="16561" href="../code/binary/Lenses.html#1464" class="Function">⦅pair⦆</a> <a id="16568" href="#16533" class="Bound">b</a> <a id="16570" class="Symbol">.</a><a id="16571" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="16576" href="#16546" class="Bound">xs</a> <a id="16579" class="Symbol">.</a><a id="16580" href="../code/binary/Lenses.html#150" class="Field">get</a>
  <a id="16586" href="#16469" class="Function">upd-lens</a> <a id="16595" href="#16595" class="Bound">b</a> <a id="16597" class="Symbol">.</a><a id="16598" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="16603" class="Symbol">(_</a> <a id="16606" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16608" href="#16608" class="Bound">xs</a> <a id="16611" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16613" class="Symbol">_)</a> <a id="16616" class="Symbol">.</a><a id="16617" href="../code/binary/Lenses.html#162" class="Field">set</a> <a id="16621" href="#16621" class="Bound">x</a> <a id="16623" class="Symbol">=</a> <a id="16625" class="Symbol">_</a> <a id="16627" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16629" href="../code/binary/Lenses.html#1464" class="Function">⦅pair⦆</a> <a id="16636" href="#16595" class="Bound">b</a> <a id="16638" class="Symbol">.</a><a id="16639" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="16644" href="#16608" class="Bound">xs</a> <a id="16647" class="Symbol">.</a><a id="16648" href="../code/binary/Lenses.html#162" class="Field">set</a> <a id="16652" href="#16621" class="Bound">x</a> <a id="16654" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16656" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
  <a id="16663" href="#16469" class="Function">upd-lens</a> <a id="16672" href="#16672" class="Bound">b</a> <a id="16674" class="Symbol">.</a><a id="16675" href="../code/binary/Lenses.html#293" class="Field">get-set</a> <a id="16683" class="Symbol">_</a> <a id="16685" class="Symbol">=</a> <a id="16687" href="../code/binary/Lenses.html#1464" class="Function">⦅pair⦆</a> <a id="16694" href="#16672" class="Bound">b</a> <a id="16696" class="Symbol">.</a><a id="16697" href="../code/binary/Lenses.html#293" class="Field">get-set</a> <a id="16705" class="Symbol">_</a>
  <a id="16709" href="#16469" class="Function">upd-lens</a> <a id="16718" href="../code/binary/Prelude.html#1388" class="InductiveConstructor">false</a> <a id="16724" class="Symbol">.</a><a id="16725" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="16733" class="Symbol">(</a><a id="16734" href="#16734" class="Bound">t</a> <a id="16736" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16738" href="#16738" class="Bound">xs</a> <a id="16741" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16743" href="#16743" class="Bound">p</a><a id="16744" class="Symbol">)</a> <a id="16746" href="#16746" class="Bound">i</a> <a id="16748" class="Symbol">.</a><a id="16749" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="16753" class="Symbol">=</a> <a id="16755" href="#16743" class="Bound">p</a> <a id="16757" href="#16746" class="Bound">i</a>
  <a id="16761" href="#16469" class="Function">upd-lens</a> <a id="16770" href="../code/binary/Prelude.html#1388" class="InductiveConstructor">false</a> <a id="16776" class="Symbol">.</a><a id="16777" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="16785" class="Symbol">(</a><a id="16786" href="#16786" class="Bound">t</a> <a id="16788" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16790" href="#16790" class="Bound">xs</a> <a id="16793" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16795" href="#16795" class="Bound">p</a><a id="16796" class="Symbol">)</a> <a id="16798" href="#16798" class="Bound">i</a> <a id="16800" class="Symbol">.</a><a id="16801" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="16805" class="Symbol">.</a><a id="16806" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="16810" class="Symbol">=</a> <a id="16812" href="#16790" class="Bound">xs</a>
  <a id="16817" href="#16469" class="Function">upd-lens</a> <a id="16826" href="../code/binary/Prelude.html#1388" class="InductiveConstructor">false</a> <a id="16832" class="Symbol">.</a><a id="16833" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="16841" class="Symbol">(</a><a id="16842" href="#16842" class="Bound">t</a> <a id="16844" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16846" href="#16846" class="Bound">xs</a> <a id="16849" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16851" href="#16851" class="Bound">p</a><a id="16852" class="Symbol">)</a> <a id="16854" href="#16854" class="Bound">i</a> <a id="16856" class="Symbol">.</a><a id="16857" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="16861" class="Symbol">.</a><a id="16862" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="16866" href="#16866" class="Bound">j</a> <a id="16868" class="Symbol">=</a> <a id="16870" href="#16851" class="Bound">p</a> <a id="16872" class="Symbol">(</a><a id="16873" href="#16854" class="Bound">i</a> <a id="16875" href="../code/binary/Agda.Primitive.Cubical.html#226" class="Primitive Operator">∧</a> <a id="16877" href="#16866" class="Bound">j</a><a id="16878" class="Symbol">)</a>
  <a id="16882" href="#16469" class="Function">upd-lens</a> <a id="16891" href="../code/binary/Prelude.html#1403" class="InductiveConstructor">true</a>  <a id="16897" class="Symbol">.</a><a id="16898" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="16906" class="Symbol">(</a><a id="16907" href="#16907" class="Bound">t</a> <a id="16909" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16911" href="#16911" class="Bound">xs</a> <a id="16914" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16916" href="#16916" class="Bound">p</a><a id="16917" class="Symbol">)</a> <a id="16919" href="#16919" class="Bound">i</a> <a id="16921" class="Symbol">.</a><a id="16922" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="16926" class="Symbol">=</a> <a id="16928" href="#16916" class="Bound">p</a> <a id="16930" href="#16919" class="Bound">i</a>
  <a id="16934" href="#16469" class="Function">upd-lens</a> <a id="16943" href="../code/binary/Prelude.html#1403" class="InductiveConstructor">true</a>  <a id="16949" class="Symbol">.</a><a id="16950" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="16958" class="Symbol">(</a><a id="16959" href="#16959" class="Bound">t</a> <a id="16961" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16963" href="#16963" class="Bound">xs</a> <a id="16966" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="16968" href="#16968" class="Bound">p</a><a id="16969" class="Symbol">)</a> <a id="16971" href="#16971" class="Bound">i</a> <a id="16973" class="Symbol">.</a><a id="16974" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="16978" class="Symbol">.</a><a id="16979" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="16983" class="Symbol">=</a> <a id="16985" href="#16963" class="Bound">xs</a>
  <a id="16990" href="#16469" class="Function">upd-lens</a> <a id="16999" href="../code/binary/Prelude.html#1403" class="InductiveConstructor">true</a>  <a id="17005" class="Symbol">.</a><a id="17006" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="17014" class="Symbol">(</a><a id="17015" href="#17015" class="Bound">t</a> <a id="17017" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17019" href="#17019" class="Bound">xs</a> <a id="17022" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17024" href="#17024" class="Bound">p</a><a id="17025" class="Symbol">)</a> <a id="17027" href="#17027" class="Bound">i</a> <a id="17029" class="Symbol">.</a><a id="17030" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17034" class="Symbol">.</a><a id="17035" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17039" href="#17039" class="Bound">j</a> <a id="17041" class="Symbol">=</a> <a id="17043" href="#17024" class="Bound">p</a> <a id="17045" class="Symbol">(</a><a id="17046" href="#17027" class="Bound">i</a> <a id="17048" href="../code/binary/Agda.Primitive.Cubical.html#226" class="Primitive Operator">∧</a> <a id="17050" href="#17039" class="Bound">j</a><a id="17051" class="Symbol">)</a>
  <a id="17055" href="#16469" class="Function">upd-lens</a> <a id="17064" href="../code/binary/Prelude.html#1388" class="InductiveConstructor">false</a> <a id="17070" class="Symbol">.</a><a id="17071" href="../code/binary/Lenses.html#395" class="Field">set-set</a> <a id="17079" class="Symbol">_</a> <a id="17081" class="Symbol">_</a> <a id="17083" class="Symbol">_</a> <a id="17085" class="Symbol">=</a> <a id="17087" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
  <a id="17094" href="#16469" class="Function">upd-lens</a> <a id="17103" href="../code/binary/Prelude.html#1403" class="InductiveConstructor">true</a>  <a id="17109" class="Symbol">.</a><a id="17110" href="../code/binary/Lenses.html#395" class="Field">set-set</a> <a id="17118" class="Symbol">_</a> <a id="17120" class="Symbol">_</a> <a id="17122" class="Symbol">_</a> <a id="17124" class="Symbol">=</a> <a id="17126" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>

  <a id="17134" href="#17134" class="Function">top</a> <a id="17138" class="Symbol">:</a> <a id="17140" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="17145" class="Symbol">(</a><a id="17146" href="#15699" class="Function">Summary</a> <a id="17154" class="Number">0</a><a id="17155" class="Symbol">)</a> <a id="17157" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a>
  <a id="17161" href="#17134" class="Function">top</a> <a id="17165" class="Symbol">.</a><a id="17166" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="17171" href="#17171" class="Bound">x</a> <a id="17173" class="Symbol">.</a><a id="17174" href="../code/binary/Lenses.html#150" class="Field">get</a> <a id="17178" class="Symbol">=</a> <a id="17180" href="#17171" class="Bound">x</a> <a id="17182" class="Symbol">.</a><a id="17183" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17187" class="Symbol">.</a><a id="17188" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="17192" class="Symbol">.</a><a id="17193" href="#15572" class="Field">val</a>
  <a id="17199" href="#17134" class="Function">top</a> <a id="17203" class="Symbol">.</a><a id="17204" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="17209" href="#17209" class="Bound">x</a> <a id="17211" class="Symbol">.</a><a id="17212" href="../code/binary/Lenses.html#162" class="Field">set</a> <a id="17216" href="#17216" class="Bound">y</a> <a id="17218" class="Symbol">.</a><a id="17219" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="17223" class="Symbol">=</a> <a id="17225" href="#17216" class="Bound">y</a>
  <a id="17229" href="#17134" class="Function">top</a> <a id="17233" class="Symbol">.</a><a id="17234" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="17239" href="#17239" class="Bound">x</a> <a id="17241" class="Symbol">.</a><a id="17242" href="../code/binary/Lenses.html#162" class="Field">set</a> <a id="17246" href="#17246" class="Bound">y</a> <a id="17248" class="Symbol">.</a><a id="17249" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17253" class="Symbol">.</a><a id="17254" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="17258" class="Symbol">.</a><a id="17259" href="#15572" class="Field">val</a> <a id="17263" class="Symbol">=</a> <a id="17265" href="#17246" class="Bound">y</a>
  <a id="17269" href="#17134" class="Function">top</a> <a id="17273" class="Symbol">.</a><a id="17274" href="../code/binary/Lenses.html#265" class="Field">into</a> <a id="17279" href="#17279" class="Bound">x</a> <a id="17281" class="Symbol">.</a><a id="17282" href="../code/binary/Lenses.html#162" class="Field">set</a> <a id="17286" href="#17286" class="Bound">y</a> <a id="17288" class="Symbol">.</a><a id="17289" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17293" class="Symbol">.</a><a id="17294" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17298" class="Symbol">=</a> <a id="17300" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
  <a id="17307" href="#17134" class="Function">top</a> <a id="17311" class="Symbol">.</a><a id="17312" href="../code/binary/Lenses.html#293" class="Field">get-set</a> <a id="17320" class="Symbol">_</a> <a id="17322" class="Symbol">_</a> <a id="17324" class="Symbol">=</a> <a id="17326" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
  <a id="17333" href="#17134" class="Function">top</a> <a id="17337" class="Symbol">.</a><a id="17338" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="17346" class="Symbol">(</a><a id="17347" href="#17347" class="Bound">x</a> <a id="17349" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17351" href="#17351" class="Bound">y</a> <a id="17353" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17355" href="#17355" class="Bound">p</a><a id="17356" class="Symbol">)</a> <a id="17358" href="#17358" class="Bound">i</a> <a id="17360" class="Symbol">.</a><a id="17361" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="17365" class="Symbol">=</a> <a id="17367" href="#17355" class="Bound">p</a> <a id="17369" href="#17358" class="Bound">i</a>
  <a id="17373" href="#17134" class="Function">top</a> <a id="17377" class="Symbol">.</a><a id="17378" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="17386" class="Symbol">(</a><a id="17387" href="#17387" class="Bound">x</a> <a id="17389" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17391" href="#17391" class="Bound">y</a> <a id="17393" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17395" href="#17395" class="Bound">p</a><a id="17396" class="Symbol">)</a> <a id="17398" href="#17398" class="Bound">i</a> <a id="17400" class="Symbol">.</a><a id="17401" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17405" class="Symbol">.</a><a id="17406" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a> <a id="17410" class="Symbol">=</a> <a id="17412" href="#17391" class="Bound">y</a>
  <a id="17416" href="#17134" class="Function">top</a> <a id="17420" class="Symbol">.</a><a id="17421" href="../code/binary/Lenses.html#345" class="Field">set-get</a> <a id="17429" class="Symbol">(</a><a id="17430" href="#17430" class="Bound">x</a> <a id="17432" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17434" href="#17434" class="Bound">y</a> <a id="17436" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17438" href="#17438" class="Bound">p</a><a id="17439" class="Symbol">)</a> <a id="17441" href="#17441" class="Bound">i</a> <a id="17443" class="Symbol">.</a><a id="17444" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17448" class="Symbol">.</a><a id="17449" href="../code/binary/Agda.Builtin.Sigma.html#237" class="Field">snd</a> <a id="17453" href="#17453" class="Bound">j</a> <a id="17455" class="Symbol">=</a> <a id="17457" href="#17438" class="Bound">p</a> <a id="17459" class="Symbol">(</a><a id="17460" href="#17441" class="Bound">i</a> <a id="17462" href="../code/binary/Agda.Primitive.Cubical.html#226" class="Primitive Operator">∧</a> <a id="17464" href="#17453" class="Bound">j</a><a id="17465" class="Symbol">)</a>
  <a id="17469" href="#17134" class="Function">top</a> <a id="17473" class="Symbol">.</a><a id="17474" href="../code/binary/Lenses.html#395" class="Field">set-set</a> <a id="17482" class="Symbol">_</a> <a id="17484" class="Symbol">_</a> <a id="17486" class="Symbol">_</a> <a id="17488" class="Symbol">=</a> <a id="17490" href="../code/binary/Cubical.Foundations.Prelude.html#856" class="Function">refl</a>
</pre>
</details>
<pre class="Agda">  <a id="17522" href="#17522" class="Function">update</a> <a id="17529" class="Symbol">:</a> <a id="17531" href="#10969" class="Datatype">Fin𝔹</a> <a id="17536" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a> <a id="17541" href="#6437" class="Generalizable">ds</a> <a id="17544" class="Symbol">→</a> <a id="17546" href="../code/binary/Lenses.html#203" class="Record">Lens</a> <a id="17551" class="Symbol">(</a><a id="17552" href="#15848" class="Function">Fenwick</a> <a id="17560" href="#6437" class="Generalizable">ds</a><a id="17562" class="Symbol">)</a> <a id="17564" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a>
  <a id="17568" href="#17522" class="Function">update</a> <a id="17575" href="#17575" class="Bound">is</a> <a id="17578" class="Symbol">=</a> <a id="17580" href="#14848" class="Function">ind-lens</a> <a id="17589" href="#16469" class="Function">upd-lens</a> <a id="17598" href="#17575" class="Bound">is</a> <a id="17601" href="../code/binary/Lenses.html#631" class="Function Operator">⋯</a> <a id="17603" href="#17134" class="Function">top</a>
</pre>
<p>Finally, here’s how we get the summary up to a particular point in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
time:</p>
<pre class="Agda">  <a id="17718" href="#17718" class="Function">running</a> <a id="17726" class="Symbol">:</a> <a id="17728" class="Symbol">(∀</a> <a id="17731" href="#17731" class="Bound">n</a> <a id="17733" class="Symbol">→</a> <a id="17735" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a> <a id="17740" class="Symbol">→</a> <a id="17742" href="#846" class="Generalizable">T</a> <a id="17744" class="Symbol">(</a><a id="17745" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="17749" href="#17731" class="Bound">n</a><a id="17750" class="Symbol">)</a> <a id="17752" class="Symbol">→</a> <a id="17754" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a> <a id="17756" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="17758" href="#846" class="Generalizable">T</a> <a id="17760" href="#17731" class="Bound">n</a><a id="17761" class="Symbol">)</a>
          <a id="17773" class="Symbol">→</a> <a id="17775" class="Symbol">(∀</a> <a id="17778" href="#17778" class="Bound">n</a> <a id="17780" class="Symbol">→</a> <a id="17782" href="#846" class="Generalizable">T</a> <a id="17784" href="#17778" class="Bound">n</a> <a id="17786" class="Symbol">→</a> <a id="17788" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a><a id="17789" class="Symbol">)</a>
          <a id="17801" class="Symbol">→</a> <a id="17803" href="#7823" class="Datatype">Array</a> <a id="17809" href="#846" class="Generalizable">T</a> <a id="17811" href="#6437" class="Generalizable">ds</a>
          <a id="17824" class="Symbol">→</a> <a id="17826" href="#10969" class="Datatype">Fin𝔹</a> <a id="17831" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a> <a id="17836" href="#6437" class="Generalizable">ds</a>
          <a id="17849" class="Symbol">→</a> <a id="17851" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a> <a id="17853" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="17855" href="#846" class="Generalizable">T</a> <a id="17857" class="Number">0</a>
  <a id="17861" href="#17718" class="Function">running</a> <a id="17869" href="#17869" class="Bound">l</a> <a id="17871" href="#17871" class="Bound">s</a> <a id="17873" class="Symbol">(</a><a id="17874" href="#17874" class="Bound">x</a> <a id="17876" href="#7886" class="InductiveConstructor Operator">∷</a> <a id="17878" href="#17878" class="Bound">xs</a><a id="17880" class="Symbol">)</a> <a id="17882" class="Symbol">(</a><a id="17883" href="#11105" class="InductiveConstructor">there</a> <a id="17889" href="#17889" class="Bound">i</a> <a id="17891" href="#17891" class="Bound">is</a><a id="17893" class="Symbol">)</a> <a id="17895" class="Symbol">=</a>
    <a id="17901" class="Keyword">let</a> <a id="17905" href="#17905" class="Bound">y</a> <a id="17907" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17909" href="#17909" class="Bound">ys</a> <a id="17912" class="Symbol">=</a> <a id="17914" href="#17718" class="Function">running</a> <a id="17922" class="Symbol">(</a><a id="17923" href="#17869" class="Bound">l</a> <a id="17925" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="17927" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="17930" class="Symbol">)</a> <a id="17932" class="Symbol">(</a><a id="17933" href="#17871" class="Bound">s</a> <a id="17935" href="../code/binary/Prelude.html#942" class="Function Operator">∘</a> <a id="17937" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="17940" class="Symbol">)</a> <a id="17942" href="#17878" class="Bound">xs</a> <a id="17945" href="#17891" class="Bound">is</a>
        <a id="17956" href="#17956" class="Bound">z</a> <a id="17958" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17960" href="#17960" class="Bound">zs</a> <a id="17963" class="Symbol">=</a> <a id="17965" href="#17869" class="Bound">l</a> <a id="17967" class="Symbol">_</a> <a id="17969" href="#17889" class="Bound">i</a> <a id="17971" href="#17909" class="Bound">ys</a>
    <a id="17978" class="Keyword">in</a> <a id="17981" href="#17871" class="Bound">s</a> <a id="17983" class="Symbol">_</a> <a id="17985" href="#17874" class="Bound">x</a> <a id="17987" href="../code/binary/Prelude.html#1196" class="Field Operator">∙</a> <a id="17989" href="#17905" class="Bound">y</a> <a id="17991" href="../code/binary/Prelude.html#1196" class="Field Operator">∙</a> <a id="17993" href="#17956" class="Bound">z</a> <a id="17995" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="17997" href="#17960" class="Bound">zs</a>
  <a id="18002" href="#17718" class="Function">running</a> <a id="18010" href="#18010" class="Bound">l</a> <a id="18012" href="#18012" class="Bound">s</a> <a id="18014" class="Symbol">(</a><a id="18015" href="#18015" class="Bound">x</a> <a id="18017" href="#7956" class="InductiveConstructor Operator">1∷</a> <a id="18020" href="#18020" class="Bound">xs</a><a id="18022" class="Symbol">)</a> <a id="18024" href="#11007" class="InductiveConstructor">here₁</a> <a id="18030" class="Symbol">=</a> <a id="18032" href="../code/binary/Prelude.html#1216" class="Field">ε</a> <a id="18034" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18036" href="#18015" class="Bound">x</a>
  <a id="18040" href="#17718" class="Function">running</a> <a id="18048" href="#18048" class="Bound">l</a> <a id="18050" href="#18050" class="Bound">s</a> <a id="18052" class="Symbol">(</a><a id="18053" href="#18053" class="Bound">x</a> <a id="18055" href="#7994" class="InductiveConstructor Operator">2∷</a> <a id="18058" href="#18058" class="Bound">xs</a><a id="18060" class="Symbol">)</a> <a id="18062" class="Symbol">(</a><a id="18063" href="#11056" class="InductiveConstructor">here₂</a> <a id="18069" href="#18069" class="Bound">i</a><a id="18070" class="Symbol">)</a> <a id="18072" class="Symbol">=</a> <a id="18074" href="#18048" class="Bound">l</a> <a id="18076" class="Symbol">_</a> <a id="18078" href="#18069" class="Bound">i</a> <a id="18080" href="#18053" class="Bound">x</a>

  <a id="18085" href="#18085" class="Function">prefix</a> <a id="18092" class="Symbol">:</a> <a id="18094" href="#15848" class="Function">Fenwick</a> <a id="18102" href="#6437" class="Generalizable">ds</a> <a id="18105" class="Symbol">→</a> <a id="18107" href="#10969" class="Datatype">Fin𝔹</a> <a id="18112" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a> <a id="18117" href="#6437" class="Generalizable">ds</a> <a id="18120" class="Symbol">→</a> <a id="18122" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a>
  <a id="18126" href="#18085" class="Function">prefix</a> <a id="18133" href="#18133" class="Bound">xs</a> <a id="18136" href="#18136" class="Bound">is</a> <a id="18139" class="Symbol">=</a> <a id="18141" class="Keyword">let</a> <a id="18145" href="#18145" class="Bound">ys</a> <a id="18148" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18150" href="#18150" class="Bound">zs</a> <a id="18153" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18155" class="Symbol">_</a> <a id="18157" class="Symbol">=</a> <a id="18159" href="#17718" class="Function">running</a> <a id="18167" href="#18214" class="Function">ind</a> <a id="18171" class="Symbol">(λ</a> <a id="18174" href="#18174" class="Bound">_</a> <a id="18176" class="Symbol">→</a> <a id="18178" href="../code/binary/Agda.Builtin.Sigma.html#225" class="Field">fst</a><a id="18181" class="Symbol">)</a> <a id="18183" href="#18133" class="Bound">xs</a> <a id="18186" href="#18136" class="Bound">is</a> <a id="18189" class="Keyword">in</a> <a id="18192" href="#18145" class="Bound">ys</a> <a id="18195" href="../code/binary/Prelude.html#1196" class="Field Operator">∙</a> <a id="18197" href="#18150" class="Bound">zs</a>
    <a id="18204" class="Keyword">where</a>
    <a id="18214" href="#18214" class="Function">ind</a> <a id="18218" class="Symbol">:</a> <a id="18220" class="Symbol">∀</a> <a id="18222" href="#18222" class="Bound">n</a> <a id="18224" class="Symbol">→</a> <a id="18226" href="../code/binary/Prelude.html#1369" class="Datatype">Bool</a> <a id="18231" class="Symbol">→</a> <a id="18233" href="#15699" class="Function">Summary</a> <a id="18241" class="Symbol">(</a><a id="18242" href="../code/binary/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="18246" href="#18222" class="Bound">n</a><a id="18247" class="Symbol">)</a> <a id="18249" class="Symbol">→</a> <a id="18251" href="../code/binary/Prelude.html#1182" class="Field">𝑆</a> <a id="18253" href="../code/binary/Prelude.html#621" class="Function Operator">×</a> <a id="18255" href="#15699" class="Function">Summary</a> <a id="18263" href="#18222" class="Bound">n</a>
    <a id="18269" href="#18214" class="Function">ind</a> <a id="18273" href="#18273" class="Bound">n</a> <a id="18275" href="../code/binary/Prelude.html#1388" class="InductiveConstructor">false</a> <a id="18281" class="Symbol">(_</a> <a id="18284" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18286" class="Symbol">(</a><a id="18287" href="#18287" class="Bound">xs</a> <a id="18290" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18292" class="Symbol">_)</a> <a id="18295" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18297" class="Symbol">_)</a> <a id="18300" class="Symbol">=</a> <a id="18302" href="../code/binary/Prelude.html#1216" class="Field">ε</a> <a id="18304" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18306" href="#18287" class="Bound">xs</a>
    <a id="18313" href="#18214" class="Function">ind</a> <a id="18317" href="#18317" class="Bound">n</a> <a id="18319" href="../code/binary/Prelude.html#1403" class="InductiveConstructor">true</a>  <a id="18325" class="Symbol">(_</a> <a id="18328" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18330" class="Symbol">((</a><a id="18332" href="#18332" class="Bound">x</a> <a id="18334" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18336" class="Symbol">_)</a> <a id="18339" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18341" class="Symbol">(</a><a id="18342" href="#18342" class="Bound">y</a> <a id="18344" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18346" href="#18346" class="Bound">ys</a><a id="18348" class="Symbol">))</a> <a id="18351" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18353" class="Symbol">_)</a> <a id="18356" class="Symbol">=</a> <a id="18358" href="#18332" class="Bound">x</a> <a id="18360" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18362" class="Symbol">(</a><a id="18363" href="#18342" class="Bound">y</a> <a id="18365" href="../code/binary/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="18367" href="#18346" class="Bound">ys</a><a id="18369" class="Symbol">)</a>
</pre>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-danvyThereBackAgain2005" class="csl-entry" role="listitem">
Danvy, Olivier, and Mayer Goldberg. 2005. <span>“There and <span>Back
Again</span>.”</span> <em>BRICS Report Series</em> 12 (3). doi:<a
href="https://doi.org/10.7146/brics.v12i3.21869">10.7146/brics.v12i3.21869</a>.
</div>
<div id="ref-fonerThereBackAgain2016" class="csl-entry" role="listitem">
Foner, Kenneth. 2016. <span>“’<span>There</span> and <span>Back
Again</span>’ and <span>What Happened After</span>.”</span> <span>New
York</span>.
</div>
<div id="ref-okasakiPurelyFunctionalRandomaccess1995" class="csl-entry"
role="listitem">
Okasaki, Chris. 1995. <span>“Purely <span>Functional
Random</span>-access <span>Lists</span>.”</span> In <em>Proceedings of
the <span>Seventh International Conference</span> on <span>Functional
Programming Languages</span> and <span>Computer
Architecture</span></em>, 86–95. <span>FPCA</span> ’95. <span>New York,
NY, USA</span>: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/224164.224187">10.1145/224164.224187</a>.
</div>
<div id="ref-swierstraHeterogeneousRandomaccessLists2019"
class="csl-entry" role="listitem">
Swierstra, Wouter. 2019. <span>“Heterogeneous random-access
lists.”</span>
</div>
</div>
]]></description>
    <pubDate>Sat, 02 Nov 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-11-02-how-to-binary-random-access-list.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>What is Good About Haskell?</title>
    <link>https://doisinkidney.com/posts/2019-10-02-what-is-good-about-haskell.html</link>
    <description><![CDATA[<div class="info">
    Posted on October  2, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Update 5/10/2019: check the bottom of this post for some links to
comments and discussion.</p>
<p>Beginners to Haskell are often confused as to what’s so great about
the language. Much of the proselytizing online focuses on pretty
abstract (and often poorly defined) concepts like “purity”, “strong
types”, and (god forbid) “monads”. These things are difficult to
understand, somewhat controversial, and not obviously beneficial
(especially when you’ve only been using the language for a short amount
of time).</p>
<p>The real tragedy is that Haskell (and other ML-family languages) are
<em>packed</em> with simple, decades-old features like pattern matching
and algebraic data types which have massive, clear benefits and few (if
any) downsides. Some of these ideas are finally filtering in to
mainstream languages (like Swift and Rust) where they’re used to great
effect, but the vast majority of programmers out there haven’t yet been
exposed to them.</p>
<p>This post aims to demonstrate some of these features in a simple (but
hopefully not too simple) example. I’m going to write and package up a
simple sorting algorithm in both Haskell and Python, and compare the
code in each. I’m choosing Python because I like it and beginners like
it, but also because it’s missing most of the features I’ll be
demonstrating. It’s important to note I’m not comparing Haskell and
Python as languages: the Python code is just there as a reference for
people less familiar with Haskell. What’s more, the comparison is
unfair, as the example deliberately plays to Haskell’s strengths (so I
can show off the features I’m interested in): it wouldn’t be difficult
to pick an example that makes Python look good and Haskell look
poor.</p>
<p>This post is not meant to say “Haskell is great, and your language
sucks”! It’s not even really about Haskell: much of what I’m talking
about here applies equally well to Ocaml, Rust, etc. I’m really writing
this as a response to the notion that functional features are somehow
experimental, overly complex, or ultimately compromised. As a result of
that idea, I feel like these features are left out of a lot of modern
languages which would benefit from them. There exists a small set of
simple, battle-tested PL ideas, which have been used for nearly forty
years now: this post aims to demonstrate them, and argue for their
inclusion in every general-purpose programming language that’s being
designed today.</p>
<h1 id="the-algorithm">The Algorithm</h1>
<p>We’ll be using a <a
href="https://en.wikipedia.org/wiki/Skew_heap">skew heap</a> to sort
lists in both languages. The basic idea is to repeatedly insert stuff
into the heap, and then repeatedly “pop” the smallest element from the
heap until it’s empty. It’s not in-place, but it is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>,
and actually performs pretty well in practice.</p>
<h1 id="a-tree">A Tree</h1>
<p>A Skew Heap is represented by a <em>binary tree</em>:</p>
<style>
.column {
    float: left;
    width: 50%;
}
.row:after {
    content: "";
    display: table;
    clear: both;
}
</style>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Leaf</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Node</span> a (<span class="dt">Tree</span> a) (<span class="dt">Tree</span> a)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb2"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Tree:</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, is_node, data, lchild, rchild):</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="va">self</span>._is_node <span class="op">=</span> is_node</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="va">self</span>._data <span class="op">=</span> data</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="va">self</span>._lchild <span class="op">=</span> lchild</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="va">self</span>._rchild <span class="op">=</span> rchild</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> leaf():</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> Tree(<span class="va">False</span>, <span class="va">None</span>, <span class="va">None</span>, <span class="va">None</span>)</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> node(data, lchild, rchild):</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> Tree(<span class="va">True</span>, data, lchild, rchild)</span></code></pre></div>
</div>
</div>
<p>I want to point out the precision of the Haskell definition: a tree
is either a leaf (an empty tree), or a node, with a payload and two
children. There are no special cases, and it took us one line to write
(spread to 3 here for legibility on smaller screens).</p>
<p>In Python, we have to write a few more lines<a href="#fn1"
class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>.
This representation uses the <code>_is_node</code> field is
<code>False</code> for an empty tree (a leaf). If it’s
<code>True</code>, the other fields are filled. We write some helper
functions to give us constructors like the leaf and node ones for the
Haskell example.</p>
<p>This isn’t the standard definition of a binary tree in Python, in
fact it might looks a little weird to most Python people. Let’s run
through some alternatives and their issues.</p>
<ol>
<li><p>The standard definition:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Tree:</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, data, lchild, rchild):</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="va">self</span>._data <span class="op">=</span> data</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="va">self</span>._lchild <span class="op">=</span> lchild</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="va">self</span>._rchild <span class="op">=</span> rchild</span></code></pre></div>
<p>Instead of having a separate field for “is this a leaf or a node”,
the empty tree is simply <code>None</code>:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> leaf():</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="va">None</span></span></code></pre></div>
<p>With this approach, if we define any <em>methods</em> on a tree, they
won’t work on the empty tree!</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> leaf().size()</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="pp">AttributeError</span>: <span class="st">&#39;NoneType&#39;</span> <span class="bu">object</span> has no attribute <span class="st">&#39;size&#39;</span></span></code></pre></div></li>
<li><p>We’ll do inheritance! Python even has a handy <code>abc</code>
library to help us with some of this:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> abc <span class="im">import</span> ABC, abstractmethod</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Tree(ABC):</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="at">@abstractmethod</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> size(<span class="va">self</span>):</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>        <span class="cf">raise</span> <span class="va">NotImplemented</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Leaf(Tree):</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">pass</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> size(<span class="va">self</span>):</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">0</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> Node(Tree):</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>, data, lchild, rchild):</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>        <span class="va">self</span>._data <span class="op">=</span> data</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>        <span class="va">self</span>._lchild <span class="op">=</span> lchild</span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>        <span class="va">self</span>._rchild <span class="op">=</span> rchild</span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> size(<span class="va">self</span>):</span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="dv">1</span> <span class="op">+</span> <span class="va">self</span>._lchild.size() <span class="op">+</span> <span class="va">self</span>._rchild.size()</span></code></pre></div>
<p>Methods will now work on an empty tree, but we’re faced with 2
problems: first, this is very verbose, and pretty complex. Secondly, we
can’t write a mutating method which changes a tree from a leaf to a
node. In other words, we can’t write an <code>insert</code>
method!</p></li>
<li><p>We won’t represent a leaf as the whole <em>tree</em> being
<code>None</code>, just the data!</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> leaf():</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Tree(<span class="va">None</span>, <span class="va">None</span>, <span class="va">None</span>)</span></code></pre></div>
<p>This (surprisingly) pops up in a few places. While it solves the
problem of methods, and the mutation problem, it has a serious bug. We
can’t have <code>None</code> as an element in the tree! In other words,
if we ask our eventual algorithm to sort a list which contains
<code>None</code>, it will silently discard some of the list, returning
the wrong answer.</p></li>
</ol>
<p>There are yet more options (using a wrapper class), none of them
ideal. Another thing to point out is that, even with our definition with
a tag, we can only represent types with 2 possible states. If there was
another type of node in the tree, we couldn’t simply use a boolean tag:
we’d have to switch to integers (and remember the meaning of each
integer), or strings! Yuck!</p>
<p>What Python is fundamentally missing here is <em>algebraic data
types</em>. This is a way of building up all of your types out of
products (“my type has this <em>and</em> this”) and sums (“my type is
this <em>or</em> this”). Python can do products perfectly well: that’s
what classes are. The tree class itself is the product of
<code>Bool</code>, <code>data</code>, <code>Tree</code>, and
<code>Tree</code>. However it’s missing an <em>entire half of the
equation</em>! This is why you just can’t express binary trees as
cleanly as you can in Swift, Haskell, OCaml, etc. Python, as well as a
host of other languages like Go, Java, etc, will let you express
<em>one</em> kind of “sum” type: “or nothing” (the null pointer).
However, it’s clunky and poorly handled in all of those languages (the
method problems above demonstrate the issues in Python), and doesn’t
work for anything other than that one special case.</p>
<p>Again, there’s nothing about algebraic data types that makes them
ill-suited to mainstream or imperative languages. Swift uses them, and
<a href="https://www.caseyliss.com/2016/2/27/swift-enums">people love
them</a>!</p>
<h1 id="a-function">A Function</h1>
<p>The core operation on skew heaps is the <em>skew merge</em>.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>merge <span class="dt">Leaf</span> ys <span class="ot">=</span> ys</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>merge xs <span class="dt">Leaf</span> <span class="ot">=</span> xs</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>merge xs<span class="op">@</span>(<span class="dt">Node</span> x xl xr) ys<span class="op">@</span>(<span class="dt">Node</span> y yl yr)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>   <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> <span class="dt">Node</span> x (merge ys xr) xl</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>   <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Node</span> y (merge xs yr) yl</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb9"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> merge(lhs, rhs):</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="kw">not</span> lhs._is_node:</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> rhs</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="kw">not</span> rhs._is_node:</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> lhs</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> lhs._data <span class="op">&lt;=</span> rhs._data:</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Tree(lhs._data,</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>                merge(rhs, lhs._rchild),</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>                lhs._lchild)</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>  <span class="cf">else</span>:</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Tree(rhs._data,</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>                merge(lhs, rhs._rchild),</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>                rhs._lchild)</span></code></pre></div>
</div>
</div>
<p>The standout feature here is pattern matching. In Haskell, we’re able
to write the function as we might describe it: “in this case, I’ll do
this, in this other case, I’ll do this, etc.”. In Python, we are forced
to think of the truth tables and sequential testing. What do I mean by
truth tables? Consider the following version of the Python function
above:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> merge(lhs, rhs):</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> lhs._is_node:</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> rhs._is_node:</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> lhs._data <span class="op">&lt;=</span> rhs._data:</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> Tree(lhs._data,</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>                    merge(rhs, lhs._rchild),</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>                    lhs._lchild)</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>      <span class="cf">else</span>:</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> Tree(rhs._data,</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>                    merge(lhs, rhs._rchild),</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>                    rhs._lchild)</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> lhs</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>  <span class="cf">else</span>:</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> rhs</span></code></pre></div>
<p>You may even write this version first: it initially seems more
natural (because <code>_is_node</code> is used in the positive). Here’s
the question, though: does it do the same thing as the previous version?
Are you <em>sure</em>? Which else is connected to which if? Does every
if have an else? (some linters will suggest you <em>remove</em> some of
the elses above, since the if-clause has a <code>return</code> statement
in it!)</p>
<p>The fact of the matter is that we are forced to do truth tables of
every condition in our minds, rather than <em>saying what we mean</em>
(as we do in the Haskell version).</p>
<p>The other thing we’re saved from in the Haskell version is accessing
undefined fields. In the Python function, we know accessing
<code>lhs._data</code> is correct since we verified that
<code>lhs</code> is a node. But the logic to do this verification is
complex: we checked if it <em>wasn’t</em> a node, and returned if that
was true… so if it <em>is true</em> that <code>lhs</code> <em>isn’t</em>
a node, we would have returned, but we didn’t, so…</p>
<p>Bear in mind all of these logic checks happened four lines before the
actual access: this can get much uglier in practice! Compare this to the
Haskell version: <em>we only get to bind variables if we’re sure they
exist</em>. The syntax itself prevents us from accessing fields which
aren’t defined, in a simple way.</p>
<p>Pattern matching has existed for years in many different forms: even
C has switch statements. The added feature of destructuring is available
in languages like Swift, Rust, and the whole ML family. Ask for it in
your language today!</p>
<p>Now that we have that function, we get to define others in terms of
it:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>insert x <span class="ot">=</span> merge (<span class="dt">Node</span> x <span class="dt">Leaf</span> <span class="dt">Leaf</span>)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb12"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> insert(element, tree):</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    tree.__dict__ <span class="op">=</span> merge(</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>        node(element, leaf(), leaf()),</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>        tree</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    ).__dict__.copy()</span></code></pre></div>
</div>
</div>
<h1 id="a-word-on-types">A Word on Types</h1>
<p>I haven’t mentioned Haskell’s type system so far, as it’s been quite
unobtrusive in the examples. And that’s kind of the point: despite more
complex examples you’ll see online demonstrating the power of type
classes and higher-kinded types, Haskell’s type system <em>excels</em>
in these simpler cases.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span></code></pre></div>
<p>Without much ceremony, this signature tells us:</p>
<ol>
<li>The function takes two trees, and returns a third.</li>
<li>Both trees have to be filled with the same types of elements.</li>
<li>Those elements must have an order defined on them.</li>
</ol>
<h1 id="type-inference">Type Inference</h1>
<p>I feel a lot of people miss the point of this particular feature.
Technically speaking, this feature allows us to write fewer type
signatures, as Haskell will be able to guess most of them. Coming from
something like Java, you might think that that’s an opportunity to
shorten up some verbose code. It’s not! You’ll rarely find a Haskell
program these days missing top-level type signatures: it’s easier to
read a program with explicit type signatures, so people are advised to
put them as much as possible.</p>
<p>(Amusingly, I often find older Haskell code snippets which are
entirely devoid of type signatures. It seems that programmers were so
excited about Hindley-Milner type inference that they would put it to
the test as often as they could.)</p>
<p>Type inference in Haskell is actually useful in a different way.
First, if I write the <em>implementation</em> of the <code>merge</code>
function, the compiler will tell <em>me</em> the signature, which is
extremely helpful for more complex examples. Take the following, for
instance:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>f x <span class="ot">=</span> ((x <span class="op">*</span> <span class="dv">2</span>) <span class="op">^</span> <span class="dv">3</span>) <span class="op">/</span> <span class="dv">4</span></span></code></pre></div>
<p>Remembering precisely which numeric type <code>x</code> needs to be
is a little difficult (<code>Floating</code>? <code>Real</code>?
<code>Fractional</code>?), but if I just ask the compiler it will tell
me without difficulty.</p>
<p>The second use is kind of the opposite: if I have a hole in my
program where I need to fill in some code, Haskell can help me along by
telling me the <em>type</em> of that hole automatically. This is often
enough information to figure out the entire implementation! In fact,
there are some programs which will use this capability of the type
checker to fill in the hole with valid programs, synthesising your code
for you.</p>
<p>So often strong type systems can make you feel like you’re fighting
more and more against the compiler. I hope these couple examples show
that it doesn’t have to be that way.</p>
<h1 id="when-things-go-wrong">When Things Go Wrong</h1>
<p>The next function is “pop-min”:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">popMin ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (a, <span class="dt">Tree</span> a)</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>popMin <span class="dt">Leaf</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>popMin (<span class="dt">Node</span> x xl xr) <span class="ot">=</span> <span class="dt">Just</span> (x, merge xl xr)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb16"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> popMin(tree):</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> tree._is_node:</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    res <span class="op">=</span> tree._data</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    tree.__dict__ <span class="op">=</span> merge(</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>        tree._lchild,</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>        tree._rchild</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>    ).__dict__.copy()</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> res</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>  <span class="cf">else</span>:</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">raise</span> <span class="pp">IndexError</span></span></code></pre></div>
</div>
</div>
<p>At first glance, this function should be right at home in Python. It
<em>mutates</em> its input, and it has an error case. The code we’ve
written here for Python is pretty idiomatic, also: other than the ugly
deep copy, we’re basically just mutating the object, and using an
exception for the exceptional state (when the tree is empty). Even the
exception we use is the same exception as when you try and
<code>pop()</code> from an empty list.</p>
<p>The Haskell code here mainly demonstrates a difference in API style
you’ll see between the two languages. If something isn’t found, we just
use <code>Maybe</code>. And instead of mutating the original variable,
we return the new state in the second part of a tuple. What’s nice about
this is that we’re only using simple core features like algebraic data
types to emulate pretty complex features like exceptions in Python.</p>
<p>You may have heard that “Haskell uses monads to do mutation and
exceptions”. This is not true. Yes, state and exceptions have patterns
which technically speaking are “monadic”. But make no mistake: when we
want to model “exceptions” in Haskell, we really just return a maybe (or
an either). And when we want to do “mutation”, we return a tuple, where
the second element is the updated state. You don’t have to understand
monads to use them, and you certainly don’t “need” monads to do them. To
drive the point home, the above code could actually equivalently have a
type which mentions “the state monad” and “the maybe monad”:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">popMin ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">StateT</span> (<span class="dt">Tree</span> a) <span class="dt">Maybe</span> a</span></code></pre></div>
<p>But there’s no need to!</p>
<h1 id="gluing-it-all-together">Gluing It All Together</h1>
<p>The main part of our task is now done: all that is left is to glue
the various bits and pieces together. Remember, the overall algorithm
builds up the heap from a list, and then tears it down using
<code>popMin</code>. First, then, to build up the heap.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">listToHeap ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>listToHeap <span class="ot">=</span> <span class="fu">foldr</span> insert <span class="dt">Leaf</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb19"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> listToHeap(elements):</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  res <span class="op">=</span> leaf()</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> el <span class="kw">in</span> elements:</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    insert(el, res)</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> res</span></code></pre></div>
</div>
</div>
<p>To my eye, the Haskell code here is significantly more “readable”
than the Python. I know that’s a very subjective judgement, but
<code>foldr</code> is a function so often used that it’s immediately
clear what’s happening in this example.</p>
<p>Why didn’t we use a similar function in Python, then? We actually
could have: python does have an equivalent to <code>foldr</code>, called
<code>reduce</code> (it’s <a
href="https://docs.python.org/3/library/functools.html#functools.reduce">been
relegated to functools</a> since Python 3 (also technically it’s
equivalent to <code>foldl</code>, not <code>foldr</code>)). We’re
encouraged <em>not</em> to use it, though: the more pythonic code uses a
for loop. Also, it wouldn’t work for our use case: the
<code>insert</code> function we wrote is <em>mutating</em>, which
doesn’t gel well with <code>reduce</code>.</p>
<p>I think this demonstrates another benefit of simple, functional APIs.
If you keep things simple, and build things out of functions, they’ll
tend to glue together <em>well</em>, without having to write any glue
code yourself. The for loop, in my opinion, is “glue code”. The next
function, <code>heapToList</code>, illustrates this even more so:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">heapToList ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>heapToList <span class="ot">=</span> unfoldr popMin</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb21"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> heapToList(tree):</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  res <span class="op">=</span> []</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">try</span>:</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="va">True</span>:</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>      res.append(popMin(tree))</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">except</span> <span class="pp">IndexError</span>:</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> res</span></code></pre></div>
</div>
</div>
<p>Again, things are kept simple in the Haskell example. We’ve stuck to
data types and functions, and these data types and functions mesh well
with each other. You might be aware that there’s some deep and
interesting mathematics behind the <code>foldr</code> and
<code>unfoldr</code> functions going on, and <a
href="https://kseo.github.io/posts/2016-12-12-unfold-and-fold.html">how
they relate</a>. We don’t need to know any of that here, though: they
just work together well.</p>
<p>Again, Python does have a function which is equivalent to
<code>unfoldr</code>: <a
href="https://docs.python.org/3/library/functions.html#iter"><code>iter</code></a>
has an overload which will repeatedly call a function until it hits a
sentinel value. But this doesn’t fit with the rest of the iterator
model! Most iterators are terminated with the <code>StopIteration</code>
exception; ours (like the <code>pop</code> function on lists) is
terminated by the <code>IndexError</code> exception; and this function
expects a third version, terminated by a sentinel!</p>
<p>Finally, let’s write <code>sort</code>:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sort</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sort</span> <span class="ot">=</span> heapToList <span class="op">.</span> listToHeap</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb23"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> sort(elements):</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> heapToList(listToHeap(elements))</span></code></pre></div>
</div>
</div>
<p>This is just driving home the point: programs work <em>well</em> when
they’re built out of functions, and you <em>want</em> your language to
encourage you to build things out of functions. In this case, the
<code>sort</code> function is built out of two smaller ones: it’s the
<em>essence</em> of function composition.</p>
<h1 id="laziness">Laziness</h1>
<p>So I fully admit that laziness is one of the features of Haskell that
does have downsides. I don’t think every language should be lazy, but I
did want to say a little about it in regards to the sorting example
here.</p>
<p>I tend to think that people overstate how hard it makes reasoning
about space: it actually follows pretty straightforward rules, which you
can generally step through in yourself (compared to, for instance,
rewrite rules, which are often black magic!)</p>
<p>In modern programming, people will tend to use laziness it anyway.
Python is a great example: the <a
href="https://docs.python.org/3/library/itertools.html">itertools</a>
library is almost entirely lazy. Actually making use of the laziness,
though, is difficult and error-prone. Above, for instance, the
<code>heapToList</code> function is lazy in Haskell, but strict in
Python. Converting it to a lazy version is not the most difficult thing
in the world:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> heapToList(tree):</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">try</span>:</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> <span class="va">True</span>:</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>      <span class="cf">yield</span> popMin(tree)</span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">except</span> <span class="pp">IndexError</span>:</span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">pass</span></span></code></pre></div>
<p>But now, suddenly, the entire list API won’t work. What’s more, if we
try and access the <em>first</em> element of the returned value, we
mutate the whole thing: anyone else looking at the output of the
generator will have it mutated out from under them!</p>
<p>Laziness fundamentally makes this more reusable. Take our
<code>popMin</code> function: if we just want to view the smallest
element, without reconstructing the rest of the tree, we can actually
use <code>popMin</code> as-is. If we don’t use the second element of the
tuple we don’t pay for it. In Python, we need to write a second
function.</p>
<h1 id="testing">Testing</h1>
<p>Testing the <code>sort</code> function in Haskell is ridiculously
easy. Say we have an example sorting function that we trust, maybe a
slow but obvious insertion sort, and we want to make sure that our fast
heap sort here does the same thing. This is the test:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>quickCheck (\xs <span class="ot">-&gt;</span> <span class="fu">sort</span> (<span class="ot">xs ::</span> [<span class="dt">Int</span>]) <span class="op">===</span> insertionSort xs)</span></code></pre></div>
<p>In that single line, the <a
href="https://hackage.haskell.org/package/QuickCheck">QuickCheck</a>
library will automatically generate random input, run each sort function
on it, and compare the two outputs, giving a rich diff if they don’t
match.</p>
<h1 id="conclusion">Conclusion</h1>
<p>This post was meant to show a few features like pattern-matching,
algebraic data types, and function-based APIs in a good light. These
ideas aren’t revolutionary any more, and plenty of languages have them,
but unfortunately several languages don’t. Hopefully the example here
illustrates a little why these features are good, and pushes back
against the idea that algebraic data types are too complex for
mainstream languages.</p>
<h1 id="update-5102019">Update 5/10/2019</h1>
<p>This got posted to <a
href="https://reddit.com/r/haskell/comments/dclflr/what_is_good_about_haskell/">/r/haskell</a>
and <a
href="https://news.ycombinator.com/item?id=21145014">hackernews</a>. You
can find me arguing in the comments there a little bit: I’m <a
href="https://news.ycombinator.com/user?id=oisdk"><code>oisdk</code> on
hackernews</a> and <a
href="https://reddit.com/user/foBrowsing">u/foBrowsing on
reddit</a>.</p>
<p>There are two topics that came up a bunch that I’d like to add to
this post. First I’ll just quote <a
href="https://news.ycombinator.com/item?id=21145374">one of the
comments</a> from <a
href="https://news.ycombinator.com/user?id=Beltiras">Beltiras</a>:</p>
<blockquote>
<p>Friend of mine is always trying to convert me. Asked me to read this
yesterday evening. This is my take on the article:</p>
</blockquote>
<blockquote>
<p>Most of my daily job goes into gluing services (API endpoints to
databases or other services, some business logic in the middle). I don’t
need to see yet another exposition of how to do algorithmic tasks.
Haven’t seen one of those since doing my BSc. Show me the tools
available to write a daemon, an http server, API endpoints, ORM-type
things and you will have provided me with tools to tackle what I do.
I’ll never write a binary tree or search or a linked list at work.</p>
</blockquote>
<blockquote>
<p>If you want to convince me, show me what I need to know to do what I
do.</p>
</blockquote>
<p>and <a href="https://news.ycombinator.com/item?id=21151580">my
response</a>:</p>
<blockquote>
<p>I wasn’t really trying to convince anyone to use Haskell at their day
job: I am just a college student, after all, so I would have no idea
what I was talking about!</p>
</blockquote>
<blockquote>
<p>I wrote the article a while ago after being frustrated using a bunch
of Go and Python at an internship. Often I really wanted simple
algebraic data types and pattern-matching, but when I looked up why Go
didn’t have them I saw a lot of justifications that amounted to
“functional features are too complex and we’re making a simple language.
Haskell is notoriously complex”. In my opinion, the
<code>res, err := fun(); if err != nil</code> (for example) pattern was
much more complex than the alternative with pattern-matching. So I
wanted to write an article demonstrating that, while Haskell has a lot
of out-there stuff in it, there’s a bunch of simple ideas which really
shouldn’t be missing from any modern general-purpose language.</p>
</blockquote>
<blockquote>
<p>As to why I used a binary tree as the example, I thought it was
pretty self-contained, and I find skew heaps quite interesting.</p>
</blockquote>
<p>The second topic was basically people having a go at my ugly Python;
to which I say: fair enough! It is not my best. I wasn’t trying
necessarily to write the best Python I could here, though, rather I was
trying to write the “normal” implementation of a binary tree. If I was
to implement a binary tree of some sort myself, though, I would
certainly write it in an immutable style rather than the style here.
Bear in mind as well that much of what I’m arguing for is stylistic: I
think (for instance) that it would be better to use <code>reduce</code>
in Python more, and I think the move away from it is a bad thing. So of
course I’m not going to use reduce when I’m showing the Python version:
I’m doing a compare and contrast!</p>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Yes, I know about the new dataclasses feature. However,
it’s wrapped up with the (also new) type hints module, and as such is
much more complicated to use. As the purpose of the Python code here is
to provide something of a lingua franca for non-Haskellers, I decided
against using it. That said, the problems outlined are <em>not</em>
solved by dataclasses.<a href="#fnref1" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Wed, 02 Oct 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-10-02-what-is-good-about-haskell.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Bachelor's Thesis</title>
    <link>https://doisinkidney.com/posts/2019-07-14-bsc-thesis.html</link>
    <description><![CDATA[<div class="info">
    Posted on July 14, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>I recently finished my undergrad degree in <a
href="https://www.ucc.ie/">UCC</a>. I’m putting my final-year project up
here for reference purposes.</p>
<p><a href="/pdfs/bsc-thesis.pdf">Here</a> is the pdf.</p>
<p>And here’s a bibtext entry:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode bib"><code class="sourceCode bibtex"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="va">@thesis</span>{<span class="ot">kidney_automatically_2019</span>,</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>	<span class="dt">address</span> = {Cork, Ireland},</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>	<span class="dt">type</span> = {Bachelor thesis},</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>	<span class="dt">title</span> = {Automatically and {Efficiently} {Illustrating} {Polynomial} {Equalities} in {Agda}},</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>	<span class="dt">url</span> = {https://doisinkidney.com/pdfs/bsc-thesis.pdf},</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>	<span class="dt">abstract</span> = {We present a new library which automates the construction of equivalence proofs between polynomials over commutative rings and semirings in the programming language Agda [20]. It is signi cantly faster than Agda’s existing solver. We use re ection to provide a sim- ple interface to the solver, and demonstrate how to use the constructed proofs to provide step-by-step solutions.},</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>	<span class="dt">language</span> = {en},</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>	<span class="dt">school</span> = {University College Cork},</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>	<span class="dt">author</span> = {Kidney, Donnacha Oisín},</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>	<span class="dt">month</span> = <span class="st">apr</span>,</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>	<span class="dt">year</span> = {2019}</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
]]></description>
    <pubDate>Sun, 14 Jul 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-07-14-bsc-thesis.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Solving Programming Puzzles without using your Brain</title>
    <link>https://doisinkidney.com/posts/2019-06-04-solving-puzzles-without-your-brain.html</link>
    <description><![CDATA[<div class="info">
    Posted on June  4, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Python&#39;." href="/tags/Python.html" rel="tag">Python</a>
    
</div>

<p>This post is a write-up of a solution to part of a programming puzzle
I did yesterday. It’s a little different than the usual “solution +
theory” approach, though: I’m going to talk about the actual steps you’d
need to take to get to the solution (i.e. what to google, what
intermediate code looks like, etc.). Often write ups like this are
presented as finished artefacts, with little info on the tricks or
techniques the author used to jog their intuition into figuring out the
puzzle (or where some intermediate step requires a leap of insight). In
actual fact, this particular puzzle requires almost no insight <em>at
all</em>: I’m going to show how to get to a working solution without
understanding any of the theory behind it!</p>
<p>Spoilers ahead for the google foobar problem “Distract the
Guards”.</p>
<h1 id="the-problem">The Problem</h1>
<p>We’re interested in a particular type of sequences of pairs of
numbers. These sequences are generated from a starting pair
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>m</mi><annotation encoding="application/x-tex">m</annotation></semantics></math>
like so:</p>
<blockquote>
<p>If
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>m</mi><annotation encoding="application/x-tex">m</annotation></semantics></math>
are equal, the sequence stops.</p>
<p>Otherwise, the smaller number is subtracted from the larger, and then
the smaller is doubled, and the sequence continues with these two
numbers.</p>
</blockquote>
<p>Here’s an example starting with 3 and 5:</p>
<pre><code>     3, 5
     6, 2
     4, 4
---- done ----</code></pre>
<p>Once it hits <code>4, 4</code>, the first condition is met, and the
sequence stops. Not all of these sequences stop, however:</p>
<pre><code>     1, 4
     2, 3
     1, 4
---- done ----</code></pre>
<p>As you can see, in this case we loop back around to
<code>1, 4</code>: our task is to figure out, given a pair of numbers,
whether the sequence generated by them loops forever, or stops at some
point.</p>
<h1 id="step-1-write-a-dumb-solution">Step 1: Write a Dumb Solution</h1>
<p>This step is crucial: before trying to figure out any of the deep
mathematics behind the problem, write the dumbest thing that could work.
You’re going to need it, anyway, to test your faster versions against,
and besides, it might be good enough as-is!</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> sequence(n,m):</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="cf">while</span> n <span class="op">!=</span> m:</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>        <span class="cf">yield</span> (n,m)</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> n <span class="op">&lt;</span> m:</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>            m <span class="op">-=</span> n</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>            n <span class="op">*=</span> <span class="dv">2</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">else</span>:</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>            n <span class="op">-=</span> m</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>            m <span class="op">*=</span> <span class="dv">2</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> loops(xs):</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    seen <span class="op">=</span> <span class="bu">set</span>()</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> x <span class="kw">in</span> xs:</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> x <span class="kw">in</span> seen:</span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>            <span class="cf">return</span> <span class="va">True</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>        <span class="cf">else</span>:</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>            seen.add(x)</span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="va">False</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> solution(n,m):</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> loops(sequence(n,m))</span></code></pre></div>
<p>The first function actually generates the sequence we’re interested
in: it uses python’s generators to do so. The second function is just a
generic function that checks a sequence for duplicates. Finally, the
last function answers the question we’re interested in.</p>
<h1 id="step-2-graph-it">Step 2: Graph it</h1>
<p>Next, we want to try and spot some patterns in the answers the
function generates. Remember, we’re not really interested in figuring
out the theory at this point: if we find out that a loop only happens
when both numbers are even (for instance), that’s good enough for us and
we can stop there!</p>
<p>We humans are pattern-matching machines: to leverage our abilities,
though, we will need to visualise the data somehow. In this case, I’m
going to plot a simple scatter graph to the terminal, using the
following code (I apologise for my terrible indentation style):</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>(</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    <span class="st">&#39;</span><span class="ch">\n</span><span class="st">&#39;</span>.join(</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>        <span class="st">&#39;&#39;</span>.join(</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>            <span class="st">&#39;*&#39;</span> <span class="cf">if</span> solution(x,y) <span class="cf">else</span> <span class="st">&#39; &#39;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>            <span class="cf">for</span> x <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">1</span>,<span class="dv">81</span>)</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>        )</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> y <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">100</span>,<span class="dv">0</span>,<span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    )</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>)</span></code></pre></div>
<p>And we get the following output:</p>
<details>
<summary>
Output
</summary>
<pre><code>*************************** ******************************* ********************
**************************** *** *********** ******************************* ***
************* *************** **************************************************
****************************** *************************************************
******************************* ************************************************
******************************** *********************** ******* ***************
********************************* **********************************************
** *************************** *** *********************************************
*********************************** ********************************************
************ ******* *************** *******************************************
***** *********************** ******* *************** *************** **********
************************************** *****************************************
*************************************** ****************************************
******** ******************* *********** ***************************************
***************************************** **************************************
****************************************** ******* *********************** *****
*********** *************** *************** ************************************
******************************************** ***********************************
********************************************* **********************************
************** *********** ******************* *************** *****************
*********************************************** *******************************
************************************************ ***************************** *
***************** ******* *********************** *************************** **
********** *********************** *************** ************************* ***
*************************************************** *********************** ****
**** *************** *** ******************* ******* ********************* *****
***************************************************** ******************* ******
****************************************************** ***************** *******
*********************** ******************************* *************** ********
******************************************************** ************* *********
********* ******************************* *************** *********** **********
********************** *** ******************************* ********* ***********
*********************************************************** ******* ************
************************************************************ ***** *************
********************* ******* ******************************* *** **************
************** *********************** *********************** * ***************
*************************************************************** ****************
 ******* *********** *********** *************** ************* * ***************
* *********************************************************** *** **************
** ********************************************************* ***** *************
*** *************** *************** *********************** ******* ************
**** ***************************************************** ********* ***********
***** *************************************************** *********** **********
****** *********** ******************* ***************** ************* *********
******* *********************************************** *************** ********
******** *************** ******* ********************* ***************** *******
********* ******* *********************** *********** ******************* ******
********** ***************************************** ********************* *****
*********** *************************************** *********************** ****
************ *** *************************** ***** ************************* ***
************* *************** ******************* *************************** **
****** ******* ********************************* ************* *************** *
*************** ******************************* *******************************
**************** ***************************** *********************************
***************** *************************** **********************************
** *********** *** ******* ******* ********* ***** *********************** *****
******************* *********************** ************************************
******************** ********************* *************************************
***** ******* ******* ******************* *********** *************** **********
********************** ***************** ***************************************
*********************** *************** ****************************************
******** *** *********** ************* ***************** ******* ***************
************************* *********** ******************************************
************************** ********* *******************************************
*********** *************** ******* *********************** ********************
**** *************** ******* ***** ********* ******************************* ***
***************************** *** **********************************************
********** *** *************** * ********************* ******* *****************
******************************* ************************************************
 ***************************** * ***********************************************
* ******* ******* *********** *** *************** *************** **************
** ************************* ***** *********************************************
*** *********************** ******* ********************************************
**** *** *********** ***** ********* ******* *********************** ***********
***** ******************* *********** *************************************** **
****** ******* ********* ************* *************** ******************* *****
******* *************** *************** ******************************* ********
******** ************* ***************** *************************** ***********
********* *********** ******************* *********************** **************
** *** *** ********* ***** ******* ******* ******************* *********** *****
*********** ******* *********************** *************** ********************
************ ***** ************************* *********** ***********************
***** ******* *** *********** *************** ******* *********************** **
************** * ***************************** *** *****************************
*************** ******************************* ********************************
 *** *** ***** * ******* ******* *********** *** *************** ***************
* *********** *** *********************** ******* ******************************
** ********* ***** ******************* *********** *****************************
*** ******* ******* *************** *************** ****************************
**** ***** ********* *********** ******************* *********************** ***
***** *** *********** ******* *********************** *************** **********
** *** * ***** ******* *** *********** *************** ******* *****************
******* *************** ******************************* ************************
 ***** * *********** *** *********************** ******* ***********************
* *** *** ******* ******* *************** *************** **********************
** * ***** *** *********** ******* *********************** *************** *****
*** ******* *************** ******************************* ********************
 * * *** *** ******* ******* *************** *************** *******************
* *** ******* *************** ******************************* ******************
 * *** ******* *************** ******************************* *****************</code></pre>
</details>
<p>There’s a clear pattern there, but it might be easier to see if we
inverted it, plotting those things which <em>don’t</em> loop:</p>
<details>
<summary>
Output
</summary>
<pre><code>                           *                               *
                            *   *           *                               *
             *               *
                              *
                               *
                                *                       *       *
                                 *
  *                           *   *
                                   *
            *       *               *
     *                       *       *               *               *
                                      *
                                       *
        *                   *           *
                                         *
                                          *       *                       *
           *               *               *
                                            *
                                             *
              *           *                   *               *
                                               *                               *
                                                *                             *
                 *       *                       *                           *
          *                       *               *                         *
                                                   *                       *
    *               *   *                   *       *                     *
                                                     *                   *
                                                      *                 *
                       *                               *               *
                                                        *             *
         *                               *               *           *
                      *   *                               *         *
                                                           *       *
                                                            *     *
                     *       *                               *   *
              *                       *                       * *
                                                               *
*       *           *           *               *             * *
 *                                                           *   *
  *                                                         *     *
   *               *               *                       *       *
    *                                                     *         *
     *                                                   *           *
      *           *                   *                 *             *
       *                                               *               *
        *               *       *                     *                 *
         *       *                       *           *                   *
          *                                         *                     *
           *                                       *                       *
            *   *                           *     *                         *
             *               *                   *                           *
      *       *                                 *             *               *
               *                               *                               *
                *                             *
                 *                           *
  *           *   *       *       *         *     *                       *
                   *                       *
                    *                     *
     *       *       *                   *           *               *
                      *                 *
                       *               *
        *   *           *             *                 *       *
                         *           *
                          *         *
           *               *       *                       *
    *               *       *     *         *                               *
                             *   *
          *   *               * *                     *       *
                               *
*                             * *
 *       *       *           *   *               *               *
  *                         *     *
   *                       *       *
    *   *           *     *         *       *                       *
     *                   *           *                                       *
      *       *         *             *               *                   *
       *               *               *                               *
        *             *                 *                           *
         *           *                   *                       *
  *   *   *         *     *       *       *                   *           *
           *       *                       *               *
            *     *                         *           *
     *       *   *           *               *       *                       *
              * *                             *   *
               *                               *
*   *   *     * *       *       *           *   *               *
 *           *   *                       *       *
  *         *     *                   *           *
   *       *       *               *               *
    *     *         *           *                   *                       *
     *   *           *       *                       *               *
  *   * *     *       *   *           *               *       *
       *               *                               *
*     * *           *   *                       *       *
 *   *   *       *       *               *               *
  * *     *   *           *       *                       *               *
   *       *               *                               *
* * *   *   *       *       *               *               *
 *   *       *               *                               *
* *   *       *               *                               *</code></pre>
</details>
<p>For this kind of thing it’s also worth getting familiar with <a
href="http://www.gnuplot.info/">gnuplot</a>.</p>
<h1 id="step-3-reduce-the-space">Step 3: Reduce The Space</h1>
<p>The clearest pattern in the graph above is the straight lines coming
from the origin. This tells me, straight away, that we have an
opportunity for optimisation if we wanted to memoize. We can’t yet be
sure, but it <em>looks</em> like every point belongs to one of these
straight lines. That means that once we find a non-looping pair like
<code>3, 5</code>, we can extend that line out to <code>6, 10</code> and
<code>9, 15</code>, etc.</p>
<p>We can also see that the graph has a symmetry through the line
<code>x = y</code>. This means that if <code>3, 5</code> doesn’t loop,
neither does <code>5, 3</code>.</p>
<p>Both of these techniques allow us to reduce the arguments to a
canonical form, making the memoization table smaller, also. In code:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> fractions <span class="im">import</span> Fraction</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> canonical(n,m):</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    f <span class="op">=</span> Fraction(n,m) <span class="cf">if</span> n <span class="op">&lt;=</span> m <span class="cf">else</span> Fraction(m,n)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> (f.numerator, f.denominator)</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>memo_dict <span class="op">=</span> {}</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> solution(n,m):</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    c <span class="op">=</span> canonical(n, m)</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">try</span>:</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> memo_dict[c]</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">except</span> <span class="pp">KeyError</span>:</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>      r <span class="op">=</span> loops(sequence(<span class="op">*</span>c))</span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>      memo_dict[c] <span class="op">=</span> r</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> r</span></code></pre></div>
<h1 id="step-4-test">Step 4: Test</h1>
<p>Now that we have our faster version, we want to be able to quickly
check that it’s equivalent to the slow. While Python is usually great
for programming puzzles, this step in particular is crying out for
something like QuickCheck: without it, we’ll have to roll our own.</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> random <span class="im">import</span> randrange</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> _ <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">1000</span>):</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    x, y <span class="op">=</span> randrange(<span class="dv">1</span>,<span class="dv">10000</span>), randrange(<span class="dv">1</span>,<span class="dv">10000</span>)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> solution_new(x,y) <span class="op">!=</span> solution_old(x,y):</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        <span class="bu">print</span>(x,y)</span></code></pre></div>
<p>We’re not looking for certainty here, just something that will
quickly spot an error if one exists.</p>
<h1 id="step-5-more-sophisticated-patterns">Step 5: More Sophisticated
Patterns</h1>
<p>Now that we’ve made some of the more obvious optimisations, it’s time
to move on to finding another pattern in the output. To do this, we’ll
use <a href="https://oeis.org/">oeis.org</a>. We want to find if the
pairs which pass our test follow some sequence which has a simple
generating function which we can adapt into a test.</p>
<p>Since the things we’re testing are pairs, rather than individual
numbers, we’ll have to fix one of them and see if there’s a pattern in
the other.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="bu">print</span>([x <span class="cf">for</span> x <span class="kw">in</span> <span class="bu">range</span>(<span class="dv">1</span>,<span class="dv">101</span>) <span class="cf">if</span> <span class="kw">not</span> solution(<span class="dv">1</span>, x)])</span></code></pre></div>
<p>This prints the following sequence:</p>
<pre><code>[1, 3, 7, 15, 31, 63]</code></pre>
<p>And when we search for it on oeis, we get <a
href="https://oeis.org/A000225">this</a> as the top result:</p>
<pre><code>0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767,
65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215,
33554431, 67108863...</code></pre>
<p>And looking at the comments under the sequence, we see the
following:</p>
<blockquote>
<p>Numbers n for which the expression 2^n/(n+1) is an integer. - <a
href="https://oeis.org/wiki/User:Paolo_P._Lava">Paolo P. Lava</a>, May
12 2006</p>
</blockquote>
<p>A test for members of the sequence, all packaged up for us!</p>
<p>But how do we generalise to pairs other than 1? Well, as a total
guess, we can see that 1 appears in one place in the formula: why not
replace that with the other member of the pair?</p>
<p>After that, we get the following function to test:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> solution(n,m):</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    nc, mc <span class="op">=</span> canonical(n,m)</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="bu">bool</span>((<span class="dv">2</span> <span class="op">**</span> mc) <span class="op">%</span> (nc <span class="op">+</span> mc))</span></code></pre></div>
<p>And it works!</p>
<h1 id="step-6-look-for-algorithms">Step 6: Look For Algorithms</h1>
<p>This last step is pretty straightforward: see if there’s an algorithm
already out there that solves your problem. In our case, taking the
modulus is still pretty slow, but it turns out that modular
exponentiation (i.e. computing expressions of the form
<code>x^y mod z</code>) can be done <a
href="https://en.wikipedia.org/wiki/Modular_exponentiation">faster</a>
than the naive way. In fact, python provides this algorithm as a
function in the standard library, making our last version of the
function the following:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> solution(n,m):</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    nc, mc <span class="op">=</span> canonical(n,m)</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="bu">bool</span>(<span class="bu">pow</span>(<span class="dv">2</span>, mc, nc <span class="op">+</span> mc))</span></code></pre></div>
<p>I’m not sure if this function is fully correct, but it was accepted
as a solution to the puzzle.</p>
<p>Anyway, in conclusion: you can get quite far through a programming
puzzle by applying some educated guesses and googling!</p>
]]></description>
    <pubDate>Tue, 04 Jun 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-06-04-solving-puzzles-without-your-brain.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Deriving a Linear-Time Applicative Traversal of a Rose Tree</title>
    <link>https://doisinkidney.com/posts/2019-05-28-linear-phases.html</link>
    <description><![CDATA[<div class="info">
    Posted on May 28, 2019
</div>
<div class="info">
    
        Part 7 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<h1 id="the-story-so-far">The Story so Far</h1>
<p>Currently, we have several different ways to enumerate a tree in
breadth-first order. The typical solution (which is the usual
recommended approach in imperative programming as well) uses a
<em>queue</em>, as described by <span class="citation"
data-cites="okasaki_breadth-first_2000">Okasaki (<a
href="#ref-okasaki_breadth-first_2000"
role="doc-biblioref">2000</a>)</span>. If we take the simplest possible
queue (a list), we get a quadratic-time algorithm, with an albeit simple
implementation. The next simplest version is to use a banker’s queue
(which is just a pair of lists). From this version, if we inline and
apply identities like the following:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldr</span> f b <span class="op">.</span> <span class="fu">reverse</span> <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">flip</span> f) b</span></code></pre></div>
<p>We’ll get to the following definition:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfe ::</span> <span class="dt">Forest</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>bfe ts <span class="ot">=</span> <span class="fu">foldr</span> f b ts []</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (xs <span class="op">:</span> bw)</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b qs []</span></code></pre></div>
<p>We can get from this function to others (like one which uses a
corecursive queue, and so on) through a similar derivation. I might some
day write a post on each derivation, starting from the simple version
and demonstrating how to get to the more efficient at each step.</p>
<p>For today, though, I’m interested in the <em>traversal</em> of a rose
tree. Traversal, here, of course, is in the applicative sense.</p>
<p>Thus far, I’ve managed to write linear-time traversals, but they’ve
been unsatisfying. They work by enumerating the tree, traversing the
effectful function over the list, and then rebuilding the tree. Since
each of those steps only takes linear time, the whole thing is indeed a
linear-time traversal, but I hadn’t been able to fuse away the
intermediate step.</p>
<h1 id="phases">Phases</h1>
<p>The template for the algorithm I want comes from the
<code>Phases</code> applicative <span class="citation"
data-cites="easterly_functions_2019">(<a
href="#ref-easterly_functions_2019" role="doc-biblioref">Easterly
2019</a>)</span>:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Phases</span> f a <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lift</span><span class="ot">   ::</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:&lt;*&gt;) ::</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f b</span></code></pre></div>
<p>We can use it to write a breadth-first traversal like so:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">traverse</span> go xs))</span></code></pre></div>
<p>The key component that makes this work is that it combines
applicative effects in parallel:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Functor</span> (<span class="dt">Phases</span> f) <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (<span class="dt">Lift</span> x) <span class="ot">=</span> <span class="dt">Lift</span> (<span class="fu">fmap</span> f x)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (fs <span class="op">:&lt;*&gt;</span> xs) <span class="ot">=</span> <span class="fu">fmap</span> (f<span class="op">.</span>) fs <span class="op">:&lt;*&gt;</span> xs</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Phases</span> f) <span class="kw">where</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Lift</span> <span class="op">.</span> <span class="fu">pure</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Lift</span> fs      <span class="op">&lt;*&gt;</span> <span class="dt">Lift</span> xs      <span class="ot">=</span> <span class="dt">Lift</span> (fs <span class="op">&lt;*&gt;</span> xs)</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    (fs <span class="op">:&lt;*&gt;</span> gs) <span class="op">&lt;*&gt;</span> <span class="dt">Lift</span> xs      <span class="ot">=</span> liftA2 <span class="fu">flip</span> fs xs <span class="op">:&lt;*&gt;</span> gs</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Lift</span> fs      <span class="op">&lt;*&gt;</span> (xs <span class="op">:&lt;*&gt;</span> ys) <span class="ot">=</span> liftA2 (<span class="op">.</span>)  fs xs <span class="op">:&lt;*&gt;</span> ys</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    (fs <span class="op">:&lt;*&gt;</span> gs) <span class="op">&lt;*&gt;</span> (xs <span class="op">:&lt;*&gt;</span> ys) <span class="ot">=</span> liftA2 c    fs xs <span class="op">:&lt;*&gt;</span> liftA2 (,) gs ys</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>        c f g <span class="op">~</span>(x,y) <span class="ot">=</span> f x (g y)</span></code></pre></div>
<p>We’re also using the following helper functions:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">runPhases ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>runPhases (<span class="dt">Lift</span> x) <span class="ot">=</span> x</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>runPhases (fs <span class="op">:&lt;*&gt;</span> xs) <span class="ot">=</span> fs <span class="op">&lt;*&gt;</span> runPhases xs</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="ot">later ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>later <span class="ot">=</span> (<span class="op">:&lt;*&gt;</span>) (<span class="fu">pure</span> <span class="fu">id</span>)</span></code></pre></div>
<p>The problem is that it’s quadratic: the <code>traverse</code> in:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">traverse</span> go xs))</span></code></pre></div>
<p>Hides some expensive calls to <code>&lt;*&gt;</code>.</p>
<h1 id="a-roadmap-for-optimisation">A Roadmap for Optimisation</h1>
<p>The problem with the <code>Phases</code> traversal is actually
analogous to another function for enumeration: <code>levels</code> from
<span class="citation" data-cites="gibbons_breadth-first_2015">Gibbons
(<a href="#ref-gibbons_breadth-first_2015"
role="doc-biblioref">2015</a>)</span>.</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levels ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>levels (<span class="dt">Node</span> x xs) <span class="ot">=</span> [x] <span class="op">:</span> <span class="fu">foldr</span> lzw [] (<span class="fu">map</span> levels xs)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    lzw [] ys <span class="ot">=</span> ys</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    lzw xs [] <span class="ot">=</span> xs</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    lzw (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> (x <span class="op">++</span> y) <span class="op">:</span> lzw xs ys</span></code></pre></div>
<p><code>lzw</code> takes the place of <code>&lt;*&gt;</code> here, but
the overall issue is the same: we’re zipping at every point, making the
whole thing quadratic.</p>
<p>However, from the above function we <em>can</em> derive a linear time
enumeration. It looks like this:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levels ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>levels ts <span class="ot">=</span> f ts []</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) (q<span class="op">:</span>qs) <span class="ot">=</span> (x<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) []     <span class="ot">=</span> [x]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>Our objective is clear, then: try to derive the linear-time
implementation of <code>bft</code> from the quadratic, in a way
analogous to the above two functions. This is actually relatively
straightforward once the target is clear: the rest of this post is
devoted to the derivation.</p>
<h1 id="derivation">Derivation</h1>
<p>First, we start off with the original <code>bft</code>.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">traverse</span> go xs))</span></code></pre></div>
<details>
<summary>
Inline <code>traverse</code>.
</summary>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (go&#39; xs))</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>    go&#39; <span class="ot">=</span> <span class="fu">foldr</span> (liftA2 (<span class="op">:</span>) <span class="op">.</span> go) (<span class="fu">pure</span> [])</span></code></pre></div>
</details>
<details>
<summary>
Factor out <code>go''</code>.
</summary>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (go&#39; xs))</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    go&#39; <span class="ot">=</span> <span class="fu">foldr</span> go&#39;&#39; (<span class="fu">pure</span> [])</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    go&#39;&#39; (<span class="dt">Node</span> x xs) ys <span class="ot">=</span> liftA2 (<span class="op">:</span>) (liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (go&#39; xs))) ys</span></code></pre></div>
</details>
<details>
<summary>
<p>Inline <code>go'</code> (and rename <code>go''</code> to
<code>go'</code>)</p>
</summary>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs))</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) ys <span class="ot">=</span> liftA2 (<span class="op">:</span>) (liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs))) ys</span></code></pre></div>
</details>
<details>
<summary>
<p>Definition of <code>liftA2</code></p>
</summary>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs))</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) ys <span class="ot">=</span> liftA2 (<span class="op">:</span>) (<span class="fu">fmap</span> <span class="dt">Node</span> (f x) <span class="op">:&lt;*&gt;</span> (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs)) ys</span></code></pre></div>
</details>
<details>
<summary>
<p>Definition of <code>liftA2</code> (pattern-matching on
<code>ys</code>)</p>
</summary>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs))</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (<span class="dt">Lift</span> ys)    <span class="ot">=</span> <span class="fu">fmap</span> (((<span class="op">:</span>)<span class="op">.</span>) <span class="op">.</span> <span class="dt">Node</span>) (f x) <span class="op">:&lt;*&gt;</span> (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs) <span class="op">&lt;*&gt;</span> <span class="dt">Lift</span> ys</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (ys <span class="op">:&lt;*&gt;</span> zs) <span class="ot">=</span> <span class="fu">fmap</span> (((<span class="op">:</span>)<span class="op">.</span>) <span class="op">.</span> <span class="dt">Node</span>) (f x) <span class="op">:&lt;*&gt;</span> (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs) <span class="op">&lt;*&gt;</span> ys <span class="op">:&lt;*&gt;</span> zs</span></code></pre></div>
</details>
<details>
<summary>
Definition of <code>&lt;*&gt;</code>.
</summary>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs))</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (<span class="dt">Lift</span> ys)    <span class="ot">=</span> liftA2 <span class="fu">flip</span> (<span class="fu">fmap</span> (((<span class="op">:</span>)<span class="op">.</span>) <span class="op">.</span> <span class="dt">Node</span>) (f x)) ys <span class="op">:&lt;*&gt;</span> <span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (ys <span class="op">:&lt;*&gt;</span> zs) <span class="ot">=</span> liftA2 c (<span class="fu">fmap</span> (((<span class="op">:</span>)<span class="op">.</span>) <span class="op">.</span> <span class="dt">Node</span>) (f x)) ys <span class="op">:&lt;*&gt;</span> liftA2 (,) (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs) zs</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>        c f g <span class="op">~</span>(x,y) <span class="ot">=</span> f x (g y)</span></code></pre></div>
</details>
<details>
<summary>
<p>Fuse <code>liftA2</code> with <code>fmap</code></p>
</summary>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> runPhases <span class="op">.</span> go</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (<span class="dt">Lift</span> (f x)) (later (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs))</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (<span class="dt">Lift</span> ys)    <span class="ot">=</span> liftA2 (<span class="fu">flip</span> <span class="op">.</span> (((<span class="op">:</span>)<span class="op">.</span>) <span class="op">.</span> <span class="dt">Node</span>)) (f x) ys <span class="op">:&lt;*&gt;</span> <span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (ys <span class="op">:&lt;*&gt;</span> zs) <span class="ot">=</span> liftA2 (c <span class="op">.</span> (((<span class="op">:</span>)<span class="op">.</span>) <span class="op">.</span> <span class="dt">Node</span>)) (f x) ys <span class="op">:&lt;*&gt;</span> liftA2 (,) (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs) zs</span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>        c f g <span class="op">~</span>(x,y) <span class="ot">=</span> f x (g y)</span></code></pre></div>
</details>
<details open>
<summary>
Beta-reduction.
</summary>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> go</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 <span class="dt">Node</span> (f x) (runPhases (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs))</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (<span class="dt">Lift</span> ys)    <span class="ot">=</span> liftA2 (\y zs ys <span class="ot">-&gt;</span> <span class="dt">Node</span> y ys <span class="op">:</span> zs) (f x) ys <span class="op">:&lt;*&gt;</span> <span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (ys <span class="op">:&lt;*&gt;</span> zs) <span class="ot">=</span> liftA2 c (f x) ys <span class="op">:&lt;*&gt;</span> liftA2 (,) (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs) zs</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>        c y g <span class="op">~</span>(ys,z) <span class="ot">=</span> <span class="dt">Node</span> y ys <span class="op">:</span> g z</span></code></pre></div>
</details>
<p>At this point, we actually hit a wall: the expression</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>liftA2 (,) (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> []) xs) zs</span></code></pre></div>
<p>Is what makes the whole thing quadratic. We need to find a way to
thread that <code>liftA2</code> along with the fold to get it to linear.
This is the only real trick in the derivation: I’ll use polymorphic
recursion to avoid the extra zip.</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="kw">forall</span> f a b<span class="op">.</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> go</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 (\y (ys,_) <span class="ot">-&gt;</span> <span class="dt">Node</span> y ys) (f x) (runPhases (<span class="fu">foldr</span> go&#39; (<span class="fu">pure</span> ([],())) xs))</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    go&#39; ::</span> <span class="kw">forall</span> c<span class="op">.</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f ([<span class="dt">Tree</span> b], c) <span class="ot">-&gt;</span> <span class="dt">Phases</span> f ([<span class="dt">Tree</span> b], c)</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) ys<span class="op">@</span>(<span class="dt">Lift</span> _)  <span class="ot">=</span> <span class="fu">fmap</span> (\y <span class="ot">-&gt;</span> first (<span class="fu">pure</span> <span class="op">.</span> <span class="dt">Node</span> y)) (f x) <span class="op">:&lt;*&gt;</span> <span class="fu">foldr</span> go&#39; ys xs</span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (ys <span class="op">:&lt;*&gt;</span> zs) <span class="ot">=</span> liftA2 c (f x) ys <span class="op">:&lt;*&gt;</span> <span class="fu">foldr</span> go&#39; (<span class="fu">fmap</span> ((,) []) zs) xs</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>        c y g <span class="op">~</span>(ys,z) <span class="ot">=</span> first (<span class="dt">Node</span> y ys<span class="op">:</span>) (g z)</span></code></pre></div>
<p>And that’s it!</p>
<h1 id="avoiding-maps">Avoiding Maps</h1>
<p>We can finally write a slightly different version that avoids some
unnecessary <code>fmap</code>s by basing <code>Phases</code> on
<code>liftA2</code> rather than <code>&lt;*&gt;</code>.</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Levels</span> f a <span class="kw">where</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Now</span><span class="ot">   ::</span> a <span class="ot">-&gt;</span> <span class="dt">Levels</span> f a</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Later</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Levels</span> f b <span class="ot">-&gt;</span> <span class="dt">Levels</span> f c</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Functor</span> (<span class="dt">Levels</span> f) <span class="kw">where</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (<span class="dt">Now</span> x) <span class="ot">=</span> <span class="dt">Now</span> (f x)</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (<span class="dt">Later</span> c xs ys) <span class="ot">=</span> <span class="dt">Later</span> ((f<span class="op">.</span>) <span class="op">.</span> c) xs ys</span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a><span class="ot">runLevels ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Levels</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>runLevels (<span class="dt">Now</span> x) <span class="ot">=</span> <span class="fu">pure</span> x</span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a>runLevels (<span class="dt">Later</span> f xs ys) <span class="ot">=</span> liftA2 f xs (runLevels ys)</span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a><span class="ot">bft ::</span> <span class="kw">forall</span> f a b<span class="op">.</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span>
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a>bft f <span class="ot">=</span> go</span>
<span id="cb21-15"><a href="#cb21-15" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb21-16"><a href="#cb21-16" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Node</span> x xs) <span class="ot">=</span> liftA2 (\y (ys,_) <span class="ot">-&gt;</span> <span class="dt">Node</span> y ys) (f x) (runLevels (<span class="fu">foldr</span> go&#39; (<span class="dt">Now</span> ([],())) xs))</span>
<span id="cb21-17"><a href="#cb21-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-18"><a href="#cb21-18" aria-hidden="true" tabindex="-1"></a><span class="ot">    go&#39; ::</span> <span class="kw">forall</span> c<span class="op">.</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Levels</span> f ([<span class="dt">Tree</span> b], c) <span class="ot">-&gt;</span> <span class="dt">Levels</span> f ([<span class="dt">Tree</span> b], c)</span>
<span id="cb21-19"><a href="#cb21-19" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) ys<span class="op">@</span>(<span class="dt">Now</span> _)      <span class="ot">=</span> <span class="dt">Later</span> (\y <span class="ot">-&gt;</span> first (<span class="fu">pure</span> <span class="op">.</span> <span class="dt">Node</span> y)) (f x) (<span class="fu">foldr</span> go&#39; ys xs)</span>
<span id="cb21-20"><a href="#cb21-20" aria-hidden="true" tabindex="-1"></a>    go&#39; (<span class="dt">Node</span> x xs) (<span class="dt">Later</span> k ys zs) <span class="ot">=</span> <span class="dt">Later</span> <span class="fu">id</span> (liftA2 c (f x) ys) (<span class="fu">foldr</span> go&#39; (<span class="fu">fmap</span> ((,) []) zs) xs)</span>
<span id="cb21-21"><a href="#cb21-21" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb21-22"><a href="#cb21-22" aria-hidden="true" tabindex="-1"></a>        c y g <span class="op">~</span>(ys,z) <span class="ot">=</span> first (<span class="dt">Node</span> y ys<span class="op">:</span>) (k g z)</span></code></pre></div>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-easterly_functions_2019" class="csl-entry" role="listitem">
Easterly, Noah. 2019. <span>“Functions and newtype wrappers for
traversing <span>Trees</span>: Rampion/tree-traversals.”</span> <a
href="https://github.com/rampion/tree-traversals">https://github.com/rampion/tree-traversals</a>.
</div>
<div id="ref-gibbons_breadth-first_2015" class="csl-entry"
role="listitem">
Gibbons, Jeremy. 2015. <span>“Breadth-<span>First
Traversal</span>.”</span> <em>Patterns in Functional Programming</em>.
<a
href="https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/">https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/</a>.
</div>
<div id="ref-okasaki_breadth-first_2000" class="csl-entry"
role="listitem">
Okasaki, Chris. 2000. <span>“Breadth-first <span>Numbering</span>:
<span>Lessons</span> from a <span>Small Exercise</span> in
<span>Algorithm Design</span>.”</span> In <em>Proceedings of the
<span>Fifth ACM SIGPLAN International Conference</span> on
<span>Functional Programming</span></em>, 131–136. <span>ICFP</span>
’00. New York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/351240.351253">10.1145/351240.351253</a>.
<a
href="https://www.cs.tufts.edu/~nr/cs257/archive/chris-okasaki/breadth-first.pdf">https://www.cs.tufts.edu/~nr/cs257/archive/chris-okasaki/breadth-first.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Tue, 28 May 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-05-28-linear-phases.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Implicit Corecursive Queues</title>
    <link>https://doisinkidney.com/posts/2019-05-14-corecursive-implicit-queues.html</link>
    <description><![CDATA[<div class="info">
    Posted on May 14, 2019
</div>
<div class="info">
    
        Part 6 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<h1 id="fusion">Fusion</h1>
<p>I was looking again at one of my implementations of breadth-first
traversals:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfe ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>bfe r <span class="ot">=</span> f r b []</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (xs <span class="op">:</span> bw)</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b qs []</span></code></pre></div>
<p>And I was wondering if I could <em>fuse</em> away the intermediate
list. On the following line:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (xs <span class="op">:</span> bw)</span></code></pre></div>
<p>The <code>xs : bw</code> is a little annoying, because we
<em>know</em> it’s going to be consumed eventually by a fold. When that
happens, it’s often a good idea to remove the list, and just inline the
fold. In other words, if you see the following:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldr</span> f b (x <span class="op">:</span> y <span class="op">:</span> [])</span></code></pre></div>
<p>You should replace it with this:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>f x (f y b)</span></code></pre></div>
<p>If you try and do that with the above definition, you get something
like the following:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfenum ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>bfenum t <span class="ot">=</span> f t b b</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> f) xs)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    b x <span class="ot">=</span> x b</span></code></pre></div>
<h1 id="infinite-types">Infinite Types</h1>
<p>The trouble is that the above comes with type errors:</p>
<pre><code>Cannot construct the infinite type: b ~ (b -&gt; c) -&gt; [a]</code></pre>
<p>This error shows up occasionally when you try and do heavy
church-encoding in Haskell. You get a similar error when trying to
encode the Y combinator:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>y <span class="ot">=</span> \f <span class="ot">-&gt;</span> (\x <span class="ot">-&gt;</span> f (x x)) (\x <span class="ot">-&gt;</span> f (x x))</span></code></pre></div>
<pre><code>• Occurs check: cannot construct the infinite type: t0 ~ t0 -&gt; t</code></pre>
<p>The solution for the y combinator is to use a newtype, where we can
catch the recursion at a certain point to help the typechecker.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Mu</span> a <span class="ot">=</span> <span class="dt">Mu</span> (<span class="dt">Mu</span> a <span class="ot">-&gt;</span> a)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>y f <span class="ot">=</span> (\h <span class="ot">-&gt;</span> h <span class="op">$</span> <span class="dt">Mu</span> h) (\x <span class="ot">-&gt;</span> f <span class="op">.</span> (\(<span class="dt">Mu</span> g) <span class="ot">-&gt;</span> g) x <span class="op">$</span> x)</span></code></pre></div>
<p>The trick for our queue is similar:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q</span> a <span class="ot">=</span> <span class="dt">Q</span> {<span class="ot"> q ::</span> (<span class="dt">Q</span> a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> [a] }</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="ot">bfenum ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>bfenum t <span class="ot">=</span> q (f t b) e</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw <span class="ot">=</span> <span class="dt">Q</span> (\bw <span class="ot">-&gt;</span> x <span class="op">:</span> q fw (bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> f) xs))</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> fix (<span class="dt">Q</span> <span class="op">.</span> <span class="fu">flip</span> <span class="fu">id</span>)</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> fix (<span class="fu">flip</span> q)</span></code></pre></div>
<p>This is actually equivalent to the continuation monad:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Fix</span> f <span class="ot">=</span> <span class="dt">Fix</span> {<span class="ot"> unFix ::</span> f (<span class="dt">Fix</span> f) }</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Q</span> a <span class="ot">=</span> <span class="dt">Fix</span> (<span class="dt">ContT</span> a [])</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>q <span class="ot">=</span> runContT <span class="op">.</span> unFix</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="ot">bfenum ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>bfenum t <span class="ot">=</span> q (f t b) e</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw <span class="ot">=</span> <span class="dt">Fix</span> (mapContT (x<span class="op">:</span>) (<span class="fu">flip</span> (<span class="fu">foldr</span> f) xs <span class="op">&lt;$&gt;</span> unFix fw))</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> fix (<span class="dt">Fix</span> <span class="op">.</span> <span class="fu">pure</span>)</span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> fix (<span class="fu">flip</span> q)</span></code></pre></div>
<h1 id="terminating">Terminating</h1>
<p>There’s a problem though: this algorithm never checks for an end.
That’s ok if there isn’t one, mind you. For instance, with the following
“unfold” function:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">9</span> <span class="op">#.</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="ot">(#.) ::</span> <span class="dt">Coercible</span> b c <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> c</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>(<span class="op">#.</span>) _ <span class="ot">=</span> coerce</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE (#.) #-}</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="ot">bfUnfold ::</span> (a <span class="ot">-&gt;</span> (b,[a])) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [b]</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>bfUnfold f t <span class="ot">=</span> g t (fix (<span class="dt">Q</span> <span class="op">#.</span> <span class="fu">flip</span> <span class="fu">id</span>)) (fix (<span class="fu">flip</span> q))</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>    g b fw bw <span class="ot">=</span> x <span class="op">:</span> q fw (bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> ((<span class="dt">Q</span> <span class="op">.</span>) <span class="op">#.</span> g)) xs)</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>        (x,xs) <span class="ot">=</span> f b</span></code></pre></div>
<p>We can write a decent enumeration of the rationals.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Stern-Brocot</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="ot">rats1 ::</span> [<span class="dt">Rational</span>]</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>rats1 <span class="ot">=</span> bfUnfold step ((<span class="dv">0</span>,<span class="dv">1</span>),(<span class="dv">1</span>,<span class="dv">0</span>))</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    step (lb,rb) <span class="ot">=</span> (n <span class="op">%</span> d,[(lb , m),(m , rb)])</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>        m<span class="op">@</span>(n,d) <span class="ot">=</span> adj lb rb</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>    adj (w,x) (y,z) <span class="ot">=</span> (w<span class="op">+</span>y,x<span class="op">+</span>z)</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- Calkin-Wilf</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a><span class="ot">rats2 ::</span> [<span class="dt">Rational</span>]</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>rats2 <span class="ot">=</span> bfUnfold step (<span class="dv">1</span>,<span class="dv">1</span>)</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>    step (m,n) <span class="ot">=</span> (m <span class="op">%</span> n,[(m,m<span class="op">+</span>n),(n<span class="op">+</span>m,n)])</span></code></pre></div>
<p>However, if we <em>do</em> want to stop at some point, we need a
slight change to the queue type.</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q</span> a <span class="ot">=</span> <span class="dt">Q</span> {<span class="ot"> q ::</span> <span class="dt">Maybe</span> (<span class="dt">Q</span> a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> [a] }</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="ot">bfenum ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>bfenum t <span class="ot">=</span> q (f t b) e</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw <span class="ot">=</span> <span class="dt">Q</span> (\bw <span class="ot">-&gt;</span> x <span class="op">:</span> q fw (<span class="dt">Just</span> (m bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> f) xs)))</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> fix (<span class="dt">Q</span> <span class="op">.</span> <span class="fu">maybe</span> [] <span class="op">.</span> <span class="fu">flip</span> (<span class="op">$</span>))</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>    m <span class="ot">=</span> fromMaybe (<span class="fu">flip</span> q e)</span></code></pre></div>
<h1 id="monadic">Monadic</h1>
<p>We can actually add in a monad to the above unfold without much
difficulty.</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q</span> m a <span class="ot">=</span> <span class="dt">Q</span> {<span class="ot"> q ::</span> <span class="dt">Maybe</span> (<span class="dt">Q</span> m a <span class="ot">-&gt;</span> m [a]) <span class="ot">-&gt;</span> m [a] }</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="ot">bfUnfold ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m (b,[a])) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> m [b]</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>bfUnfold f t <span class="ot">=</span> g t b e</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    g s fw bw <span class="ot">=</span> f s <span class="op">&gt;&gt;=</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>       \ <span class="op">~</span>(x,xs) <span class="ot">-&gt;</span> (x <span class="op">:</span>) <span class="op">&lt;$&gt;</span>  q fw (<span class="dt">Just</span> (m bw <span class="op">.</span> <span class="fu">flip</span> (<span class="fu">foldr</span> ((<span class="dt">Q</span> <span class="op">.</span>) <span class="op">#.</span> g)) xs))</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> fix (<span class="dt">Q</span> <span class="op">#.</span> <span class="fu">maybe</span> (<span class="fu">pure</span> []) <span class="op">.</span> <span class="fu">flip</span> (<span class="op">$</span>))</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>    m <span class="ot">=</span> fromMaybe (<span class="fu">flip</span> q e)</span></code></pre></div>
<p>And it passes the torture tests for a linear-time breadth-first
unfold from <span class="citation" data-cites="feuer_is_2015">Feuer (<a
href="#ref-feuer_is_2015" role="doc-biblioref">2015</a>)</span>. It
breaks when you try and use it to build a tree, though.</p>
<h1 id="phases">Phases</h1>
<p>Finally, we can try and make the above code a little more modular, by
actually packaging up the queue type as a queue.</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Q</span> a <span class="ot">=</span> <span class="dt">Q</span> {<span class="ot"> q ::</span> <span class="dt">Maybe</span> (<span class="dt">Q</span> a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> [a] }</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Queue</span> a <span class="ot">=</span> <span class="dt">Queue</span> {<span class="ot"> runQueue ::</span> <span class="dt">Q</span> a <span class="ot">-&gt;</span> <span class="dt">Q</span> a }</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">now ::</span> a <span class="ot">-&gt;</span> <span class="dt">Queue</span> a</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>now x <span class="ot">=</span> <span class="dt">Queue</span> (\fw <span class="ot">-&gt;</span> <span class="dt">Q</span> (\bw <span class="ot">-&gt;</span> x <span class="op">:</span> q fw bw))</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="ot">delay ::</span> <span class="dt">Queue</span> a <span class="ot">-&gt;</span> <span class="dt">Queue</span> a</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>delay xs <span class="ot">=</span> <span class="dt">Queue</span> (\fw <span class="ot">-&gt;</span> <span class="dt">Q</span> (\bw <span class="ot">-&gt;</span> q fw (<span class="dt">Just</span> (m bw <span class="op">.</span> runQueue xs))))</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>    m <span class="ot">=</span> fromMaybe (<span class="fu">flip</span> q <span class="dt">Nothing</span>)</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">Queue</span> a) <span class="kw">where</span></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Queue</span> <span class="fu">id</span></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mappend</span> (<span class="dt">Queue</span> xs) (<span class="dt">Queue</span> ys) <span class="ot">=</span> <span class="dt">Queue</span> (xs <span class="op">.</span> ys)</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a><span class="ot">run ::</span> <span class="dt">Queue</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>run (<span class="dt">Queue</span> xs) <span class="ot">=</span> q (xs b) <span class="dt">Nothing</span></span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> fix (<span class="dt">Q</span> <span class="op">.</span> <span class="fu">maybe</span> [] <span class="op">.</span> <span class="fu">flip</span> (<span class="op">$</span>))</span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a><span class="ot">bfenum ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a>bfenum t <span class="ot">=</span> run (f t)</span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) <span class="ot">=</span> now x <span class="op">&lt;&gt;</span> delay (<span class="fu">foldMap</span> f xs)</span></code></pre></div>
<p>At this point, our type is starting to look a lot like the <a
href="https://hackage.haskell.org/package/tree-traversals-0.1.0.0/docs/Control-Applicative-Phases.html#t:Phases"><code>Phases</code></a>
type from Noah Easterly’s tree-traversals package. This is exciting: the
<code>Phases</code> type has the ideal interface for level-wise
traversals. Unfortunately, it has the wrong time complexity for
<code>&lt;*&gt;</code> and so on: my suspicion is that the queue type
above here is to <code>Phases</code> as the continuation monad is to the
free monad. In other words, we’ll get efficient construction at the
expense of no inspection. Unfortunately, I can’t figure out how to turn
the above type into an applicative. Maybe in a future post!</p>
<p>Finally, a lot of this is working towards finally understanding <span
class="citation" data-cites="smith_lloyd_2009">Smith (<a
href="#ref-smith_lloyd_2009" role="doc-biblioref">2009</a>)</span> and
<span class="citation" data-cites="allison_circular_2006">Allison (<a
href="#ref-allison_circular_2006"
role="doc-biblioref">2006</a>)</span>.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-allison_circular_2006" class="csl-entry" role="listitem">
Allison, Lloyd. 2006. <span>“Circular <span>Programs</span> and
<span>Self</span>-<span>Referential Structures</span>.”</span>
<em>Software: Practice and Experience</em> 19 (2) (October): 99–109.
doi:<a
href="https://doi.org/10.1002/spe.4380190202">10.1002/spe.4380190202</a>.
<a
href="http://users.monash.edu/~lloyd/tildeFP/1989SPE/">http://users.monash.edu/~lloyd/tildeFP/1989SPE/</a>.
</div>
<div id="ref-feuer_is_2015" class="csl-entry" role="listitem">
Feuer, David. 2015. <span>“Is a lazy, breadth-first monadic rose tree
unfold possible?”</span> Question. <em>Stack Overflow</em>. <a
href="https://stackoverflow.com/q/27748526">https://stackoverflow.com/q/27748526</a>.
</div>
<div id="ref-smith_lloyd_2009" class="csl-entry" role="listitem">
Smith, Leon P. 2009. <span>“Lloyd <span>Allison</span>’s
<span>Corecursive Queues</span>: <span>Why Continuations
Matter</span>.”</span> <em>The Monad.Reader</em> 14 (14) (July): 28. <a
href="https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf">https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Tue, 14 May 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-05-14-corecursive-implicit-queues.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Concatenative Programming; The Free Monoid of Programming Languages</title>
    <link>https://doisinkidney.com/posts/2019-05-11-concatenative-free.html</link>
    <description><![CDATA[<div class="info">
    Posted on May 11, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Concatenative&#39;." href="/tags/Concatenative.html" rel="tag">Concatenative</a>, <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>This post demonstrates a simple encoding of a (typed) concatenative
language in Haskell.</p>
<p>Point-free style is one of the distinctive markers of functional
programming languages. Want to sum a list? That’s as easy as:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sum</span> <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span></span></code></pre></div>
<p>Now I want to sum every number after adding one to it.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>sumSuccs <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span> <span class="op">.</span> <span class="fu">map</span> ((<span class="op">+</span>) <span class="dv">1</span>)</span></code></pre></div>
<p>One more step to make this function truly abstract™ and general™:
we’ll allow the user to supply their own number to add</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>sumAdded <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span> <span class="op">.</span> <span class="fu">map</span> <span class="op">.</span> (<span class="op">+</span>)</span></code></pre></div>
<p>And here the trouble begins. The above expression won’t actually type
check. In fact, it’ll give a pretty terrible error message:</p>
<pre><code>• Non type-variable argument in the constraint: Num [a]
  (Use FlexibleContexts to permit this)
• When checking the inferred type
    sumThoseThat :: forall a.
                    (Num [a], Foldable ((-&gt;) [a])) =&gt;
                    a -&gt; [a]</code></pre>
<p>I remember as a beginner being confused by similar messages. What’s
<code>FlexibleContexts</code>? I had thought that the “point-free style”
just meant removing the last variable from an expression if it’s also
the last argument:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sum</span> xs <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span> xs</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sum</span> <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span></span></code></pre></div>
<p>Why doesn’t it work here?</p>
<p>Well, it doesn’t work because the types don’t line up, but I’m going
to try and explain a slightly different perspective on the problem,
which is <em>associativity</em>.</p>
<p>To make it a little clearer, let’s see what happens when we
point-fill the expression:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>sumAdded n xs <span class="ot">=</span> (<span class="fu">foldr</span>(<span class="op">+</span>) <span class="dv">0</span> <span class="op">.</span> (<span class="fu">map</span> <span class="op">.</span> (<span class="op">+</span>))) n xs</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=&gt;</span> <span class="fu">foldr</span>(<span class="op">+</span>) <span class="dv">0</span> ((<span class="fu">map</span> <span class="op">.</span> (<span class="op">+</span>)) n) xs</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=&gt;</span> <span class="fu">foldr</span>(<span class="op">+</span>) <span class="dv">0</span> (<span class="fu">map</span> ((<span class="op">+</span>) n)) xs</span></code></pre></div>
<p>Indeed, the problem is the placement of the parentheses. What we want
at the end is:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=&gt;</span> <span class="fu">foldr</span>(<span class="op">+</span>) <span class="dv">0</span> (<span class="fu">map</span> ((<span class="op">+</span>) n) xs)</span></code></pre></div>
<p>But, no matter. We have to jiggle the arguments around, or we could
use something terrible like this:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">9</span> <span class="op">.:</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>(<span class="op">.:</span>) <span class="ot">=</span> (<span class="op">.</span>)<span class="op">.</span>(<span class="op">.</span>)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>sumAdded <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span> <span class="op">.:</span> <span class="fu">map</span> <span class="op">.</span> (<span class="op">+</span>)</span></code></pre></div>
<p>Is there something, though, that could do this automatically?</p>
<h1 id="associativity">Associativity</h1>
<p>We run into a similar problem in Agda. We’re forever having to prove
statements like:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(</span>x + y<span class="ot">)</span> + z ≡ x + <span class="ot">(</span>y + z<span class="ot">)</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>x ≡ x + <span class="dv">0</span></span></code></pre></div>
<p>There are a couple of ways to get around the issue, and for monoids
there’s a rich theory of techniques. I’ll just show one for now, which
relies on the <em>endomorphism</em> monoid. This monoid is created by
partially applying the monoid’s binary operator:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>Endo <span class="ot">:</span> <span class="dt">Set</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>Endo <span class="ot">=</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>⟦<span class="ot">_</span>⇑⟧ <span class="ot">:</span> ℕ <span class="ot">→</span> Endo</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>⟦ n ⇑⟧ m <span class="ot">=</span> n + m</span></code></pre></div>
<p>And you can get back to the underlying monoid by applying it to the
neutral element:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>⟦<span class="ot">_</span>⇓⟧ <span class="ot">:</span> Endo <span class="ot">→</span> ℕ</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>⟦ n ⇓⟧ <span class="ot">=</span> n <span class="dv">0</span></span></code></pre></div>
<p>Here’s the important parts: first, we can lift the underlying
operation into the endomorphism:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>⊕<span class="ot">_</span> <span class="ot">:</span> Endo <span class="ot">→</span> Endo <span class="ot">→</span> Endo</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>xs ⊕ ys <span class="ot">=</span> <span class="ot">λ</span> x <span class="ot">→</span> xs <span class="ot">(</span>ys x<span class="ot">)</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>⊕-homo <span class="ot">:</span> <span class="ot">∀</span> n m <span class="ot">→</span> ⟦ ⟦ n ⇑⟧ ⊕ ⟦ m ⇑⟧ ⇓⟧ ≡ n + m</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>⊕-homo n m <span class="ot">=</span> cong <span class="ot">(</span>n +<span class="ot">_)</span> <span class="ot">(</span>+-identityʳ m<span class="ot">)</span></span></code></pre></div>
<p>And second, it’s <em>definitionally</em> associative.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>⊕-assoc <span class="ot">:</span> <span class="ot">∀</span> x y z <span class="ot">→</span> <span class="ot">(</span>x ⊕ y<span class="ot">)</span> ⊕ z ≡ x ⊕ <span class="ot">(</span>y ⊕ z<span class="ot">)</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>⊕-assoc <span class="ot">_</span> <span class="ot">_</span> <span class="ot">_</span> <span class="ot">=</span> refl</span></code></pre></div>
<p>These are all clues as to how to solve the composition problem in the
Haskell code above. We need definitional associativity, somehow. Maybe
we can get it from the endomorphism monoid?</p>
<h1 id="state">State</h1>
<p>You’re probably familiar with Haskell’s state monad:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">State</span> s a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> s <span class="ot">-&gt;</span> (a, s) }</span></code></pre></div>
<p>It can help a lot when you’re threading around fiddly accumulators
and so on.</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">nub ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>nub <span class="ot">=</span> go Set.empty</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    go seen [] <span class="ot">=</span> []</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    go seen (x<span class="op">:</span>xs)</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x <span class="ot">`Set.member`</span> seen <span class="ot">=</span> go seen xs</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> x <span class="op">:</span> go (Set.insert x seen) xs</span></code></pre></div>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">nub ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>nub <span class="ot">=</span> <span class="fu">flip</span> evalState Set.empty <span class="op">.</span> go</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>    go (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>        seen <span class="ot">&lt;-</span> gets (Set.member x)</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> seen</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>          <span class="kw">then</span> go xs</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>          <span class="kw">else</span> <span class="kw">do</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>              modify (Set.insert x)</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>              (x<span class="op">:</span>) <span class="op">&lt;$&gt;</span> go xs</span></code></pre></div>
<p>Of course, these days state is a transformer:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">StateT</span> s m a <span class="ot">=</span> <span class="dt">StateT</span> {<span class="ot"> runStateT ::</span> s <span class="ot">-&gt;</span> m (a, s) }</span></code></pre></div>
<p>This lets us stack multiple effects on top of each other: error
handling, IO, randomness, even another state monad. In fact, if you
<em>do</em> stack another state monad on top, you might be surprised by
the efficiency of the code it generates:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">DoubleState</span> s1 s2 a <span class="ot">=</span> <span class="dt">StateT</span> s1 (<span class="dt">State</span> s2) a</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>                        <span class="ot">=&gt;</span> s1 <span class="ot">-&gt;</span> <span class="dt">State</span> s2 (a, s1)</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>                        <span class="ot">=&gt;</span> s1 <span class="ot">-&gt;</span> s2 <span class="ot">-&gt;</span> ((a, s1), s2)</span></code></pre></div>
<p>It’s nothing earth shattering, but it inlines and optimises well.
That output is effectively a left-nested list, also.</p>
<h1 id="multi-state">Multi-State</h1>
<p>If we can do one, and we can do two, why not more? Can we generalise
the state pattern to an arbitrary number of variables? First we’ll need
a generic tuple:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Stack</span> (<span class="ot">xs ::</span> [<span class="dt">Type</span>])<span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">Stack</span> &#39;[]</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    (:-) ::</span> x <span class="ot">-&gt;</span> <span class="dt">Stack</span> xs <span class="ot">-&gt;</span> <span class="dt">Stack</span> (x <span class="op">:</span> xs)</span></code></pre></div>
<p>Then, the state type.</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">State</span> xs a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> <span class="dt">Stack</span> xs <span class="ot">-&gt;</span> (a, <span class="dt">Stack</span> xs) }</span></code></pre></div>
<p>We can actually clean the definition up a little: instead of a tuple
at the other end, why not push it onto the stack.</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">State</span> xs a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> <span class="dt">Stack</span> xs <span class="ot">-&gt;</span> <span class="dt">Stack</span> (a <span class="op">:</span> xs) }</span></code></pre></div>
<p>In fact, let’s make this as polymorphic as possible. We should be
able to change the state if we so desire.</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">0</span> <span class="op">:-&gt;</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> (<span class="op">:-&gt;</span>) xs ys <span class="ot">=</span> <span class="dt">Stack</span> xs <span class="ot">-&gt;</span> <span class="dt">Stack</span> ys</span></code></pre></div>
<p>And suddenly, our endomorphism type from above shows up again.</p>
<p>We can, of course, get back our original types.</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">State</span> xs a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> xs <span class="op">:-&gt;</span> a <span class="op">:</span> xs }</span></code></pre></div>
<p>And it comes with all of the instances you might expect:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">State</span> xs) <span class="kw">where</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f xs <span class="ot">=</span> <span class="dt">State</span> (\s <span class="ot">-&gt;</span> <span class="kw">case</span> runState xs s <span class="kw">of</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>        (x <span class="op">:-</span> ys) <span class="ot">-&gt;</span> f x <span class="op">:-</span> ys)</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> (<span class="dt">State</span> xs) <span class="kw">where</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">State</span> (x <span class="op">:-</span>)</span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>    fs <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> <span class="dt">State</span> (\s <span class="ot">-&gt;</span> <span class="kw">case</span> runState fs s <span class="kw">of</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>        (f <span class="op">:-</span> s&#39;) <span class="ot">-&gt;</span> <span class="kw">case</span> runState xs s&#39; <span class="kw">of</span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>            (x <span class="op">:-</span> s&#39;&#39;) <span class="ot">-&gt;</span> f x <span class="op">:-</span> s&#39;&#39;)</span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> (<span class="dt">State</span> xs) <span class="kw">where</span></span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a>    xs <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="dt">State</span> (\s <span class="ot">-&gt;</span> <span class="kw">case</span> runState xs s <span class="kw">of</span></span>
<span id="cb24-13"><a href="#cb24-13" aria-hidden="true" tabindex="-1"></a>        y <span class="op">:-</span> ys <span class="ot">-&gt;</span> runState (f y) ys)</span></code></pre></div>
<h1 id="polymorphism">Polymorphism</h1>
<p>But what’s the point? So far we’ve basically just encoded an
unnecessarily complicated state transformer. Think back to the stacking
of states. Written in the <a
href="https://hackage.haskell.org/package/mtl">mtl</a> style, the main
advantage of stacking monads like that is you can write code like the
following:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">pop ::</span> (<span class="dt">MonadState</span> [a] m, <span class="dt">MonadError</span> <span class="dt">String</span> m) <span class="ot">=&gt;</span> m a</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>pop <span class="ot">=</span> get <span class="op">&gt;&gt;=</span> \<span class="kw">case</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>    [] <span class="ot">-&gt;</span> throwError <span class="st">&quot;pop: empty list&quot;</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>    x<span class="op">:</span>xs <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>        put xs</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>        <span class="fu">pure</span> x</span></code></pre></div>
<p>In other words, we don’t care about the rest of <code>m</code>, we
just care that it has, somewhere, state for an <code>[a]</code>.</p>
<p>This logic should apply to our stack transformer, as well. If it only
cares about the top two variables, it shouldn’t care what the rest of
the list is. In types:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">0</span> <span class="op">:-&gt;</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> (<span class="op">:-&gt;</span>) xs ys <span class="ot">=</span> <span class="kw">forall</span> zs<span class="op">.</span> <span class="dt">Stack</span> (xs <span class="op">++</span> zs) <span class="ot">-&gt;</span> <span class="dt">Stack</span> (ys <span class="op">++</span> zs)</span></code></pre></div>
<p>And straight away we can write some of the standard combinators:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dup ::</span> &#39;[a] <span class="op">:-&gt;</span> &#39;[a,a]</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>dup (x <span class="op">:-</span> xs) <span class="ot">=</span> (x <span class="op">:-</span> x <span class="op">:-</span> xs)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a><span class="ot">swap ::</span> &#39;[x,y] <span class="op">:-&gt;</span> &#39;[y,x]</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>swap (x <span class="op">:-</span> y <span class="op">:-</span> xs) <span class="ot">=</span> y <span class="op">:-</span> x <span class="op">:-</span> xs</span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a><span class="fu">drop</span><span class="ot"> ::</span> &#39;[x,y] <span class="op">:-&gt;</span> &#39;[y]</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a><span class="fu">drop</span> (_ <span class="op">:-</span> xs) <span class="ot">=</span> xs</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">9</span> <span class="op">!</span></span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a>(f <span class="op">!</span> g) x <span class="ot">=</span> g (f x)</span></code></pre></div>
<p>You’ll immediately run into trouble if you try to work with some of
the more involved combinators, though. Quote should have the following
type, for instance:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="ot">quote ::</span> (xs <span class="op">:-&gt;</span> ys) <span class="ot">-&gt;</span> &#39;[] <span class="op">:-&gt;</span> &#39;[ xs <span class="op">:-&gt;</span> ys ]</span></code></pre></div>
<p>But GHC complains again:</p>
<pre><code>• Illegal polymorphic type: xs :-&gt; ys
  GHC doesn&#39;t yet support impredicative polymorphism
• In the type signature:
    quote :: (xs :-&gt; ys) -&gt; &#39;[] :-&gt; &#39;[xs :-&gt; ys]</code></pre>
<p>I won’t go into the detail of this particular error: if you’ve been
around the block with Haskell you know that it means “wrap it in a
newtype”. If we do <em>that</em>, though, we get yet more errors:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> (<span class="op">:~&gt;</span>) xs ys <span class="ot">=</span> <span class="dt">Q</span> {<span class="ot"> d ::</span> xs <span class="op">:-&gt;</span> ys }</span></code></pre></div>
<pre><code>• Couldn&#39;t match type ‘ys ++ zs0’ with ‘ys ++ zs’
  Expected type: Stack (xs ++ zs) -&gt; Stack (ys ++ zs)
    Actual type: Stack (xs ++ zs0) -&gt; Stack (ys ++ zs0)
  NB: ‘++’ is a type function, and may not be injective</code></pre>
<p>This injectivity error comes up often. It means that GHC needs to
prove that the input to two functions is equal, but it only knows that
their outputs are. This is a doubly serious problem for us, as we can’t
do type family injectivity on two type variables (in current Haskell).
To solve the problem, we need to rely on a weird mishmash of type
families and functional dependencies:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> (<span class="op">++</span>) xs ys <span class="kw">where</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>    &#39;[] <span class="op">++</span> ys <span class="ot">=</span> ys</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    (x <span class="op">:</span> xs) <span class="op">++</span> ys <span class="ot">=</span> x <span class="op">:</span> (xs <span class="op">++</span> ys)</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (xs <span class="op">++</span> ys <span class="op">~</span> zs) <span class="ot">=&gt;</span> <span class="dt">Conc</span> xs ys zs <span class="op">|</span> xs zs <span class="ot">-&gt;</span> ys <span class="kw">where</span></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    conc ::</span> <span class="dt">Stack</span> xs <span class="ot">-&gt;</span> <span class="dt">Stack</span> ys <span class="ot">-&gt;</span> <span class="dt">Stack</span> zs</span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Conc</span> &#39;[] ys ys <span class="kw">where</span></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>    conc _ ys <span class="ot">=</span> ys</span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Conc</span> xs ys zs <span class="ot">=&gt;</span> <span class="dt">Conc</span> (x <span class="op">:</span> xs) ys (x <span class="op">:</span> zs) <span class="kw">where</span></span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>    conc (x <span class="op">:-</span> xs) ys <span class="ot">=</span> x <span class="op">:-</span> conc xs ys</span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-14"><a href="#cb32-14" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">0</span> <span class="op">:-&gt;</span></span>
<span id="cb32-15"><a href="#cb32-15" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> (<span class="op">:-&gt;</span>) xs ys <span class="ot">=</span> <span class="kw">forall</span> zs yszs<span class="op">.</span> <span class="dt">Conc</span> ys zs yszs <span class="ot">=&gt;</span> <span class="dt">Stack</span> (xs <span class="op">++</span> zs) <span class="ot">-&gt;</span> <span class="dt">Stack</span> yszs</span></code></pre></div>
<p>And it does indeed work:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="fu">pure</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> &#39;[] <span class="op">:-&gt;</span> &#39;[a]</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a><span class="fu">pure</span> <span class="ot">=</span> (<span class="op">:-</span>)</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> (<span class="op">:~&gt;</span>) xs ys <span class="ot">=</span> <span class="dt">Q</span> {<span class="ot"> d ::</span> xs <span class="op">:-&gt;</span> ys }</span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a><span class="ot">quote ::</span> (xs <span class="op">:-&gt;</span> ys) <span class="ot">-&gt;</span> &#39;[] <span class="op">:-&gt;</span> &#39;[ xs <span class="op">:~&gt;</span> ys ]</span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>quote x <span class="ot">=</span> <span class="fu">pure</span> (<span class="dt">Q</span> x)</span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a><span class="ot">dot ::</span> <span class="kw">forall</span> xs ys<span class="op">.</span> ((xs <span class="op">:~&gt;</span> ys) <span class="op">:</span> xs) <span class="op">:-&gt;</span> ys</span>
<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a>dot (x <span class="op">:-</span> xs) <span class="ot">=</span> d x xs</span>
<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-12"><a href="#cb33-12" aria-hidden="true" tabindex="-1"></a><span class="ot">true ::</span> (xs <span class="op">:~&gt;</span> ys) <span class="op">:</span> (xs <span class="op">:~&gt;</span> ys) <span class="op">:</span> xs <span class="op">:-&gt;</span> ys</span>
<span id="cb33-13"><a href="#cb33-13" aria-hidden="true" tabindex="-1"></a>true <span class="ot">=</span> swap <span class="op">!</span> <span class="fu">drop</span> <span class="op">!</span> dot</span>
<span id="cb33-14"><a href="#cb33-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-15"><a href="#cb33-15" aria-hidden="true" tabindex="-1"></a><span class="ot">false ::</span> (xs <span class="op">:~&gt;</span> ys) <span class="op">:</span> (xs <span class="op">:~&gt;</span> ys) <span class="op">:</span> xs <span class="op">:-&gt;</span> ys</span>
<span id="cb33-16"><a href="#cb33-16" aria-hidden="true" tabindex="-1"></a>false <span class="ot">=</span> <span class="fu">drop</span> <span class="op">!</span> dot</span>
<span id="cb33-17"><a href="#cb33-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-18"><a href="#cb33-18" aria-hidden="true" tabindex="-1"></a><span class="ot">test ::</span> &#39;[] <span class="op">:-&gt;</span> &#39;[ &#39;[a] <span class="op">:~&gt;</span> &#39;[a,a] ]</span>
<span id="cb33-19"><a href="#cb33-19" aria-hidden="true" tabindex="-1"></a>test <span class="ot">=</span> quote dup</span></code></pre></div>
<p>Interestingly, these combinators represent the monadic operations on
state (<code>dot</code> = <code>join</code>, <code>pure</code> =
<code>pure</code>, etc.)</p>
<p>And can we get the nicer composition of the function from the intro?
Kind of:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>sumAdded <span class="ot">=</span> quote add <span class="op">!</span> <span class="fu">curry</span> <span class="op">!</span> dot <span class="op">!</span> <span class="fu">map</span> <span class="op">!</span> <span class="fu">sum</span></span></code></pre></div>
<p>Here are some references for concatenative languages: <span
class="citation" data-cites="okasaki_techniques_2002">Okasaki (<a
href="#ref-okasaki_techniques_2002"
role="doc-biblioref">2002</a>)</span>, <span class="citation"
data-cites="purdy_big_2012">Purdy (<a href="#ref-purdy_big_2012"
role="doc-biblioref">2012</a>)</span>, <span class="citation"
data-cites="kerby_theory_2007">Kerby (<a href="#ref-kerby_theory_2007"
role="doc-biblioref">2007</a>)</span>, <span class="citation"
data-cites="okasaki_theoretical_2003">Okasaki (<a
href="#ref-okasaki_theoretical_2003"
role="doc-biblioref">2003</a>)</span>.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-kerby_theory_2007" class="csl-entry" role="listitem">
Kerby, Brent. 2007. <span>“The <span>Theory</span> of
<span>Concatenative Combinators</span>.”</span> <a
href="http://tunes.org/\%7Eiepos/joy.html">http://tunes.org/\%7Eiepos/joy.html</a>.
</div>
<div id="ref-okasaki_techniques_2002" class="csl-entry" role="listitem">
Okasaki, Chris. 2002. <span>“Techniques for embedding postfix languages
in <span>Haskell</span>.”</span> In <em>Proceedings of the <span>ACM
SIGPLAN</span> workshop on <span>Haskell</span> - <span>Haskell</span>
’02</em>, 105–113. Pittsburgh, Pennsylvania: <span>ACM Press</span>.
doi:<a
href="https://doi.org/10.1145/581690.581699">10.1145/581690.581699</a>.
<a
href="http://portal.acm.org/citation.cfm?doid=581690.581699">http://portal.acm.org/citation.cfm?doid=581690.581699</a>.
</div>
<div id="ref-okasaki_theoretical_2003" class="csl-entry"
role="listitem">
———. 2003. <span>“<span>THEORETICAL PEARLS</span>:
<span>Flattening</span> combinators: Surviving without
parentheses.”</span> <em>Journal of Functional Programming</em> 13 (4)
(July): 815–822. doi:<a
href="https://doi.org/10.1017/S0956796802004483">10.1017/S0956796802004483</a>.
<a
href="https://www.cambridge.org/core/journals/journal-of-functional-programming/article/theoretical-pearls/3E99993FE5464986AD94D292FF5EA275">https://www.cambridge.org/core/journals/journal-of-functional-programming/article/theoretical-pearls/3E99993FE5464986AD94D292FF5EA275</a>.
</div>
<div id="ref-purdy_big_2012" class="csl-entry" role="listitem">
Purdy, Jon. 2012. <span>“The <span>Big Mud Puddle</span>: <span>Why
Concatenative Programming Matters</span>.”</span> <em>The Big Mud
Puddle</em>. <a
href="https://evincarofautumn.blogspot.com/2012/02/why-concatenative-programming-matters.html">https://evincarofautumn.blogspot.com/2012/02/why-concatenative-programming-matters.html</a>.
</div>
</div>
]]></description>
    <pubDate>Sat, 11 May 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-05-11-concatenative-free.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Some Tricks for List Manipulation</title>
    <link>https://doisinkidney.com/posts/2019-05-08-list-manipulation-tricks.html</link>
    <description><![CDATA[<div class="info">
    Posted on May  8, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>This post is a collection of some of the tricks I’ve learned for
manipulating lists in Haskell. Each one starts with a puzzle: you should
try the puzzle yourself before seeing the solution!</p>
<h1 id="the-tortoise-and-the-hare">The Tortoise and the Hare</h1>
<blockquote>
<p>How can you split a list in half, in one pass, without taking its
length?</p>
</blockquote>
<p>This first one is a relatively well-known trick, but it occasionally
comes in handy, so I thought I’d mention it. The naive way is as
follows:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>splitHalf xs <span class="ot">=</span> <span class="fu">splitAt</span> (<span class="fu">length</span> xs <span class="ot">`div`</span> <span class="dv">2</span>) xs</span></code></pre></div>
<p>But it’s unsatisfying: we have to traverse the list twice, and we’re
taking its length (which is almost always a bad idea). Instead, we use
the following function:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">splitHalf ::</span> [a] <span class="ot">-&gt;</span> ([a],[a])</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>splitHalf xs <span class="ot">=</span> go xs xs</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    go (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> first (y<span class="op">:</span>) (go ys zs)</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    go ys _ <span class="ot">=</span> ([],ys)</span></code></pre></div>
<p>The “tortoise and the hare” is the two arguments to <code>go</code>:
it traverses the second one twice as fast, so when it hits the end, we
know that the first list must be halfway done.</p>
<h1 id="there-and-back-again">There and Back Again</h1>
<blockquote>
<p>Given two lists, <code>xs</code> and <code>ys</code>, write a
function which zips <code>xs</code> with the <em>reverse</em> of
<code>ys</code> (in one pass).</p>
</blockquote>
<p>There’s a lovely paper <span class="citation"
data-cites="danvy_there_2005">(<a href="#ref-danvy_there_2005"
role="doc-biblioref">Danvy and Goldberg 2005</a>)</span> which goes
though a number of tricks for how to do certain list manipulations “in
reverse”. Their technique is known as “there and back again”. However,
I’d like to describe a different way to get to the same technique, using
folds.</p>
<p>Whenever I need to do some list manipulation in reverse (i.e., I need
the input list to be reversed), I first see if I can rewrite the
function as a fold, and then just switch out <code>foldr</code> for
<code>foldl</code>.</p>
<p>For our puzzle here, we need to first write <code>zip</code> as a
fold:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> <span class="ot">=</span> <span class="fu">foldr</span> f b</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    f x k (y<span class="op">:</span>ys) <span class="ot">=</span> (x,y) <span class="op">:</span> k ys</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    f x k [] <span class="ot">=</span> []</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    b _ <span class="ot">=</span> []</span></code></pre></div>
<p>If that looks complex, or difficult to write, don’t worry! There’s a
systematic way to get to the above definition from the normal version of
<code>zip</code>. First, let’s start with a normal <code>zip</code>:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> [] ys <span class="ot">=</span> []</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs [] <span class="ot">=</span> []</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> (x,y) <span class="op">:</span> <span class="fu">zip</span> xs ys</span></code></pre></div>
<p>Then, we need to turn it into a case-tree, where the first branch is
on the list we want to fold over. In other words, we want the function
to look like this:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs <span class="ot">=</span> <span class="kw">case</span> xs <span class="kw">of</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">???</span></span></code></pre></div>
<p>To figure out the cases, we factor out the cases in the original
function. Since the second clause (<code>zip xs [] = []</code>) is only
reachable when <code>xs /= []</code>, it’s effectively a case for the
<code>x:xs</code> branch.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs <span class="ot">=</span> <span class="kw">case</span> xs <span class="kw">of</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    [] <span class="ot">-&gt;</span> \_ <span class="ot">-&gt;</span> []</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    x<span class="op">:</span>xs <span class="ot">-&gt;</span> \<span class="kw">case</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>        [] <span class="ot">-&gt;</span> []</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>        y<span class="op">:</span>ys <span class="ot">-&gt;</span> (x,y) <span class="op">:</span> <span class="fu">zip</span> xs ys</span></code></pre></div>
<p>Now, we rewrite the different cases to be auxiliary functions:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs <span class="ot">=</span> <span class="kw">case</span> xs <span class="kw">of</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    [] <span class="ot">-&gt;</span> b</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    x<span class="op">:</span>xs <span class="ot">-&gt;</span> f x xs</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> \_ <span class="ot">-&gt;</span> []</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    f <span class="ot">=</span> \x xs <span class="ot">-&gt;</span> \<span class="kw">case</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>        [] <span class="ot">-&gt;</span> []</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>        y<span class="op">:</span>ys <span class="ot">-&gt;</span> (x,y) <span class="op">:</span> <span class="fu">zip</span> xs ys</span></code></pre></div>
<p>And finally, we <em>refactor</em> the recursive call to the first
case expression.</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs <span class="ot">=</span> <span class="kw">case</span> xs <span class="kw">of</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    [] <span class="ot">-&gt;</span> b</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    x<span class="op">:</span>xs <span class="ot">-&gt;</span> f x (<span class="fu">zip</span> xs)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">=</span> \_ <span class="ot">-&gt;</span> []</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    f <span class="ot">=</span> \x xs <span class="ot">-&gt;</span> \<span class="kw">case</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>        [] <span class="ot">-&gt;</span> []</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>        y<span class="op">:</span>ys <span class="ot">-&gt;</span> (x,y) <span class="op">:</span> xs ys</span></code></pre></div>
<p>Then those two auxiliary functions are what you pass to
<code>foldr</code>!</p>
<p>So, to reverse it, we simply take wherever we wrote
<code>foldr f b</code>, and replace it with
<code>foldl (flip f) b</code>:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipRev ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>zipRev <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">flip</span> f) b</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    f x k (y<span class="op">:</span>ys) <span class="ot">=</span> (x,y) <span class="op">:</span> k ys</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    f x k [] <span class="ot">=</span> []</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    b _ <span class="ot">=</span> []</span></code></pre></div>
<p>Of course, we’re reversing the wrong list here. Fixing that is
simple:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipRev ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>zipRev <span class="ot">=</span> <span class="fu">flip</span> (<span class="fu">foldl</span> (<span class="fu">flip</span> f) b)</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    f y k (x<span class="op">:</span>xs) <span class="ot">=</span> (x,y) <span class="op">:</span> k xs</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    f y k [] <span class="ot">=</span> []</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    b _ <span class="ot">=</span> []</span></code></pre></div>
<h1 id="maintaining-laziness">Maintaining Laziness</h1>
<blockquote>
<p>Rewrite the above function without using continuations.</p>
</blockquote>
<p><code>zipRev</code>, as written above, actually uses
<em>continuation-passing style</em>. In most languages (including
standard ML, which was the one used in <span class="citation"
data-cites="danvy_there_2005">Danvy and Goldberg (<a
href="#ref-danvy_there_2005" role="doc-biblioref">2005</a>)</span>),
this is pretty much equivalent to a direct-style implementation (modulo
some performance weirdness). In a lazy language like Haskell, though,
continuation-passing style often makes things unnecessarily strict.</p>
<p>Consider the church-encoded pairs:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Pair</span> a b</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Pair</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runPair ::</span> <span class="kw">forall</span> c<span class="op">.</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> c</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="ot">firstC ::</span> (a <span class="ot">-&gt;</span> a&#39;) <span class="ot">-&gt;</span> <span class="dt">Pair</span> a b <span class="ot">-&gt;</span> <span class="dt">Pair</span> a&#39; b</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>firstC f p <span class="ot">=</span> <span class="dt">Pair</span> (\k <span class="ot">-&gt;</span> runPair p (k <span class="op">.</span> f))</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a><span class="ot">firstD ::</span> (a <span class="ot">-&gt;</span> a&#39;) <span class="ot">-&gt;</span> (a, b) <span class="ot">-&gt;</span> (a&#39;, b)</span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>firstD f <span class="op">~</span>(x,y) <span class="ot">=</span> (f x, y)</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a><span class="ot">fstD ::</span> (a, b) <span class="ot">-&gt;</span> a</span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>fstD <span class="op">~</span>(x,y) <span class="ot">=</span> x</span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a><span class="ot">fstC ::</span> <span class="dt">Pair</span> a b <span class="ot">-&gt;</span> a</span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a>fstC p <span class="ot">=</span> runPair p <span class="fu">const</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> fstC (firstC (<span class="fu">const</span> ()) <span class="fu">undefined</span>)</span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a><span class="fu">undefined</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> fstD (firstD (<span class="fu">const</span> ()) <span class="fu">undefined</span>)</span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a>()</span></code></pre></div>
<p>So it’s sometimes worth trying to avoid continuations if there is a
fast direct-style solution. (alternatively, continuations can give you
extra strictness when you <em>do</em> want it)</p>
<p>First, I’m going to write a different version of <code>zipRev</code>,
which folds on the first list, not the second.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>zipRev xs ys <span class="ot">=</span> <span class="fu">foldl</span> f (\_ r <span class="ot">-&gt;</span> r) xs ys []</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    f k x (y<span class="op">:</span>ys) r <span class="ot">=</span> k ys ((x,y)<span class="op">:</span>r)</span></code></pre></div>
<p>Then, we inline the definition of <code>foldl</code>:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>zipRev xs ys <span class="ot">=</span> <span class="fu">foldr</span> f <span class="fu">id</span> xs (\_ r <span class="ot">-&gt;</span> r) ys []</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    f x k c <span class="ot">=</span> k (\(y<span class="op">:</span>ys) r <span class="ot">-&gt;</span> c ys ((x,y)<span class="op">:</span>r))</span></code></pre></div>
<p>Then, as a hint, we tuple up the two accumulating parameters:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>zipRev xs ys <span class="ot">=</span> <span class="fu">foldr</span> f <span class="fu">id</span> xs <span class="fu">snd</span> (ys,[])</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    f x k c <span class="ot">=</span> k (\((y<span class="op">:</span>ys),r) <span class="ot">-&gt;</span> c (ys,(x,y)<span class="op">:</span>r))</span></code></pre></div>
<p>What we can see here is that we have two continuations stacked on top
of each other. When this happens, they can often “cancel out”, like
so:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>zipRev xs ys <span class="ot">=</span> <span class="fu">snd</span> (<span class="fu">foldr</span> f (ys,[]) xs)</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    f x (y<span class="op">:</span>ys,r) <span class="ot">=</span> (ys,(x,y)<span class="op">:</span>r)</span></code></pre></div>
<p>And we have our direct-style implementation!</p>
<p>Note 14/05/2019: the “cancel-out” explanation there is a little
handwavy, as I’m sure you’ll notice. However, there are a number of <a
href="https://stackoverflow.com/questions/56122022/how-can-two-continuations-cancel-each-other-out">excellent
explanations on this stackoverflow thread</a> which explain it much
better than I ever could. Thanks to Anders Kaseorg, Will Ness,
user11228628, and to Joseph Sible <span class="citation"
data-cites="sible_how_2019">(<a href="#ref-sible_how_2019"
role="doc-biblioref">2019</a>)</span> for asking the question.</p>
<h1 id="manual-fusion">Manual Fusion</h1>
<blockquote>
<p>Detect that a list is a palindrome, in one pass.</p>
</blockquote>
<p>We now know a good way to split a list in two, and a good way to zip
a list with its reverse. We can <em>combine</em> the two to get a
program that checks if a list is a palindrome. Here’s a first
attempt:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>isPal xs <span class="ot">=</span> <span class="fu">all</span> (<span class="fu">uncurry</span> (<span class="op">==</span>)) (<span class="fu">uncurry</span> zipRev (splitHalf xs))</span></code></pre></div>
<p>But this is doing <em>three</em> passes!</p>
<p>To get around it, we can manually do some fusion. Fusion is a
technique where we can spot scenarios like the following:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldr</span> f b (x <span class="op">:</span> y <span class="op">:</span> [])</span></code></pre></div>
<p>And translate them into a version without a list:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>x <span class="ot">`f`</span> (y <span class="ot">`f`</span> b)</span></code></pre></div>
<p>The trick is making sure that the consumer is written as a fold, and
then we just put its <code>f</code> and <code>b</code> in place of the
<code>:</code> and <code>[]</code> in the producer.</p>
<p>So, when we inline the definition of <code>splitHalf</code> into
<code>zipRev</code>, we get the following:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipRevHalf ::</span> [a] <span class="ot">-&gt;</span> [(a,a)]</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>zipRevHalf xs <span class="ot">=</span> <span class="fu">snd</span> (go xs xs)</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    go (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> f y (go ys zs)</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>    go (_<span class="op">:</span>ys) [_]      <span class="ot">=</span> (ys,[])</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>    go ys []           <span class="ot">=</span> (ys,[])</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>    f x (y<span class="op">:</span>ys,r) <span class="ot">=</span> (ys,(x,y)<span class="op">:</span>r)</span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>isPal xs <span class="ot">=</span> <span class="fu">all</span> (<span class="fu">uncurry</span> (<span class="op">==</span>)) (zipRevHalf xs)</span></code></pre></div>
<p>(adding a special case for odd-length lists)</p>
<p>Finally, the <code>all (uncurry (==))</code> is implemented as a fold
also. So we can fuse it with the rest of the definitions:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">isPal ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>isPal xs <span class="ot">=</span> <span class="fu">snd</span> (go xs xs)</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>    go (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> f y (go ys zs)</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    go (_<span class="op">:</span>ys) [_]      <span class="ot">=</span> (ys,<span class="dt">True</span>)</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    go ys     []       <span class="ot">=</span> (ys,<span class="dt">True</span>)</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>    f x (y<span class="op">:</span>ys,r) <span class="ot">=</span> (ys,(x <span class="op">==</span> y) <span class="op">&amp;&amp;</span> r)</span></code></pre></div>
<p>You may have spotted the writer monad over <code>All</code> there.
Indeed, we can rewrite it to use the monadic bind:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">isPal ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>isPal xs <span class="ot">=</span> getAll (<span class="fu">fst</span> (go xs xs)) <span class="kw">where</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  go (y<span class="op">:</span>ys) (_<span class="op">:</span>_<span class="op">:</span>zs) <span class="ot">=</span> f y <span class="op">=&lt;&lt;</span> go ys zs</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>  go (_<span class="op">:</span>ys) [_]      <span class="ot">=</span> <span class="fu">pure</span> ys</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>  go ys     []       <span class="ot">=</span> <span class="fu">pure</span> ys</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>  f y (z<span class="op">:</span>zs) <span class="ot">=</span> (<span class="dt">All</span> (y <span class="op">==</span> z), zs)</span></code></pre></div>
<h1 id="eliminating-multiple-passes-with-laziness">Eliminating Multiple
Passes with Laziness</h1>
<blockquote>
<p>Construct a Braun tree from a list in linear time.</p>
</blockquote>
<p>This is also a very well-known trick <span class="citation"
data-cites="bird_using_1984">(<a href="#ref-bird_using_1984"
role="doc-biblioref">Bird 1984</a>)</span>, but today I’m going to use
it to write a function for constructing Braun trees.</p>
<p>A Braun tree is a peculiar structure. It’s a binary tree, where
adjacent branches can differ in size by only 1. When used as an array,
it has
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
lookup times. It’s enumerated like so:</p>
<pre><code>     ┌─7
   ┌3┤
   │ └11
 ┌1┤
 │ │ ┌─9
 │ └5┤
 │   └13
0┤
 │   ┌─8
 │ ┌4┤
 │ │ └12
 └2┤
   │ ┌10
   └6┤
     └14</code></pre>
<p>The objective is to construct a tree from a list in linear time, in
the order defined above. <span class="citation"
data-cites="okasaki_three_1997">Okasaki (<a
href="#ref-okasaki_three_1997" role="doc-biblioref">1997</a>)</span>
observed that, from the list:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>[<span class="dv">0</span><span class="op">..</span><span class="dv">14</span>]</span></code></pre></div>
<p>Each level in the tree is constructed from chucks of powers of two.
In other words:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">0</span>],[<span class="dv">1</span>,<span class="dv">2</span>],[<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>],[<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">10</span>,<span class="dv">11</span>,<span class="dv">12</span>,<span class="dv">13</span>,<span class="dv">14</span>]]</span></code></pre></div>
<p>From this, we can write the following function:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>rows k [] <span class="ot">=</span> []</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>rows k xs <span class="ot">=</span> (k , <span class="fu">take</span> k xs) <span class="op">:</span> rows (<span class="dv">2</span><span class="op">*</span>k) (<span class="fu">drop</span> k xs)</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>build (k,xs) ts <span class="ot">=</span> <span class="fu">zipWith3</span> <span class="dt">Node</span> xs ts1 ts2</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>    (ts1,ts2) <span class="ot">=</span> <span class="fu">splitAt</span> k (ts <span class="op">++</span> <span class="fu">repeat</span> <span class="dt">Leaf</span>)</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>fromList <span class="ot">=</span> <span class="fu">head</span> <span class="op">.</span> <span class="fu">foldr</span> build [<span class="dt">Leaf</span>] <span class="op">.</span> rows <span class="dv">1</span></span></code></pre></div>
<p>The first place we’ll look to eliminate a pass is the
<code>build</code> function. It combines two rows by splitting the
second in half, and zipping it with the first.</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> build (<span class="dv">3</span>, [x1,x2,x3]) [y1,y2,y3,y4,y5,y6]</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>[(x1,y1,y4),(x2,y2,y5),(x3,y3,y6)]</span></code></pre></div>
<p>We don’t need to store the length of the first list, though, as we
are only using it to split the second, and we can do <em>that</em> at
the same time as the zipping.</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipUntil ::</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> ([c],[b])</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>zipUntil _ [] ys <span class="ot">=</span> ([],ys)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>zipUntil f (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> first (f x y<span class="op">:</span>) (zipUntil f xs ys)</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> zipUntil (,) [<span class="dv">1</span>,<span class="dv">2</span>] <span class="st">&quot;abc&quot;</span></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a>([(<span class="dv">1</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">2</span>,<span class="ch">&#39;b&#39;</span>)],<span class="st">&quot;c&quot;</span>)</span></code></pre></div>
<p>Using this function in <code>build</code> looks like the
following:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>build (k,xs) ts <span class="ot">=</span> <span class="fu">zipWith</span> (<span class="op">$</span>) ys ts2</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    (ys,ts2) <span class="ot">=</span> zipUntil <span class="dt">Node</span> xs (ts <span class="op">++</span> <span class="fu">repeat</span> <span class="dt">Leaf</span>)</span></code></pre></div>
<p>That top-level <code>zipWith</code> is <em>also</em> unnecessary,
though. If we make the program circular, we can produce <code>ts2</code>
as we consume it, making the whole thing single-pass.</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>build xs ts <span class="ot">=</span> ys</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    (ys,ts2) <span class="ot">=</span> zip3Node xs (ts <span class="op">++</span> <span class="fu">repeat</span> <span class="dt">Leaf</span>) ts2</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>    zip3Node (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="op">~</span>(z<span class="op">:</span>zs) <span class="ot">=</span> first (<span class="dt">Node</span> x y z<span class="op">:</span>) (zip3Node xs ys zs)</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>    zip3Node [] ys _ <span class="ot">=</span> ([], ys)</span></code></pre></div>
<p>That <code>zip3Node</code> is a good candidate for rewriting as a
fold, also, making the whole thing look like this:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a>rows k [] <span class="ot">=</span> []</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>rows k xs <span class="ot">=</span> <span class="fu">take</span> k xs <span class="op">:</span> rows (<span class="dv">2</span><span class="op">*</span>k) (<span class="fu">drop</span> k xs)</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>build xs ts <span class="ot">=</span> ys</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>    (ys,zs) <span class="ot">=</span> <span class="fu">foldr</span> f b xs ts zs</span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>    f x xs (y<span class="op">:</span>ys) <span class="op">~</span>(z<span class="op">:</span>zs) <span class="ot">=</span> first (<span class="dt">Node</span> x y z<span class="op">:</span>) (xs ys zs)</span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>    b ys _ <span class="ot">=</span> ([],ys)</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>fromList <span class="ot">=</span> <span class="fu">head</span> <span class="op">.</span> <span class="fu">foldr</span> build (<span class="fu">repeat</span> <span class="dt">Leaf</span>) <span class="op">.</span> rows <span class="dv">1</span></span></code></pre></div>
<p>To fuse all of those definitions, we first will need to rewrite
<code>rows</code> as a fold:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>rows xs <span class="ot">=</span> <span class="fu">uncurry</span> (<span class="op">:</span>) (<span class="fu">foldr</span> f b xs <span class="dv">1</span> <span class="dv">2</span>)</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>    b _ _ <span class="ot">=</span> ([],[])</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>    f x k <span class="dv">0</span> j <span class="ot">=</span> ([], <span class="fu">uncurry</span> (<span class="op">:</span>) (f x k j (j<span class="op">*</span><span class="dv">2</span>)))</span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>    f x k i j <span class="ot">=</span> first (x<span class="op">:</span>) (k (i<span class="op">-</span><span class="dv">1</span>) j)</span></code></pre></div>
<p>Once we have everything as a fold, the rest of the transformation is
pretty mechanical. At the end of it all, we get the following
linear-time function for constructing a Braun tree from a list:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fromList ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>fromList xs <span class="ot">=</span> <span class="fu">head</span> (l (<span class="fu">foldr</span> f b xs <span class="dv">1</span> <span class="dv">2</span>))</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>    b _ _ ys zs <span class="ot">=</span> (<span class="fu">repeat</span> <span class="dt">Leaf</span>, (<span class="fu">repeat</span> <span class="dt">Leaf</span>, ys))</span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>    l k <span class="ot">=</span> <span class="kw">let</span> (xs, ys) <span class="ot">=</span> <span class="fu">uncurry</span> k ys <span class="kw">in</span> xs</span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>    f x k <span class="dv">0</span> j ys zs           <span class="ot">=</span> ([], (l (f x k j (j<span class="op">*</span><span class="dv">2</span>)), ys))</span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>    f x k i j <span class="op">~</span>(y<span class="op">:</span>ys) <span class="op">~</span>(z<span class="op">:</span>zs) <span class="ot">=</span> first (<span class="dt">Node</span> x y z<span class="op">:</span>) (k (i<span class="op">-</span><span class="dv">1</span>) j ys zs)</span></code></pre></div>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-bird_using_1984" class="csl-entry" role="listitem">
Bird, R. S. 1984. <span>“Using <span>Circular Programs</span> to
<span>Eliminate Multiple Traversals</span> of <span>Data</span>.”</span>
<em>Acta Inf.</em> 21 (3) (October): 239–250. doi:<a
href="https://doi.org/10.1007/BF00264249">10.1007/BF00264249</a>.
</div>
<div id="ref-danvy_there_2005" class="csl-entry" role="listitem">
Danvy, Olivier, and Mayer Goldberg. 2005. <span>“There and <span>Back
Again</span>.”</span> <em>Fundamenta Informaticae</em> 66 (4)
(December): 397–413. <a
href="https://cs.au.dk/~danvy/DSc/08_danvy-goldberg_fi-2005.pdf">https://cs.au.dk/~danvy/DSc/08_danvy-goldberg_fi-2005.pdf</a>.
</div>
<div id="ref-okasaki_three_1997" class="csl-entry" role="listitem">
Okasaki, Chris. 1997. <span>“Three <span>Algorithms</span> on
<span>Braun Trees</span>.”</span> <em>Journal of Functional
Programming</em> 7 (6) (November): 661–666. doi:<a
href="https://doi.org/10.1017/S0956796897002876">10.1017/S0956796897002876</a>.
</div>
<div id="ref-sible_how_2019" class="csl-entry" role="listitem">
Sible, Joseph. 2019. <span>“How can two continuations cancel each other
out?”</span> <em>Stack Overflow</em>. <a
href="https://stackoverflow.com/questions/56122022/how-can-two-continuations-cancel-each-other-out">https://stackoverflow.com/questions/56122022/how-can-two-continuations-cancel-each-other-out</a>.
</div>
</div>
]]></description>
    <pubDate>Wed, 08 May 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-05-08-list-manipulation-tricks.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>List Syntax in Agda</title>
    <link>https://doisinkidney.com/posts/2019-04-20-ListSyntax.html</link>
    <description><![CDATA[<div class="info">
    Posted on April 20, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>Just some silly examples of how to get a nice list syntax with mixfix
operators in Agda.</p>
<details>
<summary>
Intro and Imports
</summary>
<pre class="Agda"><a id="169" class="Symbol">{-#</a> <a id="173" class="Keyword">OPTIONS</a> <a id="181" class="Pragma">--without-K</a> <a id="193" class="Pragma">--safe</a> <a id="200" class="Symbol">#-}</a>

<a id="205" class="Keyword">module</a> <a id="212" href="ListSyntax.html" class="Module">ListSyntax</a> <a id="223" class="Keyword">where</a>

<a id="230" class="Keyword">open</a> <a id="235" class="Keyword">import</a> <a id="242" href="https://agda.github.io/agda-stdlib/Data.List.html" class="Module">Data.List</a> <a id="252" class="Symbol">as</a> <a id="255" class="Module">List</a> <a id="260" class="Keyword">using</a> <a id="266" class="Symbol">(</a><a id="267" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#121" class="Datatype">List</a><a id="271" class="Symbol">;</a> <a id="273" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#173" class="InductiveConstructor Operator">_∷_</a><a id="276" class="Symbol">;</a> <a id="278" href="https://agda.github.io/agda-stdlib/Data.List.Base.html#8781" class="InductiveConstructor">[]</a><a id="280" class="Symbol">)</a>
<a id="282" class="Keyword">open</a> <a id="287" class="Keyword">import</a> <a id="294" href="https://agda.github.io/agda-stdlib/Data.Product.html" class="Module">Data.Product</a>
<a id="307" class="Keyword">open</a> <a id="312" class="Keyword">import</a> <a id="319" href="https://agda.github.io/agda-stdlib/Level.html" class="Module">Level</a> <a id="325" class="Keyword">using</a> <a id="331" class="Symbol">(</a><a id="332" href="https://agda.github.io/agda-stdlib/Agda.Primitive.html#657" class="Primitive Operator">_⊔_</a><a id="335" class="Symbol">;</a> <a id="337" href="https://agda.github.io/agda-stdlib/Agda.Primitive.html#408" class="Postulate">Level</a><a id="342" class="Symbol">)</a>
<a id="344" class="Keyword">open</a> <a id="349" class="Keyword">import</a> <a id="356" href="https://agda.github.io/agda-stdlib/Data.Nat.html" class="Module">Data.Nat</a> <a id="365" class="Keyword">using</a> <a id="371" class="Symbol">(</a><a id="372" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a><a id="373" class="Symbol">;</a> <a id="375" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#298" class="Primitive Operator">_+_</a><a id="378" class="Symbol">;</a> <a id="380" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a><a id="383" class="Symbol">;</a> <a id="385" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#183" class="InductiveConstructor">zero</a><a id="389" class="Symbol">)</a>
<a id="391" class="Keyword">open</a> <a id="396" class="Keyword">import</a> <a id="403" href="https://agda.github.io/agda-stdlib/Function.html" class="Module">Function</a>

<a id="413" class="Keyword">variable</a>
  <a id="424" href="ListSyntax.html#424" class="Generalizable">a</a> <a id="426" href="ListSyntax.html#426" class="Generalizable">b</a> <a id="428" class="Symbol">:</a> <a id="430" href="https://agda.github.io/agda-stdlib/Agda.Primitive.html#408" class="Postulate">Level</a>
  <a id="438" href="ListSyntax.html#438" class="Generalizable">A</a> <a id="440" class="Symbol">:</a> <a id="442" class="PrimitiveType">Set</a> <a id="446" href="ListSyntax.html#424" class="Generalizable">a</a>
  <a id="450" href="ListSyntax.html#450" class="Generalizable">B</a> <a id="452" class="Symbol">:</a> <a id="454" class="PrimitiveType">Set</a> <a id="458" href="ListSyntax.html#426" class="Generalizable">b</a>
</pre>
</details>
<h1 id="approach-1">Approach 1:</h1>
<p>With instance search.</p>
<pre class="Agda"><a id="522" class="Keyword">module</a> <a id="Instance"></a><a id="529" href="ListSyntax.html#529" class="Module">Instance</a> <a id="538" class="Keyword">where</a>
  <a id="546" class="Keyword">record</a> <a id="Instance.ListSyntax"></a><a id="553" href="ListSyntax.html#553" class="Record">ListSyntax</a> <a id="564" class="Symbol">{</a><a id="565" href="ListSyntax.html#565" class="Bound">a</a> <a id="567" href="ListSyntax.html#567" class="Bound">b</a><a id="568" class="Symbol">}</a> <a id="570" class="Symbol">(</a><a id="571" href="ListSyntax.html#571" class="Bound">A</a> <a id="573" class="Symbol">:</a> <a id="575" class="PrimitiveType">Set</a> <a id="579" href="ListSyntax.html#565" class="Bound">a</a><a id="580" class="Symbol">)</a> <a id="582" class="Symbol">(</a><a id="583" href="ListSyntax.html#583" class="Bound">B</a> <a id="585" class="Symbol">:</a> <a id="587" class="PrimitiveType">Set</a> <a id="591" href="ListSyntax.html#567" class="Bound">b</a><a id="592" class="Symbol">)</a> <a id="594" class="Symbol">:</a> <a id="596" class="PrimitiveType">Set</a> <a id="600" class="Symbol">(</a><a id="601" href="ListSyntax.html#565" class="Bound">a</a> <a id="603" href="https://agda.github.io/agda-stdlib/Agda.Primitive.html#657" class="Primitive Operator">⊔</a> <a id="605" href="ListSyntax.html#567" class="Bound">b</a><a id="606" class="Symbol">)</a> <a id="608" class="Keyword">where</a>
    <a id="618" class="Keyword">field</a> <a id="Instance.ListSyntax.[_]"></a><a id="624" href="ListSyntax.html#624" class="Field Operator">[_]</a> <a id="628" class="Symbol">:</a> <a id="630" href="ListSyntax.html#583" class="Bound">B</a> <a id="632" class="Symbol">→</a> <a id="634" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#121" class="Datatype">List</a> <a id="639" href="ListSyntax.html#571" class="Bound">A</a>

  <a id="644" class="Keyword">open</a> <a id="649" href="ListSyntax.html#553" class="Module">ListSyntax</a> <a id="660" class="Symbol">⦃</a> <a id="662" class="Symbol">...</a> <a id="666" class="Symbol">⦄</a> <a id="668" class="Keyword">public</a>

  <a id="678" class="Keyword">instance</a>
    <a id="Instance.cons"></a><a id="691" href="ListSyntax.html#691" class="Function">cons</a> <a id="696" class="Symbol">:</a> <a id="698" class="Symbol">∀</a> <a id="700" class="Symbol">{</a><a id="701" href="ListSyntax.html#701" class="Bound">a</a> <a id="703" href="ListSyntax.html#703" class="Bound">b</a><a id="704" class="Symbol">}</a> <a id="706" class="Symbol">{</a><a id="707" href="ListSyntax.html#707" class="Bound">A</a> <a id="709" class="Symbol">:</a> <a id="711" class="PrimitiveType">Set</a> <a id="715" href="ListSyntax.html#701" class="Bound">a</a><a id="716" class="Symbol">}</a> <a id="718" class="Symbol">{</a><a id="719" href="ListSyntax.html#719" class="Bound">B</a> <a id="721" class="Symbol">:</a> <a id="723" class="PrimitiveType">Set</a> <a id="727" href="ListSyntax.html#703" class="Bound">b</a><a id="728" class="Symbol">}</a> <a id="730" class="Symbol">⦃</a> <a id="732" href="ListSyntax.html#732" class="Bound">_</a> <a id="734" class="Symbol">:</a> <a id="736" href="ListSyntax.html#553" class="Record">ListSyntax</a> <a id="747" href="ListSyntax.html#707" class="Bound">A</a> <a id="749" href="ListSyntax.html#719" class="Bound">B</a> <a id="751" class="Symbol">⦄</a>
         <a id="762" class="Symbol">→</a>  <a id="765" href="ListSyntax.html#553" class="Record">ListSyntax</a> <a id="776" href="ListSyntax.html#707" class="Bound">A</a> <a id="778" class="Symbol">(</a><a id="779" href="ListSyntax.html#707" class="Bound">A</a> <a id="781" href="https://agda.github.io/agda-stdlib/Data.Product.html#1162" class="Function Operator">×</a> <a id="783" href="ListSyntax.html#719" class="Bound">B</a><a id="784" class="Symbol">)</a>
    <a id="790" href="ListSyntax.html#624" class="Field Operator">[_]</a> <a id="794" class="Symbol">⦃</a> <a id="796" href="ListSyntax.html#691" class="Function">cons</a> <a id="801" class="Symbol">⦄</a> <a id="803" class="Symbol">(</a><a id="804" href="ListSyntax.html#804" class="Bound">x</a> <a id="806" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="808" href="ListSyntax.html#808" class="Bound">xs</a><a id="810" class="Symbol">)</a> <a id="812" class="Symbol">=</a> <a id="814" href="ListSyntax.html#804" class="Bound">x</a> <a id="816" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#173" class="InductiveConstructor Operator">∷</a> <a id="818" href="ListSyntax.html#624" class="Field Operator">[</a> <a id="820" href="ListSyntax.html#808" class="Bound">xs</a> <a id="823" href="ListSyntax.html#624" class="Field Operator">]</a>

  <a id="828" class="Keyword">instance</a>
    <a id="Instance.sing"></a><a id="841" href="ListSyntax.html#841" class="Function">sing</a> <a id="846" class="Symbol">:</a> <a id="848" class="Symbol">∀</a> <a id="850" class="Symbol">{</a><a id="851" href="ListSyntax.html#851" class="Bound">a</a><a id="852" class="Symbol">}</a> <a id="854" class="Symbol">{</a><a id="855" href="ListSyntax.html#855" class="Bound">A</a> <a id="857" class="Symbol">:</a> <a id="859" class="PrimitiveType">Set</a> <a id="863" href="ListSyntax.html#851" class="Bound">a</a><a id="864" class="Symbol">}</a> <a id="866" class="Symbol">→</a> <a id="868" href="ListSyntax.html#553" class="Record">ListSyntax</a> <a id="879" href="ListSyntax.html#855" class="Bound">A</a> <a id="881" href="ListSyntax.html#855" class="Bound">A</a>
    <a id="887" href="ListSyntax.html#624" class="Field Operator">[_]</a> <a id="891" class="Symbol">⦃</a> <a id="893" href="ListSyntax.html#841" class="Function">sing</a> <a id="898" class="Symbol">⦄</a> <a id="900" class="Symbol">=</a> <a id="902" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#173" class="InductiveConstructor Operator">_∷</a> <a id="905" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#158" class="InductiveConstructor">[]</a>
</pre>
<h2 id="advantages">Advantages:</h2>
No type annotation needed for singleton list.
<pre class="Agda"><a id="983" class="Comment">--_ : List ℕ ← not needed</a>
  <a id="1011" href="ListSyntax.html#1011" class="Function">_</a> <a id="1013" class="Symbol">=</a> <a id="1015" href="ListSyntax.html#624" class="Field Operator">[</a> <a id="1017" class="Number">1</a> <a id="1019" href="ListSyntax.html#624" class="Field Operator">]</a>
</pre>
It can even work as a standalone function:
<pre class="Agda">  <a id="1078" href="ListSyntax.html#1078" class="Function">_</a> <a id="1080" class="Symbol">:</a> <a id="1082" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#121" class="Datatype">List</a> <a id="1087" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="1089" class="Symbol">→</a> <a id="1091" class="Symbol">_</a>
  <a id="1095" class="Symbol">_</a> <a id="1097" class="Symbol">=</a> <a id="1099" href="https://agda.github.io/agda-stdlib/Data.List.Base.html#1299" class="Function">List.map</a> <a id="1108" href="ListSyntax.html#624" class="Field Operator">[_]</a>
</pre>
It uses a closed operator, so we don’t need parentheses to parse it:
<pre class="Agda">  <a id="1195" href="ListSyntax.html#1195" class="Function">_</a> <a id="1197" class="Symbol">=</a> <a id="1199" href="https://agda.github.io/agda-stdlib/Data.List.Base.html#3427" class="Function">List.foldr</a> <a id="1210" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#298" class="Primitive Operator">_+_</a> <a id="1214" class="Number">0</a> <a id="1216" href="ListSyntax.html#624" class="Field Operator">[</a> <a id="1218" class="Number">1</a> <a id="1220" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="1222" class="Number">2</a> <a id="1224" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="1226" class="Number">3</a> <a id="1228" href="ListSyntax.html#624" class="Field Operator">]</a>
</pre>
And it doesn’t clash with product:
<pre class="Agda">  <a id="1275" href="ListSyntax.html#1275" class="Function">_</a> <a id="1277" class="Symbol">:</a> <a id="1279" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="1281" href="https://agda.github.io/agda-stdlib/Data.Product.html#1162" class="Function Operator">×</a> <a id="1283" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
  <a id="1287" class="Symbol">_</a> <a id="1289" class="Symbol">=</a> <a id="1291" class="Number">1</a> <a id="1293" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="1295" class="Number">2</a>
</pre>
It allows nesting:
<pre class="Agda">  <a id="1330" href="ListSyntax.html#1330" class="Function">_</a> <a id="1332" class="Symbol">:</a> <a id="1334" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#121" class="Datatype">List</a> <a id="1339" class="Symbol">(</a><a id="1340" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#121" class="Datatype">List</a> <a id="1345" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a><a id="1346" class="Symbol">)</a>
  <a id="1350" class="Symbol">_</a> <a id="1352" class="Symbol">=</a> <a id="1354" href="ListSyntax.html#624" class="Field Operator">[</a> <a id="1356" href="ListSyntax.html#624" class="Field Operator">[</a> <a id="1358" class="Number">1</a> <a id="1360" href="ListSyntax.html#624" class="Field Operator">]</a> <a id="1362" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="1364" href="ListSyntax.html#624" class="Field Operator">[</a> <a id="1366" class="Number">2</a> <a id="1368" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="1370" class="Number">3</a> <a id="1372" href="ListSyntax.html#624" class="Field Operator">]</a> <a id="1374" href="ListSyntax.html#624" class="Field Operator">]</a>
</pre>
<h2 id="disadvantages">Disadvantages</h2>
However, it needs type annotations when there is more than one item in
the list and there’s no other way to guess the items.
<pre class="Agda">  <a id="1533" href="ListSyntax.html#1533" class="Function">_</a> <a id="1535" class="Symbol">:</a> <a id="1537" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#121" class="Datatype">List</a> <a id="1542" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
  <a id="1546" class="Symbol">_</a> <a id="1548" class="Symbol">=</a> <a id="1550" href="ListSyntax.html#624" class="Field Operator">[</a> <a id="1552" class="Number">1</a> <a id="1554" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="1556" class="Number">2</a> <a id="1558" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="1560" class="Number">3</a> <a id="1562" href="ListSyntax.html#624" class="Field Operator">]</a>
</pre>
<h1 id="approach-2-with-a-datatype">Approach 2: With a Datatype</h1>
<pre class="Agda"><a id="1608" class="Keyword">module</a> <a id="DataType"></a><a id="1615" href="ListSyntax.html#1615" class="Module">DataType</a> <a id="1624" class="Keyword">where</a>
  <a id="1632" class="Keyword">infixr</a> <a id="1639" class="Number">5</a> <a id="1641" href="ListSyntax.html#1741" class="InductiveConstructor Operator">_]</a>
  <a id="1646" class="Keyword">data</a> <a id="DataType.ListBuilder"></a><a id="1651" href="ListSyntax.html#1651" class="Datatype">ListBuilder</a> <a id="1663" class="Symbol">{</a><a id="1664" href="ListSyntax.html#1664" class="Bound">a</a><a id="1665" class="Symbol">}</a> <a id="1667" class="Symbol">(</a><a id="1668" href="ListSyntax.html#1668" class="Bound">A</a> <a id="1670" class="Symbol">:</a> <a id="1672" class="PrimitiveType">Set</a> <a id="1676" href="ListSyntax.html#1664" class="Bound">a</a><a id="1677" class="Symbol">)</a> <a id="1679" class="Symbol">:</a> <a id="1681" class="PrimitiveType">Set</a> <a id="1685" href="ListSyntax.html#1664" class="Bound">a</a> <a id="1687" class="Keyword">where</a>
    <a id="DataType.ListBuilder._,_"></a><a id="1697" href="ListSyntax.html#1697" class="InductiveConstructor Operator">_,_</a> <a id="1701" class="Symbol">:</a> <a id="1703" href="ListSyntax.html#1668" class="Bound">A</a> <a id="1705" class="Symbol">→</a> <a id="1707" href="ListSyntax.html#1651" class="Datatype">ListBuilder</a> <a id="1719" href="ListSyntax.html#1668" class="Bound">A</a> <a id="1721" class="Symbol">→</a> <a id="1723" href="ListSyntax.html#1651" class="Datatype">ListBuilder</a> <a id="1735" href="ListSyntax.html#1668" class="Bound">A</a>
    <a id="DataType.ListBuilder._]"></a><a id="1741" href="ListSyntax.html#1741" class="InductiveConstructor Operator">_]</a> <a id="1744" class="Symbol">:</a> <a id="1746" href="ListSyntax.html#1668" class="Bound">A</a> <a id="1748" class="Symbol">→</a> <a id="1750" href="ListSyntax.html#1651" class="Datatype">ListBuilder</a> <a id="1762" href="ListSyntax.html#1668" class="Bound">A</a>

  <a id="1767" class="Keyword">infixr</a> <a id="1774" class="Number">4</a> <a id="1776" href="ListSyntax.html#1781" class="Function Operator">[_</a>
  <a id="DataType.[_"></a><a id="1781" href="ListSyntax.html#1781" class="Function Operator">[_</a> <a id="1784" class="Symbol">:</a> <a id="1786" href="ListSyntax.html#1651" class="Datatype">ListBuilder</a> <a id="1798" href="ListSyntax.html#438" class="Generalizable">A</a> <a id="1800" class="Symbol">→</a> <a id="1802" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#121" class="Datatype">List</a> <a id="1807" href="ListSyntax.html#438" class="Generalizable">A</a>
  <a id="1811" href="ListSyntax.html#1781" class="Function Operator">[</a> <a id="1813" href="ListSyntax.html#1813" class="Bound">x</a> <a id="1815" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="1817" href="ListSyntax.html#1817" class="Bound">xs</a> <a id="1820" class="Symbol">=</a> <a id="1822" href="ListSyntax.html#1813" class="Bound">x</a> <a id="1824" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#173" class="InductiveConstructor Operator">∷</a> <a id="1826" class="Symbol">(</a><a id="1827" href="ListSyntax.html#1781" class="Function Operator">[</a> <a id="1829" href="ListSyntax.html#1817" class="Bound">xs</a><a id="1831" class="Symbol">)</a>
  <a id="1835" href="ListSyntax.html#1781" class="Function Operator">[</a> <a id="1837" href="ListSyntax.html#1837" class="Bound">x</a> <a id="1839" href="ListSyntax.html#1741" class="InductiveConstructor Operator">]</a> <a id="1841" class="Symbol">=</a> <a id="1843" href="ListSyntax.html#1837" class="Bound">x</a> <a id="1845" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#173" class="InductiveConstructor Operator">∷</a> <a id="1847" href="https://agda.github.io/agda-stdlib/Agda.Builtin.List.html#158" class="InductiveConstructor">[]</a>
</pre>
<h2 id="advantages-1">Advantages:</h2>
Single and multi-item lists without type annotation:
<pre class="Agda"><a id="1930" class="Comment">--_ : List ℕ ← not needed</a>
  <a id="1958" href="ListSyntax.html#1958" class="Function">_</a> <a id="1960" class="Symbol">=</a> <a id="1962" href="ListSyntax.html#1781" class="Function Operator">[</a> <a id="1964" class="Number">1</a> <a id="1966" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="1968" class="Number">2</a> <a id="1970" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="1972" class="Number">3</a> <a id="1974" href="ListSyntax.html#1741" class="InductiveConstructor Operator">]</a>

<a id="1977" class="Comment">--_ : List ℕ ← not needed</a>
  <a id="2005" href="ListSyntax.html#2005" class="Function">_</a> <a id="2007" class="Symbol">=</a> <a id="2009" href="ListSyntax.html#1781" class="Function Operator">[</a> <a id="2011" class="Number">1</a> <a id="2013" href="ListSyntax.html#1741" class="InductiveConstructor Operator">]</a>
</pre>
<p>Doesn’t clash with product:</p>
<pre class="Agda">  <a id="2058" href="ListSyntax.html#2058" class="Function">_</a> <a id="2060" class="Symbol">:</a> <a id="2062" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="2064" href="https://agda.github.io/agda-stdlib/Data.Product.html#1162" class="Function Operator">×</a> <a id="2066" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
  <a id="2070" class="Symbol">_</a> <a id="2072" class="Symbol">=</a> <a id="2074" class="Number">1</a> <a id="2076" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Sigma.html#209" class="InductiveConstructor Operator">,</a> <a id="2078" class="Number">2</a>
</pre>
Can choose different “list-like” type based on first bracket:
<pre class="Agda">  <a id="2156" class="Keyword">open</a> <a id="2161" class="Keyword">import</a> <a id="2168" href="https://agda.github.io/agda-stdlib/Data.Vec.html" class="Module">Data.Vec</a> <a id="2177" class="Symbol">as</a> <a id="2180" class="Module">Vec</a> <a id="2184" class="Keyword">using</a> <a id="2190" class="Symbol">(</a><a id="2191" href="https://agda.github.io/agda-stdlib/Data.Vec.html#942" class="InductiveConstructor Operator">_∷_</a><a id="2194" class="Symbol">;</a> <a id="2196" href="https://agda.github.io/agda-stdlib/Data.Vec.html#923" class="InductiveConstructor">[]</a><a id="2198" class="Symbol">;</a> <a id="2200" href="https://agda.github.io/agda-stdlib/Data.Vec.html#887" class="Datatype">Vec</a><a id="2203" class="Symbol">)</a>

  <a id="DataType.len-1"></a><a id="2208" href="ListSyntax.html#2208" class="Function">len-1</a> <a id="2214" class="Symbol">:</a> <a id="2216" href="ListSyntax.html#1651" class="Datatype">ListBuilder</a> <a id="2228" href="ListSyntax.html#438" class="Generalizable">A</a> <a id="2230" class="Symbol">→</a> <a id="2232" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
  <a id="2236" href="ListSyntax.html#2208" class="Function">len-1</a> <a id="2242" class="Symbol">(</a><a id="2243" href="ListSyntax.html#2243" class="Bound">x</a> <a id="2245" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="2247" href="ListSyntax.html#2247" class="Bound">xs</a><a id="2249" class="Symbol">)</a> <a id="2251" class="Symbol">=</a> <a id="2253" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="2257" class="Symbol">(</a><a id="2258" href="ListSyntax.html#2208" class="Function">len-1</a> <a id="2264" href="ListSyntax.html#2247" class="Bound">xs</a><a id="2266" class="Symbol">)</a>
  <a id="2270" href="ListSyntax.html#2208" class="Function">len-1</a> <a id="2276" class="Symbol">(</a><a id="2277" href="ListSyntax.html#2277" class="Bound">x</a> <a id="2279" href="ListSyntax.html#1741" class="InductiveConstructor Operator">]</a><a id="2280" class="Symbol">)</a> <a id="2282" class="Symbol">=</a> <a id="2284" class="Number">0</a>

  <a id="2289" class="Keyword">infixr</a> <a id="2296" class="Number">4</a> <a id="2298" href="ListSyntax.html#2304" class="Function Operator">v[_</a>
  <a id="DataType.v[_"></a><a id="2304" href="ListSyntax.html#2304" class="Function Operator">v[_</a> <a id="2308" class="Symbol">:</a> <a id="2310" class="Symbol">(</a><a id="2311" href="ListSyntax.html#2311" class="Bound">xs</a> <a id="2314" class="Symbol">:</a> <a id="2316" href="ListSyntax.html#1651" class="Datatype">ListBuilder</a> <a id="2328" href="ListSyntax.html#438" class="Generalizable">A</a><a id="2329" class="Symbol">)</a> <a id="2331" class="Symbol">→</a> <a id="2333" href="https://agda.github.io/agda-stdlib/Data.Vec.html#887" class="Datatype">Vec</a> <a id="2337" href="ListSyntax.html#438" class="Generalizable">A</a> <a id="2339" class="Symbol">(</a><a id="2340" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#196" class="InductiveConstructor">suc</a> <a id="2344" class="Symbol">(</a><a id="2345" href="ListSyntax.html#2208" class="Function">len-1</a> <a id="2351" href="ListSyntax.html#2311" class="Bound">xs</a><a id="2353" class="Symbol">))</a>
  <a id="2358" href="ListSyntax.html#2304" class="Function Operator">v[</a> <a id="2361" class="Symbol">(</a><a id="2362" href="ListSyntax.html#2362" class="Bound">x</a> <a id="2364" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="2366" href="ListSyntax.html#2366" class="Bound">xs</a><a id="2368" class="Symbol">)</a> <a id="2370" class="Symbol">=</a> <a id="2372" href="ListSyntax.html#2362" class="Bound">x</a> <a id="2374" href="https://agda.github.io/agda-stdlib/Data.Vec.html#942" class="InductiveConstructor Operator">∷</a> <a id="2376" class="Symbol">(</a><a id="2377" href="ListSyntax.html#2304" class="Function Operator">v[</a> <a id="2380" href="ListSyntax.html#2366" class="Bound">xs</a><a id="2382" class="Symbol">)</a>
  <a id="2386" href="ListSyntax.html#2304" class="Function Operator">v[</a> <a id="2389" href="ListSyntax.html#2389" class="Bound">x</a> <a id="2391" href="ListSyntax.html#1741" class="InductiveConstructor Operator">]</a> <a id="2393" class="Symbol">=</a> <a id="2395" href="ListSyntax.html#2389" class="Bound">x</a> <a id="2397" href="https://agda.github.io/agda-stdlib/Data.Vec.html#942" class="InductiveConstructor Operator">∷</a> <a id="2399" href="https://agda.github.io/agda-stdlib/Data.Vec.html#923" class="InductiveConstructor">[]</a>

  <a id="2405" href="ListSyntax.html#2405" class="Function">_</a> <a id="2407" class="Symbol">:</a> <a id="2409" href="https://agda.github.io/agda-stdlib/Data.Vec.html#887" class="Datatype">Vec</a> <a id="2413" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="2415" class="Number">3</a>
  <a id="2419" class="Symbol">_</a> <a id="2421" class="Symbol">=</a> <a id="2423" href="ListSyntax.html#2304" class="Function Operator">v[</a> <a id="2426" class="Number">1</a> <a id="2428" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="2430" class="Number">2</a> <a id="2432" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="2434" class="Number">3</a> <a id="2436" href="ListSyntax.html#1741" class="InductiveConstructor Operator">]</a>
</pre>
<h2 id="disadvantages-1">Disadvantages</h2>
<p>Not a closed operator, so need parens:</p>
<pre class="Agda">  <a id="2510" href="ListSyntax.html#2510" class="Function">_</a> <a id="2512" class="Symbol">=</a> <a id="2514" href="https://agda.github.io/agda-stdlib/Data.List.Base.html#3427" class="Function">List.foldr</a> <a id="2525" href="https://agda.github.io/agda-stdlib/Agda.Builtin.Nat.html#298" class="Primitive Operator">_+_</a> <a id="2529" class="Number">0</a> <a id="2531" class="Symbol">(</a><a id="2532" href="ListSyntax.html#1781" class="Function Operator">[</a> <a id="2534" class="Number">1</a> <a id="2536" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="2538" class="Number">2</a> <a id="2540" href="ListSyntax.html#1697" class="InductiveConstructor Operator">,</a> <a id="2542" class="Number">3</a> <a id="2544" href="ListSyntax.html#1741" class="InductiveConstructor Operator">]</a><a id="2545" class="Symbol">)</a>
</pre>
Singleton isn’t a function
<pre class="Agda"><a id="2586" class="Comment">--_ = [_]</a>
</pre>
Doesn’t nest
<pre class="Agda"><a id="2622" class="Comment">--_ = [ [ 1 ] , [ 2 , 3 ] ]</a>
</pre>
]]></description>
    <pubDate>Sat, 20 Apr 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-04-20-ListSyntax.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Probability Monads in Cubical Agda</title>
    <link>https://doisinkidney.com/posts/2019-04-17-cubical-probability.html</link>
    <description><![CDATA[<div class="info">
    Posted on April 17, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>, <a title="All pages tagged &#39;Probability&#39;." href="/tags/Probability.html" rel="tag">Probability</a>
    
</div>

<p><a
href="https://agda.readthedocs.io/en/latest/language/cubical.html">Cubical
Agda</a> has just come out, and I’ve been playing around with it for a
bit. There’s a bunch of info out there on the theory of cubical types,
and Homotopy Type Theory more generally (cubical type theory is kind of
like an “implementation” of Homotopy type theory), but I wanted to make
a post demonstrating cubical Agda in practice, and one of its cool uses
from a programming perspective.</p>
<h1 id="so-what-is-cubical-agda">So What is Cubical Agda?</h1>
<p>I don’t really know! Cubical type theory is quite complex (even for a
type theory), and I’m not nearly qualified to properly explain it. In
lieu of a proper first-principles explanation, then, I’ll try and give a
few examples of how it differs from normal Agda, before moving on to the
main example of this post.</p>
<details>
<summary>
Imports
</summary>
<pre class="Agda"><a id="920" class="Symbol">{-#</a> <a id="924" class="Keyword">OPTIONS</a> <a id="932" class="Pragma">--cubical</a> <a id="942" class="Symbol">#-}</a>

<a id="947" class="Keyword">open</a> <a id="952" class="Keyword">import</a> <a id="959" href="../code/probability/ProbabilityModule.Semirings.html" class="Module">ProbabilityModule.Semirings</a>

<a id="988" class="Keyword">module</a> <a id="995" href="" class="Module">ProbabilityModule.Monad</a> <a id="1019" class="Symbol">{</a><a id="1020" href="#1020" class="Bound">s</a><a id="1021" class="Symbol">}</a> <a id="1023" class="Symbol">(</a><a id="1024" href="#1024" class="Bound">rng</a> <a id="1028" class="Symbol">:</a> <a id="1030" href="../code/probability/ProbabilityModule.Semirings.html#125" class="Record">Semiring</a> <a id="1039" href="#1020" class="Bound">s</a><a id="1040" class="Symbol">)</a> <a id="1042" class="Keyword">where</a>

<a id="1049" class="Keyword">open</a> <a id="1054" class="Keyword">import</a> <a id="1061" href="../code/probability/Cubical.Core.Everything.html" class="Module">Cubical.Core.Everything</a>
<a id="1085" class="Keyword">open</a> <a id="1090" class="Keyword">import</a> <a id="1097" href="../code/probability/Cubical.Relation.Everything.html" class="Module">Cubical.Relation.Everything</a>
<a id="1125" class="Keyword">open</a> <a id="1130" class="Keyword">import</a> <a id="1137" href="../code/probability/Cubical.Foundations.Prelude.html" class="Module">Cubical.Foundations.Prelude</a> <a id="1165" class="Keyword">hiding</a> <a id="1172" class="Symbol">(</a><a id="1173" href="../code/probability/Cubical.Foundations.Prelude.html#2539" class="Function Operator">_≡⟨_⟩_</a><a id="1179" class="Symbol">)</a> <a id="1181" class="Keyword">renaming</a> <a id="1190" class="Symbol">(</a><a id="1191" href="../code/probability/Cubical.Foundations.Prelude.html#1674" class="Function Operator">_∙_</a> <a id="1195" class="Symbol">to</a> <a id="1198" href="../code/probability/Cubical.Foundations.Prelude.html#1674" class="Function Operator">_;_</a><a id="1201" class="Symbol">)</a>
<a id="1203" class="Keyword">open</a> <a id="1208" class="Keyword">import</a> <a id="1215" href="../code/probability/Cubical.HITs.SetTruncation.html" class="Module">Cubical.HITs.SetTruncation</a>
<a id="1242" class="Keyword">open</a> <a id="1247" class="Keyword">import</a> <a id="1254" href="../code/probability/ProbabilityModule.Utils.html" class="Module">ProbabilityModule.Utils</a>
</pre>
</details>
<dl>
<dt>Extensionality</dt>
<dd>
One of the big annoyances in standard Agda is that we can’t prove the
following:
<pre class="Agda"><a id="extensionality"></a><a id="1407" href="#1407" class="Function">extensionality</a> <a id="1422" class="Symbol">:</a> <a id="1424" class="Symbol">∀</a> <a id="1426" class="Symbol">{</a><a id="1427" href="#1427" class="Bound">f</a> <a id="1429" href="#1429" class="Bound">g</a> <a id="1431" class="Symbol">:</a> <a id="1433" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="1435" class="Symbol">→</a> <a id="1437" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="1438" class="Symbol">}</a>
           <a id="1455" class="Symbol">→</a> <a id="1457" class="Symbol">(∀</a> <a id="1460" href="#1460" class="Bound">x</a> <a id="1462" class="Symbol">→</a> <a id="1464" href="#1427" class="Bound">f</a> <a id="1466" href="#1460" class="Bound">x</a> <a id="1468" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="1470" href="#1429" class="Bound">g</a> <a id="1472" href="#1460" class="Bound">x</a><a id="1473" class="Symbol">)</a>
           <a id="1490" class="Symbol">→</a> <a id="1492" href="#1427" class="Bound">f</a> <a id="1494" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="1496" href="#1429" class="Bound">g</a>
</pre>
It’s emblematic of a wider problem in Agda: we can’t say “two things are
equal if they always behave the same”. Infinite types, for instance
(like streams) are often only equal via bisimulation: we can’t translate
this into normal equality in standard Agda. Cubical type theory, though,
has a different notion of “equality”, which allow a wide variety of
things (including bisimulations and extensional proofs) to be translated
into a proper equality
<pre class="Agda"><a id="1989" href="#1407" class="Function">extensionality</a> <a id="2004" class="Symbol">=</a> <a id="2006" href="../code/probability/Cubical.Foundations.Prelude.html#4401" class="Function">funExt</a>
</pre>
</dd>
<dt>Isomorphisms</dt>
<dd>
One of these such things we can promote to a “proper equality” is an
isomorphism. In the <a href="https://github.com/agda/cubical">cubical
repo</a> this is used to <a
href="https://github.com/agda/cubical/blob/8391a4835b3d2478e9394c6c3ec7e6fff42ede62/Cubical/Data/BinNat/BinNat.agda">prove
things about binary numbers</a>: by proving that there’s an isomorphism
between the Peano numbers and binary numbers, they can lift any
properties on the Peano numbers to the binary numbers.
</dd>
</dl>
<p>So those are two useful examples, but the <em>most</em> interesting
use I’ve seen so far is the following:</p>
<h1 id="higher-inductive-types">Higher Inductive Types</h1>
Higher Inductive Types are an extension of normal inductive types, like
the list:
<pre class="Agda"><a id="2741" class="Keyword">module</a> <a id="NormalList"></a><a id="2748" href="#2748" class="Module">NormalList</a> <a id="2759" class="Keyword">where</a>
 <a id="2766" class="Keyword">data</a> <a id="NormalList.List"></a><a id="2771" href="#2771" class="Datatype">List</a> <a id="2776" class="Symbol">{</a><a id="2777" href="#2777" class="Bound">a</a><a id="2778" class="Symbol">}</a> <a id="2780" class="Symbol">(</a><a id="2781" href="#2781" class="Bound">A</a> <a id="2783" class="Symbol">:</a> <a id="2785" class="PrimitiveType">Set</a> <a id="2789" href="#2777" class="Bound">a</a><a id="2790" class="Symbol">)</a> <a id="2792" class="Symbol">:</a> <a id="2794" class="PrimitiveType">Set</a> <a id="2798" href="#2777" class="Bound">a</a> <a id="2800" class="Keyword">where</a>
   <a id="NormalList.List.[]"></a><a id="2809" href="#2809" class="InductiveConstructor">[]</a> <a id="2812" class="Symbol">:</a> <a id="2814" href="#2771" class="Datatype">List</a> <a id="2819" href="#2781" class="Bound">A</a>
   <a id="NormalList.List._∷_"></a><a id="2824" href="#2824" class="InductiveConstructor Operator">_∷_</a> <a id="2828" class="Symbol">:</a> <a id="2830" href="#2781" class="Bound">A</a> <a id="2832" class="Symbol">→</a> <a id="2834" href="#2771" class="Datatype">List</a> <a id="2839" href="#2781" class="Bound">A</a> <a id="2841" class="Symbol">→</a> <a id="2843" href="#2771" class="Datatype">List</a> <a id="2848" href="#2781" class="Bound">A</a>
</pre>
<p>They allow us to add new equations to a type, as well as
constructors. To demonstrate what this means, as well as why you’d want
it, I’m going to talk about free objects.</p>
<p>Very informally, a free object on some algebra is the
<em>minimal</em> type which satisfies the laws of the algebra. Lists,
for instance, are the free monoid. They satisfy all of the monoid laws
(<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>•</mi><annotation encoding="application/x-tex">\bullet</annotation></semantics></math>
is <code>++</code> and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>ϵ</mi><annotation encoding="application/x-tex">\epsilon</annotation></semantics></math>
is <code>[]</code>):</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>•</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo><mo>•</mo><mi>z</mi><mo>=</mo><mi>x</mi><mo>•</mo><mo stretchy="false" form="prefix">(</mo><mi>y</mi><mo>•</mo><mi>z</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(x \bullet y) \bullet z = x \bullet (y \bullet z)</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>•</mo><mi>ϵ</mi><mo>=</mo><mi>x</mi></mrow><annotation encoding="application/x-tex">x \bullet \epsilon = x</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>ϵ</mi><mo>•</mo><mi>x</mi><mo>=</mo><mi>x</mi></mrow><annotation encoding="application/x-tex">\epsilon \bullet x = x</annotation></semantics></math></p>
<p>But <em>nothing else</em>. That means they don’t satisfy any extra
laws (like, for example, commutativity), and they don’t have any extra
structure they don’t need.</p>
<p>How did we get to the definition of lists from the monoid laws,
though? It doesn’t look anything like them. It would be nice if there
was some systematic way to construct the corresponding free object given
the laws of an algebra. Unfortunately, in normal Agda, this isn’t
possible. Consider, for instance, if we added the commutativity law to
the algebra:
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>•</mo><mi>y</mi><mo>=</mo><mi>y</mi><mo>•</mo><mi>x</mi></mrow><annotation encoding="application/x-tex">x \bullet y = y \bullet x</annotation></semantics></math>
Not only is it not obvious how we’d write the corresponding free object,
it’s actually <em>not possible</em> in normal Agda!</p>
<p>This kind of problem comes up a lot: we have a type, and we want it
to obey just <em>one more</em> equation, but there is no inductive type
which does so. Higher Inductive Types solve the problem in quite a
straightforward way. So we want lists to satisfy another equation? Well,
just add it to the definition!</p>
<pre class="Agda"><a id="4347" class="Keyword">module</a> <a id="OddList"></a><a id="4354" href="#4354" class="Module">OddList</a> <a id="4362" class="Keyword">where</a>
 <a id="4369" class="Keyword">mutual</a>
  <a id="4378" class="Keyword">data</a> <a id="OddList.List"></a><a id="4383" href="#4383" class="Datatype">List</a> <a id="4388" class="Symbol">{</a><a id="4389" href="#4389" class="Bound">a</a><a id="4390" class="Symbol">}</a> <a id="4392" class="Symbol">(</a><a id="4393" href="#4393" class="Bound">A</a> <a id="4395" class="Symbol">:</a> <a id="4397" class="PrimitiveType">Set</a> <a id="4401" href="#4389" class="Bound">a</a><a id="4402" class="Symbol">)</a> <a id="4404" class="Symbol">:</a> <a id="4406" class="PrimitiveType">Set</a> <a id="4410" href="#4389" class="Bound">a</a> <a id="4412" class="Keyword">where</a>
    <a id="OddList.List.[]"></a><a id="4422" href="#4422" class="InductiveConstructor">[]</a> <a id="4425" class="Symbol">:</a> <a id="4427" href="#4383" class="Datatype">List</a> <a id="4432" href="#4393" class="Bound">A</a>
    <a id="OddList.List._∷_"></a><a id="4438" href="#4438" class="InductiveConstructor Operator">_∷_</a> <a id="4442" class="Symbol">:</a> <a id="4444" href="#4393" class="Bound">A</a> <a id="4446" class="Symbol">→</a> <a id="4448" href="#4383" class="Datatype">List</a> <a id="4453" href="#4393" class="Bound">A</a> <a id="4455" class="Symbol">→</a> <a id="4457" href="#4383" class="Datatype">List</a> <a id="4462" href="#4393" class="Bound">A</a>
    <a id="OddList.List.comm"></a><a id="4468" href="#4468" class="InductiveConstructor">comm</a> <a id="4473" class="Symbol">:</a> <a id="4475" class="Symbol">∀</a> <a id="4477" href="#4477" class="Bound">xs</a> <a id="4480" href="#4480" class="Bound">ys</a> <a id="4483" class="Symbol">→</a> <a id="4485" href="#4477" class="Bound">xs</a> <a id="4488" href="#4518" class="Postulate Operator">++</a> <a id="4491" href="#4480" class="Bound">ys</a> <a id="4494" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="4496" href="#4480" class="Bound">ys</a> <a id="4499" href="#4518" class="Postulate Operator">++</a> <a id="4502" href="#4477" class="Bound">xs</a>

  <a id="4508" class="Keyword">postulate</a> <a id="OddList._++_"></a><a id="4518" href="#4518" class="Postulate Operator">_++_</a> <a id="4523" class="Symbol">:</a> <a id="4525" href="#4383" class="Datatype">List</a> <a id="4530" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="4532" class="Symbol">→</a> <a id="4534" href="#4383" class="Datatype">List</a> <a id="4539" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="4541" class="Symbol">→</a> <a id="4543" href="#4383" class="Datatype">List</a> <a id="4548" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a>
</pre>
Now, when we write a function that processes lists, Agda will check that
the function behaves the same on <code>xs ++ ys</code> and
<code>ys ++ xs</code>. As an example, here’s how you might define the
free monoid as a HIT:
<pre class="Agda"><a id="4765" class="Keyword">data</a> <a id="FreeMonoid"></a><a id="4770" href="#4770" class="Datatype">FreeMonoid</a> <a id="4781" class="Symbol">{</a><a id="4782" href="#4782" class="Bound">a</a><a id="4783" class="Symbol">}</a> <a id="4785" class="Symbol">(</a><a id="4786" href="#4786" class="Bound">A</a> <a id="4788" class="Symbol">:</a> <a id="4790" class="PrimitiveType">Set</a> <a id="4794" href="#4782" class="Bound">a</a><a id="4795" class="Symbol">)</a> <a id="4797" class="Symbol">:</a> <a id="4799" class="PrimitiveType">Set</a> <a id="4803" href="#4782" class="Bound">a</a> <a id="4805" class="Keyword">where</a>
  <a id="FreeMonoid.[_]"></a><a id="4813" href="#4813" class="InductiveConstructor Operator">[_]</a> <a id="4817" class="Symbol">:</a> <a id="4819" href="#4786" class="Bound">A</a> <a id="4821" class="Symbol">→</a> <a id="4823" href="#4770" class="Datatype">FreeMonoid</a> <a id="4834" href="#4786" class="Bound">A</a>
  <a id="FreeMonoid._∙_"></a><a id="4838" href="#4838" class="InductiveConstructor Operator">_∙_</a> <a id="4842" class="Symbol">:</a> <a id="4844" href="#4770" class="Datatype">FreeMonoid</a> <a id="4855" href="#4786" class="Bound">A</a> <a id="4857" class="Symbol">→</a> <a id="4859" href="#4770" class="Datatype">FreeMonoid</a> <a id="4870" href="#4786" class="Bound">A</a> <a id="4872" class="Symbol">→</a> <a id="4874" href="#4770" class="Datatype">FreeMonoid</a> <a id="4885" href="#4786" class="Bound">A</a>
  <a id="FreeMonoid.ε"></a><a id="4889" href="#4889" class="InductiveConstructor">ε</a> <a id="4891" class="Symbol">:</a> <a id="4893" href="#4770" class="Datatype">FreeMonoid</a> <a id="4904" href="#4786" class="Bound">A</a>
  <a id="FreeMonoid.∙ε"></a><a id="4908" href="#4908" class="InductiveConstructor">∙ε</a> <a id="4911" class="Symbol">:</a> <a id="4913" class="Symbol">∀</a> <a id="4915" href="#4915" class="Bound">x</a> <a id="4917" class="Symbol">→</a> <a id="4919" href="#4915" class="Bound">x</a> <a id="4921" href="#4838" class="InductiveConstructor Operator">∙</a> <a id="4923" href="#4889" class="InductiveConstructor">ε</a> <a id="4925" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="4927" href="#4915" class="Bound">x</a>
  <a id="FreeMonoid.ε∙"></a><a id="4931" href="#4931" class="InductiveConstructor">ε∙</a> <a id="4934" class="Symbol">:</a> <a id="4936" class="Symbol">∀</a> <a id="4938" href="#4938" class="Bound">x</a> <a id="4940" class="Symbol">→</a> <a id="4942" href="#4889" class="InductiveConstructor">ε</a> <a id="4944" href="#4838" class="InductiveConstructor Operator">∙</a> <a id="4946" href="#4938" class="Bound">x</a> <a id="4948" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="4950" href="#4938" class="Bound">x</a>
  <a id="FreeMonoid.assoc"></a><a id="4954" href="#4954" class="InductiveConstructor">assoc</a> <a id="4960" class="Symbol">:</a> <a id="4962" class="Symbol">∀</a> <a id="4964" href="#4964" class="Bound">x</a> <a id="4966" href="#4966" class="Bound">y</a> <a id="4968" href="#4968" class="Bound">z</a> <a id="4970" class="Symbol">→</a> <a id="4972" class="Symbol">(</a><a id="4973" href="#4964" class="Bound">x</a> <a id="4975" href="#4838" class="InductiveConstructor Operator">∙</a> <a id="4977" href="#4966" class="Bound">y</a><a id="4978" class="Symbol">)</a> <a id="4980" href="#4838" class="InductiveConstructor Operator">∙</a> <a id="4982" href="#4968" class="Bound">z</a> <a id="4984" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="4986" href="#4964" class="Bound">x</a> <a id="4988" href="#4838" class="InductiveConstructor Operator">∙</a> <a id="4990" class="Symbol">(</a><a id="4991" href="#4966" class="Bound">y</a> <a id="4993" href="#4838" class="InductiveConstructor Operator">∙</a> <a id="4995" href="#4968" class="Bound">z</a><a id="4996" class="Symbol">)</a>
</pre>
<p>It’s quite a satisfying definition, and very easy to see how we got
to it from the monoid laws.</p>
Now, when we write functions, we have to prove that those functions
themselves also obey the monoid laws. For instance, here’s how we would
take the length:
<pre class="Agda"><a id="5265" class="Keyword">module</a> <a id="Length"></a><a id="5272" href="#5272" class="Module">Length</a> <a id="5279" class="Keyword">where</a>
  <a id="5287" class="Keyword">open</a> <a id="5292" class="Keyword">import</a> <a id="5299" href="../code/probability/ProbabilityModule.Semirings.Nat.html" class="Module">ProbabilityModule.Semirings.Nat</a>
  <a id="5333" class="Keyword">open</a> <a id="5338" href="../code/probability/ProbabilityModule.Semirings.html#125" class="Module">Semiring</a> <a id="5347" href="../code/probability/ProbabilityModule.Semirings.Nat.html#1820" class="Function">+-*-𝕊</a>

  <a id="Length.length"></a><a id="5356" href="#5356" class="Function">length</a> <a id="5363" class="Symbol">:</a> <a id="5365" href="#4770" class="Datatype">FreeMonoid</a> <a id="5376" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="5378" class="Symbol">→</a> <a id="5380" href="Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
  <a id="5384" href="#5356" class="Function">length</a> <a id="5391" href="#4813" class="InductiveConstructor Operator">[</a> <a id="5393" href="#5393" class="Bound">x</a> <a id="5395" href="#4813" class="InductiveConstructor Operator">]</a> <a id="5397" class="Symbol">=</a> <a id="5399" class="Number">1</a>
  <a id="5403" href="#5356" class="Function">length</a> <a id="5410" class="Symbol">(</a><a id="5411" href="#5411" class="Bound">xs</a> <a id="5414" href="#4838" class="InductiveConstructor Operator">∙</a> <a id="5416" href="#5416" class="Bound">ys</a><a id="5418" class="Symbol">)</a> <a id="5420" class="Symbol">=</a> <a id="5422" href="#5356" class="Function">length</a> <a id="5429" href="#5411" class="Bound">xs</a> <a id="5432" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Function Operator">+</a> <a id="5434" href="#5356" class="Function">length</a> <a id="5441" href="#5416" class="Bound">ys</a>
  <a id="5446" href="#5356" class="Function">length</a> <a id="5453" href="#4889" class="InductiveConstructor">ε</a> <a id="5455" class="Symbol">=</a> <a id="5457" class="Number">0</a>
  <a id="5461" href="#5356" class="Function">length</a> <a id="5468" class="Symbol">(</a><a id="5469" href="#4908" class="InductiveConstructor">∙ε</a> <a id="5472" href="#5472" class="Bound">xs</a> <a id="5475" href="#5475" class="Bound">i</a><a id="5476" class="Symbol">)</a> <a id="5478" class="Symbol">=</a> <a id="5480" href="../code/probability/ProbabilityModule.Semirings.html#660" class="Function">+0</a> <a id="5483" class="Symbol">(</a><a id="5484" href="#5356" class="Function">length</a> <a id="5491" href="#5472" class="Bound">xs</a><a id="5493" class="Symbol">)</a> <a id="5495" href="#5475" class="Bound">i</a>
  <a id="5499" href="#5356" class="Function">length</a> <a id="5506" class="Symbol">(</a><a id="5507" href="#4931" class="InductiveConstructor">ε∙</a> <a id="5510" href="#5510" class="Bound">xs</a> <a id="5513" href="#5513" class="Bound">i</a><a id="5514" class="Symbol">)</a> <a id="5516" class="Symbol">=</a> <a id="5518" href="../code/probability/ProbabilityModule.Semirings.html#430" class="Function">0+</a> <a id="5521" class="Symbol">(</a><a id="5522" href="#5356" class="Function">length</a> <a id="5529" href="#5510" class="Bound">xs</a><a id="5531" class="Symbol">)</a> <a id="5533" href="#5513" class="Bound">i</a>
  <a id="5537" href="#5356" class="Function">length</a> <a id="5544" class="Symbol">(</a><a id="5545" href="#4954" class="InductiveConstructor">assoc</a> <a id="5551" href="#5551" class="Bound">xs</a> <a id="5554" href="#5554" class="Bound">ys</a> <a id="5557" href="#5557" class="Bound">zs</a> <a id="5560" href="#5560" class="Bound">i</a><a id="5561" class="Symbol">)</a> <a id="5563" class="Symbol">=</a> <a id="5565" href="../code/probability/ProbabilityModule.Semirings.html#276" class="Function">+-assoc</a> <a id="5573" class="Symbol">(</a><a id="5574" href="#5356" class="Function">length</a> <a id="5581" href="#5551" class="Bound">xs</a><a id="5583" class="Symbol">)</a> <a id="5585" class="Symbol">(</a><a id="5586" href="#5356" class="Function">length</a> <a id="5593" href="#5554" class="Bound">ys</a><a id="5595" class="Symbol">)</a> <a id="5597" class="Symbol">(</a><a id="5598" href="#5356" class="Function">length</a> <a id="5605" href="#5557" class="Bound">zs</a><a id="5607" class="Symbol">)</a> <a id="5609" href="#5560" class="Bound">i</a>
</pre>
<p>The first three clauses are the actual function: they deal with the
three normal constructors of the type. The next three clauses prove that
those previous clauses obey the equalities defined on the type.</p>
<p>With the preliminary stuff out of the way, let’s get on to the type I
wanted to talk about:</p>
<h1 id="probability">Probability</h1>
<p>First things first, let’s remember the classic definition of the
probability monad:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> a <span class="ot">=</span> <span class="dt">Prob</span> {<span class="ot"> runProb ::</span> [(a, <span class="dt">Rational</span>)] }</span></code></pre></div>
<p>Definitionally speaking, this doesn’t really represent what we’re
talking about. For instance, the following two things express the same
distribution, but have different representations:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Prob</span> [(<span class="dt">True</span>, <span class="dv">1</span> <span class="op">/</span> <span class="dv">4</span>), (<span class="dt">True</span>, <span class="dv">1</span> <span class="op">/</span> <span class="dv">4</span>), (<span class="dt">False</span>, <span class="dv">1</span> <span class="op">/</span> <span class="dv">2</span>)]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Prob</span> [(<span class="dt">True</span> , <span class="dv">1</span> <span class="op">/</span> <span class="dv">2</span>), (<span class="dt">False</span>, <span class="dv">1</span> <span class="op">/</span> <span class="dv">2</span>)]</span></code></pre></div>
<p>So it’s the perfect candidate for an extra equality clause like we
had above.</p>
<p>Second, in an effort to generalise, we won’t deal specifically with
<code>Rational</code>, and instead we’ll use any semiring. After all of
that, we get the following definition:</p>
<pre class="Agda"><a id="6634" class="Keyword">open</a> <a id="6639" href="../code/probability/ProbabilityModule.Semirings.html#125" class="Module">Semiring</a> <a id="6648" href="#1024" class="Bound">rng</a>

<a id="6653" class="Keyword">module</a> <a id="Initial"></a><a id="6660" href="#6660" class="Module">Initial</a> <a id="6668" class="Keyword">where</a>
 <a id="6675" class="Keyword">infixr</a> <a id="6682" class="Number">5</a> <a id="6684" href="#6746" class="InductiveConstructor Operator">_&amp;_∷_</a>
 <a id="6691" class="Keyword">data</a> <a id="Initial.𝒫"></a><a id="6696" href="#6696" class="Datatype">𝒫</a> <a id="6698" class="Symbol">(</a><a id="6699" href="#6699" class="Bound">A</a> <a id="6701" class="Symbol">:</a> <a id="6703" class="PrimitiveType">Set</a> <a id="6707" href="../code/probability/ProbabilityModule.Utils.html#178" class="Generalizable">a</a><a id="6708" class="Symbol">)</a> <a id="6710" class="Symbol">:</a> <a id="6712" class="PrimitiveType">Set</a> <a id="6716" class="Symbol">(</a><a id="6717" href="#6707" class="Bound">a</a> <a id="6719" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="6721" href="#1020" class="Bound">s</a><a id="6722" class="Symbol">)</a> <a id="6724" class="Keyword">where</a>
   <a id="Initial.𝒫.[]"></a><a id="6733" href="#6733" class="InductiveConstructor">[]</a>  <a id="6737" class="Symbol">:</a> <a id="6739" href="#6696" class="Datatype">𝒫</a> <a id="6741" href="#6699" class="Bound">A</a>
   <a id="Initial.𝒫._&amp;_∷_"></a><a id="6746" href="#6746" class="InductiveConstructor Operator">_&amp;_∷_</a> <a id="6752" class="Symbol">:</a> <a id="6754" class="Symbol">(</a><a id="6755" href="#6755" class="Bound">p</a> <a id="6757" class="Symbol">:</a> <a id="6759" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a><a id="6760" class="Symbol">)</a> <a id="6762" class="Symbol">→</a> <a id="6764" class="Symbol">(</a><a id="6765" href="#6765" class="Bound">x</a> <a id="6767" class="Symbol">:</a> <a id="6769" href="#6699" class="Bound">A</a><a id="6770" class="Symbol">)</a> <a id="6772" class="Symbol">→</a> <a id="6774" href="#6696" class="Datatype">𝒫</a> <a id="6776" href="#6699" class="Bound">A</a> <a id="6778" class="Symbol">→</a> <a id="6780" href="#6696" class="Datatype">𝒫</a> <a id="6782" href="#6699" class="Bound">A</a>
   <a id="Initial.𝒫.dup"></a><a id="6787" href="#6787" class="InductiveConstructor">dup</a> <a id="6791" class="Symbol">:</a> <a id="6793" class="Symbol">∀</a> <a id="6795" href="#6795" class="Bound">p</a> <a id="6797" href="#6797" class="Bound">q</a> <a id="6799" href="#6799" class="Bound">x</a> <a id="6801" href="#6801" class="Bound">xs</a> <a id="6804" class="Symbol">→</a> <a id="6806" href="#6795" class="Bound">p</a> <a id="6808" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6810" href="#6799" class="Bound">x</a> <a id="6812" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6814" href="#6797" class="Bound">q</a> <a id="6816" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6818" href="#6799" class="Bound">x</a> <a id="6820" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6822" href="#6801" class="Bound">xs</a> <a id="6825" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="6827" href="#6795" class="Bound">p</a> <a id="6829" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="6831" href="#6797" class="Bound">q</a> <a id="6833" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6835" href="#6799" class="Bound">x</a> <a id="6837" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6839" href="#6801" class="Bound">xs</a>
   <a id="Initial.𝒫.com"></a><a id="6845" href="#6845" class="InductiveConstructor">com</a> <a id="6849" class="Symbol">:</a> <a id="6851" class="Symbol">∀</a> <a id="6853" href="#6853" class="Bound">p</a> <a id="6855" href="#6855" class="Bound">x</a> <a id="6857" href="#6857" class="Bound">q</a> <a id="6859" href="#6859" class="Bound">y</a> <a id="6861" href="#6861" class="Bound">xs</a> <a id="6864" class="Symbol">→</a> <a id="6866" href="#6853" class="Bound">p</a> <a id="6868" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6870" href="#6855" class="Bound">x</a> <a id="6872" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6874" href="#6857" class="Bound">q</a> <a id="6876" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6878" href="#6859" class="Bound">y</a> <a id="6880" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6882" href="#6861" class="Bound">xs</a> <a id="6885" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="6887" href="#6857" class="Bound">q</a> <a id="6889" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6891" href="#6859" class="Bound">y</a> <a id="6893" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6895" href="#6853" class="Bound">p</a> <a id="6897" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6899" href="#6855" class="Bound">x</a> <a id="6901" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6903" href="#6861" class="Bound">xs</a>
   <a id="Initial.𝒫.del"></a><a id="6909" href="#6909" class="InductiveConstructor">del</a> <a id="6913" class="Symbol">:</a> <a id="6915" class="Symbol">∀</a> <a id="6917" href="#6917" class="Bound">x</a> <a id="6919" href="#6919" class="Bound">xs</a> <a id="6922" class="Symbol">→</a> <a id="6924" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="6927" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="6929" href="#6917" class="Bound">x</a> <a id="6931" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="6933" href="#6919" class="Bound">xs</a> <a id="6936" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="6938" href="#6919" class="Bound">xs</a>
</pre>
<p>The three extra conditions are pretty sensible: the first removes
duplicates, the second makes things commutative, and the third removes
impossible events.</p>
<p>Let’s get to writing some functions, then:</p>
<pre class="Agda"> <a id="Initial.∫"></a><a id="7156" href="#7156" class="Function">∫</a> <a id="7158" class="Symbol">:</a> <a id="7160" class="Symbol">(</a><a id="7161" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="7163" class="Symbol">→</a> <a id="7165" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a><a id="7166" class="Symbol">)</a> <a id="7168" class="Symbol">→</a> <a id="7170" href="#6696" class="Datatype">𝒫</a> <a id="7172" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="7174" class="Symbol">→</a> <a id="7176" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a>
 <a id="7179" href="#7156" class="Function">∫</a> <a id="7181" href="#7181" class="Bound">f</a> <a id="7183" href="#6733" class="InductiveConstructor">[]</a> <a id="7186" class="Symbol">=</a> <a id="7188" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a>
 <a id="7192" href="#7156" class="Function">∫</a> <a id="7194" href="#7194" class="Bound">f</a> <a id="7196" class="Symbol">(</a><a id="7197" href="#7197" class="Bound">p</a> <a id="7199" href="#6746" class="InductiveConstructor Operator">&amp;</a> <a id="7201" href="#7201" class="Bound">x</a> <a id="7203" href="#6746" class="InductiveConstructor Operator">∷</a> <a id="7205" href="#7205" class="Bound">xs</a><a id="7207" class="Symbol">)</a> <a id="7209" class="Symbol">=</a> <a id="7211" href="#7197" class="Bound">p</a> <a id="7213" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7215" href="#7194" class="Bound">f</a> <a id="7217" href="#7201" class="Bound">x</a> <a id="7219" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7221" href="#7156" class="Function">∫</a> <a id="7223" href="#7194" class="Bound">f</a> <a id="7225" href="#7205" class="Bound">xs</a>
 <a id="7229" href="#7156" class="Function">∫</a> <a id="7231" href="#7231" class="Bound">f</a> <a id="7233" class="Symbol">(</a><a id="7234" href="#6787" class="InductiveConstructor">dup</a> <a id="7238" href="#7238" class="Bound">p</a> <a id="7240" href="#7240" class="Bound">q</a> <a id="7242" href="#7242" class="Bound">x</a> <a id="7244" href="#7244" class="Bound">xs</a> <a id="7247" href="#7247" class="Bound">i</a><a id="7248" class="Symbol">)</a> <a id="7250" class="Symbol">=</a> <a id="7252" href="../code/probability/ProbabilityModule.Utils.html#645" class="Function Operator">begin[</a> <a id="7259" href="#7247" class="Bound">i</a> <a id="7261" href="../code/probability/ProbabilityModule.Utils.html#645" class="Function Operator">]</a>
   <a id="7266" href="#7238" class="Bound">p</a> <a id="7268" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7270" href="#7231" class="Bound">f</a> <a id="7272" href="#7242" class="Bound">x</a> <a id="7274" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7276" class="Symbol">(</a><a id="7277" href="#7240" class="Bound">q</a> <a id="7279" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7281" href="#7231" class="Bound">f</a> <a id="7283" href="#7242" class="Bound">x</a> <a id="7285" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7287" href="#7156" class="Function">∫</a> <a id="7289" href="#7231" class="Bound">f</a> <a id="7291" href="#7244" class="Bound">xs</a><a id="7293" class="Symbol">)</a> <a id="7295" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="7299" href="../code/probability/ProbabilityModule.Semirings.html#276" class="Field">+-assoc</a> <a id="7307" class="Symbol">(</a><a id="7308" href="#7238" class="Bound">p</a> <a id="7310" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7312" href="#7231" class="Bound">f</a> <a id="7314" href="#7242" class="Bound">x</a><a id="7315" class="Symbol">)</a> <a id="7317" class="Symbol">(</a><a id="7318" href="#7240" class="Bound">q</a> <a id="7320" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7322" href="#7231" class="Bound">f</a> <a id="7324" href="#7242" class="Bound">x</a><a id="7325" class="Symbol">)</a> <a id="7327" class="Symbol">(</a><a id="7328" href="#7156" class="Function">∫</a> <a id="7330" href="#7231" class="Bound">f</a> <a id="7332" href="#7244" class="Bound">xs</a><a id="7334" class="Symbol">)</a> <a id="7336" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
   <a id="7341" class="Symbol">(</a><a id="7342" href="#7238" class="Bound">p</a> <a id="7344" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7346" href="#7231" class="Bound">f</a> <a id="7348" href="#7242" class="Bound">x</a> <a id="7350" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7352" href="#7240" class="Bound">q</a> <a id="7354" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7356" href="#7231" class="Bound">f</a> <a id="7358" href="#7242" class="Bound">x</a><a id="7359" class="Symbol">)</a> <a id="7361" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7363" href="#7156" class="Function">∫</a> <a id="7365" href="#7231" class="Bound">f</a> <a id="7367" href="#7244" class="Bound">xs</a> <a id="7370" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="7374" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="7379" class="Symbol">(</a><a id="7380" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">_+</a> <a id="7383" href="#7156" class="Function">∫</a> <a id="7385" href="#7231" class="Bound">f</a> <a id="7387" href="#7244" class="Bound">xs</a><a id="7389" class="Symbol">)</a> <a id="7391" class="Symbol">(</a><a id="7392" href="../code/probability/ProbabilityModule.Semirings.html#592" class="Field">⟨+⟩*</a> <a id="7397" href="#7238" class="Bound">p</a> <a id="7399" href="#7240" class="Bound">q</a> <a id="7401" class="Symbol">(</a><a id="7402" href="#7231" class="Bound">f</a> <a id="7404" href="#7242" class="Bound">x</a><a id="7405" class="Symbol">))</a>  <a id="7409" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
   <a id="7414" class="Symbol">(</a><a id="7415" href="#7238" class="Bound">p</a> <a id="7417" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7419" href="#7240" class="Bound">q</a><a id="7420" class="Symbol">)</a> <a id="7422" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7424" href="#7231" class="Bound">f</a> <a id="7426" href="#7242" class="Bound">x</a> <a id="7428" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7430" href="#7156" class="Function">∫</a> <a id="7432" href="#7231" class="Bound">f</a> <a id="7434" href="#7244" class="Bound">xs</a> <a id="7437" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
 <a id="7440" href="#7156" class="Function">∫</a> <a id="7442" href="#7442" class="Bound">f</a> <a id="7444" class="Symbol">(</a><a id="7445" href="#6845" class="InductiveConstructor">com</a> <a id="7449" href="#7449" class="Bound">p</a> <a id="7451" href="#7451" class="Bound">x</a> <a id="7453" href="#7453" class="Bound">q</a> <a id="7455" href="#7455" class="Bound">y</a> <a id="7457" href="#7457" class="Bound">xs</a> <a id="7460" href="#7460" class="Bound">i</a><a id="7461" class="Symbol">)</a> <a id="7463" class="Symbol">=</a> <a id="7465" href="../code/probability/ProbabilityModule.Utils.html#645" class="Function Operator">begin[</a> <a id="7472" href="#7460" class="Bound">i</a> <a id="7474" href="../code/probability/ProbabilityModule.Utils.html#645" class="Function Operator">]</a>
   <a id="7479" href="#7449" class="Bound">p</a> <a id="7481" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7483" href="#7442" class="Bound">f</a> <a id="7485" href="#7451" class="Bound">x</a> <a id="7487" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7489" class="Symbol">(</a><a id="7490" href="#7453" class="Bound">q</a> <a id="7492" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7494" href="#7442" class="Bound">f</a> <a id="7496" href="#7455" class="Bound">y</a> <a id="7498" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7500" href="#7156" class="Function">∫</a> <a id="7502" href="#7442" class="Bound">f</a> <a id="7504" href="#7457" class="Bound">xs</a><a id="7506" class="Symbol">)</a> <a id="7508" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="7512" href="../code/probability/ProbabilityModule.Semirings.html#276" class="Field">+-assoc</a> <a id="7520" class="Symbol">(</a><a id="7521" href="#7449" class="Bound">p</a> <a id="7523" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7525" href="#7442" class="Bound">f</a> <a id="7527" href="#7451" class="Bound">x</a><a id="7528" class="Symbol">)</a> <a id="7530" class="Symbol">(</a><a id="7531" href="#7453" class="Bound">q</a> <a id="7533" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7535" href="#7442" class="Bound">f</a> <a id="7537" href="#7455" class="Bound">y</a><a id="7538" class="Symbol">)</a> <a id="7540" class="Symbol">(</a><a id="7541" href="#7156" class="Function">∫</a> <a id="7543" href="#7442" class="Bound">f</a> <a id="7545" href="#7457" class="Bound">xs</a><a id="7547" class="Symbol">)</a> <a id="7549" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
   <a id="7554" href="#7449" class="Bound">p</a> <a id="7556" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7558" href="#7442" class="Bound">f</a> <a id="7560" href="#7451" class="Bound">x</a> <a id="7562" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7564" href="#7453" class="Bound">q</a> <a id="7566" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7568" href="#7442" class="Bound">f</a> <a id="7570" href="#7455" class="Bound">y</a> <a id="7572" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7574" href="#7156" class="Function">∫</a> <a id="7576" href="#7442" class="Bound">f</a> <a id="7578" href="#7457" class="Bound">xs</a>   <a id="7583" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="7586" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="7591" class="Symbol">(</a><a id="7592" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">_+</a> <a id="7595" href="#7156" class="Function">∫</a> <a id="7597" href="#7442" class="Bound">f</a> <a id="7599" href="#7457" class="Bound">xs</a><a id="7601" class="Symbol">)</a> <a id="7603" class="Symbol">(</a><a id="7604" href="../code/probability/ProbabilityModule.Semirings.html#508" class="Field">+-comm</a> <a id="7611" class="Symbol">(</a><a id="7612" href="#7449" class="Bound">p</a> <a id="7614" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7616" href="#7442" class="Bound">f</a> <a id="7618" href="#7451" class="Bound">x</a><a id="7619" class="Symbol">)</a> <a id="7621" class="Symbol">(</a><a id="7622" href="#7453" class="Bound">q</a> <a id="7624" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7626" href="#7442" class="Bound">f</a> <a id="7628" href="#7455" class="Bound">y</a><a id="7629" class="Symbol">))</a> <a id="7632" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
   <a id="7637" href="#7453" class="Bound">q</a> <a id="7639" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7641" href="#7442" class="Bound">f</a> <a id="7643" href="#7455" class="Bound">y</a> <a id="7645" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7647" href="#7449" class="Bound">p</a> <a id="7649" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7651" href="#7442" class="Bound">f</a> <a id="7653" href="#7451" class="Bound">x</a> <a id="7655" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7657" href="#7156" class="Function">∫</a> <a id="7659" href="#7442" class="Bound">f</a> <a id="7661" href="#7457" class="Bound">xs</a>   <a id="7666" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="7669" href="../code/probability/ProbabilityModule.Semirings.html#276" class="Field">+-assoc</a> <a id="7677" class="Symbol">(</a><a id="7678" href="#7453" class="Bound">q</a> <a id="7680" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7682" href="#7442" class="Bound">f</a> <a id="7684" href="#7455" class="Bound">y</a><a id="7685" class="Symbol">)</a> <a id="7687" class="Symbol">(</a><a id="7688" href="#7449" class="Bound">p</a> <a id="7690" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7692" href="#7442" class="Bound">f</a> <a id="7694" href="#7451" class="Bound">x</a><a id="7695" class="Symbol">)</a> <a id="7697" class="Symbol">(</a><a id="7698" href="#7156" class="Function">∫</a> <a id="7700" href="#7442" class="Bound">f</a> <a id="7702" href="#7457" class="Bound">xs</a><a id="7704" class="Symbol">)</a> <a id="7706" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
   <a id="7711" href="#7453" class="Bound">q</a> <a id="7713" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7715" href="#7442" class="Bound">f</a> <a id="7717" href="#7455" class="Bound">y</a> <a id="7719" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7721" class="Symbol">(</a><a id="7722" href="#7449" class="Bound">p</a> <a id="7724" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7726" href="#7442" class="Bound">f</a> <a id="7728" href="#7451" class="Bound">x</a> <a id="7730" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7732" href="#7156" class="Function">∫</a> <a id="7734" href="#7442" class="Bound">f</a> <a id="7736" href="#7457" class="Bound">xs</a><a id="7738" class="Symbol">)</a> <a id="7740" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
 <a id="7743" href="#7156" class="Function">∫</a> <a id="7745" href="#7745" class="Bound">f</a> <a id="7747" class="Symbol">(</a><a id="7748" href="#6909" class="InductiveConstructor">del</a> <a id="7752" href="#7752" class="Bound">x</a> <a id="7754" href="#7754" class="Bound">xs</a> <a id="7757" href="#7757" class="Bound">i</a><a id="7758" class="Symbol">)</a> <a id="7760" class="Symbol">=</a> <a id="7762" href="../code/probability/ProbabilityModule.Utils.html#645" class="Function Operator">begin[</a> <a id="7769" href="#7757" class="Bound">i</a> <a id="7771" href="../code/probability/ProbabilityModule.Utils.html#645" class="Function Operator">]</a>
   <a id="7776" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="7779" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="7781" href="#7745" class="Bound">f</a> <a id="7783" href="#7752" class="Bound">x</a> <a id="7785" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7787" href="#7156" class="Function">∫</a> <a id="7789" href="#7745" class="Bound">f</a> <a id="7791" href="#7754" class="Bound">xs</a> <a id="7794" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="7797" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="7802" class="Symbol">(</a><a id="7803" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">_+</a> <a id="7806" href="#7156" class="Function">∫</a> <a id="7808" href="#7745" class="Bound">f</a> <a id="7810" href="#7754" class="Bound">xs</a><a id="7812" class="Symbol">)</a> <a id="7814" class="Symbol">(</a><a id="7815" href="../code/probability/ProbabilityModule.Semirings.html#403" class="Field">0*</a> <a id="7818" class="Symbol">(</a><a id="7819" href="#7745" class="Bound">f</a> <a id="7821" href="#7752" class="Bound">x</a><a id="7822" class="Symbol">))</a> <a id="7825" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
   <a id="7830" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="7833" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="7835" href="#7156" class="Function">∫</a> <a id="7837" href="#7745" class="Bound">f</a> <a id="7839" href="#7754" class="Bound">xs</a>       <a id="7848" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="7851" href="../code/probability/ProbabilityModule.Semirings.html#430" class="Field">0+</a> <a id="7854" class="Symbol">(</a><a id="7855" href="#7156" class="Function">∫</a> <a id="7857" href="#7745" class="Bound">f</a> <a id="7859" href="#7754" class="Bound">xs</a><a id="7861" class="Symbol">)</a> <a id="7863" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
   <a id="7868" href="#7156" class="Function">∫</a> <a id="7870" href="#7745" class="Bound">f</a> <a id="7872" href="#7754" class="Bound">xs</a> <a id="7875" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
</pre>
<p>This is much more involved than the free monoid function, but the
principle is the same: we first write the actual function (on the first
three lines), and then we show that the function doesn’t care about the
“rewrite rules” we have in the next three clauses.</p>
<p>Before going any further, we will have to amend the definition a
little. The problem is that if we tried to prove something about any
function on our <code>𝒫</code> type, we’d have to prove equalities
<em>between equalities</em> as well. I’m sure that this is possible, but
it’s very annoying, so I’m going to use a technique I saw in <a
href="https://github.com/L-TChen/FiniteSets">this repository</a>. We add
another rule to our type, stating that all equalities on the type are
themselves equal. The new definition looks like this:</p>
<pre class="Agda"><a id="8659" class="Keyword">infixr</a> <a id="8666" class="Number">5</a> <a id="8668" href="#8727" class="InductiveConstructor Operator">_&amp;_∷_</a>
<a id="8674" class="Keyword">data</a> <a id="𝒫"></a><a id="8679" href="#8679" class="Datatype">𝒫</a> <a id="8681" class="Symbol">(</a><a id="8682" href="#8682" class="Bound">A</a> <a id="8684" class="Symbol">:</a> <a id="8686" class="PrimitiveType">Set</a> <a id="8690" href="../code/probability/ProbabilityModule.Utils.html#178" class="Generalizable">a</a><a id="8691" class="Symbol">)</a> <a id="8693" class="Symbol">:</a> <a id="8695" class="PrimitiveType">Set</a> <a id="8699" class="Symbol">(</a><a id="8700" href="#8690" class="Bound">a</a> <a id="8702" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="8704" href="#1020" class="Bound">s</a><a id="8705" class="Symbol">)</a> <a id="8707" class="Keyword">where</a>
  <a id="𝒫.[]"></a><a id="8715" href="#8715" class="InductiveConstructor">[]</a>  <a id="8719" class="Symbol">:</a> <a id="8721" href="#8679" class="Datatype">𝒫</a> <a id="8723" href="#8682" class="Bound">A</a>
  <a id="𝒫._&amp;_∷_"></a><a id="8727" href="#8727" class="InductiveConstructor Operator">_&amp;_∷_</a> <a id="8733" class="Symbol">:</a> <a id="8735" class="Symbol">(</a><a id="8736" href="#8736" class="Bound">p</a> <a id="8738" class="Symbol">:</a> <a id="8740" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a><a id="8741" class="Symbol">)</a> <a id="8743" class="Symbol">→</a> <a id="8745" class="Symbol">(</a><a id="8746" href="#8746" class="Bound">x</a> <a id="8748" class="Symbol">:</a> <a id="8750" href="#8682" class="Bound">A</a><a id="8751" class="Symbol">)</a> <a id="8753" class="Symbol">→</a> <a id="8755" href="#8679" class="Datatype">𝒫</a> <a id="8757" href="#8682" class="Bound">A</a> <a id="8759" class="Symbol">→</a> <a id="8761" href="#8679" class="Datatype">𝒫</a> <a id="8763" href="#8682" class="Bound">A</a>
  <a id="𝒫.dup"></a><a id="8767" href="#8767" class="InductiveConstructor">dup</a> <a id="8771" class="Symbol">:</a> <a id="8773" class="Symbol">∀</a> <a id="8775" href="#8775" class="Bound">p</a> <a id="8777" href="#8777" class="Bound">q</a> <a id="8779" href="#8779" class="Bound">x</a> <a id="8781" href="#8781" class="Bound">xs</a> <a id="8784" class="Symbol">→</a> <a id="8786" href="#8775" class="Bound">p</a> <a id="8788" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8790" href="#8779" class="Bound">x</a> <a id="8792" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8794" href="#8777" class="Bound">q</a> <a id="8796" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8798" href="#8779" class="Bound">x</a> <a id="8800" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8802" href="#8781" class="Bound">xs</a> <a id="8805" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="8807" href="#8775" class="Bound">p</a> <a id="8809" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="8811" href="#8777" class="Bound">q</a> <a id="8813" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8815" href="#8779" class="Bound">x</a> <a id="8817" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8819" href="#8781" class="Bound">xs</a>
  <a id="𝒫.com"></a><a id="8824" href="#8824" class="InductiveConstructor">com</a> <a id="8828" class="Symbol">:</a> <a id="8830" class="Symbol">∀</a> <a id="8832" href="#8832" class="Bound">p</a> <a id="8834" href="#8834" class="Bound">x</a> <a id="8836" href="#8836" class="Bound">q</a> <a id="8838" href="#8838" class="Bound">y</a> <a id="8840" href="#8840" class="Bound">xs</a> <a id="8843" class="Symbol">→</a> <a id="8845" href="#8832" class="Bound">p</a> <a id="8847" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8849" href="#8834" class="Bound">x</a> <a id="8851" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8853" href="#8836" class="Bound">q</a> <a id="8855" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8857" href="#8838" class="Bound">y</a> <a id="8859" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8861" href="#8840" class="Bound">xs</a> <a id="8864" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="8866" href="#8836" class="Bound">q</a> <a id="8868" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8870" href="#8838" class="Bound">y</a> <a id="8872" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8874" href="#8832" class="Bound">p</a> <a id="8876" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8878" href="#8834" class="Bound">x</a> <a id="8880" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8882" href="#8840" class="Bound">xs</a>
  <a id="𝒫.del"></a><a id="8887" href="#8887" class="InductiveConstructor">del</a> <a id="8891" class="Symbol">:</a> <a id="8893" class="Symbol">∀</a> <a id="8895" href="#8895" class="Bound">x</a> <a id="8897" href="#8897" class="Bound">xs</a> <a id="8900" class="Symbol">→</a> <a id="8902" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="8905" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="8907" href="#8895" class="Bound">x</a> <a id="8909" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="8911" href="#8897" class="Bound">xs</a> <a id="8914" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="8916" href="#8897" class="Bound">xs</a>
  <a id="𝒫.trunc"></a><a id="8921" href="#8921" class="InductiveConstructor">trunc</a> <a id="8927" class="Symbol">:</a> <a id="8929" href="../code/probability/Cubical.Foundations.Prelude.html#5455" class="Function">isSet</a> <a id="8935" class="Symbol">(</a><a id="8936" href="#8679" class="Datatype">𝒫</a> <a id="8938" href="#8682" class="Bound">A</a><a id="8939" class="Symbol">)</a>
</pre>
<h1 id="eliminators">Eliminators</h1>
<p>Unfortunately, after adding that case we have to deal with it
explicitly in every pattern-match on <code>𝒫</code>. We can get around
it by writing an eliminator for the type which deals with it itself.
Eliminators are often irritating to work with, though: we give up the
nice pattern-matching syntax we get when we program directly. It’s a bit
like having to rely on church encoding everywhere.</p>
<p>However, we can get back some pattern-like syntax if we use
<em>copatterns</em>. Here’s an example of what I mean, for folds on
lists:</p>
<pre class="Agda"><a id="9484" class="Keyword">module</a> <a id="ListElim"></a><a id="9491" href="#9491" class="Module">ListElim</a> <a id="9500" class="Keyword">where</a>
 <a id="9507" class="Keyword">open</a> <a id="9512" href="#2748" class="Module">NormalList</a>
 <a id="9524" class="Keyword">open</a> <a id="9529" class="Keyword">import</a> <a id="9536" href="../code/probability/ProbabilityModule.Semirings.Nat.html" class="Module">ProbabilityModule.Semirings.Nat</a>
 <a id="9569" class="Keyword">open</a> <a id="9574" href="../code/probability/ProbabilityModule.Semirings.html#125" class="Module">Semiring</a> <a id="9583" href="../code/probability/ProbabilityModule.Semirings.Nat.html#1820" class="Function">+-*-𝕊</a> <a id="9589" class="Keyword">renaming</a> <a id="9598" class="Symbol">(</a>_+_ <a id="9603" class="Symbol">to</a> _ℕ+_<a id="9610" class="Symbol">)</a>

 <a id="9614" class="Keyword">record</a> <a id="ListElim.[_↦_]"></a><a id="9621" href="#9621" class="Record Operator">[_↦_]</a> <a id="9627" class="Symbol">(</a><a id="9628" href="#9628" class="Bound">A</a> <a id="9630" class="Symbol">:</a> <a id="9632" class="PrimitiveType">Set</a> <a id="9636" href="../code/probability/ProbabilityModule.Utils.html#178" class="Generalizable">a</a><a id="9637" class="Symbol">)</a> <a id="9639" class="Symbol">(</a><a id="9640" href="#9640" class="Bound">B</a> <a id="9642" class="Symbol">:</a> <a id="9644" class="PrimitiveType">Set</a> <a id="9648" href="../code/probability/ProbabilityModule.Utils.html#180" class="Generalizable">b</a><a id="9649" class="Symbol">)</a> <a id="9651" class="Symbol">:</a> <a id="9653" class="PrimitiveType">Set</a> <a id="9657" class="Symbol">(</a><a id="9658" href="#9636" class="Bound">a</a> <a id="9660" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="9662" href="#9648" class="Bound">b</a><a id="9663" class="Symbol">)</a> <a id="9665" class="Keyword">where</a>
   <a id="9674" class="Keyword">field</a>
     <a id="ListElim.[_↦_].[_][]"></a><a id="9685" href="#9685" class="Field Operator">[_][]</a> <a id="9691" class="Symbol">:</a> <a id="9693" href="#9640" class="Bound">B</a>
     <a id="ListElim.[_↦_].[_]_∷_"></a><a id="9700" href="#9700" class="Field Operator">[_]_∷_</a> <a id="9707" class="Symbol">:</a> <a id="9709" href="#9628" class="Bound">A</a> <a id="9711" class="Symbol">→</a> <a id="9713" href="#9640" class="Bound">B</a> <a id="9715" class="Symbol">→</a> <a id="9717" href="#9640" class="Bound">B</a>
   <a id="ListElim.[_↦_].[_]↓"></a><a id="9722" href="#9722" class="Function Operator">[_]↓</a> <a id="9727" class="Symbol">:</a> <a id="9729" href="#2771" class="Datatype">List</a> <a id="9734" href="#9628" class="Bound">A</a> <a id="9736" class="Symbol">→</a> <a id="9738" href="#9640" class="Bound">B</a>
   <a id="9743" href="#9722" class="Function Operator">[</a> <a id="9745" href="#2809" class="InductiveConstructor">[]</a> <a id="9748" href="#9722" class="Function Operator">]↓</a> <a id="9751" class="Symbol">=</a> <a id="9753" href="#9685" class="Field Operator">[_][]</a>
   <a id="9762" href="#9722" class="Function Operator">[</a> <a id="9764" href="#9764" class="Bound">x</a> <a id="9766" href="#2824" class="InductiveConstructor Operator">∷</a> <a id="9768" href="#9768" class="Bound">xs</a> <a id="9771" href="#9722" class="Function Operator">]↓</a> <a id="9774" class="Symbol">=</a> <a id="9776" href="#9700" class="Field Operator">[_]_∷_</a> <a id="9783" href="#9764" class="Bound">x</a> <a id="9785" href="#9722" class="Function Operator">[</a> <a id="9787" href="#9768" class="Bound">xs</a> <a id="9790" href="#9722" class="Function Operator">]↓</a>
 <a id="9794" class="Keyword">open</a> <a id="9799" href="#9621" class="Module Operator">[_↦_]</a>

 <a id="ListElim.sum-alg"></a><a id="9808" href="#9808" class="Function">sum-alg</a> <a id="9816" class="Symbol">:</a> <a id="9818" href="#9621" class="Record Operator">[</a> <a id="9820" href="Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="9822" href="#9621" class="Record Operator">↦</a> <a id="9824" href="Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="9826" href="#9621" class="Record Operator">]</a>
 <a id="9829" href="#9685" class="Field Operator">[</a> <a id="9831" href="#9808" class="Function">sum-alg</a> <a id="9839" href="#9685" class="Field Operator">][]</a> <a id="9843" class="Symbol">=</a> <a id="9845" class="Number">0</a>
 <a id="9848" href="#9700" class="Field Operator">[</a> <a id="9850" href="#9808" class="Function">sum-alg</a> <a id="9858" href="#9700" class="Field Operator">]</a> <a id="9860" href="#9860" class="Bound">x</a> <a id="9862" href="#9700" class="Field Operator">∷</a> <a id="9864" href="#9864" class="Bound">xs</a> <a id="9867" class="Symbol">=</a> <a id="9869" href="#9860" class="Bound">x</a> <a id="9871" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Function Operator">ℕ+</a> <a id="9874" href="#9864" class="Bound">xs</a>

 <a id="ListElim.sum"></a><a id="9880" href="#9880" class="Function">sum</a> <a id="9884" class="Symbol">:</a> <a id="9886" href="#2771" class="Datatype">List</a> <a id="9891" href="Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a> <a id="9893" class="Symbol">→</a> <a id="9895" href="Agda.Builtin.Nat.html#165" class="Datatype">ℕ</a>
 <a id="9898" href="#9880" class="Function">sum</a> <a id="9902" class="Symbol">=</a> <a id="9904" href="#9722" class="Function Operator">[</a> <a id="9906" href="#9808" class="Function">sum-alg</a> <a id="9914" href="#9722" class="Function Operator">]↓</a>
</pre>
<p>For the probability monad, there’s an eliminator for the whole thing,
and eliminator for propositional proofs, and a normal eliminator for
folding. Their definitions are quite long, but mechanical.</p>
<details>
<summary>
Eliminator Definitions
</summary>
<pre class="Agda"><a id="10181" class="Keyword">record</a> <a id="⟅_↝_⟆"></a><a id="10188" href="#10188" class="Record Operator">⟅_↝_⟆</a> <a id="10194" class="Symbol">{</a><a id="10195" href="#10195" class="Bound">a</a> <a id="10197" href="#10197" class="Bound">ℓ</a><a id="10198" class="Symbol">}</a> <a id="10200" class="Symbol">(</a><a id="10201" href="#10201" class="Bound">A</a> <a id="10203" class="Symbol">:</a> <a id="10205" class="PrimitiveType">Set</a> <a id="10209" href="#10195" class="Bound">a</a><a id="10210" class="Symbol">)</a> <a id="10212" class="Symbol">(</a><a id="10213" href="#10213" class="Bound">P</a> <a id="10215" class="Symbol">:</a> <a id="10217" href="#8679" class="Datatype">𝒫</a> <a id="10219" href="#10201" class="Bound">A</a> <a id="10221" class="Symbol">→</a> <a id="10223" class="PrimitiveType">Set</a> <a id="10227" href="#10197" class="Bound">ℓ</a><a id="10228" class="Symbol">)</a> <a id="10230" class="Symbol">:</a> <a id="10232" class="PrimitiveType">Set</a> <a id="10236" class="Symbol">(</a><a id="10237" href="#10195" class="Bound">a</a> <a id="10239" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="10241" href="#10197" class="Bound">ℓ</a> <a id="10243" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="10245" href="#1020" class="Bound">s</a><a id="10246" class="Symbol">)</a> <a id="10248" class="Keyword">where</a>
  <a id="10256" class="Keyword">constructor</a> <a id="⟅_↝_⟆.elim"></a><a id="10268" href="#10268" class="InductiveConstructor">elim</a>
  <a id="10275" class="Keyword">field</a>
    <a id="⟅_↝_⟆.⟅_⟆-set"></a><a id="10285" href="#10285" class="Field Operator">⟅_⟆-set</a> <a id="10293" class="Symbol">:</a> <a id="10295" class="Symbol">∀</a> <a id="10297" class="Symbol">{</a><a id="10298" href="#10298" class="Bound">xs</a><a id="10300" class="Symbol">}</a> <a id="10302" class="Symbol">→</a> <a id="10304" href="../code/probability/Cubical.Foundations.Prelude.html#5455" class="Function">isSet</a> <a id="10310" class="Symbol">(</a><a id="10311" href="#10213" class="Bound">P</a> <a id="10313" href="#10298" class="Bound">xs</a><a id="10315" class="Symbol">)</a>
    <a id="⟅_↝_⟆.⟅_⟆[]"></a><a id="10321" href="#10321" class="Field Operator">⟅_⟆[]</a> <a id="10327" class="Symbol">:</a> <a id="10329" href="#10213" class="Bound">P</a> <a id="10331" href="#8715" class="InductiveConstructor">[]</a>
    <a id="⟅_↝_⟆.⟅_⟆_&amp;_∷_"></a><a id="10338" href="#10338" class="Field Operator">⟅_⟆_&amp;_∷_</a> <a id="10347" class="Symbol">:</a> <a id="10349" class="Symbol">∀</a> <a id="10351" href="#10351" class="Bound">p</a> <a id="10353" href="#10353" class="Bound">x</a> <a id="10355" href="#10355" class="Bound">xs</a> <a id="10358" class="Symbol">→</a> <a id="10360" href="#10213" class="Bound">P</a> <a id="10362" href="#10355" class="Bound">xs</a> <a id="10365" class="Symbol">→</a> <a id="10367" href="#10213" class="Bound">P</a> <a id="10369" class="Symbol">(</a><a id="10370" href="#10351" class="Bound">p</a> <a id="10372" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="10374" href="#10353" class="Bound">x</a> <a id="10376" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="10378" href="#10355" class="Bound">xs</a><a id="10380" class="Symbol">)</a>
  <a id="10384" class="Keyword">private</a> <a id="⟅_↝_⟆.z"></a><a id="10392" href="#10392" class="Function">z</a> <a id="10394" class="Symbol">=</a> <a id="10396" href="#10321" class="Field Operator">⟅_⟆[]</a><a id="10401" class="Symbol">;</a> <a id="⟅_↝_⟆.f"></a><a id="10403" href="#10403" class="Function">f</a> <a id="10405" class="Symbol">=</a> <a id="10407" href="#10338" class="Field Operator">⟅_⟆_&amp;_∷_</a>
  <a id="10418" class="Keyword">field</a>
    <a id="⟅_↝_⟆.⟅_⟆-dup"></a><a id="10428" href="#10428" class="Field Operator">⟅_⟆-dup</a> <a id="10436" class="Symbol">:</a> <a id="10438" class="Symbol">(∀</a> <a id="10441" href="#10441" class="Bound">p</a> <a id="10443" href="#10443" class="Bound">q</a> <a id="10445" href="#10445" class="Bound">x</a> <a id="10447" href="#10447" class="Bound">xs</a> <a id="10450" href="#10450" class="Bound">pxs</a> <a id="10454" class="Symbol">→</a> <a id="10456" href="Agda.Builtin.Cubical.Path.html#162" class="Postulate">PathP</a> <a id="10462" class="Symbol">(λ</a> <a id="10465" href="#10465" class="Bound">i</a> <a id="10467" class="Symbol">→</a> <a id="10469" href="#10213" class="Bound">P</a> <a id="10471" class="Symbol">(</a><a id="10472" href="#8767" class="InductiveConstructor">dup</a> <a id="10476" href="#10441" class="Bound">p</a> <a id="10478" href="#10443" class="Bound">q</a> <a id="10480" href="#10445" class="Bound">x</a> <a id="10482" href="#10447" class="Bound">xs</a> <a id="10485" href="#10465" class="Bound">i</a><a id="10486" class="Symbol">))</a>
              <a id="10503" class="Symbol">(</a><a id="10504" href="#10403" class="Function">f</a> <a id="10506" href="#10441" class="Bound">p</a> <a id="10508" href="#10445" class="Bound">x</a> <a id="10510" class="Symbol">(</a><a id="10511" href="#10443" class="Bound">q</a> <a id="10513" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="10515" href="#10445" class="Bound">x</a> <a id="10517" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="10519" href="#10447" class="Bound">xs</a><a id="10521" class="Symbol">)</a> <a id="10523" class="Symbol">(</a><a id="10524" href="#10403" class="Function">f</a> <a id="10526" href="#10443" class="Bound">q</a> <a id="10528" href="#10445" class="Bound">x</a> <a id="10530" href="#10447" class="Bound">xs</a> <a id="10533" href="#10450" class="Bound">pxs</a><a id="10536" class="Symbol">))</a> <a id="10539" class="Symbol">(</a><a id="10540" href="#10403" class="Function">f</a> <a id="10542" class="Symbol">(</a><a id="10543" href="#10441" class="Bound">p</a> <a id="10545" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="10547" href="#10443" class="Bound">q</a><a id="10548" class="Symbol">)</a> <a id="10550" href="#10445" class="Bound">x</a> <a id="10552" href="#10447" class="Bound">xs</a> <a id="10555" href="#10450" class="Bound">pxs</a><a id="10558" class="Symbol">))</a>
    <a id="⟅_↝_⟆.⟅_⟆-com"></a><a id="10565" href="#10565" class="Field Operator">⟅_⟆-com</a> <a id="10573" class="Symbol">:</a> <a id="10575" class="Symbol">(∀</a> <a id="10578" href="#10578" class="Bound">p</a> <a id="10580" href="#10580" class="Bound">x</a> <a id="10582" href="#10582" class="Bound">q</a> <a id="10584" href="#10584" class="Bound">y</a> <a id="10586" href="#10586" class="Bound">xs</a> <a id="10589" href="#10589" class="Bound">pxs</a> <a id="10593" class="Symbol">→</a> <a id="10595" href="Agda.Builtin.Cubical.Path.html#162" class="Postulate">PathP</a> <a id="10601" class="Symbol">(λ</a> <a id="10604" href="#10604" class="Bound">i</a> <a id="10606" class="Symbol">→</a> <a id="10608" href="#10213" class="Bound">P</a> <a id="10610" class="Symbol">(</a><a id="10611" href="#8824" class="InductiveConstructor">com</a> <a id="10615" href="#10578" class="Bound">p</a> <a id="10617" href="#10580" class="Bound">x</a> <a id="10619" href="#10582" class="Bound">q</a> <a id="10621" href="#10584" class="Bound">y</a> <a id="10623" href="#10586" class="Bound">xs</a> <a id="10626" href="#10604" class="Bound">i</a><a id="10627" class="Symbol">))</a>
              <a id="10644" class="Symbol">(</a><a id="10645" href="#10403" class="Function">f</a> <a id="10647" href="#10578" class="Bound">p</a> <a id="10649" href="#10580" class="Bound">x</a> <a id="10651" class="Symbol">(</a><a id="10652" href="#10582" class="Bound">q</a> <a id="10654" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="10656" href="#10584" class="Bound">y</a> <a id="10658" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="10660" href="#10586" class="Bound">xs</a><a id="10662" class="Symbol">)</a> <a id="10664" class="Symbol">(</a><a id="10665" href="#10403" class="Function">f</a> <a id="10667" href="#10582" class="Bound">q</a> <a id="10669" href="#10584" class="Bound">y</a> <a id="10671" href="#10586" class="Bound">xs</a> <a id="10674" href="#10589" class="Bound">pxs</a><a id="10677" class="Symbol">))</a> <a id="10680" class="Symbol">(</a><a id="10681" href="#10403" class="Function">f</a> <a id="10683" href="#10582" class="Bound">q</a> <a id="10685" href="#10584" class="Bound">y</a> <a id="10687" class="Symbol">(</a><a id="10688" href="#10578" class="Bound">p</a> <a id="10690" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="10692" href="#10580" class="Bound">x</a> <a id="10694" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="10696" href="#10586" class="Bound">xs</a><a id="10698" class="Symbol">)</a> <a id="10700" class="Symbol">(</a><a id="10701" href="#10403" class="Function">f</a> <a id="10703" href="#10578" class="Bound">p</a> <a id="10705" href="#10580" class="Bound">x</a> <a id="10707" href="#10586" class="Bound">xs</a> <a id="10710" href="#10589" class="Bound">pxs</a><a id="10713" class="Symbol">)))</a>
    <a id="⟅_↝_⟆.⟅_⟆-del"></a><a id="10721" href="#10721" class="Field Operator">⟅_⟆-del</a> <a id="10729" class="Symbol">:</a> <a id="10731" class="Symbol">(∀</a> <a id="10734" href="#10734" class="Bound">x</a> <a id="10736" href="#10736" class="Bound">xs</a> <a id="10739" href="#10739" class="Bound">pxs</a> <a id="10743" class="Symbol">→</a> <a id="10745" href="Agda.Builtin.Cubical.Path.html#162" class="Postulate">PathP</a> <a id="10751" class="Symbol">(λ</a> <a id="10754" href="#10754" class="Bound">i</a> <a id="10756" class="Symbol">→</a> <a id="10758" href="#10213" class="Bound">P</a> <a id="10760" class="Symbol">(</a><a id="10761" href="#8887" class="InductiveConstructor">del</a> <a id="10765" href="#10734" class="Bound">x</a> <a id="10767" href="#10736" class="Bound">xs</a> <a id="10770" href="#10754" class="Bound">i</a><a id="10771" class="Symbol">))</a>
              <a id="10788" class="Symbol">(</a><a id="10789" href="#10403" class="Function">f</a> <a id="10791" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="10794" href="#10734" class="Bound">x</a> <a id="10796" href="#10736" class="Bound">xs</a> <a id="10799" href="#10739" class="Bound">pxs</a><a id="10802" class="Symbol">)</a> <a id="10804" href="#10739" class="Bound">pxs</a><a id="10807" class="Symbol">)</a>
  <a id="⟅_↝_⟆.⟅_⟆⇓"></a><a id="10811" href="#10811" class="Function Operator">⟅_⟆⇓</a> <a id="10816" class="Symbol">:</a> <a id="10818" class="Symbol">(</a><a id="10819" href="#10819" class="Bound">xs</a> <a id="10822" class="Symbol">:</a> <a id="10824" href="#8679" class="Datatype">𝒫</a> <a id="10826" href="#10201" class="Bound">A</a><a id="10827" class="Symbol">)</a> <a id="10829" class="Symbol">→</a> <a id="10831" href="#10213" class="Bound">P</a> <a id="10833" href="#10819" class="Bound">xs</a>
  <a id="10838" href="#10811" class="Function Operator">⟅</a> <a id="10840" href="#8715" class="InductiveConstructor">[]</a> <a id="10843" href="#10811" class="Function Operator">⟆⇓</a> <a id="10846" class="Symbol">=</a> <a id="10848" href="#10392" class="Function">z</a>
  <a id="10852" href="#10811" class="Function Operator">⟅</a> <a id="10854" href="#10854" class="Bound">p</a> <a id="10856" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="10858" href="#10858" class="Bound">x</a> <a id="10860" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="10862" href="#10862" class="Bound">xs</a> <a id="10865" href="#10811" class="Function Operator">⟆⇓</a> <a id="10868" class="Symbol">=</a> <a id="10870" href="#10403" class="Function">f</a> <a id="10872" href="#10854" class="Bound">p</a> <a id="10874" href="#10858" class="Bound">x</a> <a id="10876" href="#10862" class="Bound">xs</a> <a id="10879" href="#10811" class="Function Operator">⟅</a> <a id="10881" href="#10862" class="Bound">xs</a> <a id="10884" href="#10811" class="Function Operator">⟆⇓</a>
  <a id="10889" href="#10811" class="Function Operator">⟅</a> <a id="10891" href="#8767" class="InductiveConstructor">dup</a> <a id="10895" href="#10895" class="Bound">p</a> <a id="10897" href="#10897" class="Bound">q</a> <a id="10899" href="#10899" class="Bound">x</a> <a id="10901" href="#10901" class="Bound">xs</a> <a id="10904" href="#10904" class="Bound">i</a> <a id="10906" href="#10811" class="Function Operator">⟆⇓</a> <a id="10909" class="Symbol">=</a> <a id="10911" href="#10428" class="Field Operator">⟅_⟆-dup</a> <a id="10919" href="#10895" class="Bound">p</a> <a id="10921" href="#10897" class="Bound">q</a> <a id="10923" href="#10899" class="Bound">x</a> <a id="10925" href="#10901" class="Bound">xs</a> <a id="10928" href="#10811" class="Function Operator">⟅</a> <a id="10930" href="#10901" class="Bound">xs</a> <a id="10933" href="#10811" class="Function Operator">⟆⇓</a> <a id="10936" href="#10904" class="Bound">i</a>
  <a id="10940" href="#10811" class="Function Operator">⟅</a> <a id="10942" href="#8824" class="InductiveConstructor">com</a> <a id="10946" href="#10946" class="Bound">p</a> <a id="10948" href="#10948" class="Bound">x</a> <a id="10950" href="#10950" class="Bound">q</a> <a id="10952" href="#10952" class="Bound">y</a> <a id="10954" href="#10954" class="Bound">xs</a> <a id="10957" href="#10957" class="Bound">i</a> <a id="10959" href="#10811" class="Function Operator">⟆⇓</a> <a id="10962" class="Symbol">=</a> <a id="10964" href="#10565" class="Field Operator">⟅_⟆-com</a> <a id="10972" href="#10946" class="Bound">p</a> <a id="10974" href="#10948" class="Bound">x</a> <a id="10976" href="#10950" class="Bound">q</a> <a id="10978" href="#10952" class="Bound">y</a> <a id="10980" href="#10954" class="Bound">xs</a> <a id="10983" href="#10811" class="Function Operator">⟅</a> <a id="10985" href="#10954" class="Bound">xs</a> <a id="10988" href="#10811" class="Function Operator">⟆⇓</a> <a id="10991" href="#10957" class="Bound">i</a>
  <a id="10995" href="#10811" class="Function Operator">⟅</a> <a id="10997" href="#8887" class="InductiveConstructor">del</a> <a id="11001" href="#11001" class="Bound">x</a> <a id="11003" href="#11003" class="Bound">xs</a> <a id="11006" href="#11006" class="Bound">i</a> <a id="11008" href="#10811" class="Function Operator">⟆⇓</a> <a id="11011" class="Symbol">=</a> <a id="11013" href="#10721" class="Field Operator">⟅_⟆-del</a> <a id="11021" href="#11001" class="Bound">x</a> <a id="11023" href="#11003" class="Bound">xs</a> <a id="11026" href="#10811" class="Function Operator">⟅</a> <a id="11028" href="#11003" class="Bound">xs</a> <a id="11031" href="#10811" class="Function Operator">⟆⇓</a> <a id="11034" href="#11006" class="Bound">i</a>
  <a id="11038" href="#10811" class="Function Operator">⟅</a> <a id="11040" href="#8921" class="InductiveConstructor">trunc</a> <a id="11046" href="#11046" class="Bound">xs</a> <a id="11049" href="#11049" class="Bound">ys</a> <a id="11052" href="#11052" class="Bound">p</a> <a id="11054" href="#11054" class="Bound">q</a> <a id="11056" href="#11056" class="Bound">i</a> <a id="11058" href="#11058" class="Bound">j</a> <a id="11060" href="#10811" class="Function Operator">⟆⇓</a> <a id="11063" class="Symbol">=</a>
    <a id="11069" href="../code/probability/Cubical.HITs.SetTruncation.Properties.html#434" class="Function">elimSquash₀</a> <a id="11081" class="Symbol">(λ</a> <a id="11084" href="#11084" class="Bound">xs</a> <a id="11087" class="Symbol">→</a> <a id="11089" href="#10285" class="Field Operator">⟅_⟆-set</a> <a id="11097" class="Symbol">{</a><a id="11098" href="#11084" class="Bound">xs</a><a id="11100" class="Symbol">})</a> <a id="11103" class="Symbol">(</a><a id="11104" href="#8921" class="InductiveConstructor">trunc</a> <a id="11110" href="#11046" class="Bound">xs</a> <a id="11113" href="#11049" class="Bound">ys</a> <a id="11116" href="#11052" class="Bound">p</a> <a id="11118" href="#11054" class="Bound">q</a><a id="11119" class="Symbol">)</a> <a id="11121" href="#10811" class="Function Operator">⟅</a> <a id="11123" href="#11046" class="Bound">xs</a> <a id="11126" href="#10811" class="Function Operator">⟆⇓</a> <a id="11129" href="#10811" class="Function Operator">⟅</a> <a id="11131" href="#11049" class="Bound">ys</a> <a id="11134" href="#10811" class="Function Operator">⟆⇓</a> <a id="11137" class="Symbol">(</a><a id="11138" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="11143" href="#10811" class="Function Operator">⟅_⟆⇓</a> <a id="11148" href="#11052" class="Bound">p</a><a id="11149" class="Symbol">)</a> <a id="11151" class="Symbol">(</a><a id="11152" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="11157" href="#10811" class="Function Operator">⟅_⟆⇓</a> <a id="11162" href="#11054" class="Bound">q</a><a id="11163" class="Symbol">)</a> <a id="11165" href="#11056" class="Bound">i</a> <a id="11167" href="#11058" class="Bound">j</a>

<a id="11170" class="Keyword">open</a> <a id="11175" href="#10188" class="Module Operator">⟅_↝_⟆</a> <a id="11181" class="Keyword">public</a>
<a id="elim-syntax"></a><a id="11188" href="#11188" class="Function">elim-syntax</a> <a id="11200" class="Symbol">:</a> <a id="11202" class="Symbol">∀</a> <a id="11204" class="Symbol">{</a><a id="11205" href="#11205" class="Bound">a</a> <a id="11207" href="#11207" class="Bound">ℓ</a><a id="11208" class="Symbol">}</a> <a id="11210" class="Symbol">→</a> <a id="11212" class="Symbol">(</a><a id="11213" href="#11213" class="Bound">A</a> <a id="11215" class="Symbol">:</a> <a id="11217" class="PrimitiveType">Set</a> <a id="11221" href="#11205" class="Bound">a</a><a id="11222" class="Symbol">)</a> <a id="11224" class="Symbol">→</a> <a id="11226" class="Symbol">(</a><a id="11227" href="#8679" class="Datatype">𝒫</a> <a id="11229" href="#11213" class="Bound">A</a> <a id="11231" class="Symbol">→</a> <a id="11233" class="PrimitiveType">Set</a> <a id="11237" href="#11207" class="Bound">ℓ</a><a id="11238" class="Symbol">)</a> <a id="11240" class="Symbol">→</a> <a id="11242" class="PrimitiveType">Set</a> <a id="11246" class="Symbol">(</a><a id="11247" href="#11205" class="Bound">a</a> <a id="11249" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="11251" href="#11207" class="Bound">ℓ</a> <a id="11253" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="11255" href="#1020" class="Bound">s</a><a id="11256" class="Symbol">)</a>
<a id="11258" href="#11188" class="Function">elim-syntax</a> <a id="11270" class="Symbol">=</a> <a id="11272" href="#10188" class="Record Operator">⟅_↝_⟆</a>

<a id="11279" class="Keyword">syntax</a> <a id="11286" href="#11188" class="Function">elim-syntax</a> <a id="11298" class="Bound">A</a> <a id="11300" class="Symbol">(λ</a> <a id="11303" class="Bound">xs</a> <a id="11306" class="Symbol">→</a> <a id="11308" class="Bound">Pxs</a><a id="11311" class="Symbol">)</a> <a id="11313" class="Symbol">=</a> <a id="11315" class="Function">[</a> <a id="11317" class="Bound">xs</a> <a id="11320" class="Function">∈𝒫</a> <a id="11323" class="Bound">A</a> <a id="11325" class="Function">↝</a> <a id="11327" class="Bound">Pxs</a> <a id="11331" class="Function">]</a>

<a id="11334" class="Keyword">record</a> <a id="⟦_⇒_⟧"></a><a id="11341" href="#11341" class="Record Operator">⟦_⇒_⟧</a> <a id="11347" class="Symbol">{</a><a id="11348" href="#11348" class="Bound">a</a> <a id="11350" href="#11350" class="Bound">ℓ</a><a id="11351" class="Symbol">}</a> <a id="11353" class="Symbol">(</a><a id="11354" href="#11354" class="Bound">A</a> <a id="11356" class="Symbol">:</a> <a id="11358" class="PrimitiveType">Set</a> <a id="11362" href="#11348" class="Bound">a</a><a id="11363" class="Symbol">)</a> <a id="11365" class="Symbol">(</a><a id="11366" href="#11366" class="Bound">P</a> <a id="11368" class="Symbol">:</a> <a id="11370" href="#8679" class="Datatype">𝒫</a> <a id="11372" href="#11354" class="Bound">A</a> <a id="11374" class="Symbol">→</a> <a id="11376" class="PrimitiveType">Set</a> <a id="11380" href="#11350" class="Bound">ℓ</a><a id="11381" class="Symbol">)</a> <a id="11383" class="Symbol">:</a> <a id="11385" class="PrimitiveType">Set</a> <a id="11389" class="Symbol">(</a><a id="11390" href="#11348" class="Bound">a</a> <a id="11392" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="11394" href="#11350" class="Bound">ℓ</a> <a id="11396" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="11398" href="#1020" class="Bound">s</a><a id="11399" class="Symbol">)</a> <a id="11401" class="Keyword">where</a>
  <a id="11409" class="Keyword">constructor</a> <a id="⟦_⇒_⟧.elim-prop"></a><a id="11421" href="#11421" class="InductiveConstructor">elim-prop</a>
  <a id="11433" class="Keyword">field</a>
    <a id="⟦_⇒_⟧.⟦_⟧-prop"></a><a id="11443" href="#11443" class="Field Operator">⟦_⟧-prop</a> <a id="11452" class="Symbol">:</a> <a id="11454" class="Symbol">∀</a> <a id="11456" class="Symbol">{</a><a id="11457" href="#11457" class="Bound">xs</a><a id="11459" class="Symbol">}</a> <a id="11461" class="Symbol">→</a> <a id="11463" href="../code/probability/Cubical.Foundations.Prelude.html#5402" class="Function">isProp</a> <a id="11470" class="Symbol">(</a><a id="11471" href="#11366" class="Bound">P</a> <a id="11473" href="#11457" class="Bound">xs</a><a id="11475" class="Symbol">)</a>
    <a id="⟦_⇒_⟧.⟦_⟧[]"></a><a id="11481" href="#11481" class="Field Operator">⟦_⟧[]</a> <a id="11487" class="Symbol">:</a> <a id="11489" href="#11366" class="Bound">P</a> <a id="11491" href="#8715" class="InductiveConstructor">[]</a>
    <a id="⟦_⇒_⟧.⟦_⟧_&amp;_∷_⟨_⟩"></a><a id="11498" href="#11498" class="Field Operator">⟦_⟧_&amp;_∷_⟨_⟩</a> <a id="11510" class="Symbol">:</a> <a id="11512" class="Symbol">∀</a> <a id="11514" href="#11514" class="Bound">p</a> <a id="11516" href="#11516" class="Bound">x</a> <a id="11518" href="#11518" class="Bound">xs</a> <a id="11521" class="Symbol">→</a> <a id="11523" href="#11366" class="Bound">P</a> <a id="11525" href="#11518" class="Bound">xs</a> <a id="11528" class="Symbol">→</a> <a id="11530" href="#11366" class="Bound">P</a> <a id="11532" class="Symbol">(</a><a id="11533" href="#11514" class="Bound">p</a> <a id="11535" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="11537" href="#11516" class="Bound">x</a> <a id="11539" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="11541" href="#11518" class="Bound">xs</a><a id="11543" class="Symbol">)</a>
  <a id="11547" class="Keyword">private</a> <a id="⟦_⇒_⟧.z"></a><a id="11555" href="#11555" class="Function">z</a> <a id="11557" class="Symbol">=</a> <a id="11559" href="#11481" class="Field Operator">⟦_⟧[]</a><a id="11564" class="Symbol">;</a> <a id="⟦_⇒_⟧.f"></a><a id="11566" href="#11566" class="Function">f</a> <a id="11568" class="Symbol">=</a> <a id="11570" href="#11498" class="Field Operator">⟦_⟧_&amp;_∷_⟨_⟩</a>
  <a id="⟦_⇒_⟧.⟦_⟧⇑"></a><a id="11584" href="#11584" class="Function Operator">⟦_⟧⇑</a> <a id="11589" class="Symbol">=</a> <a id="11591" href="#10268" class="InductiveConstructor">elim</a>
          <a id="11606" class="Symbol">(</a><a id="11607" href="../code/probability/Cubical.Foundations.Prelude.html#6576" class="Function">isProp→isSet</a> <a id="11620" href="#11443" class="Field Operator">⟦_⟧-prop</a><a id="11628" class="Symbol">)</a>
          <a id="11640" href="#11555" class="Function">z</a> <a id="11642" href="#11566" class="Function">f</a>
          <a id="11654" class="Symbol">(λ</a> <a id="11657" href="#11657" class="Bound">p</a> <a id="11659" href="#11659" class="Bound">q</a> <a id="11661" href="#11661" class="Bound">x</a> <a id="11663" href="#11663" class="Bound">xs</a> <a id="11666" href="#11666" class="Bound">pxs</a> <a id="11670" class="Symbol">→</a>
            <a id="11684" href="../code/probability/Cubical.Foundations.Prelude.html#5003" class="Function">toPathP</a> <a id="11692" class="Symbol">(</a><a id="11693" href="#11443" class="Field Operator">⟦_⟧-prop</a> <a id="11702" class="Symbol">(</a><a id="11703" href="Agda.Primitive.Cubical.html#1279" class="Primitive">transp</a> <a id="11710" class="Symbol">(λ</a> <a id="11713" href="#11713" class="Bound">i</a> <a id="11715" class="Symbol">→</a> <a id="11717" href="#11366" class="Bound">P</a> <a id="11719" class="Symbol">(</a><a id="11720" href="#8767" class="InductiveConstructor">dup</a> <a id="11724" href="#11657" class="Bound">p</a> <a id="11726" href="#11659" class="Bound">q</a> <a id="11728" href="#11661" class="Bound">x</a> <a id="11730" href="#11663" class="Bound">xs</a> <a id="11733" href="#11713" class="Bound">i</a><a id="11734" class="Symbol">))</a>
            <a id="11749" href="Agda.Primitive.Cubical.html#128" class="InductiveConstructor">i0</a>
            <a id="11764" class="Symbol">(</a><a id="11765" href="#11566" class="Function">f</a> <a id="11767" href="#11657" class="Bound">p</a> <a id="11769" href="#11661" class="Bound">x</a> <a id="11771" class="Symbol">(</a><a id="11772" href="#11659" class="Bound">q</a> <a id="11774" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="11776" href="#11661" class="Bound">x</a> <a id="11778" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="11780" href="#11663" class="Bound">xs</a><a id="11782" class="Symbol">)</a> <a id="11784" class="Symbol">(</a><a id="11785" href="#11566" class="Function">f</a> <a id="11787" href="#11659" class="Bound">q</a> <a id="11789" href="#11661" class="Bound">x</a> <a id="11791" href="#11663" class="Bound">xs</a> <a id="11794" href="#11666" class="Bound">pxs</a><a id="11797" class="Symbol">)))</a> <a id="11801" class="Symbol">(</a><a id="11802" href="#11566" class="Function">f</a> <a id="11804" class="Symbol">(</a><a id="11805" href="#11657" class="Bound">p</a> <a id="11807" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="11809" href="#11659" class="Bound">q</a><a id="11810" class="Symbol">)</a> <a id="11812" href="#11661" class="Bound">x</a> <a id="11814" href="#11663" class="Bound">xs</a> <a id="11817" href="#11666" class="Bound">pxs</a><a id="11820" class="Symbol">)</a> <a id="11822" class="Symbol">))</a>
          <a id="11835" class="Symbol">(λ</a> <a id="11838" href="#11838" class="Bound">p</a> <a id="11840" href="#11840" class="Bound">x</a> <a id="11842" href="#11842" class="Bound">q</a> <a id="11844" href="#11844" class="Bound">y</a> <a id="11846" href="#11846" class="Bound">xs</a> <a id="11849" href="#11849" class="Bound">pxs</a> <a id="11853" class="Symbol">→</a> <a id="11855" href="../code/probability/Cubical.Foundations.Prelude.html#5003" class="Function">toPathP</a> <a id="11863" class="Symbol">(</a><a id="11864" href="#11443" class="Field Operator">⟦_⟧-prop</a> <a id="11873" class="Symbol">(</a><a id="11874" href="Agda.Primitive.Cubical.html#1279" class="Primitive">transp</a> <a id="11881" class="Symbol">(λ</a> <a id="11884" href="#11884" class="Bound">i</a> <a id="11886" class="Symbol">→</a> <a id="11888" href="#11366" class="Bound">P</a> <a id="11890" class="Symbol">(</a><a id="11891" href="#8824" class="InductiveConstructor">com</a> <a id="11895" href="#11838" class="Bound">p</a> <a id="11897" href="#11840" class="Bound">x</a> <a id="11899" href="#11842" class="Bound">q</a> <a id="11901" href="#11844" class="Bound">y</a> <a id="11903" href="#11846" class="Bound">xs</a> <a id="11906" href="#11884" class="Bound">i</a><a id="11907" class="Symbol">))</a> <a id="11910" href="Agda.Primitive.Cubical.html#128" class="InductiveConstructor">i0</a>
            <a id="11925" class="Symbol">(</a><a id="11926" href="#11566" class="Function">f</a> <a id="11928" href="#11838" class="Bound">p</a> <a id="11930" href="#11840" class="Bound">x</a> <a id="11932" class="Symbol">(</a><a id="11933" href="#11842" class="Bound">q</a> <a id="11935" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="11937" href="#11844" class="Bound">y</a> <a id="11939" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="11941" href="#11846" class="Bound">xs</a><a id="11943" class="Symbol">)</a> <a id="11945" class="Symbol">(</a><a id="11946" href="#11566" class="Function">f</a> <a id="11948" href="#11842" class="Bound">q</a> <a id="11950" href="#11844" class="Bound">y</a> <a id="11952" href="#11846" class="Bound">xs</a> <a id="11955" href="#11849" class="Bound">pxs</a><a id="11958" class="Symbol">)))</a> <a id="11962" class="Symbol">(</a><a id="11963" href="#11566" class="Function">f</a> <a id="11965" href="#11842" class="Bound">q</a> <a id="11967" href="#11844" class="Bound">y</a> <a id="11969" class="Symbol">(</a><a id="11970" href="#11838" class="Bound">p</a> <a id="11972" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="11974" href="#11840" class="Bound">x</a> <a id="11976" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="11978" href="#11846" class="Bound">xs</a><a id="11980" class="Symbol">)</a> <a id="11982" class="Symbol">(</a><a id="11983" href="#11566" class="Function">f</a> <a id="11985" href="#11838" class="Bound">p</a> <a id="11987" href="#11840" class="Bound">x</a> <a id="11989" href="#11846" class="Bound">xs</a> <a id="11992" href="#11849" class="Bound">pxs</a><a id="11995" class="Symbol">))))</a>
            <a id="12012" class="Symbol">λ</a> <a id="12014" href="#12014" class="Bound">x</a> <a id="12016" href="#12016" class="Bound">xs</a> <a id="12019" href="#12019" class="Bound">pxs</a> <a id="12023" class="Symbol">→</a> <a id="12025" href="../code/probability/Cubical.Foundations.Prelude.html#5003" class="Function">toPathP</a> <a id="12033" class="Symbol">(</a><a id="12034" href="#11443" class="Field Operator">⟦_⟧-prop</a> <a id="12043" class="Symbol">(</a><a id="12044" href="Agda.Primitive.Cubical.html#1279" class="Primitive">transp</a> <a id="12051" class="Symbol">(λ</a> <a id="12054" href="#12054" class="Bound">i</a> <a id="12056" class="Symbol">→</a> <a id="12058" href="#11366" class="Bound">P</a> <a id="12060" class="Symbol">(</a><a id="12061" href="#8887" class="InductiveConstructor">del</a> <a id="12065" href="#12014" class="Bound">x</a> <a id="12067" href="#12016" class="Bound">xs</a> <a id="12070" href="#12054" class="Bound">i</a><a id="12071" class="Symbol">))</a> <a id="12074" href="Agda.Primitive.Cubical.html#128" class="InductiveConstructor">i0</a> <a id="12077" class="Symbol">((</a><a id="12079" href="#11566" class="Function">f</a> <a id="12081" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="12084" href="#12014" class="Bound">x</a> <a id="12086" href="#12016" class="Bound">xs</a> <a id="12089" href="#12019" class="Bound">pxs</a><a id="12092" class="Symbol">)))</a> <a id="12096" href="#12019" class="Bound">pxs</a><a id="12099" class="Symbol">)</a>
  <a id="⟦_⇒_⟧.⟦_⟧⇓"></a><a id="12103" href="#12103" class="Function Operator">⟦_⟧⇓</a> <a id="12108" class="Symbol">=</a> <a id="12110" href="#10811" class="Function Operator">⟅</a> <a id="12112" href="#11584" class="Function Operator">⟦_⟧⇑</a> <a id="12117" href="#10811" class="Function Operator">⟆⇓</a>

<a id="12121" class="Keyword">open</a> <a id="12126" href="#11341" class="Module Operator">⟦_⇒_⟧</a> <a id="12132" class="Keyword">public</a>
<a id="elim-prop-syntax"></a><a id="12139" href="#12139" class="Function">elim-prop-syntax</a> <a id="12156" class="Symbol">:</a> <a id="12158" class="Symbol">∀</a> <a id="12160" class="Symbol">{</a><a id="12161" href="#12161" class="Bound">a</a> <a id="12163" href="#12163" class="Bound">ℓ</a><a id="12164" class="Symbol">}</a> <a id="12166" class="Symbol">→</a> <a id="12168" class="Symbol">(</a><a id="12169" href="#12169" class="Bound">A</a> <a id="12171" class="Symbol">:</a> <a id="12173" class="PrimitiveType">Set</a> <a id="12177" href="#12161" class="Bound">a</a><a id="12178" class="Symbol">)</a> <a id="12180" class="Symbol">→</a> <a id="12182" class="Symbol">(</a><a id="12183" href="#8679" class="Datatype">𝒫</a> <a id="12185" href="#12169" class="Bound">A</a> <a id="12187" class="Symbol">→</a> <a id="12189" class="PrimitiveType">Set</a> <a id="12193" href="#12163" class="Bound">ℓ</a><a id="12194" class="Symbol">)</a> <a id="12196" class="Symbol">→</a> <a id="12198" class="PrimitiveType">Set</a> <a id="12202" class="Symbol">(</a><a id="12203" href="#12161" class="Bound">a</a> <a id="12205" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="12207" href="#12163" class="Bound">ℓ</a> <a id="12209" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="12211" href="#1020" class="Bound">s</a><a id="12212" class="Symbol">)</a>
<a id="12214" href="#12139" class="Function">elim-prop-syntax</a> <a id="12231" class="Symbol">=</a> <a id="12233" href="#11341" class="Record Operator">⟦_⇒_⟧</a>

<a id="12240" class="Keyword">syntax</a> <a id="12247" href="#12139" class="Function">elim-prop-syntax</a> <a id="12264" class="Bound">A</a> <a id="12266" class="Symbol">(λ</a> <a id="12269" class="Bound">xs</a> <a id="12272" class="Symbol">→</a> <a id="12274" class="Bound">Pxs</a><a id="12277" class="Symbol">)</a> <a id="12279" class="Symbol">=</a> <a id="12281" class="Function">⟦</a> <a id="12283" class="Bound">xs</a> <a id="12286" class="Function">∈𝒫</a> <a id="12289" class="Bound">A</a> <a id="12291" class="Function">⇒</a> <a id="12293" class="Bound">Pxs</a> <a id="12297" class="Function">⟧</a>

<a id="12300" class="Keyword">record</a> <a id="[_↦_]"></a><a id="12307" href="#12307" class="Record Operator">[_↦_]</a> <a id="12313" class="Symbol">{</a><a id="12314" href="#12314" class="Bound">a</a> <a id="12316" href="#12316" class="Bound">b</a><a id="12317" class="Symbol">}</a> <a id="12319" class="Symbol">(</a><a id="12320" href="#12320" class="Bound">A</a> <a id="12322" class="Symbol">:</a> <a id="12324" class="PrimitiveType">Set</a> <a id="12328" href="#12314" class="Bound">a</a><a id="12329" class="Symbol">)</a> <a id="12331" class="Symbol">(</a><a id="12332" href="#12332" class="Bound">B</a> <a id="12334" class="Symbol">:</a> <a id="12336" class="PrimitiveType">Set</a> <a id="12340" href="#12316" class="Bound">b</a><a id="12341" class="Symbol">)</a> <a id="12343" class="Symbol">:</a> <a id="12345" class="PrimitiveType">Set</a> <a id="12349" class="Symbol">(</a><a id="12350" href="#12314" class="Bound">a</a> <a id="12352" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="12354" href="#12316" class="Bound">b</a> <a id="12356" href="../code/probability/ProbabilityModule.Utils.html#242" class="Function Operator">⊔</a> <a id="12358" href="#1020" class="Bound">s</a><a id="12359" class="Symbol">)</a> <a id="12361" class="Keyword">where</a>
  <a id="12369" class="Keyword">constructor</a> <a id="[_↦_].rec"></a><a id="12381" href="#12381" class="InductiveConstructor">rec</a>
  <a id="12387" class="Keyword">field</a>
    <a id="[_↦_].[_]-set"></a><a id="12397" href="#12397" class="Field Operator">[_]-set</a>  <a id="12406" class="Symbol">:</a> <a id="12408" href="../code/probability/Cubical.Foundations.Prelude.html#5455" class="Function">isSet</a> <a id="12414" href="#12332" class="Bound">B</a>
    <a id="[_↦_].[_]_&amp;_∷_"></a><a id="12420" href="#12420" class="Field Operator">[_]_&amp;_∷_</a> <a id="12429" class="Symbol">:</a> <a id="12431" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a> <a id="12433" class="Symbol">→</a> <a id="12435" href="#12320" class="Bound">A</a> <a id="12437" class="Symbol">→</a> <a id="12439" href="#12332" class="Bound">B</a> <a id="12441" class="Symbol">→</a> <a id="12443" href="#12332" class="Bound">B</a>
    <a id="[_↦_].[_][]"></a><a id="12449" href="#12449" class="Field Operator">[_][]</a>    <a id="12458" class="Symbol">:</a> <a id="12460" href="#12332" class="Bound">B</a>
  <a id="12464" class="Keyword">private</a> <a id="[_↦_].f"></a><a id="12472" href="#12472" class="Function">f</a> <a id="12474" class="Symbol">=</a> <a id="12476" href="#12420" class="Field Operator">[_]_&amp;_∷_</a><a id="12484" class="Symbol">;</a> <a id="[_↦_].z"></a><a id="12486" href="#12486" class="Function">z</a> <a id="12488" class="Symbol">=</a> <a id="12490" href="#12449" class="Field Operator">[_][]</a>
  <a id="12498" class="Keyword">field</a>
    <a id="[_↦_].[_]-dup"></a><a id="12508" href="#12508" class="Field Operator">[_]-dup</a>  <a id="12517" class="Symbol">:</a> <a id="12519" class="Symbol">∀</a> <a id="12521" href="#12521" class="Bound">p</a> <a id="12523" href="#12523" class="Bound">q</a> <a id="12525" href="#12525" class="Bound">x</a> <a id="12527" href="#12527" class="Bound">xs</a> <a id="12530" class="Symbol">→</a> <a id="12532" href="#12472" class="Function">f</a> <a id="12534" href="#12521" class="Bound">p</a> <a id="12536" href="#12525" class="Bound">x</a> <a id="12538" class="Symbol">(</a><a id="12539" href="#12472" class="Function">f</a> <a id="12541" href="#12523" class="Bound">q</a> <a id="12543" href="#12525" class="Bound">x</a> <a id="12545" href="#12527" class="Bound">xs</a><a id="12547" class="Symbol">)</a> <a id="12549" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="12551" href="#12472" class="Function">f</a> <a id="12553" class="Symbol">(</a><a id="12554" href="#12521" class="Bound">p</a> <a id="12556" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="12558" href="#12523" class="Bound">q</a><a id="12559" class="Symbol">)</a> <a id="12561" href="#12525" class="Bound">x</a> <a id="12563" href="#12527" class="Bound">xs</a>
    <a id="[_↦_].[_]-com"></a><a id="12570" href="#12570" class="Field Operator">[_]-com</a> <a id="12578" class="Symbol">:</a> <a id="12580" class="Symbol">∀</a> <a id="12582" href="#12582" class="Bound">p</a> <a id="12584" href="#12584" class="Bound">x</a> <a id="12586" href="#12586" class="Bound">q</a> <a id="12588" href="#12588" class="Bound">y</a> <a id="12590" href="#12590" class="Bound">xs</a> <a id="12593" class="Symbol">→</a> <a id="12595" href="#12472" class="Function">f</a> <a id="12597" href="#12582" class="Bound">p</a> <a id="12599" href="#12584" class="Bound">x</a> <a id="12601" class="Symbol">(</a><a id="12602" href="#12472" class="Function">f</a> <a id="12604" href="#12586" class="Bound">q</a> <a id="12606" href="#12588" class="Bound">y</a> <a id="12608" href="#12590" class="Bound">xs</a><a id="12610" class="Symbol">)</a> <a id="12612" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="12614" href="#12472" class="Function">f</a> <a id="12616" href="#12586" class="Bound">q</a> <a id="12618" href="#12588" class="Bound">y</a> <a id="12620" class="Symbol">(</a><a id="12621" href="#12472" class="Function">f</a> <a id="12623" href="#12582" class="Bound">p</a> <a id="12625" href="#12584" class="Bound">x</a> <a id="12627" href="#12590" class="Bound">xs</a><a id="12629" class="Symbol">)</a>
    <a id="[_↦_].[_]-del"></a><a id="12635" href="#12635" class="Field Operator">[_]-del</a> <a id="12643" class="Symbol">:</a> <a id="12645" class="Symbol">∀</a> <a id="12647" href="#12647" class="Bound">x</a> <a id="12649" href="#12649" class="Bound">xs</a> <a id="12652" class="Symbol">→</a> <a id="12654" href="#12472" class="Function">f</a> <a id="12656" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="12659" href="#12647" class="Bound">x</a> <a id="12661" href="#12649" class="Bound">xs</a> <a id="12664" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="12666" href="#12649" class="Bound">xs</a>
  <a id="[_↦_].[_]⇑"></a><a id="12671" href="#12671" class="Function Operator">[_]⇑</a> <a id="12676" class="Symbol">=</a> <a id="12678" href="#10268" class="InductiveConstructor">elim</a>
            <a id="12695" href="#12397" class="Field Operator">[_]-set</a>
            <a id="12715" href="#12486" class="Function">z</a>
            <a id="12729" class="Symbol">(λ</a> <a id="12732" href="#12732" class="Bound">p</a> <a id="12734" href="#12734" class="Bound">x</a> <a id="12736" href="#12736" class="Bound">_</a> <a id="12738" href="#12738" class="Bound">xs</a> <a id="12741" class="Symbol">→</a> <a id="12743" href="#12472" class="Function">f</a> <a id="12745" href="#12732" class="Bound">p</a> <a id="12747" href="#12734" class="Bound">x</a> <a id="12749" href="#12738" class="Bound">xs</a><a id="12751" class="Symbol">)</a>
            <a id="12765" class="Symbol">(λ</a> <a id="12768" href="#12768" class="Bound">p</a> <a id="12770" href="#12770" class="Bound">q</a> <a id="12772" href="#12772" class="Bound">x</a> <a id="12774" href="#12774" class="Bound">xs</a> <a id="12777" class="Symbol">→</a> <a id="12779" href="#12508" class="Field Operator">[_]-dup</a> <a id="12787" href="#12768" class="Bound">p</a> <a id="12789" href="#12770" class="Bound">q</a> <a id="12791" href="#12772" class="Bound">x</a><a id="12792" class="Symbol">)</a>
            <a id="12806" class="Symbol">(λ</a> <a id="12809" href="#12809" class="Bound">p</a> <a id="12811" href="#12811" class="Bound">x</a> <a id="12813" href="#12813" class="Bound">q</a> <a id="12815" href="#12815" class="Bound">y</a> <a id="12817" href="#12817" class="Bound">xs</a> <a id="12820" class="Symbol">→</a> <a id="12822" href="#12570" class="Field Operator">[_]-com</a> <a id="12830" href="#12809" class="Bound">p</a> <a id="12832" href="#12811" class="Bound">x</a> <a id="12834" href="#12813" class="Bound">q</a> <a id="12836" href="#12815" class="Bound">y</a><a id="12837" class="Symbol">)</a>
            <a id="12851" class="Symbol">(λ</a> <a id="12854" href="#12854" class="Bound">x</a> <a id="12856" href="#12856" class="Bound">xs</a> <a id="12859" class="Symbol">→</a> <a id="12861" href="#12635" class="Field Operator">[_]-del</a> <a id="12869" href="#12854" class="Bound">x</a><a id="12870" class="Symbol">)</a>
  <a id="[_↦_].[_]↓"></a><a id="12874" href="#12874" class="Function Operator">[_]↓</a> <a id="12879" class="Symbol">=</a> <a id="12881" href="#10811" class="Function Operator">⟅</a> <a id="12883" href="#12671" class="Function Operator">[_]⇑</a> <a id="12888" href="#10811" class="Function Operator">⟆⇓</a>
<a id="12891" class="Keyword">open</a> <a id="12896" href="#12307" class="Module Operator">[_↦_]</a> <a id="12902" class="Keyword">public</a>
</pre>
</details>
<p>Here’s one in action, to define <code>map</code>:</p>
<pre class="Agda"><a id="map"></a><a id="12972" href="#12972" class="Function">map</a> <a id="12976" class="Symbol">:</a> <a id="12978" class="Symbol">(</a><a id="12979" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="12981" class="Symbol">→</a> <a id="12983" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="12984" class="Symbol">)</a> <a id="12986" class="Symbol">→</a> <a id="12988" href="#8679" class="Datatype">𝒫</a> <a id="12990" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="12992" class="Symbol">→</a> <a id="12994" href="#8679" class="Datatype">𝒫</a> <a id="12996" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a>
<a id="12998" href="#12972" class="Function">map</a> <a id="13002" class="Symbol">=</a> <a id="13004" class="Symbol">λ</a> <a id="13006" href="#13006" class="Bound">f</a> <a id="13008" class="Symbol">→</a> <a id="13010" href="#12874" class="Function Operator">[</a> <a id="13012" href="#13043" class="Function">map′</a> <a id="13017" href="#13006" class="Bound">f</a> <a id="13019" href="#12874" class="Function Operator">]↓</a>
  <a id="13024" class="Keyword">module</a> <a id="Map"></a><a id="13031" href="#13031" class="Module">Map</a> <a id="13035" class="Keyword">where</a>
  <a id="Map.map′"></a><a id="13043" href="#13043" class="Function">map′</a> <a id="13048" class="Symbol">:</a> <a id="13050" class="Symbol">(</a><a id="13051" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13053" class="Symbol">→</a> <a id="13055" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="13056" class="Symbol">)</a> <a id="13058" class="Symbol">→</a> <a id="13060" href="#12307" class="Record Operator">[</a> <a id="13062" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13064" href="#12307" class="Record Operator">↦</a> <a id="13066" href="#8679" class="Datatype">𝒫</a> <a id="13068" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a> <a id="13070" href="#12307" class="Record Operator">]</a>
  <a id="13074" href="#12420" class="Field Operator">[</a> <a id="13076" href="#13043" class="Function">map′</a> <a id="13081" href="#13081" class="Bound">f</a> <a id="13083" href="#12420" class="Field Operator">]</a> <a id="13085" href="#13085" class="Bound">p</a> <a id="13087" href="#12420" class="Field Operator">&amp;</a> <a id="13089" href="#13089" class="Bound">x</a> <a id="13091" href="#12420" class="Field Operator">∷</a> <a id="13093" href="#13093" class="Bound">xs</a> <a id="13096" class="Symbol">=</a> <a id="13098" href="#13085" class="Bound">p</a> <a id="13100" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="13102" href="#13081" class="Bound">f</a> <a id="13104" href="#13089" class="Bound">x</a> <a id="13106" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="13108" href="#13093" class="Bound">xs</a>
  <a id="13113" href="#12449" class="Field Operator">[</a> <a id="13115" href="#13043" class="Function">map′</a> <a id="13120" href="#13120" class="Bound">f</a> <a id="13122" href="#12449" class="Field Operator">][]</a> <a id="13126" class="Symbol">=</a> <a id="13128" href="#8715" class="InductiveConstructor">[]</a>
  <a id="13133" href="#12397" class="Field Operator">[</a> <a id="13135" href="#13043" class="Function">map′</a> <a id="13140" href="#13140" class="Bound">f</a> <a id="13142" href="#12397" class="Field Operator">]-set</a> <a id="13148" class="Symbol">=</a> <a id="13150" href="#8921" class="InductiveConstructor">trunc</a>
  <a id="13158" href="#12508" class="Field Operator">[</a> <a id="13160" href="#13043" class="Function">map′</a> <a id="13165" href="#13165" class="Bound">f</a> <a id="13167" href="#12508" class="Field Operator">]-dup</a> <a id="13173" href="#13173" class="Bound">p</a> <a id="13175" href="#13175" class="Bound">q</a> <a id="13177" href="#13177" class="Bound">x</a> <a id="13179" href="#13179" class="Bound">xs</a> <a id="13182" class="Symbol">=</a> <a id="13184" href="#8767" class="InductiveConstructor">dup</a> <a id="13188" href="#13173" class="Bound">p</a> <a id="13190" href="#13175" class="Bound">q</a> <a id="13192" class="Symbol">(</a><a id="13193" href="#13165" class="Bound">f</a> <a id="13195" href="#13177" class="Bound">x</a><a id="13196" class="Symbol">)</a> <a id="13198" href="#13179" class="Bound">xs</a>
  <a id="13203" href="#12570" class="Field Operator">[</a> <a id="13205" href="#13043" class="Function">map′</a> <a id="13210" href="#13210" class="Bound">f</a> <a id="13212" href="#12570" class="Field Operator">]-com</a> <a id="13218" href="#13218" class="Bound">p</a> <a id="13220" href="#13220" class="Bound">x</a> <a id="13222" href="#13222" class="Bound">q</a> <a id="13224" href="#13224" class="Bound">y</a> <a id="13226" href="#13226" class="Bound">xs</a> <a id="13229" class="Symbol">=</a> <a id="13231" href="#8824" class="InductiveConstructor">com</a> <a id="13235" href="#13218" class="Bound">p</a> <a id="13237" class="Symbol">(</a><a id="13238" href="#13210" class="Bound">f</a> <a id="13240" href="#13220" class="Bound">x</a><a id="13241" class="Symbol">)</a> <a id="13243" href="#13222" class="Bound">q</a> <a id="13245" class="Symbol">(</a><a id="13246" href="#13210" class="Bound">f</a> <a id="13248" href="#13224" class="Bound">y</a><a id="13249" class="Symbol">)</a> <a id="13251" href="#13226" class="Bound">xs</a>
  <a id="13256" href="#12635" class="Field Operator">[</a> <a id="13258" href="#13043" class="Function">map′</a> <a id="13263" href="#13263" class="Bound">f</a> <a id="13265" href="#12635" class="Field Operator">]-del</a> <a id="13271" href="#13271" class="Bound">x</a> <a id="13273" href="#13273" class="Bound">xs</a> <a id="13276" class="Symbol">=</a> <a id="13278" href="#8887" class="InductiveConstructor">del</a> <a id="13282" class="Symbol">(</a><a id="13283" href="#13263" class="Bound">f</a> <a id="13285" href="#13271" class="Bound">x</a><a id="13286" class="Symbol">)</a> <a id="13288" href="#13273" class="Bound">xs</a>
</pre>
<p>And here’s how we’d define union, and then prove that it’s
associative:</p>
<pre class="Agda"><a id="13377" class="Keyword">infixr</a> <a id="13384" class="Number">5</a> <a id="13386" href="#13390" class="Function Operator">_∪_</a>
<a id="_∪_"></a><a id="13390" href="#13390" class="Function Operator">_∪_</a> <a id="13394" class="Symbol">:</a> <a id="13396" href="#8679" class="Datatype">𝒫</a> <a id="13398" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13400" class="Symbol">→</a> <a id="13402" href="#8679" class="Datatype">𝒫</a> <a id="13404" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13406" class="Symbol">→</a> <a id="13408" href="#8679" class="Datatype">𝒫</a> <a id="13410" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a>
<a id="13412" href="#13390" class="Function Operator">_∪_</a> <a id="13416" class="Symbol">=</a> <a id="13418" class="Symbol">λ</a> <a id="13420" href="#13420" class="Bound">xs</a> <a id="13423" href="#13423" class="Bound">ys</a> <a id="13426" class="Symbol">→</a> <a id="13428" href="#12874" class="Function Operator">[</a> <a id="13430" href="#13468" class="Function">union</a> <a id="13436" href="#13423" class="Bound">ys</a> <a id="13439" href="#12874" class="Function Operator">]↓</a> <a id="13442" href="#13420" class="Bound">xs</a>
  <a id="13447" class="Keyword">module</a> <a id="Union"></a><a id="13454" href="#13454" class="Module">Union</a> <a id="13460" class="Keyword">where</a>
  <a id="Union.union"></a><a id="13468" href="#13468" class="Function">union</a> <a id="13474" class="Symbol">:</a> <a id="13476" href="#8679" class="Datatype">𝒫</a> <a id="13478" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13480" class="Symbol">→</a> <a id="13482" href="#12307" class="Record Operator">[</a> <a id="13484" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13486" href="#12307" class="Record Operator">↦</a> <a id="13488" href="#8679" class="Datatype">𝒫</a> <a id="13490" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13492" href="#12307" class="Record Operator">]</a>
  <a id="13496" href="#12397" class="Field Operator">[</a> <a id="13498" href="#13468" class="Function">union</a> <a id="13504" href="#13504" class="Bound">ys</a> <a id="13507" href="#12397" class="Field Operator">]-set</a> <a id="13513" class="Symbol">=</a> <a id="13515" href="#8921" class="InductiveConstructor">trunc</a>
  <a id="13523" href="#12420" class="Field Operator">[</a> <a id="13525" href="#13468" class="Function">union</a> <a id="13531" href="#13531" class="Bound">ys</a> <a id="13534" href="#12420" class="Field Operator">]</a> <a id="13536" href="#13536" class="Bound">p</a> <a id="13538" href="#12420" class="Field Operator">&amp;</a> <a id="13540" href="#13540" class="Bound">x</a> <a id="13542" href="#12420" class="Field Operator">∷</a> <a id="13544" href="#13544" class="Bound">xs</a> <a id="13547" class="Symbol">=</a> <a id="13549" href="#13536" class="Bound">p</a> <a id="13551" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="13553" href="#13540" class="Bound">x</a> <a id="13555" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="13557" href="#13544" class="Bound">xs</a>
  <a id="13562" href="#12449" class="Field Operator">[</a> <a id="13564" href="#13468" class="Function">union</a> <a id="13570" href="#13570" class="Bound">ys</a> <a id="13573" href="#12449" class="Field Operator">][]</a> <a id="13577" class="Symbol">=</a> <a id="13579" href="#13570" class="Bound">ys</a>
  <a id="13584" href="#12508" class="Field Operator">[</a> <a id="13586" href="#13468" class="Function">union</a> <a id="13592" href="#13592" class="Bound">ys</a> <a id="13595" href="#12508" class="Field Operator">]-dup</a> <a id="13601" class="Symbol">=</a> <a id="13603" href="#8767" class="InductiveConstructor">dup</a>
  <a id="13609" href="#12570" class="Field Operator">[</a> <a id="13611" href="#13468" class="Function">union</a> <a id="13617" href="#13617" class="Bound">ys</a> <a id="13620" href="#12570" class="Field Operator">]-com</a> <a id="13626" class="Symbol">=</a> <a id="13628" href="#8824" class="InductiveConstructor">com</a>
  <a id="13634" href="#12635" class="Field Operator">[</a> <a id="13636" href="#13468" class="Function">union</a> <a id="13642" href="#13642" class="Bound">ys</a> <a id="13645" href="#12635" class="Field Operator">]-del</a> <a id="13651" class="Symbol">=</a> <a id="13653" href="#8887" class="InductiveConstructor">del</a>

<a id="∪-assoc"></a><a id="13658" href="#13658" class="Function">∪-assoc</a> <a id="13666" class="Symbol">:</a> <a id="13668" class="Symbol">(</a><a id="13669" href="#13669" class="Bound">xs</a> <a id="13672" href="#13672" class="Bound">ys</a> <a id="13675" href="#13675" class="Bound">zs</a> <a id="13678" class="Symbol">:</a> <a id="13680" href="#8679" class="Datatype">𝒫</a> <a id="13682" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="13683" class="Symbol">)</a> <a id="13685" class="Symbol">→</a> <a id="13687" href="#13669" class="Bound">xs</a> <a id="13690" href="#13390" class="Function Operator">∪</a> <a id="13692" class="Symbol">(</a><a id="13693" href="#13672" class="Bound">ys</a> <a id="13696" href="#13390" class="Function Operator">∪</a> <a id="13698" href="#13675" class="Bound">zs</a><a id="13700" class="Symbol">)</a> <a id="13702" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="13704" class="Symbol">(</a><a id="13705" href="#13669" class="Bound">xs</a> <a id="13708" href="#13390" class="Function Operator">∪</a> <a id="13710" href="#13672" class="Bound">ys</a><a id="13712" class="Symbol">)</a> <a id="13714" href="#13390" class="Function Operator">∪</a> <a id="13716" href="#13675" class="Bound">zs</a>
<a id="13719" href="#13658" class="Function">∪-assoc</a> <a id="13727" class="Symbol">=</a> <a id="13729" class="Symbol">λ</a> <a id="13731" href="#13731" class="Bound">xs</a> <a id="13734" href="#13734" class="Bound">ys</a> <a id="13737" href="#13737" class="Bound">zs</a> <a id="13740" class="Symbol">→</a> <a id="13742" href="#12103" class="Function Operator">⟦</a> <a id="13744" href="#13789" class="Function">∪-assoc′</a> <a id="13753" href="#13734" class="Bound">ys</a> <a id="13756" href="#13737" class="Bound">zs</a> <a id="13759" href="#12103" class="Function Operator">⟧⇓</a> <a id="13762" href="#13731" class="Bound">xs</a>
  <a id="13767" class="Keyword">module</a> <a id="UAssoc"></a><a id="13774" href="#13774" class="Module">UAssoc</a> <a id="13781" class="Keyword">where</a>
  <a id="UAssoc.∪-assoc′"></a><a id="13789" href="#13789" class="Function">∪-assoc′</a> <a id="13798" class="Symbol">:</a> <a id="13800" class="Symbol">∀</a> <a id="13802" href="#13802" class="Bound">ys</a> <a id="13805" href="#13805" class="Bound">zs</a> <a id="13808" class="Symbol">→</a> <a id="13810" href="#12139" class="Function">⟦</a> <a id="13812" href="#13812" class="Bound">xs</a> <a id="13815" href="#12139" class="Function">∈𝒫</a> <a id="13818" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="13820" href="#12139" class="Function">⇒</a> <a id="13822" href="#13812" class="Bound">xs</a> <a id="13825" href="#13390" class="Function Operator">∪</a> <a id="13827" class="Symbol">(</a><a id="13828" href="#13802" class="Bound">ys</a> <a id="13831" href="#13390" class="Function Operator">∪</a> <a id="13833" href="#13805" class="Bound">zs</a><a id="13835" class="Symbol">)</a> <a id="13837" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="13839" class="Symbol">(</a><a id="13840" href="#13812" class="Bound">xs</a> <a id="13843" href="#13390" class="Function Operator">∪</a> <a id="13845" href="#13802" class="Bound">ys</a><a id="13847" class="Symbol">)</a> <a id="13849" href="#13390" class="Function Operator">∪</a> <a id="13851" href="#13805" class="Bound">zs</a> <a id="13854" href="#12139" class="Function">⟧</a>
  <a id="13858" href="#11443" class="Field Operator">⟦</a> <a id="13860" href="#13789" class="Function">∪-assoc′</a> <a id="13869" href="#13869" class="Bound">ys</a> <a id="13872" href="#13872" class="Bound">zs</a> <a id="13875" href="#11443" class="Field Operator">⟧-prop</a> <a id="13882" class="Symbol">=</a> <a id="13884" href="#8921" class="InductiveConstructor">trunc</a> <a id="13890" class="Symbol">_</a> <a id="13892" class="Symbol">_</a>
  <a id="13896" href="#11481" class="Field Operator">⟦</a> <a id="13898" href="#13789" class="Function">∪-assoc′</a> <a id="13907" href="#13907" class="Bound">ys</a> <a id="13910" href="#13910" class="Bound">zs</a> <a id="13913" href="#11481" class="Field Operator">⟧[]</a> <a id="13917" class="Symbol">=</a> <a id="13919" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="13926" href="#11498" class="Field Operator">⟦</a> <a id="13928" href="#13789" class="Function">∪-assoc′</a> <a id="13937" href="#13937" class="Bound">ys</a> <a id="13940" href="#13940" class="Bound">zs</a> <a id="13943" href="#11498" class="Field Operator">⟧</a> <a id="13945" href="#13945" class="Bound">p</a> <a id="13947" href="#11498" class="Field Operator">&amp;</a> <a id="13949" href="#13949" class="Bound">x</a> <a id="13951" href="#11498" class="Field Operator">∷</a> <a id="13953" href="#13953" class="Bound">xs</a> <a id="13956" href="#11498" class="Field Operator">⟨</a> <a id="13958" href="#13958" class="Bound">P</a> <a id="13960" href="#11498" class="Field Operator">⟩</a> <a id="13962" class="Symbol">=</a> <a id="13964" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="13969" class="Symbol">(</a><a id="13970" href="#13945" class="Bound">p</a> <a id="13972" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="13974" href="#13949" class="Bound">x</a> <a id="13976" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="13978" class="Symbol">)</a> <a id="13980" href="#13958" class="Bound">P</a>
</pre>
<p>There’s a lot more stuff here that I won’t bore you with.</p>
<details>
<summary>
Boring Stuff
</summary>
<pre class="Agda"><a id="14096" class="Keyword">infixl</a> <a id="14103" class="Number">7</a> <a id="14105" href="#14109" class="Function Operator">_⋊_</a>
<a id="_⋊_"></a><a id="14109" href="#14109" class="Function Operator">_⋊_</a> <a id="14113" class="Symbol">:</a> <a id="14115" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a> <a id="14117" class="Symbol">→</a> <a id="14119" href="#8679" class="Datatype">𝒫</a> <a id="14121" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="14123" class="Symbol">→</a> <a id="14125" href="#8679" class="Datatype">𝒫</a> <a id="14127" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a>
<a id="14129" href="#14109" class="Function Operator">_⋊_</a> <a id="14133" class="Symbol">=</a> <a id="14135" class="Symbol">λ</a> <a id="14137" href="#14137" class="Bound">p</a> <a id="14139" class="Symbol">→</a> <a id="14141" href="#12874" class="Function Operator">[</a> <a id="14143" href="#14137" class="Bound">p</a> <a id="14145" href="#14173" class="Function Operator">⋊′</a> <a id="14148" href="#12874" class="Function Operator">]↓</a>
  <a id="14153" class="Keyword">module</a> <a id="Cond"></a><a id="14160" href="#14160" class="Module">Cond</a> <a id="14165" class="Keyword">where</a>
  <a id="Cond._⋊′"></a><a id="14173" href="#14173" class="Function Operator">_⋊′</a> <a id="14177" class="Symbol">:</a> <a id="14179" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a> <a id="14181" class="Symbol">→</a> <a id="14183" href="#12307" class="Record Operator">[</a> <a id="14185" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="14187" href="#12307" class="Record Operator">↦</a> <a id="14189" href="#8679" class="Datatype">𝒫</a> <a id="14191" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="14193" href="#12307" class="Record Operator">]</a>
  <a id="14197" href="#12397" class="Field Operator">[</a> <a id="14199" href="#14199" class="Bound">p</a> <a id="14201" href="#14173" class="Function Operator">⋊′</a> <a id="14204" href="#12397" class="Field Operator">]-set</a> <a id="14210" class="Symbol">=</a> <a id="14212" href="#8921" class="InductiveConstructor">trunc</a>
  <a id="14220" href="#12449" class="Field Operator">[</a> <a id="14222" href="#14222" class="Bound">p</a> <a id="14224" href="#14173" class="Function Operator">⋊′</a> <a id="14227" href="#12449" class="Field Operator">][]</a> <a id="14231" class="Symbol">=</a> <a id="14233" href="#8715" class="InductiveConstructor">[]</a>
  <a id="14238" href="#12420" class="Field Operator">[</a> <a id="14240" href="#14240" class="Bound">p</a> <a id="14242" href="#14173" class="Function Operator">⋊′</a> <a id="14245" href="#12420" class="Field Operator">]</a> <a id="14247" href="#14247" class="Bound">q</a> <a id="14249" href="#12420" class="Field Operator">&amp;</a> <a id="14251" href="#14251" class="Bound">x</a> <a id="14253" href="#12420" class="Field Operator">∷</a> <a id="14255" href="#14255" class="Bound">xs</a> <a id="14258" class="Symbol">=</a> <a id="14260" href="#14240" class="Bound">p</a> <a id="14262" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14264" href="#14247" class="Bound">q</a> <a id="14266" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="14268" href="#14251" class="Bound">x</a> <a id="14270" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14272" href="#14255" class="Bound">xs</a>
  <a id="14277" href="#12570" class="Field Operator">[</a> <a id="14279" href="#14279" class="Bound">p</a> <a id="14281" href="#14173" class="Function Operator">⋊′</a> <a id="14284" href="#12570" class="Field Operator">]-com</a> <a id="14290" href="#14290" class="Bound">q</a> <a id="14292" href="#14292" class="Bound">x</a> <a id="14294" href="#14294" class="Bound">r</a> <a id="14296" href="#14296" class="Bound">y</a> <a id="14298" href="#14298" class="Bound">xs</a> <a id="14301" class="Symbol">=</a> <a id="14303" href="#8824" class="InductiveConstructor">com</a> <a id="14307" class="Symbol">(</a><a id="14308" href="#14279" class="Bound">p</a> <a id="14310" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14312" href="#14290" class="Bound">q</a><a id="14313" class="Symbol">)</a> <a id="14315" href="#14292" class="Bound">x</a> <a id="14317" class="Symbol">(</a><a id="14318" href="#14279" class="Bound">p</a> <a id="14320" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14322" href="#14294" class="Bound">r</a><a id="14323" class="Symbol">)</a> <a id="14325" href="#14296" class="Bound">y</a> <a id="14327" href="#14298" class="Bound">xs</a>
  <a id="14332" href="#12508" class="Field Operator">[</a> <a id="14334" href="#14334" class="Bound">p</a> <a id="14336" href="#14173" class="Function Operator">⋊′</a> <a id="14339" href="#12508" class="Field Operator">]-dup</a> <a id="14345" href="#14345" class="Bound">q</a> <a id="14347" href="#14347" class="Bound">r</a> <a id="14349" href="#14349" class="Bound">x</a> <a id="14351" href="#14351" class="Bound">xs</a> <a id="14354" class="Symbol">=</a>
    <a id="14360" href="#14334" class="Bound">p</a> <a id="14362" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14364" href="#14345" class="Bound">q</a> <a id="14366" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="14368" href="#14349" class="Bound">x</a> <a id="14370" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14372" href="#14334" class="Bound">p</a> <a id="14374" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14376" href="#14347" class="Bound">r</a> <a id="14378" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="14380" href="#14349" class="Bound">x</a> <a id="14382" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14384" href="#14351" class="Bound">xs</a> <a id="14387" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="14390" href="#8767" class="InductiveConstructor">dup</a> <a id="14394" class="Symbol">(</a><a id="14395" href="#14334" class="Bound">p</a> <a id="14397" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14399" href="#14345" class="Bound">q</a><a id="14400" class="Symbol">)</a> <a id="14402" class="Symbol">(</a><a id="14403" href="#14334" class="Bound">p</a> <a id="14405" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14407" href="#14347" class="Bound">r</a><a id="14408" class="Symbol">)</a> <a id="14410" href="#14349" class="Bound">x</a> <a id="14412" href="#14351" class="Bound">xs</a> <a id="14415" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="14421" href="#14334" class="Bound">p</a> <a id="14423" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14425" href="#14345" class="Bound">q</a> <a id="14427" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14429" href="#14334" class="Bound">p</a> <a id="14431" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14433" href="#14347" class="Bound">r</a> <a id="14435" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="14437" href="#14349" class="Bound">x</a> <a id="14439" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14441" href="#14351" class="Bound">xs</a>     <a id="14448" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="14452" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="14457" class="Symbol">(</a><a id="14458" href="#8727" class="InductiveConstructor Operator">_&amp;</a> <a id="14461" href="#14349" class="Bound">x</a> <a id="14463" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14465" href="#14351" class="Bound">xs</a><a id="14467" class="Symbol">)</a> <a id="14469" class="Symbol">(</a><a id="14470" href="../code/probability/ProbabilityModule.Semirings.html#543" class="Field">*⟨+⟩</a> <a id="14475" href="#14334" class="Bound">p</a> <a id="14477" href="#14345" class="Bound">q</a> <a id="14479" href="#14347" class="Bound">r</a><a id="14480" class="Symbol">)</a> <a id="14482" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
    <a id="14488" href="#14334" class="Bound">p</a> <a id="14490" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14492" class="Symbol">(</a><a id="14493" href="#14345" class="Bound">q</a> <a id="14495" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14497" href="#14347" class="Bound">r</a><a id="14498" class="Symbol">)</a> <a id="14500" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="14502" href="#14349" class="Bound">x</a> <a id="14504" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14506" href="#14351" class="Bound">xs</a>       <a id="14515" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
  <a id="14519" href="#12635" class="Field Operator">[</a> <a id="14521" href="#14521" class="Bound">p</a> <a id="14523" href="#14173" class="Function Operator">⋊′</a> <a id="14526" href="#12635" class="Field Operator">]-del</a> <a id="14532" href="#14532" class="Bound">x</a> <a id="14534" href="#14534" class="Bound">xs</a> <a id="14537" class="Symbol">=</a>
    <a id="14543" href="#14521" class="Bound">p</a> <a id="14545" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14547" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="14550" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="14552" href="#14532" class="Bound">x</a> <a id="14554" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14556" href="#14534" class="Bound">xs</a> <a id="14559" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="14562" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="14567" class="Symbol">(</a><a id="14568" href="#8727" class="InductiveConstructor Operator">_&amp;</a> <a id="14571" href="#14532" class="Bound">x</a> <a id="14573" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14575" href="#14534" class="Bound">xs</a><a id="14577" class="Symbol">)</a> <a id="14579" class="Symbol">(</a><a id="14580" href="../code/probability/ProbabilityModule.Semirings.html#376" class="Field">*0</a> <a id="14583" href="#14521" class="Bound">p</a><a id="14584" class="Symbol">)</a> <a id="14586" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="14592" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="14595" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="14597" href="#14532" class="Bound">x</a> <a id="14599" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="14601" href="#14534" class="Bound">xs</a>     <a id="14608" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="14611" href="#8887" class="InductiveConstructor">del</a> <a id="14615" href="#14532" class="Bound">x</a> <a id="14617" href="#14534" class="Bound">xs</a> <a id="14620" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="14626" href="#14534" class="Bound">xs</a>              <a id="14642" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="∫"></a><a id="14645" href="#14645" class="Function">∫</a> <a id="14647" class="Symbol">:</a> <a id="14649" class="Symbol">(</a><a id="14650" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="14652" class="Symbol">→</a> <a id="14654" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a><a id="14655" class="Symbol">)</a> <a id="14657" class="Symbol">→</a> <a id="14659" href="#8679" class="Datatype">𝒫</a> <a id="14661" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="14663" class="Symbol">→</a> <a id="14665" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a>
<a id="14667" href="#14645" class="Function">∫</a> <a id="14669" class="Symbol">=</a> <a id="14671" class="Symbol">λ</a> <a id="14673" href="#14673" class="Bound">f</a> <a id="14675" class="Symbol">→</a> <a id="14677" href="#12874" class="Function Operator">[</a> <a id="14679" href="#14711" class="Function">∫′</a> <a id="14682" href="#14673" class="Bound">f</a> <a id="14684" href="#12874" class="Function Operator">]↓</a>
  <a id="14689" class="Keyword">module</a> <a id="Expect"></a><a id="14696" href="#14696" class="Module">Expect</a> <a id="14703" class="Keyword">where</a>
  <a id="Expect.∫′"></a><a id="14711" href="#14711" class="Function">∫′</a> <a id="14714" class="Symbol">:</a> <a id="14716" class="Symbol">(</a><a id="14717" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="14719" class="Symbol">→</a> <a id="14721" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a><a id="14722" class="Symbol">)</a> <a id="14724" class="Symbol">→</a> <a id="14726" href="#12307" class="Record Operator">[</a> <a id="14728" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="14730" href="#12307" class="Record Operator">↦</a> <a id="14732" href="../code/probability/ProbabilityModule.Semirings.html#200" class="Field">R</a> <a id="14734" href="#12307" class="Record Operator">]</a>
  <a id="14738" href="#12397" class="Field Operator">[</a> <a id="14740" href="#14711" class="Function">∫′</a> <a id="14743" href="#14743" class="Bound">f</a> <a id="14745" href="#12397" class="Field Operator">]-set</a> <a id="14751" class="Symbol">=</a> <a id="14753" href="../code/probability/ProbabilityModule.Semirings.html#641" class="Field">sIsSet</a>
  <a id="14762" href="#12420" class="Field Operator">[</a> <a id="14764" href="#14711" class="Function">∫′</a> <a id="14767" href="#14767" class="Bound">f</a> <a id="14769" href="#12420" class="Field Operator">]</a> <a id="14771" href="#14771" class="Bound">p</a> <a id="14773" href="#12420" class="Field Operator">&amp;</a> <a id="14775" href="#14775" class="Bound">x</a> <a id="14777" href="#12420" class="Field Operator">∷</a> <a id="14779" href="#14779" class="Bound">xs</a> <a id="14782" class="Symbol">=</a> <a id="14784" href="#14771" class="Bound">p</a> <a id="14786" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14788" href="#14767" class="Bound">f</a> <a id="14790" href="#14775" class="Bound">x</a> <a id="14792" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14794" href="#14779" class="Bound">xs</a>
  <a id="14799" href="#12449" class="Field Operator">[</a> <a id="14801" href="#14711" class="Function">∫′</a> <a id="14804" href="#14804" class="Bound">f</a> <a id="14806" href="#12449" class="Field Operator">][]</a> <a id="14810" class="Symbol">=</a> <a id="14812" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a>
  <a id="14817" href="#12508" class="Field Operator">[</a> <a id="14819" href="#14711" class="Function">∫′</a> <a id="14822" href="#14822" class="Bound">f</a> <a id="14824" href="#12508" class="Field Operator">]-dup</a> <a id="14830" href="#14830" class="Bound">p</a> <a id="14832" href="#14832" class="Bound">q</a> <a id="14834" href="#14834" class="Bound">x</a> <a id="14836" href="#14836" class="Bound">xs</a> <a id="14839" class="Symbol">=</a>
    <a id="14845" href="#14830" class="Bound">p</a> <a id="14847" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14849" href="#14822" class="Bound">f</a> <a id="14851" href="#14834" class="Bound">x</a> <a id="14853" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14855" class="Symbol">(</a><a id="14856" href="#14832" class="Bound">q</a> <a id="14858" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14860" href="#14822" class="Bound">f</a> <a id="14862" href="#14834" class="Bound">x</a> <a id="14864" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14866" href="#14836" class="Bound">xs</a><a id="14868" class="Symbol">)</a> <a id="14870" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="14874" href="../code/probability/ProbabilityModule.Semirings.html#276" class="Field">+-assoc</a> <a id="14882" class="Symbol">(</a><a id="14883" href="#14830" class="Bound">p</a> <a id="14885" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14887" href="#14822" class="Bound">f</a> <a id="14889" href="#14834" class="Bound">x</a><a id="14890" class="Symbol">)</a> <a id="14892" class="Symbol">(</a><a id="14893" href="#14832" class="Bound">q</a> <a id="14895" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14897" href="#14822" class="Bound">f</a> <a id="14899" href="#14834" class="Bound">x</a><a id="14900" class="Symbol">)</a> <a id="14902" href="#14836" class="Bound">xs</a> <a id="14905" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
    <a id="14911" class="Symbol">(</a><a id="14912" href="#14830" class="Bound">p</a> <a id="14914" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14916" href="#14822" class="Bound">f</a> <a id="14918" href="#14834" class="Bound">x</a> <a id="14920" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14922" href="#14832" class="Bound">q</a> <a id="14924" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14926" href="#14822" class="Bound">f</a> <a id="14928" href="#14834" class="Bound">x</a><a id="14929" class="Symbol">)</a> <a id="14931" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14933" href="#14836" class="Bound">xs</a> <a id="14936" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="14940" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="14945" class="Symbol">(</a><a id="14946" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">_+</a> <a id="14949" href="#14836" class="Bound">xs</a><a id="14951" class="Symbol">)</a> <a id="14953" class="Symbol">(</a><a id="14954" href="../code/probability/ProbabilityModule.Semirings.html#592" class="Field">⟨+⟩*</a> <a id="14959" href="#14830" class="Bound">p</a> <a id="14961" href="#14832" class="Bound">q</a> <a id="14963" class="Symbol">(</a><a id="14964" href="#14822" class="Bound">f</a> <a id="14966" href="#14834" class="Bound">x</a><a id="14967" class="Symbol">))</a> <a id="14970" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
    <a id="14976" class="Symbol">(</a><a id="14977" href="#14830" class="Bound">p</a> <a id="14979" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14981" href="#14832" class="Bound">q</a><a id="14982" class="Symbol">)</a> <a id="14984" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="14986" href="#14822" class="Bound">f</a> <a id="14988" href="#14834" class="Bound">x</a> <a id="14990" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="14992" href="#14836" class="Bound">xs</a> <a id="14995" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
  <a id="14999" href="#12570" class="Field Operator">[</a> <a id="15001" href="#14711" class="Function">∫′</a> <a id="15004" href="#15004" class="Bound">f</a> <a id="15006" href="#12570" class="Field Operator">]-com</a> <a id="15012" href="#15012" class="Bound">p</a> <a id="15014" href="#15014" class="Bound">x</a> <a id="15016" href="#15016" class="Bound">q</a> <a id="15018" href="#15018" class="Bound">y</a> <a id="15020" href="#15020" class="Bound">xs</a> <a id="15023" class="Symbol">=</a>
    <a id="15029" href="#15012" class="Bound">p</a> <a id="15031" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15033" href="#15004" class="Bound">f</a> <a id="15035" href="#15014" class="Bound">x</a> <a id="15037" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15039" class="Symbol">(</a><a id="15040" href="#15016" class="Bound">q</a> <a id="15042" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15044" href="#15004" class="Bound">f</a> <a id="15046" href="#15018" class="Bound">y</a> <a id="15048" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15050" href="#15020" class="Bound">xs</a><a id="15052" class="Symbol">)</a> <a id="15054" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="15058" href="../code/probability/ProbabilityModule.Semirings.html#276" class="Field">+-assoc</a> <a id="15066" class="Symbol">(</a><a id="15067" href="#15012" class="Bound">p</a> <a id="15069" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15071" href="#15004" class="Bound">f</a> <a id="15073" href="#15014" class="Bound">x</a><a id="15074" class="Symbol">)</a> <a id="15076" class="Symbol">(</a><a id="15077" href="#15016" class="Bound">q</a> <a id="15079" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15081" href="#15004" class="Bound">f</a> <a id="15083" href="#15018" class="Bound">y</a><a id="15084" class="Symbol">)</a> <a id="15086" class="Symbol">(</a><a id="15087" href="#15020" class="Bound">xs</a><a id="15089" class="Symbol">)</a> <a id="15091" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
    <a id="15097" href="#15012" class="Bound">p</a> <a id="15099" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15101" href="#15004" class="Bound">f</a> <a id="15103" href="#15014" class="Bound">x</a> <a id="15105" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15107" href="#15016" class="Bound">q</a> <a id="15109" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15111" href="#15004" class="Bound">f</a> <a id="15113" href="#15018" class="Bound">y</a> <a id="15115" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15117" href="#15020" class="Bound">xs</a>   <a id="15122" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="15125" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="15130" class="Symbol">(</a><a id="15131" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">_+</a> <a id="15134" href="#15020" class="Bound">xs</a><a id="15136" class="Symbol">)</a> <a id="15138" class="Symbol">(</a><a id="15139" href="../code/probability/ProbabilityModule.Semirings.html#508" class="Field">+-comm</a> <a id="15146" class="Symbol">(</a><a id="15147" href="#15012" class="Bound">p</a> <a id="15149" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15151" href="#15004" class="Bound">f</a> <a id="15153" href="#15014" class="Bound">x</a><a id="15154" class="Symbol">)</a> <a id="15156" class="Symbol">(</a><a id="15157" href="#15016" class="Bound">q</a> <a id="15159" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15161" href="#15004" class="Bound">f</a> <a id="15163" href="#15018" class="Bound">y</a><a id="15164" class="Symbol">))</a> <a id="15167" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="15173" href="#15016" class="Bound">q</a> <a id="15175" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15177" href="#15004" class="Bound">f</a> <a id="15179" href="#15018" class="Bound">y</a> <a id="15181" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15183" href="#15012" class="Bound">p</a> <a id="15185" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15187" href="#15004" class="Bound">f</a> <a id="15189" href="#15014" class="Bound">x</a> <a id="15191" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15193" href="#15020" class="Bound">xs</a>   <a id="15198" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="15201" href="../code/probability/ProbabilityModule.Semirings.html#276" class="Field">+-assoc</a> <a id="15209" class="Symbol">(</a><a id="15210" href="#15016" class="Bound">q</a> <a id="15212" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15214" href="#15004" class="Bound">f</a> <a id="15216" href="#15018" class="Bound">y</a><a id="15217" class="Symbol">)</a> <a id="15219" class="Symbol">(</a><a id="15220" href="#15012" class="Bound">p</a> <a id="15222" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15224" href="#15004" class="Bound">f</a> <a id="15226" href="#15014" class="Bound">x</a><a id="15227" class="Symbol">)</a> <a id="15229" class="Symbol">(</a><a id="15230" href="#15020" class="Bound">xs</a><a id="15232" class="Symbol">)</a> <a id="15234" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="15240" href="#15016" class="Bound">q</a> <a id="15242" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15244" href="#15004" class="Bound">f</a> <a id="15246" href="#15018" class="Bound">y</a> <a id="15248" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15250" class="Symbol">(</a><a id="15251" href="#15012" class="Bound">p</a> <a id="15253" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15255" href="#15004" class="Bound">f</a> <a id="15257" href="#15014" class="Bound">x</a> <a id="15259" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15261" href="#15020" class="Bound">xs</a><a id="15263" class="Symbol">)</a> <a id="15265" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
  <a id="15269" href="#12635" class="Field Operator">[</a> <a id="15271" href="#14711" class="Function">∫′</a> <a id="15274" href="#15274" class="Bound">f</a> <a id="15276" href="#12635" class="Field Operator">]-del</a> <a id="15282" href="#15282" class="Bound">x</a> <a id="15284" href="#15284" class="Bound">xs</a> <a id="15287" class="Symbol">=</a>
    <a id="15293" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="15296" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="15298" href="#15274" class="Bound">f</a> <a id="15300" href="#15282" class="Bound">x</a> <a id="15302" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15304" href="#15284" class="Bound">xs</a> <a id="15307" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="15310" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="15315" class="Symbol">(</a><a id="15316" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">_+</a> <a id="15319" href="#15284" class="Bound">xs</a><a id="15321" class="Symbol">)</a> <a id="15323" class="Symbol">(</a><a id="15324" href="../code/probability/ProbabilityModule.Semirings.html#403" class="Field">0*</a> <a id="15327" class="Symbol">(</a><a id="15328" href="#15274" class="Bound">f</a> <a id="15330" href="#15282" class="Bound">x</a><a id="15331" class="Symbol">))</a> <a id="15334" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="15340" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="15343" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15345" href="#15284" class="Bound">xs</a>       <a id="15354" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="15357" href="../code/probability/ProbabilityModule.Semirings.html#430" class="Field">0+</a> <a id="15360" class="Symbol">(</a><a id="15361" href="#15284" class="Bound">xs</a><a id="15363" class="Symbol">)</a> <a id="15365" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="15371" href="#15284" class="Bound">xs</a>            <a id="15385" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="15388" class="Keyword">syntax</a> <a id="15395" href="#14645" class="Function">∫</a> <a id="15397" class="Symbol">(λ</a> <a id="15400" class="Bound">x</a> <a id="15402" class="Symbol">→</a> <a id="15404" class="Bound">e</a><a id="15405" class="Symbol">)</a> <a id="15407" class="Symbol">=</a> <a id="15409" class="Function">∫</a> <a id="15411" class="Bound">e</a> <a id="15413" class="Function">𝑑</a> <a id="15415" class="Bound">x</a>

<a id="pure"></a><a id="15418" href="#15418" class="Function">pure</a> <a id="15423" class="Symbol">:</a> <a id="15425" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="15427" class="Symbol">→</a> <a id="15429" href="#8679" class="Datatype">𝒫</a> <a id="15431" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a>
<a id="15433" href="#15418" class="Function">pure</a> <a id="15438" href="#15438" class="Bound">x</a> <a id="15440" class="Symbol">=</a> <a id="15442" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="15445" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="15447" href="#15438" class="Bound">x</a> <a id="15449" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="15451" href="#8715" class="InductiveConstructor">[]</a>

<a id="∪-cons"></a><a id="15455" href="#15455" class="Function">∪-cons</a> <a id="15462" class="Symbol">:</a> <a id="15464" class="Symbol">∀</a> <a id="15466" href="#15466" class="Bound">p</a> <a id="15468" class="Symbol">(</a><a id="15469" href="#15469" class="Bound">x</a> <a id="15471" class="Symbol">:</a> <a id="15473" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="15474" class="Symbol">)</a> <a id="15476" href="#15476" class="Bound">xs</a> <a id="15479" href="#15479" class="Bound">ys</a> <a id="15482" class="Symbol">→</a> <a id="15484" href="#15476" class="Bound">xs</a> <a id="15487" href="#13390" class="Function Operator">∪</a> <a id="15489" href="#15466" class="Bound">p</a> <a id="15491" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="15493" href="#15469" class="Bound">x</a> <a id="15495" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="15497" href="#15479" class="Bound">ys</a> <a id="15500" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="15502" href="#15466" class="Bound">p</a> <a id="15504" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="15506" href="#15469" class="Bound">x</a> <a id="15508" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="15510" href="#15476" class="Bound">xs</a> <a id="15513" href="#13390" class="Function Operator">∪</a> <a id="15515" href="#15479" class="Bound">ys</a>
<a id="15518" href="#15455" class="Function">∪-cons</a> <a id="15525" class="Symbol">=</a> <a id="15527" class="Symbol">λ</a> <a id="15529" href="#15529" class="Bound">p</a> <a id="15531" href="#15531" class="Bound">x</a> <a id="15533" href="#15533" class="Bound">xs</a> <a id="15536" href="#15536" class="Bound">ys</a> <a id="15539" class="Symbol">→</a> <a id="15541" href="#12103" class="Function Operator">⟦</a> <a id="15543" href="#15587" class="Function">∪-cons′</a> <a id="15551" href="#15529" class="Bound">p</a> <a id="15553" href="#15531" class="Bound">x</a> <a id="15555" href="#15536" class="Bound">ys</a> <a id="15558" href="#12103" class="Function Operator">⟧⇓</a> <a id="15561" href="#15533" class="Bound">xs</a>
  <a id="15566" class="Keyword">module</a> <a id="UCons"></a><a id="15573" href="#15573" class="Module">UCons</a> <a id="15579" class="Keyword">where</a>
  <a id="UCons.∪-cons′"></a><a id="15587" href="#15587" class="Function">∪-cons′</a> <a id="15595" class="Symbol">:</a> <a id="15597" class="Symbol">∀</a> <a id="15599" href="#15599" class="Bound">p</a> <a id="15601" href="#15601" class="Bound">x</a> <a id="15603" href="#15603" class="Bound">ys</a> <a id="15606" class="Symbol">→</a> <a id="15608" href="#12139" class="Function">⟦</a> <a id="15610" href="#15610" class="Bound">xs</a> <a id="15613" href="#12139" class="Function">∈𝒫</a> <a id="15616" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="15618" href="#12139" class="Function">⇒</a> <a id="15620" href="#15610" class="Bound">xs</a> <a id="15623" href="#13390" class="Function Operator">∪</a> <a id="15625" href="#15599" class="Bound">p</a> <a id="15627" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="15629" href="#15601" class="Bound">x</a> <a id="15631" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="15633" href="#15603" class="Bound">ys</a> <a id="15636" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="15638" href="#15599" class="Bound">p</a> <a id="15640" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="15642" href="#15601" class="Bound">x</a> <a id="15644" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="15646" href="#15610" class="Bound">xs</a> <a id="15649" href="#13390" class="Function Operator">∪</a> <a id="15651" href="#15603" class="Bound">ys</a> <a id="15654" href="#12139" class="Function">⟧</a>
  <a id="15658" href="#11443" class="Field Operator">⟦</a> <a id="15660" href="#15587" class="Function">∪-cons′</a> <a id="15668" href="#15668" class="Bound">p</a> <a id="15670" href="#15670" class="Bound">x</a> <a id="15672" href="#15672" class="Bound">ys</a> <a id="15675" href="#11443" class="Field Operator">⟧-prop</a> <a id="15682" class="Symbol">=</a> <a id="15684" href="#8921" class="InductiveConstructor">trunc</a> <a id="15690" class="Symbol">_</a> <a id="15692" class="Symbol">_</a>
  <a id="15696" href="#11481" class="Field Operator">⟦</a> <a id="15698" href="#15587" class="Function">∪-cons′</a> <a id="15706" href="#15706" class="Bound">p</a> <a id="15708" href="#15708" class="Bound">x</a> <a id="15710" href="#15710" class="Bound">ys</a> <a id="15713" href="#11481" class="Field Operator">⟧[]</a> <a id="15717" class="Symbol">=</a> <a id="15719" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="15726" href="#11498" class="Field Operator">⟦</a> <a id="15728" href="#15587" class="Function">∪-cons′</a> <a id="15736" href="#15736" class="Bound">p</a> <a id="15738" href="#15738" class="Bound">x</a> <a id="15740" href="#15740" class="Bound">ys</a> <a id="15743" href="#11498" class="Field Operator">⟧</a> <a id="15745" href="#15745" class="Bound">r</a> <a id="15747" href="#11498" class="Field Operator">&amp;</a> <a id="15749" href="#15749" class="Bound">y</a> <a id="15751" href="#11498" class="Field Operator">∷</a> <a id="15753" href="#15753" class="Bound">xs</a> <a id="15756" href="#11498" class="Field Operator">⟨</a> <a id="15758" href="#15758" class="Bound">P</a> <a id="15760" href="#11498" class="Field Operator">⟩</a> <a id="15762" class="Symbol">=</a> <a id="15764" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="15769" class="Symbol">(</a><a id="15770" href="#15745" class="Bound">r</a> <a id="15772" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="15774" href="#15749" class="Bound">y</a> <a id="15776" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="15778" class="Symbol">)</a> <a id="15780" href="#15758" class="Bound">P</a> <a id="15782" href="../code/probability/Cubical.Foundations.Prelude.html#1674" class="Function Operator">;</a> <a id="15784" href="#8824" class="InductiveConstructor">com</a> <a id="15788" href="#15745" class="Bound">r</a> <a id="15790" href="#15749" class="Bound">y</a> <a id="15792" href="#15736" class="Bound">p</a> <a id="15794" href="#15738" class="Bound">x</a> <a id="15796" class="Symbol">(</a><a id="15797" href="#15753" class="Bound">xs</a> <a id="15800" href="#13390" class="Function Operator">∪</a> <a id="15802" href="#15740" class="Bound">ys</a><a id="15804" class="Symbol">)</a>

<a id="⋊-distribʳ"></a><a id="15807" href="#15807" class="Function">⋊-distribʳ</a> <a id="15818" class="Symbol">:</a> <a id="15820" class="Symbol">∀</a> <a id="15822" href="#15822" class="Bound">p</a> <a id="15824" href="#15824" class="Bound">q</a> <a id="15826" class="Symbol">→</a> <a id="15828" class="Symbol">(</a><a id="15829" href="#15829" class="Bound">xs</a> <a id="15832" class="Symbol">:</a> <a id="15834" href="#8679" class="Datatype">𝒫</a> <a id="15836" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="15837" class="Symbol">)</a> <a id="15839" class="Symbol">→</a> <a id="15841" href="#15822" class="Bound">p</a> <a id="15843" href="#14109" class="Function Operator">⋊</a> <a id="15845" href="#15829" class="Bound">xs</a> <a id="15848" href="#13390" class="Function Operator">∪</a> <a id="15850" href="#15824" class="Bound">q</a> <a id="15852" href="#14109" class="Function Operator">⋊</a> <a id="15854" href="#15829" class="Bound">xs</a> <a id="15857" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="15859" class="Symbol">(</a><a id="15860" href="#15822" class="Bound">p</a> <a id="15862" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15864" href="#15824" class="Bound">q</a><a id="15865" class="Symbol">)</a> <a id="15867" href="#14109" class="Function Operator">⋊</a> <a id="15869" href="#15829" class="Bound">xs</a>
<a id="15872" href="#15807" class="Function">⋊-distribʳ</a> <a id="15883" class="Symbol">=</a> <a id="15885" class="Symbol">λ</a> <a id="15887" href="#15887" class="Bound">p</a> <a id="15889" href="#15889" class="Bound">q</a> <a id="15891" class="Symbol">→</a> <a id="15893" href="#12103" class="Function Operator">⟦</a> <a id="15895" href="#15940" class="Function">⋊-distribʳ′</a> <a id="15907" href="#15887" class="Bound">p</a> <a id="15909" href="#15889" class="Bound">q</a> <a id="15911" href="#12103" class="Function Operator">⟧⇓</a>
  <a id="15916" class="Keyword">module</a> <a id="JDistrib"></a><a id="15923" href="#15923" class="Module">JDistrib</a> <a id="15932" class="Keyword">where</a>
  <a id="JDistrib.⋊-distribʳ′"></a><a id="15940" href="#15940" class="Function">⋊-distribʳ′</a> <a id="15952" class="Symbol">:</a> <a id="15954" class="Symbol">∀</a> <a id="15956" href="#15956" class="Bound">p</a> <a id="15958" href="#15958" class="Bound">q</a> <a id="15960" class="Symbol">→</a> <a id="15962" href="#12139" class="Function">⟦</a> <a id="15964" href="#15964" class="Bound">xs</a> <a id="15967" href="#12139" class="Function">∈𝒫</a> <a id="15970" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="15972" href="#12139" class="Function">⇒</a> <a id="15974" href="#15956" class="Bound">p</a> <a id="15976" href="#14109" class="Function Operator">⋊</a> <a id="15978" href="#15964" class="Bound">xs</a> <a id="15981" href="#13390" class="Function Operator">∪</a> <a id="15983" href="#15958" class="Bound">q</a> <a id="15985" href="#14109" class="Function Operator">⋊</a> <a id="15987" href="#15964" class="Bound">xs</a> <a id="15990" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="15992" class="Symbol">(</a><a id="15993" href="#15956" class="Bound">p</a> <a id="15995" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="15997" href="#15958" class="Bound">q</a><a id="15998" class="Symbol">)</a> <a id="16000" href="#14109" class="Function Operator">⋊</a> <a id="16002" href="#15964" class="Bound">xs</a> <a id="16005" href="#12139" class="Function">⟧</a>
  <a id="16009" href="#11443" class="Field Operator">⟦</a> <a id="16011" href="#15940" class="Function">⋊-distribʳ′</a> <a id="16023" href="#16023" class="Bound">p</a> <a id="16025" href="#16025" class="Bound">q</a> <a id="16027" href="#11443" class="Field Operator">⟧-prop</a> <a id="16034" class="Symbol">=</a> <a id="16036" href="#8921" class="InductiveConstructor">trunc</a> <a id="16042" class="Symbol">_</a> <a id="16044" class="Symbol">_</a>
  <a id="16048" href="#11481" class="Field Operator">⟦</a> <a id="16050" href="#15940" class="Function">⋊-distribʳ′</a> <a id="16062" href="#16062" class="Bound">p</a> <a id="16064" href="#16064" class="Bound">q</a> <a id="16066" href="#11481" class="Field Operator">⟧[]</a> <a id="16070" class="Symbol">=</a> <a id="16072" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="16079" href="#11498" class="Field Operator">⟦</a> <a id="16081" href="#15940" class="Function">⋊-distribʳ′</a> <a id="16093" href="#16093" class="Bound">p</a> <a id="16095" href="#16095" class="Bound">q</a> <a id="16097" href="#11498" class="Field Operator">⟧</a> <a id="16099" href="#16099" class="Bound">r</a> <a id="16101" href="#11498" class="Field Operator">&amp;</a> <a id="16103" href="#16103" class="Bound">x</a> <a id="16105" href="#11498" class="Field Operator">∷</a> <a id="16107" href="#16107" class="Bound">xs</a> <a id="16110" href="#11498" class="Field Operator">⟨</a> <a id="16112" href="#16112" class="Bound">P</a> <a id="16114" href="#11498" class="Field Operator">⟩</a> <a id="16116" class="Symbol">=</a>
    <a id="16122" href="#16093" class="Bound">p</a> <a id="16124" href="#14109" class="Function Operator">⋊</a> <a id="16126" class="Symbol">(</a><a id="16127" href="#16099" class="Bound">r</a> <a id="16129" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16131" href="#16103" class="Bound">x</a> <a id="16133" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16135" href="#16107" class="Bound">xs</a><a id="16137" class="Symbol">)</a> <a id="16139" href="#13390" class="Function Operator">∪</a> <a id="16141" href="#16095" class="Bound">q</a> <a id="16143" href="#14109" class="Function Operator">⋊</a> <a id="16145" class="Symbol">(</a><a id="16146" href="#16099" class="Bound">r</a> <a id="16148" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16150" href="#16103" class="Bound">x</a> <a id="16152" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16154" href="#16107" class="Bound">xs</a><a id="16156" class="Symbol">)</a>   <a id="16160" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="16163" href="#15455" class="Function">∪-cons</a> <a id="16170" class="Symbol">(</a><a id="16171" href="#16095" class="Bound">q</a> <a id="16173" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16175" href="#16099" class="Bound">r</a><a id="16176" class="Symbol">)</a> <a id="16178" href="#16103" class="Bound">x</a> <a id="16180" class="Symbol">(</a><a id="16181" href="#16093" class="Bound">p</a> <a id="16183" href="#14109" class="Function Operator">⋊</a> <a id="16185" class="Symbol">(</a><a id="16186" href="#16099" class="Bound">r</a> <a id="16188" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16190" href="#16103" class="Bound">x</a> <a id="16192" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16194" href="#16107" class="Bound">xs</a><a id="16196" class="Symbol">))</a> <a id="16199" class="Symbol">(</a><a id="16200" href="#16095" class="Bound">q</a> <a id="16202" href="#14109" class="Function Operator">⋊</a> <a id="16204" href="#16107" class="Bound">xs</a><a id="16206" class="Symbol">)</a>  <a id="16209" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="16215" href="#16095" class="Bound">q</a> <a id="16217" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16219" href="#16099" class="Bound">r</a> <a id="16221" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16223" href="#16103" class="Bound">x</a> <a id="16225" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16227" href="#16093" class="Bound">p</a> <a id="16229" href="#14109" class="Function Operator">⋊</a> <a id="16231" class="Symbol">(</a><a id="16232" href="#16099" class="Bound">r</a> <a id="16234" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16236" href="#16103" class="Bound">x</a> <a id="16238" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16240" href="#16107" class="Bound">xs</a><a id="16242" class="Symbol">)</a> <a id="16244" href="#13390" class="Function Operator">∪</a> <a id="16246" href="#16095" class="Bound">q</a> <a id="16248" href="#14109" class="Function Operator">⋊</a> <a id="16250" href="#16107" class="Bound">xs</a> <a id="16253" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="16256" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="16261" class="Symbol">(</a><a id="16262" href="#13390" class="Function Operator">_∪</a> <a id="16265" href="#16095" class="Bound">q</a> <a id="16267" href="#14109" class="Function Operator">⋊</a> <a id="16269" href="#16107" class="Bound">xs</a><a id="16271" class="Symbol">)</a> <a id="16273" class="Symbol">(</a><a id="16274" href="#8767" class="InductiveConstructor">dup</a> <a id="16278" class="Symbol">(</a><a id="16279" href="#16095" class="Bound">q</a> <a id="16281" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16283" href="#16099" class="Bound">r</a><a id="16284" class="Symbol">)</a> <a id="16286" class="Symbol">(</a><a id="16287" href="#16093" class="Bound">p</a> <a id="16289" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16291" href="#16099" class="Bound">r</a><a id="16292" class="Symbol">)</a> <a id="16294" href="#16103" class="Bound">x</a> <a id="16296" class="Symbol">(</a><a id="16297" href="#16093" class="Bound">p</a> <a id="16299" href="#14109" class="Function Operator">⋊</a> <a id="16301" href="#16107" class="Bound">xs</a><a id="16303" class="Symbol">))</a> <a id="16306" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="16312" href="#16095" class="Bound">q</a> <a id="16314" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16316" href="#16099" class="Bound">r</a> <a id="16318" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16320" href="#16093" class="Bound">p</a> <a id="16322" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16324" href="#16099" class="Bound">r</a> <a id="16326" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16328" href="#16103" class="Bound">x</a> <a id="16330" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16332" href="#16093" class="Bound">p</a> <a id="16334" href="#14109" class="Function Operator">⋊</a> <a id="16336" href="#16107" class="Bound">xs</a> <a id="16339" href="#13390" class="Function Operator">∪</a> <a id="16341" href="#16095" class="Bound">q</a> <a id="16343" href="#14109" class="Function Operator">⋊</a> <a id="16345" href="#16107" class="Bound">xs</a>   <a id="16350" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="16354" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="16359" class="Symbol">(</a><a id="16360" href="#8727" class="InductiveConstructor Operator">_&amp;</a> <a id="16363" href="#16103" class="Bound">x</a> <a id="16365" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16367" class="Symbol">(</a><a id="16368" href="#16093" class="Bound">p</a> <a id="16370" href="#14109" class="Function Operator">⋊</a> <a id="16372" href="#16107" class="Bound">xs</a> <a id="16375" href="#13390" class="Function Operator">∪</a> <a id="16377" href="#16095" class="Bound">q</a> <a id="16379" href="#14109" class="Function Operator">⋊</a> <a id="16381" href="#16107" class="Bound">xs</a><a id="16383" class="Symbol">))</a> <a id="16386" class="Symbol">(</a><a id="16387" href="../code/probability/ProbabilityModule.Semirings.html#592" class="Field">⟨+⟩*</a> <a id="16392" href="#16095" class="Bound">q</a> <a id="16394" href="#16093" class="Bound">p</a> <a id="16396" href="#16099" class="Bound">r</a><a id="16397" class="Symbol">)</a> <a id="16399" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
    <a id="16405" class="Symbol">(</a><a id="16406" href="#16095" class="Bound">q</a> <a id="16408" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16410" href="#16093" class="Bound">p</a><a id="16411" class="Symbol">)</a> <a id="16413" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16415" href="#16099" class="Bound">r</a> <a id="16417" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16419" href="#16103" class="Bound">x</a> <a id="16421" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16423" href="#16093" class="Bound">p</a> <a id="16425" href="#14109" class="Function Operator">⋊</a> <a id="16427" href="#16107" class="Bound">xs</a> <a id="16430" href="#13390" class="Function Operator">∪</a> <a id="16432" href="#16095" class="Bound">q</a> <a id="16434" href="#14109" class="Function Operator">⋊</a> <a id="16436" href="#16107" class="Bound">xs</a>     <a id="16443" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="16446" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="16451" class="Symbol">((</a><a id="16453" href="#16095" class="Bound">q</a> <a id="16455" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16457" href="#16093" class="Bound">p</a><a id="16458" class="Symbol">)</a> <a id="16460" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16462" href="#16099" class="Bound">r</a> <a id="16464" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16466" href="#16103" class="Bound">x</a> <a id="16468" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="16470" class="Symbol">)</a> <a id="16472" href="#16112" class="Bound">P</a> <a id="16474" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="16480" class="Symbol">(</a><a id="16481" href="#16095" class="Bound">q</a> <a id="16483" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16485" href="#16093" class="Bound">p</a><a id="16486" class="Symbol">)</a> <a id="16488" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16490" href="#16099" class="Bound">r</a> <a id="16492" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16494" href="#16103" class="Bound">x</a> <a id="16496" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16498" class="Symbol">(</a><a id="16499" href="#16093" class="Bound">p</a> <a id="16501" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16503" href="#16095" class="Bound">q</a><a id="16504" class="Symbol">)</a> <a id="16506" href="#14109" class="Function Operator">⋊</a> <a id="16508" href="#16107" class="Bound">xs</a>        <a id="16518" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="16521" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="16526" class="Symbol">(λ</a> <a id="16529" href="#16529" class="Bound">pq</a> <a id="16532" class="Symbol">→</a> <a id="16534" href="#16529" class="Bound">pq</a> <a id="16537" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16539" href="#16099" class="Bound">r</a> <a id="16541" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16543" href="#16103" class="Bound">x</a> <a id="16545" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16547" class="Symbol">(</a><a id="16548" href="#16093" class="Bound">p</a> <a id="16550" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16552" href="#16095" class="Bound">q</a><a id="16553" class="Symbol">)</a> <a id="16555" href="#14109" class="Function Operator">⋊</a> <a id="16557" href="#16107" class="Bound">xs</a><a id="16559" class="Symbol">)</a> <a id="16561" class="Symbol">(</a><a id="16562" href="../code/probability/ProbabilityModule.Semirings.html#508" class="Field">+-comm</a> <a id="16569" href="#16095" class="Bound">q</a> <a id="16571" href="#16093" class="Bound">p</a><a id="16572" class="Symbol">)</a> <a id="16574" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="16580" class="Symbol">(</a><a id="16581" href="#16093" class="Bound">p</a> <a id="16583" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16585" href="#16095" class="Bound">q</a><a id="16586" class="Symbol">)</a> <a id="16588" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="16590" href="#16099" class="Bound">r</a> <a id="16592" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16594" href="#16103" class="Bound">x</a> <a id="16596" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16598" class="Symbol">(</a><a id="16599" href="#16093" class="Bound">p</a> <a id="16601" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16603" href="#16095" class="Bound">q</a><a id="16604" class="Symbol">)</a> <a id="16606" href="#14109" class="Function Operator">⋊</a> <a id="16608" href="#16107" class="Bound">xs</a>        <a id="16618" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="16626" href="#14109" class="Function Operator">_⋊_</a> <a id="16630" class="Symbol">(</a><a id="16631" href="#16093" class="Bound">p</a> <a id="16633" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="16635" href="#16095" class="Bound">q</a><a id="16636" class="Symbol">)</a> <a id="16638" class="Symbol">(</a><a id="16639" href="#16099" class="Bound">r</a> <a id="16641" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16643" href="#16103" class="Bound">x</a> <a id="16645" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16647" href="#16107" class="Bound">xs</a><a id="16649" class="Symbol">)</a> <a id="16651" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="⋊-distribˡ"></a><a id="16654" href="#16654" class="Function">⋊-distribˡ</a> <a id="16665" class="Symbol">:</a> <a id="16667" class="Symbol">∀</a> <a id="16669" href="#16669" class="Bound">p</a> <a id="16671" class="Symbol">→</a> <a id="16673" class="Symbol">(</a><a id="16674" href="#16674" class="Bound">xs</a> <a id="16677" href="#16677" class="Bound">ys</a> <a id="16680" class="Symbol">:</a> <a id="16682" href="#8679" class="Datatype">𝒫</a> <a id="16684" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="16685" class="Symbol">)</a> <a id="16687" class="Symbol">→</a> <a id="16689" href="#16669" class="Bound">p</a> <a id="16691" href="#14109" class="Function Operator">⋊</a> <a id="16693" href="#16674" class="Bound">xs</a> <a id="16696" href="#13390" class="Function Operator">∪</a> <a id="16698" href="#16669" class="Bound">p</a> <a id="16700" href="#14109" class="Function Operator">⋊</a> <a id="16702" href="#16677" class="Bound">ys</a> <a id="16705" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="16707" href="#16669" class="Bound">p</a> <a id="16709" href="#14109" class="Function Operator">⋊</a> <a id="16711" class="Symbol">(</a><a id="16712" href="#16674" class="Bound">xs</a> <a id="16715" href="#13390" class="Function Operator">∪</a> <a id="16717" href="#16677" class="Bound">ys</a><a id="16719" class="Symbol">)</a>
<a id="16721" href="#16654" class="Function">⋊-distribˡ</a> <a id="16732" class="Symbol">=</a> <a id="16734" class="Symbol">λ</a> <a id="16736" href="#16736" class="Bound">p</a> <a id="16738" href="#16738" class="Bound">xs</a> <a id="16741" href="#16741" class="Bound">ys</a> <a id="16744" class="Symbol">→</a> <a id="16746" href="#12103" class="Function Operator">⟦</a> <a id="16748" href="#16798" class="Function">⋊-distribˡ′</a> <a id="16760" href="#16736" class="Bound">p</a> <a id="16762" href="#16741" class="Bound">ys</a> <a id="16765" href="#12103" class="Function Operator">⟧⇓</a> <a id="16768" href="#16738" class="Bound">xs</a>
  <a id="16773" class="Keyword">module</a> <a id="JDistribL"></a><a id="16780" href="#16780" class="Module">JDistribL</a> <a id="16790" class="Keyword">where</a>
  <a id="JDistribL.⋊-distribˡ′"></a><a id="16798" href="#16798" class="Function">⋊-distribˡ′</a> <a id="16810" class="Symbol">:</a> <a id="16812" class="Symbol">∀</a> <a id="16814" href="#16814" class="Bound">p</a> <a id="16816" href="#16816" class="Bound">ys</a> <a id="16819" class="Symbol">→</a> <a id="16821" href="#12139" class="Function">⟦</a> <a id="16823" href="#16823" class="Bound">xs</a> <a id="16826" href="#12139" class="Function">∈𝒫</a> <a id="16829" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="16831" href="#12139" class="Function">⇒</a> <a id="16833" href="#16814" class="Bound">p</a> <a id="16835" href="#14109" class="Function Operator">⋊</a> <a id="16837" href="#16823" class="Bound">xs</a> <a id="16840" href="#13390" class="Function Operator">∪</a> <a id="16842" href="#16814" class="Bound">p</a> <a id="16844" href="#14109" class="Function Operator">⋊</a> <a id="16846" href="#16816" class="Bound">ys</a> <a id="16849" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="16851" href="#16814" class="Bound">p</a> <a id="16853" href="#14109" class="Function Operator">⋊</a> <a id="16855" class="Symbol">(</a><a id="16856" href="#16823" class="Bound">xs</a> <a id="16859" href="#13390" class="Function Operator">∪</a> <a id="16861" href="#16816" class="Bound">ys</a><a id="16863" class="Symbol">)</a> <a id="16865" href="#12139" class="Function">⟧</a>
  <a id="16869" href="#11443" class="Field Operator">⟦</a> <a id="16871" href="#16798" class="Function">⋊-distribˡ′</a> <a id="16883" href="#16883" class="Bound">p</a> <a id="16885" href="#16885" class="Bound">ys</a> <a id="16888" href="#11443" class="Field Operator">⟧-prop</a> <a id="16895" class="Symbol">=</a> <a id="16897" href="#8921" class="InductiveConstructor">trunc</a> <a id="16903" class="Symbol">_</a> <a id="16905" class="Symbol">_</a>
  <a id="16909" href="#11481" class="Field Operator">⟦</a> <a id="16911" href="#16798" class="Function">⋊-distribˡ′</a> <a id="16923" href="#16923" class="Bound">p</a> <a id="16925" href="#16925" class="Bound">ys</a> <a id="16928" href="#11481" class="Field Operator">⟧[]</a> <a id="16932" class="Symbol">=</a> <a id="16934" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="16941" href="#11498" class="Field Operator">⟦</a> <a id="16943" href="#16798" class="Function">⋊-distribˡ′</a> <a id="16955" href="#16955" class="Bound">p</a> <a id="16957" href="#16957" class="Bound">ys</a> <a id="16960" href="#11498" class="Field Operator">⟧</a> <a id="16962" href="#16962" class="Bound">q</a> <a id="16964" href="#11498" class="Field Operator">&amp;</a> <a id="16966" href="#16966" class="Bound">x</a> <a id="16968" href="#11498" class="Field Operator">∷</a> <a id="16970" href="#16970" class="Bound">xs</a> <a id="16973" href="#11498" class="Field Operator">⟨</a> <a id="16975" href="#16975" class="Bound">P</a> <a id="16977" href="#11498" class="Field Operator">⟩</a> <a id="16979" class="Symbol">=</a>
    <a id="16985" href="#16955" class="Bound">p</a> <a id="16987" href="#14109" class="Function Operator">⋊</a> <a id="16989" class="Symbol">(</a><a id="16990" href="#16962" class="Bound">q</a> <a id="16992" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="16994" href="#16966" class="Bound">x</a> <a id="16996" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="16998" href="#16970" class="Bound">xs</a><a id="17000" class="Symbol">)</a> <a id="17002" href="#13390" class="Function Operator">∪</a> <a id="17004" href="#16955" class="Bound">p</a> <a id="17006" href="#14109" class="Function Operator">⋊</a> <a id="17008" href="#16957" class="Bound">ys</a> <a id="17011" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="17019" href="#16955" class="Bound">p</a> <a id="17021" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="17023" href="#16962" class="Bound">q</a> <a id="17025" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17027" href="#16966" class="Bound">x</a> <a id="17029" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="17031" href="#16955" class="Bound">p</a> <a id="17033" href="#14109" class="Function Operator">⋊</a> <a id="17035" href="#16970" class="Bound">xs</a> <a id="17038" href="#13390" class="Function Operator">∪</a> <a id="17040" href="#16955" class="Bound">p</a> <a id="17042" href="#14109" class="Function Operator">⋊</a> <a id="17044" href="#16957" class="Bound">ys</a> <a id="17047" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="17050" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="17055" class="Symbol">(</a><a id="17056" href="#16955" class="Bound">p</a> <a id="17058" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="17060" href="#16962" class="Bound">q</a> <a id="17062" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17064" href="#16966" class="Bound">x</a> <a id="17066" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="17068" class="Symbol">)</a> <a id="17070" href="#16975" class="Bound">P</a> <a id="17072" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="17078" href="#16955" class="Bound">p</a> <a id="17080" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="17082" href="#16962" class="Bound">q</a> <a id="17084" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17086" href="#16966" class="Bound">x</a> <a id="17088" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="17090" href="#16955" class="Bound">p</a> <a id="17092" href="#14109" class="Function Operator">⋊</a> <a id="17094" class="Symbol">(</a><a id="17095" href="#16970" class="Bound">xs</a> <a id="17098" href="#13390" class="Function Operator">∪</a> <a id="17100" href="#16957" class="Bound">ys</a><a id="17102" class="Symbol">)</a> <a id="17104" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="17112" href="#16955" class="Bound">p</a> <a id="17114" href="#14109" class="Function Operator">⋊</a> <a id="17116" class="Symbol">((</a><a id="17118" href="#16962" class="Bound">q</a> <a id="17120" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17122" href="#16966" class="Bound">x</a> <a id="17124" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="17126" href="#16970" class="Bound">xs</a><a id="17128" class="Symbol">)</a> <a id="17130" href="#13390" class="Function Operator">∪</a> <a id="17132" href="#16957" class="Bound">ys</a><a id="17134" class="Symbol">)</a> <a id="17136" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>


<a id="∪-idʳ"></a><a id="17140" href="#17140" class="Function">∪-idʳ</a> <a id="17146" class="Symbol">:</a> <a id="17148" class="Symbol">(</a><a id="17149" href="#17149" class="Bound">xs</a> <a id="17152" class="Symbol">:</a> <a id="17154" href="#8679" class="Datatype">𝒫</a> <a id="17156" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="17157" class="Symbol">)</a> <a id="17159" class="Symbol">→</a> <a id="17161" href="#17149" class="Bound">xs</a> <a id="17164" href="#13390" class="Function Operator">∪</a> <a id="17166" href="#8715" class="InductiveConstructor">[]</a> <a id="17169" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="17171" href="#17149" class="Bound">xs</a>
<a id="17174" href="#17140" class="Function">∪-idʳ</a> <a id="17180" class="Symbol">=</a> <a id="17182" href="#12103" class="Function Operator">⟦</a> <a id="17184" href="#17216" class="Function">∪-idʳ′</a> <a id="17191" href="#12103" class="Function Operator">⟧⇓</a>
  <a id="17196" class="Keyword">module</a> <a id="UIdR"></a><a id="17203" href="#17203" class="Module">UIdR</a> <a id="17208" class="Keyword">where</a>
  <a id="UIdR.∪-idʳ′"></a><a id="17216" href="#17216" class="Function">∪-idʳ′</a> <a id="17223" class="Symbol">:</a> <a id="17225" href="#12139" class="Function">⟦</a> <a id="17227" href="#17227" class="Bound">xs</a> <a id="17230" href="#12139" class="Function">∈𝒫</a> <a id="17233" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="17235" href="#12139" class="Function">⇒</a> <a id="17237" href="#17227" class="Bound">xs</a> <a id="17240" href="#13390" class="Function Operator">∪</a> <a id="17242" href="#8715" class="InductiveConstructor">[]</a> <a id="17245" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="17247" href="#17227" class="Bound">xs</a> <a id="17250" href="#12139" class="Function">⟧</a>
  <a id="17254" href="#11443" class="Field Operator">⟦</a> <a id="17256" href="#17216" class="Function">∪-idʳ′</a> <a id="17263" href="#11443" class="Field Operator">⟧-prop</a> <a id="17270" class="Symbol">=</a> <a id="17272" href="#8921" class="InductiveConstructor">trunc</a> <a id="17278" class="Symbol">_</a> <a id="17280" class="Symbol">_</a>
  <a id="17284" href="#11481" class="Field Operator">⟦</a> <a id="17286" href="#17216" class="Function">∪-idʳ′</a> <a id="17293" href="#11481" class="Field Operator">⟧[]</a> <a id="17297" class="Symbol">=</a> <a id="17299" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="17306" href="#11498" class="Field Operator">⟦</a> <a id="17308" href="#17216" class="Function">∪-idʳ′</a> <a id="17315" href="#11498" class="Field Operator">⟧</a> <a id="17317" href="#17317" class="Bound">p</a> <a id="17319" href="#11498" class="Field Operator">&amp;</a> <a id="17321" href="#17321" class="Bound">x</a> <a id="17323" href="#11498" class="Field Operator">∷</a> <a id="17325" href="#17325" class="Bound">xs</a> <a id="17328" href="#11498" class="Field Operator">⟨</a> <a id="17330" href="#17330" class="Bound">P</a> <a id="17332" href="#11498" class="Field Operator">⟩</a> <a id="17334" class="Symbol">=</a> <a id="17336" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="17341" class="Symbol">(</a><a id="17342" href="#17317" class="Bound">p</a> <a id="17344" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17346" href="#17321" class="Bound">x</a> <a id="17348" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="17350" class="Symbol">)</a> <a id="17352" href="#17330" class="Bound">P</a>

<a id="∪-comm"></a><a id="17355" href="#17355" class="Function">∪-comm</a> <a id="17362" class="Symbol">:</a> <a id="17364" class="Symbol">(</a><a id="17365" href="#17365" class="Bound">xs</a> <a id="17368" href="#17368" class="Bound">ys</a> <a id="17371" class="Symbol">:</a> <a id="17373" href="#8679" class="Datatype">𝒫</a> <a id="17375" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="17376" class="Symbol">)</a> <a id="17378" class="Symbol">→</a> <a id="17380" href="#17365" class="Bound">xs</a> <a id="17383" href="#13390" class="Function Operator">∪</a> <a id="17385" href="#17368" class="Bound">ys</a> <a id="17388" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="17390" href="#17368" class="Bound">ys</a> <a id="17393" href="#13390" class="Function Operator">∪</a> <a id="17395" href="#17365" class="Bound">xs</a>
<a id="17398" href="#17355" class="Function">∪-comm</a> <a id="17405" class="Symbol">=</a> <a id="17407" class="Symbol">λ</a> <a id="17409" href="#17409" class="Bound">xs</a> <a id="17412" href="#17412" class="Bound">ys</a> <a id="17415" class="Symbol">→</a> <a id="17417" href="#12103" class="Function Operator">⟦</a> <a id="17419" href="#17459" class="Function">∪-comm′</a> <a id="17427" href="#17412" class="Bound">ys</a> <a id="17430" href="#12103" class="Function Operator">⟧⇓</a> <a id="17433" href="#17409" class="Bound">xs</a>
  <a id="17438" class="Keyword">module</a> <a id="UComm"></a><a id="17445" href="#17445" class="Module">UComm</a> <a id="17451" class="Keyword">where</a>
  <a id="UComm.∪-comm′"></a><a id="17459" href="#17459" class="Function">∪-comm′</a> <a id="17467" class="Symbol">:</a> <a id="17469" class="Symbol">∀</a> <a id="17471" href="#17471" class="Bound">ys</a> <a id="17474" class="Symbol">→</a> <a id="17476" href="#12139" class="Function">⟦</a> <a id="17478" href="#17478" class="Bound">xs</a> <a id="17481" href="#12139" class="Function">∈𝒫</a> <a id="17484" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="17486" href="#12139" class="Function">⇒</a> <a id="17488" href="#17478" class="Bound">xs</a> <a id="17491" href="#13390" class="Function Operator">∪</a> <a id="17493" href="#17471" class="Bound">ys</a> <a id="17496" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="17498" href="#17471" class="Bound">ys</a> <a id="17501" href="#13390" class="Function Operator">∪</a> <a id="17503" href="#17478" class="Bound">xs</a> <a id="17506" href="#12139" class="Function">⟧</a>
  <a id="17510" href="#11443" class="Field Operator">⟦</a> <a id="17512" href="#17459" class="Function">∪-comm′</a> <a id="17520" href="#17520" class="Bound">ys</a> <a id="17523" href="#11443" class="Field Operator">⟧-prop</a> <a id="17530" class="Symbol">=</a> <a id="17532" href="#8921" class="InductiveConstructor">trunc</a> <a id="17538" class="Symbol">_</a> <a id="17540" class="Symbol">_</a>
  <a id="17544" href="#11481" class="Field Operator">⟦</a> <a id="17546" href="#17459" class="Function">∪-comm′</a> <a id="17554" href="#17554" class="Bound">ys</a> <a id="17557" href="#11481" class="Field Operator">⟧[]</a> <a id="17561" class="Symbol">=</a> <a id="17563" href="../code/probability/Cubical.Foundations.Prelude.html#864" class="Function">sym</a> <a id="17567" class="Symbol">(</a><a id="17568" href="#17140" class="Function">∪-idʳ</a> <a id="17574" href="#17554" class="Bound">ys</a><a id="17576" class="Symbol">)</a>
  <a id="17580" href="#11498" class="Field Operator">⟦</a> <a id="17582" href="#17459" class="Function">∪-comm′</a> <a id="17590" href="#17590" class="Bound">ys</a> <a id="17593" href="#11498" class="Field Operator">⟧</a> <a id="17595" href="#17595" class="Bound">p</a> <a id="17597" href="#11498" class="Field Operator">&amp;</a> <a id="17599" href="#17599" class="Bound">x</a> <a id="17601" href="#11498" class="Field Operator">∷</a> <a id="17603" href="#17603" class="Bound">xs</a> <a id="17606" href="#11498" class="Field Operator">⟨</a> <a id="17608" href="#17608" class="Bound">P</a> <a id="17610" href="#11498" class="Field Operator">⟩</a> <a id="17612" class="Symbol">=</a> <a id="17614" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="17619" class="Symbol">(</a><a id="17620" href="#17595" class="Bound">p</a> <a id="17622" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17624" href="#17599" class="Bound">x</a> <a id="17626" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="17628" class="Symbol">)</a> <a id="17630" href="#17608" class="Bound">P</a> <a id="17632" href="../code/probability/Cubical.Foundations.Prelude.html#1674" class="Function Operator">;</a> <a id="17634" href="../code/probability/Cubical.Foundations.Prelude.html#864" class="Function">sym</a> <a id="17638" class="Symbol">(</a><a id="17639" href="#15455" class="Function">∪-cons</a> <a id="17646" href="#17595" class="Bound">p</a> <a id="17648" href="#17599" class="Bound">x</a> <a id="17650" href="#17590" class="Bound">ys</a> <a id="17653" href="#17603" class="Bound">xs</a><a id="17655" class="Symbol">)</a>

<a id="0⋊"></a><a id="17658" href="#17658" class="Function">0⋊</a> <a id="17661" class="Symbol">:</a> <a id="17663" class="Symbol">(</a><a id="17664" href="#17664" class="Bound">xs</a> <a id="17667" class="Symbol">:</a> <a id="17669" href="#8679" class="Datatype">𝒫</a> <a id="17671" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="17672" class="Symbol">)</a> <a id="17674" class="Symbol">→</a> <a id="17676" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17679" href="#14109" class="Function Operator">⋊</a> <a id="17681" href="#17664" class="Bound">xs</a> <a id="17684" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="17686" href="#8715" class="InductiveConstructor">[]</a>
<a id="17689" href="#17658" class="Function">0⋊</a> <a id="17692" class="Symbol">=</a> <a id="17694" href="#12103" class="Function Operator">⟦</a> <a id="17696" href="#17726" class="Function">0⋊′</a> <a id="17700" href="#12103" class="Function Operator">⟧⇓</a>
  <a id="17705" class="Keyword">module</a> <a id="ZeroJ"></a><a id="17712" href="#17712" class="Module">ZeroJ</a> <a id="17718" class="Keyword">where</a>
  <a id="ZeroJ.0⋊′"></a><a id="17726" href="#17726" class="Function">0⋊′</a> <a id="17730" class="Symbol">:</a> <a id="17732" href="#12139" class="Function">⟦</a> <a id="17734" href="#17734" class="Bound">xs</a> <a id="17737" href="#12139" class="Function">∈𝒫</a> <a id="17740" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="17742" href="#12139" class="Function">⇒</a> <a id="17744" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17747" href="#14109" class="Function Operator">⋊</a> <a id="17749" href="#17734" class="Bound">xs</a> <a id="17752" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="17754" href="#8715" class="InductiveConstructor">[]</a> <a id="17757" href="#12139" class="Function">⟧</a>
  <a id="17761" href="#11443" class="Field Operator">⟦</a> <a id="17763" href="#17726" class="Function">0⋊′</a> <a id="17767" href="#11443" class="Field Operator">⟧-prop</a> <a id="17774" class="Symbol">=</a> <a id="17776" href="#8921" class="InductiveConstructor">trunc</a> <a id="17782" class="Symbol">_</a> <a id="17784" class="Symbol">_</a>
  <a id="17788" href="#11481" class="Field Operator">⟦</a> <a id="17790" href="#17726" class="Function">0⋊′</a> <a id="17794" href="#11481" class="Field Operator">⟧[]</a> <a id="17798" class="Symbol">=</a> <a id="17800" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="17807" href="#11498" class="Field Operator">⟦</a> <a id="17809" href="#17726" class="Function">0⋊′</a> <a id="17813" href="#11498" class="Field Operator">⟧</a> <a id="17815" href="#17815" class="Bound">p</a> <a id="17817" href="#11498" class="Field Operator">&amp;</a> <a id="17819" href="#17819" class="Bound">x</a> <a id="17821" href="#11498" class="Field Operator">∷</a> <a id="17823" href="#17823" class="Bound">xs</a> <a id="17826" href="#11498" class="Field Operator">⟨</a> <a id="17828" href="#17828" class="Bound">P</a> <a id="17830" href="#11498" class="Field Operator">⟩</a> <a id="17832" class="Symbol">=</a>
    <a id="17838" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17841" href="#14109" class="Function Operator">⋊</a> <a id="17843" class="Symbol">(</a><a id="17844" href="#17815" class="Bound">p</a> <a id="17846" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17848" href="#17819" class="Bound">x</a> <a id="17850" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="17852" href="#17823" class="Bound">xs</a><a id="17854" class="Symbol">)</a>    <a id="17859" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="17867" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17870" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="17872" href="#17815" class="Bound">p</a> <a id="17874" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17876" href="#17819" class="Bound">x</a> <a id="17878" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="17880" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17883" href="#14109" class="Function Operator">⋊</a> <a id="17885" href="#17823" class="Bound">xs</a> <a id="17888" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="17891" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="17896" class="Symbol">(</a><a id="17897" href="#8727" class="InductiveConstructor Operator">_&amp;</a> <a id="17900" href="#17819" class="Bound">x</a> <a id="17902" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="17904" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17907" href="#14109" class="Function Operator">⋊</a> <a id="17909" href="#17823" class="Bound">xs</a><a id="17911" class="Symbol">)</a> <a id="17913" class="Symbol">(</a><a id="17914" href="../code/probability/ProbabilityModule.Semirings.html#403" class="Field">0*</a> <a id="17917" href="#17815" class="Bound">p</a><a id="17918" class="Symbol">)</a> <a id="17920" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="17926" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17929" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="17931" href="#17819" class="Bound">x</a> <a id="17933" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="17935" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17938" href="#14109" class="Function Operator">⋊</a> <a id="17940" href="#17823" class="Bound">xs</a>     <a id="17947" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="17950" href="#8887" class="InductiveConstructor">del</a> <a id="17954" href="#17819" class="Bound">x</a> <a id="17956" class="Symbol">(</a><a id="17957" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17960" href="#14109" class="Function Operator">⋊</a> <a id="17962" href="#17823" class="Bound">xs</a><a id="17964" class="Symbol">)</a> <a id="17966" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="17972" href="../code/probability/ProbabilityModule.Semirings.html#254" class="Field">0#</a> <a id="17975" href="#14109" class="Function Operator">⋊</a> <a id="17977" href="#17823" class="Bound">xs</a>              <a id="17993" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="17996" href="#17828" class="Bound">P</a> <a id="17998" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="18004" href="#8715" class="InductiveConstructor">[]</a> <a id="18007" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
</pre>
</details>
<p>However, I <em>can</em> demonstrate the monadic bind:</p>
<pre class="Agda"><a id="_&gt;&gt;=_"></a><a id="18081" href="#18081" class="Function Operator">_&gt;&gt;=_</a> <a id="18087" class="Symbol">:</a> <a id="18089" href="#8679" class="Datatype">𝒫</a> <a id="18091" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="18093" class="Symbol">→</a> <a id="18095" class="Symbol">(</a><a id="18096" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="18098" class="Symbol">→</a> <a id="18100" href="#8679" class="Datatype">𝒫</a> <a id="18102" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="18103" class="Symbol">)</a> <a id="18105" class="Symbol">→</a> <a id="18107" href="#8679" class="Datatype">𝒫</a> <a id="18109" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a>
<a id="18111" href="#18111" class="Bound">xs</a> <a id="18114" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="18118" href="#18118" class="Bound">f</a> <a id="18120" class="Symbol">=</a> <a id="18122" href="#12874" class="Function Operator">[</a> <a id="18124" href="#18118" class="Bound">f</a> <a id="18126" href="#18158" class="Function Operator">=&lt;&lt;</a> <a id="18130" href="#12874" class="Function Operator">]↓</a> <a id="18133" href="#18111" class="Bound">xs</a>
  <a id="18138" class="Keyword">module</a> <a id="Bind"></a><a id="18145" href="#18145" class="Module">Bind</a> <a id="18150" class="Keyword">where</a>
  <a id="Bind._=&lt;&lt;"></a><a id="18158" href="#18158" class="Function Operator">_=&lt;&lt;</a> <a id="18163" class="Symbol">:</a> <a id="18165" class="Symbol">(</a><a id="18166" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="18168" class="Symbol">→</a> <a id="18170" href="#8679" class="Datatype">𝒫</a> <a id="18172" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="18173" class="Symbol">)</a> <a id="18175" class="Symbol">→</a> <a id="18177" href="#12307" class="Record Operator">[</a> <a id="18179" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="18181" href="#12307" class="Record Operator">↦</a> <a id="18183" href="#8679" class="Datatype">𝒫</a> <a id="18185" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a> <a id="18187" href="#12307" class="Record Operator">]</a>
  <a id="18191" href="#12420" class="Field Operator">[</a> <a id="18193" href="#18193" class="Bound">f</a> <a id="18195" href="#18158" class="Function Operator">=&lt;&lt;</a> <a id="18199" href="#12420" class="Field Operator">]</a> <a id="18201" href="#18201" class="Bound">p</a> <a id="18203" href="#12420" class="Field Operator">&amp;</a> <a id="18205" href="#18205" class="Bound">x</a> <a id="18207" href="#12420" class="Field Operator">∷</a> <a id="18209" href="#18209" class="Bound">xs</a> <a id="18212" class="Symbol">=</a> <a id="18214" href="#18201" class="Bound">p</a> <a id="18216" href="#14109" class="Function Operator">⋊</a> <a id="18218" class="Symbol">(</a><a id="18219" href="#18193" class="Bound">f</a> <a id="18221" href="#18205" class="Bound">x</a><a id="18222" class="Symbol">)</a> <a id="18224" href="#13390" class="Function Operator">∪</a> <a id="18226" href="#18209" class="Bound">xs</a>
  <a id="18231" href="#12449" class="Field Operator">[</a> <a id="18233" href="#18233" class="Bound">f</a> <a id="18235" href="#18158" class="Function Operator">=&lt;&lt;</a> <a id="18239" href="#12449" class="Field Operator">][]</a> <a id="18243" class="Symbol">=</a> <a id="18245" href="#8715" class="InductiveConstructor">[]</a>
  <a id="18250" href="#12397" class="Field Operator">[</a> <a id="18252" href="#18252" class="Bound">f</a> <a id="18254" href="#18158" class="Function Operator">=&lt;&lt;</a> <a id="18258" href="#12397" class="Field Operator">]-set</a> <a id="18264" class="Symbol">=</a> <a id="18266" href="#8921" class="InductiveConstructor">trunc</a>
  <a id="18274" href="#12635" class="Field Operator">[</a> <a id="18276" href="#18276" class="Bound">f</a> <a id="18278" href="#18158" class="Function Operator">=&lt;&lt;</a> <a id="18282" href="#12635" class="Field Operator">]-del</a> <a id="18288" href="#18288" class="Bound">x</a> <a id="18290" href="#18290" class="Bound">xs</a> <a id="18293" class="Symbol">=</a> <a id="18295" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="18300" class="Symbol">(</a><a id="18301" href="#13390" class="Function Operator">_∪</a> <a id="18304" href="#18290" class="Bound">xs</a><a id="18306" class="Symbol">)</a> <a id="18308" class="Symbol">(</a><a id="18309" href="#17658" class="Function">0⋊</a> <a id="18312" class="Symbol">(</a><a id="18313" href="#18276" class="Bound">f</a> <a id="18315" href="#18288" class="Bound">x</a><a id="18316" class="Symbol">))</a>
  <a id="18321" href="#12508" class="Field Operator">[</a> <a id="18323" href="#18323" class="Bound">f</a> <a id="18325" href="#18158" class="Function Operator">=&lt;&lt;</a> <a id="18329" href="#12508" class="Field Operator">]-dup</a> <a id="18335" href="#18335" class="Bound">p</a> <a id="18337" href="#18337" class="Bound">q</a> <a id="18339" href="#18339" class="Bound">x</a> <a id="18341" href="#18341" class="Bound">xs</a> <a id="18344" class="Symbol">=</a>
    <a id="18350" href="#18335" class="Bound">p</a> <a id="18352" href="#14109" class="Function Operator">⋊</a> <a id="18354" class="Symbol">(</a><a id="18355" href="#18323" class="Bound">f</a> <a id="18357" href="#18339" class="Bound">x</a><a id="18358" class="Symbol">)</a> <a id="18360" href="#13390" class="Function Operator">∪</a> <a id="18362" href="#18337" class="Bound">q</a> <a id="18364" href="#14109" class="Function Operator">⋊</a> <a id="18366" class="Symbol">(</a><a id="18367" href="#18323" class="Bound">f</a> <a id="18369" href="#18339" class="Bound">x</a><a id="18370" class="Symbol">)</a> <a id="18372" href="#13390" class="Function Operator">∪</a> <a id="18374" href="#18341" class="Bound">xs</a>   <a id="18379" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="18382" href="#13658" class="Function">∪-assoc</a> <a id="18390" class="Symbol">(</a><a id="18391" href="#18335" class="Bound">p</a> <a id="18393" href="#14109" class="Function Operator">⋊</a> <a id="18395" href="#18323" class="Bound">f</a> <a id="18397" href="#18339" class="Bound">x</a><a id="18398" class="Symbol">)</a> <a id="18400" class="Symbol">(</a><a id="18401" href="#18337" class="Bound">q</a> <a id="18403" href="#14109" class="Function Operator">⋊</a> <a id="18405" href="#18323" class="Bound">f</a> <a id="18407" href="#18339" class="Bound">x</a><a id="18408" class="Symbol">)</a> <a id="18410" href="#18341" class="Bound">xs</a> <a id="18413" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="18419" class="Symbol">(</a><a id="18420" href="#18335" class="Bound">p</a> <a id="18422" href="#14109" class="Function Operator">⋊</a> <a id="18424" class="Symbol">(</a><a id="18425" href="#18323" class="Bound">f</a> <a id="18427" href="#18339" class="Bound">x</a><a id="18428" class="Symbol">)</a> <a id="18430" href="#13390" class="Function Operator">∪</a> <a id="18432" href="#18337" class="Bound">q</a> <a id="18434" href="#14109" class="Function Operator">⋊</a> <a id="18436" class="Symbol">(</a><a id="18437" href="#18323" class="Bound">f</a> <a id="18439" href="#18339" class="Bound">x</a><a id="18440" class="Symbol">))</a> <a id="18443" href="#13390" class="Function Operator">∪</a> <a id="18445" href="#18341" class="Bound">xs</a> <a id="18448" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="18451" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="18456" class="Symbol">(</a><a id="18457" href="#13390" class="Function Operator">_∪</a> <a id="18460" href="#18341" class="Bound">xs</a><a id="18462" class="Symbol">)</a> <a id="18464" class="Symbol">(</a><a id="18465" href="#15807" class="Function">⋊-distribʳ</a> <a id="18476" href="#18335" class="Bound">p</a> <a id="18478" href="#18337" class="Bound">q</a> <a id="18480" class="Symbol">(</a><a id="18481" href="#18323" class="Bound">f</a> <a id="18483" href="#18339" class="Bound">x</a><a id="18484" class="Symbol">)</a> <a id="18486" class="Symbol">)</a> <a id="18488" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="18494" href="#14109" class="Function Operator">_⋊_</a> <a id="18498" class="Symbol">(</a><a id="18499" href="#18335" class="Bound">p</a> <a id="18501" href="../code/probability/ProbabilityModule.Semirings.html#214" class="Field Operator">+</a> <a id="18503" href="#18337" class="Bound">q</a><a id="18504" class="Symbol">)</a> <a id="18506" class="Symbol">(</a><a id="18507" href="#18323" class="Bound">f</a> <a id="18509" href="#18339" class="Bound">x</a><a id="18510" class="Symbol">)</a> <a id="18512" href="#13390" class="Function Operator">∪</a> <a id="18514" href="#18341" class="Bound">xs</a> <a id="18517" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
  <a id="18521" href="#12570" class="Field Operator">[</a> <a id="18523" href="#18523" class="Bound">f</a> <a id="18525" href="#18158" class="Function Operator">=&lt;&lt;</a> <a id="18529" href="#12570" class="Field Operator">]-com</a> <a id="18535" href="#18535" class="Bound">p</a> <a id="18537" href="#18537" class="Bound">x</a> <a id="18539" href="#18539" class="Bound">q</a> <a id="18541" href="#18541" class="Bound">y</a> <a id="18543" href="#18543" class="Bound">xs</a> <a id="18546" class="Symbol">=</a>
    <a id="18552" href="#18535" class="Bound">p</a> <a id="18554" href="#14109" class="Function Operator">⋊</a> <a id="18556" class="Symbol">(</a><a id="18557" href="#18523" class="Bound">f</a> <a id="18559" href="#18537" class="Bound">x</a><a id="18560" class="Symbol">)</a> <a id="18562" href="#13390" class="Function Operator">∪</a> <a id="18564" href="#18539" class="Bound">q</a> <a id="18566" href="#14109" class="Function Operator">⋊</a> <a id="18568" class="Symbol">(</a><a id="18569" href="#18523" class="Bound">f</a> <a id="18571" href="#18541" class="Bound">y</a><a id="18572" class="Symbol">)</a> <a id="18574" href="#13390" class="Function Operator">∪</a> <a id="18576" href="#18543" class="Bound">xs</a>   <a id="18581" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="18584" href="#13658" class="Function">∪-assoc</a> <a id="18592" class="Symbol">(</a><a id="18593" href="#18535" class="Bound">p</a> <a id="18595" href="#14109" class="Function Operator">⋊</a> <a id="18597" href="#18523" class="Bound">f</a> <a id="18599" href="#18537" class="Bound">x</a><a id="18600" class="Symbol">)</a> <a id="18602" class="Symbol">(</a><a id="18603" href="#18539" class="Bound">q</a> <a id="18605" href="#14109" class="Function Operator">⋊</a> <a id="18607" href="#18523" class="Bound">f</a> <a id="18609" href="#18541" class="Bound">y</a><a id="18610" class="Symbol">)</a> <a id="18612" href="#18543" class="Bound">xs</a> <a id="18615" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="18621" class="Symbol">(</a><a id="18622" href="#18535" class="Bound">p</a> <a id="18624" href="#14109" class="Function Operator">⋊</a> <a id="18626" class="Symbol">(</a><a id="18627" href="#18523" class="Bound">f</a> <a id="18629" href="#18537" class="Bound">x</a><a id="18630" class="Symbol">)</a> <a id="18632" href="#13390" class="Function Operator">∪</a> <a id="18634" href="#18539" class="Bound">q</a> <a id="18636" href="#14109" class="Function Operator">⋊</a> <a id="18638" class="Symbol">(</a><a id="18639" href="#18523" class="Bound">f</a> <a id="18641" href="#18541" class="Bound">y</a><a id="18642" class="Symbol">))</a> <a id="18645" href="#13390" class="Function Operator">∪</a> <a id="18647" href="#18543" class="Bound">xs</a> <a id="18650" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="18653" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="18658" class="Symbol">(</a><a id="18659" href="#13390" class="Function Operator">_∪</a> <a id="18662" href="#18543" class="Bound">xs</a><a id="18664" class="Symbol">)</a> <a id="18666" class="Symbol">(</a><a id="18667" href="#17355" class="Function">∪-comm</a> <a id="18674" class="Symbol">(</a><a id="18675" href="#18535" class="Bound">p</a> <a id="18677" href="#14109" class="Function Operator">⋊</a> <a id="18679" href="#18523" class="Bound">f</a> <a id="18681" href="#18537" class="Bound">x</a><a id="18682" class="Symbol">)</a> <a id="18684" class="Symbol">(</a><a id="18685" href="#18539" class="Bound">q</a> <a id="18687" href="#14109" class="Function Operator">⋊</a> <a id="18689" href="#18523" class="Bound">f</a> <a id="18691" href="#18541" class="Bound">y</a><a id="18692" class="Symbol">))</a> <a id="18695" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="18701" class="Symbol">(</a><a id="18702" href="#18539" class="Bound">q</a> <a id="18704" href="#14109" class="Function Operator">⋊</a> <a id="18706" class="Symbol">(</a><a id="18707" href="#18523" class="Bound">f</a> <a id="18709" href="#18541" class="Bound">y</a><a id="18710" class="Symbol">)</a> <a id="18712" href="#13390" class="Function Operator">∪</a> <a id="18714" href="#18535" class="Bound">p</a> <a id="18716" href="#14109" class="Function Operator">⋊</a> <a id="18718" class="Symbol">(</a><a id="18719" href="#18523" class="Bound">f</a> <a id="18721" href="#18537" class="Bound">x</a><a id="18722" class="Symbol">))</a> <a id="18725" href="#13390" class="Function Operator">∪</a> <a id="18727" href="#18543" class="Bound">xs</a> <a id="18730" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">≡˘⟨</a> <a id="18734" href="#13658" class="Function">∪-assoc</a> <a id="18742" class="Symbol">(</a><a id="18743" href="#18539" class="Bound">q</a> <a id="18745" href="#14109" class="Function Operator">⋊</a> <a id="18747" href="#18523" class="Bound">f</a> <a id="18749" href="#18541" class="Bound">y</a><a id="18750" class="Symbol">)</a> <a id="18752" class="Symbol">(</a><a id="18753" href="#18535" class="Bound">p</a> <a id="18755" href="#14109" class="Function Operator">⋊</a> <a id="18757" href="#18523" class="Bound">f</a> <a id="18759" href="#18537" class="Bound">x</a><a id="18760" class="Symbol">)</a> <a id="18762" href="#18543" class="Bound">xs</a> <a id="18765" href="../code/probability/ProbabilityModule.Utils.html#295" class="Function">⟩</a>
    <a id="18771" href="#18539" class="Bound">q</a> <a id="18773" href="#14109" class="Function Operator">⋊</a> <a id="18775" class="Symbol">(</a><a id="18776" href="#18523" class="Bound">f</a> <a id="18778" href="#18541" class="Bound">y</a><a id="18779" class="Symbol">)</a> <a id="18781" href="#13390" class="Function Operator">∪</a> <a id="18783" href="#18535" class="Bound">p</a> <a id="18785" href="#14109" class="Function Operator">⋊</a> <a id="18787" class="Symbol">(</a><a id="18788" href="#18523" class="Bound">f</a> <a id="18790" href="#18537" class="Bound">x</a><a id="18791" class="Symbol">)</a> <a id="18793" href="#13390" class="Function Operator">∪</a> <a id="18795" href="#18543" class="Bound">xs</a> <a id="18798" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
</pre>
<p>And we can prove the monad laws, also:</p>
<details>
<summary>
Proofs of Monad Laws
</summary>
<pre class="Agda"><a id="1⋊"></a><a id="18904" href="#18904" class="Function">1⋊</a> <a id="18907" class="Symbol">:</a> <a id="18909" class="Symbol">(</a><a id="18910" href="#18910" class="Bound">xs</a> <a id="18913" class="Symbol">:</a> <a id="18915" href="#8679" class="Datatype">𝒫</a> <a id="18917" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="18918" class="Symbol">)</a> <a id="18920" class="Symbol">→</a> <a id="18922" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="18925" href="#14109" class="Function Operator">⋊</a> <a id="18927" href="#18910" class="Bound">xs</a> <a id="18930" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="18932" href="#18910" class="Bound">xs</a>
<a id="18935" href="#18904" class="Function">1⋊</a> <a id="18938" class="Symbol">=</a> <a id="18940" href="#12103" class="Function Operator">⟦</a> <a id="18942" href="#18974" class="Function">1⋊′</a> <a id="18946" href="#12103" class="Function Operator">⟧⇓</a>
  <a id="18951" class="Keyword">module</a> <a id="OneJoin"></a><a id="18958" href="#18958" class="Module">OneJoin</a> <a id="18966" class="Keyword">where</a>
  <a id="OneJoin.1⋊′"></a><a id="18974" href="#18974" class="Function">1⋊′</a> <a id="18978" class="Symbol">:</a> <a id="18980" href="#12139" class="Function">⟦</a> <a id="18982" href="#18982" class="Bound">xs</a> <a id="18985" href="#12139" class="Function">∈𝒫</a> <a id="18988" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="18990" href="#12139" class="Function">⇒</a> <a id="18992" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="18995" href="#14109" class="Function Operator">⋊</a> <a id="18997" href="#18982" class="Bound">xs</a> <a id="19000" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="19002" href="#18982" class="Bound">xs</a> <a id="19005" href="#12139" class="Function">⟧</a>
  <a id="19009" href="#11443" class="Field Operator">⟦</a> <a id="19011" href="#18974" class="Function">1⋊′</a> <a id="19015" href="#11443" class="Field Operator">⟧-prop</a> <a id="19022" class="Symbol">=</a> <a id="19024" href="#8921" class="InductiveConstructor">trunc</a> <a id="19030" class="Symbol">_</a> <a id="19032" class="Symbol">_</a>
  <a id="19036" href="#11481" class="Field Operator">⟦</a> <a id="19038" href="#18974" class="Function">1⋊′</a> <a id="19042" href="#11481" class="Field Operator">⟧[]</a> <a id="19046" class="Symbol">=</a> <a id="19048" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="19055" href="#11498" class="Field Operator">⟦</a> <a id="19057" href="#18974" class="Function">1⋊′</a> <a id="19061" href="#11498" class="Field Operator">⟧</a> <a id="19063" href="#19063" class="Bound">p</a> <a id="19065" href="#11498" class="Field Operator">&amp;</a> <a id="19067" href="#19067" class="Bound">x</a> <a id="19069" href="#11498" class="Field Operator">∷</a> <a id="19071" href="#19071" class="Bound">xs</a> <a id="19074" href="#11498" class="Field Operator">⟨</a> <a id="19076" href="#19076" class="Bound">P</a> <a id="19078" href="#11498" class="Field Operator">⟩</a> <a id="19080" class="Symbol">=</a>
    <a id="19086" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="19089" href="#14109" class="Function Operator">⋊</a> <a id="19091" class="Symbol">(</a><a id="19092" href="#19063" class="Bound">p</a> <a id="19094" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19096" href="#19067" class="Bound">x</a> <a id="19098" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19100" href="#19071" class="Bound">xs</a><a id="19102" class="Symbol">)</a> <a id="19104" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="19112" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="19115" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="19117" href="#19063" class="Bound">p</a> <a id="19119" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19121" href="#19067" class="Bound">x</a> <a id="19123" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19125" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="19128" href="#14109" class="Function Operator">⋊</a> <a id="19130" href="#19071" class="Bound">xs</a> <a id="19133" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="19136" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="19141" class="Symbol">(</a><a id="19142" href="#8727" class="InductiveConstructor Operator">_&amp;</a> <a id="19145" href="#19067" class="Bound">x</a> <a id="19147" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19149" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="19152" href="#14109" class="Function Operator">⋊</a> <a id="19154" href="#19071" class="Bound">xs</a><a id="19156" class="Symbol">)</a> <a id="19158" class="Symbol">(</a><a id="19159" href="../code/probability/ProbabilityModule.Semirings.html#482" class="Field">1*</a> <a id="19162" href="#19063" class="Bound">p</a><a id="19163" class="Symbol">)</a> <a id="19165" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="19171" href="#19063" class="Bound">p</a> <a id="19173" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19175" href="#19067" class="Bound">x</a> <a id="19177" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19179" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="19182" href="#14109" class="Function Operator">⋊</a> <a id="19184" href="#19071" class="Bound">xs</a> <a id="19187" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="19190" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="19195" class="Symbol">(</a><a id="19196" href="#19063" class="Bound">p</a> <a id="19198" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19200" href="#19067" class="Bound">x</a> <a id="19202" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="19204" class="Symbol">)</a> <a id="19206" href="#19076" class="Bound">P</a> <a id="19208" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="19214" href="#19063" class="Bound">p</a> <a id="19216" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19218" href="#19067" class="Bound">x</a> <a id="19220" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19222" href="#19071" class="Bound">xs</a> <a id="19225" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="&gt;&gt;=-distrib"></a><a id="19228" href="#19228" class="Function">&gt;&gt;=-distrib</a> <a id="19240" class="Symbol">:</a> <a id="19242" class="Symbol">(</a><a id="19243" href="#19243" class="Bound">xs</a> <a id="19246" href="#19246" class="Bound">ys</a> <a id="19249" class="Symbol">:</a> <a id="19251" href="#8679" class="Datatype">𝒫</a> <a id="19253" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="19254" class="Symbol">)</a> <a id="19256" class="Symbol">(</a><a id="19257" href="#19257" class="Bound">g</a> <a id="19259" class="Symbol">:</a> <a id="19261" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="19263" class="Symbol">→</a> <a id="19265" href="#8679" class="Datatype">𝒫</a> <a id="19267" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="19268" class="Symbol">)</a> <a id="19270" class="Symbol">→</a> <a id="19272" class="Symbol">(</a><a id="19273" href="#19243" class="Bound">xs</a> <a id="19276" href="#13390" class="Function Operator">∪</a> <a id="19278" href="#19246" class="Bound">ys</a><a id="19280" class="Symbol">)</a> <a id="19282" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19286" href="#19257" class="Bound">g</a> <a id="19288" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="19290" class="Symbol">(</a><a id="19291" href="#19243" class="Bound">xs</a> <a id="19294" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19298" href="#19257" class="Bound">g</a><a id="19299" class="Symbol">)</a> <a id="19301" href="#13390" class="Function Operator">∪</a> <a id="19303" class="Symbol">(</a><a id="19304" href="#19246" class="Bound">ys</a> <a id="19307" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19311" href="#19257" class="Bound">g</a><a id="19312" class="Symbol">)</a>
<a id="19314" href="#19228" class="Function">&gt;&gt;=-distrib</a> <a id="19326" class="Symbol">=</a> <a id="19328" class="Symbol">λ</a> <a id="19330" href="#19330" class="Bound">xs</a> <a id="19333" href="#19333" class="Bound">ys</a> <a id="19336" href="#19336" class="Bound">g</a> <a id="19338" class="Symbol">→</a> <a id="19340" href="#12103" class="Function Operator">⟦</a> <a id="19342" href="#19395" class="Function">&gt;&gt;=-distrib′</a> <a id="19355" href="#19333" class="Bound">ys</a> <a id="19358" href="#19336" class="Bound">g</a> <a id="19360" href="#12103" class="Function Operator">⟧⇓</a> <a id="19363" href="#19330" class="Bound">xs</a>
  <a id="19368" class="Keyword">module</a> <a id="BindDistrib"></a><a id="19375" href="#19375" class="Module">BindDistrib</a> <a id="19387" class="Keyword">where</a>
  <a id="BindDistrib.&gt;&gt;=-distrib′"></a><a id="19395" href="#19395" class="Function">&gt;&gt;=-distrib′</a> <a id="19408" class="Symbol">:</a> <a id="19410" class="Symbol">(</a><a id="19411" href="#19411" class="Bound">ys</a> <a id="19414" class="Symbol">:</a> <a id="19416" href="#8679" class="Datatype">𝒫</a> <a id="19418" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="19419" class="Symbol">)</a> <a id="19421" class="Symbol">(</a><a id="19422" href="#19422" class="Bound">g</a> <a id="19424" class="Symbol">:</a> <a id="19426" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="19428" class="Symbol">→</a> <a id="19430" href="#8679" class="Datatype">𝒫</a> <a id="19432" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="19433" class="Symbol">)</a> <a id="19435" class="Symbol">→</a> <a id="19437" href="#12139" class="Function">⟦</a> <a id="19439" href="#19439" class="Bound">xs</a> <a id="19442" href="#12139" class="Function">∈𝒫</a> <a id="19445" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="19447" href="#12139" class="Function">⇒</a> <a id="19449" class="Symbol">((</a><a id="19451" href="#19439" class="Bound">xs</a> <a id="19454" href="#13390" class="Function Operator">∪</a> <a id="19456" href="#19411" class="Bound">ys</a><a id="19458" class="Symbol">)</a> <a id="19460" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19464" href="#19422" class="Bound">g</a><a id="19465" class="Symbol">)</a> <a id="19467" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="19469" class="Symbol">(</a><a id="19470" href="#19439" class="Bound">xs</a> <a id="19473" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19477" href="#19422" class="Bound">g</a><a id="19478" class="Symbol">)</a> <a id="19480" href="#13390" class="Function Operator">∪</a> <a id="19482" class="Symbol">(</a><a id="19483" href="#19411" class="Bound">ys</a> <a id="19486" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19490" href="#19422" class="Bound">g</a><a id="19491" class="Symbol">)</a> <a id="19493" href="#12139" class="Function">⟧</a>
  <a id="19497" href="#11443" class="Field Operator">⟦</a> <a id="19499" href="#19395" class="Function">&gt;&gt;=-distrib′</a> <a id="19512" href="#19512" class="Bound">ys</a> <a id="19515" href="#19515" class="Bound">g</a> <a id="19517" href="#11443" class="Field Operator">⟧-prop</a> <a id="19524" class="Symbol">=</a> <a id="19526" href="#8921" class="InductiveConstructor">trunc</a> <a id="19532" class="Symbol">_</a> <a id="19534" class="Symbol">_</a>
  <a id="19538" href="#11481" class="Field Operator">⟦</a> <a id="19540" href="#19395" class="Function">&gt;&gt;=-distrib′</a> <a id="19553" href="#19553" class="Bound">ys</a> <a id="19556" href="#19556" class="Bound">g</a> <a id="19558" href="#11481" class="Field Operator">⟧[]</a> <a id="19562" class="Symbol">=</a> <a id="19564" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="19571" href="#11498" class="Field Operator">⟦</a> <a id="19573" href="#19395" class="Function">&gt;&gt;=-distrib′</a> <a id="19586" href="#19586" class="Bound">ys</a> <a id="19589" href="#19589" class="Bound">g</a> <a id="19591" href="#11498" class="Field Operator">⟧</a> <a id="19593" href="#19593" class="Bound">p</a> <a id="19595" href="#11498" class="Field Operator">&amp;</a> <a id="19597" href="#19597" class="Bound">x</a> <a id="19599" href="#11498" class="Field Operator">∷</a> <a id="19601" href="#19601" class="Bound">xs</a> <a id="19604" href="#11498" class="Field Operator">⟨</a> <a id="19606" href="#19606" class="Bound">P</a> <a id="19608" href="#11498" class="Field Operator">⟩</a> <a id="19610" class="Symbol">=</a>
    <a id="19616" class="Symbol">(((</a><a id="19619" href="#19593" class="Bound">p</a> <a id="19621" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19623" href="#19597" class="Bound">x</a> <a id="19625" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19627" href="#19601" class="Bound">xs</a><a id="19629" class="Symbol">)</a> <a id="19631" href="#13390" class="Function Operator">∪</a> <a id="19633" href="#19586" class="Bound">ys</a><a id="19635" class="Symbol">)</a> <a id="19637" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19641" href="#19589" class="Bound">g</a><a id="19642" class="Symbol">)</a> <a id="19644" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="19652" class="Symbol">(</a><a id="19653" href="#19593" class="Bound">p</a> <a id="19655" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19657" href="#19597" class="Bound">x</a> <a id="19659" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19661" href="#19601" class="Bound">xs</a> <a id="19664" href="#13390" class="Function Operator">∪</a> <a id="19666" href="#19586" class="Bound">ys</a><a id="19668" class="Symbol">)</a> <a id="19670" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19674" href="#19589" class="Bound">g</a> <a id="19676" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="19684" href="#19593" class="Bound">p</a> <a id="19686" href="#14109" class="Function Operator">⋊</a> <a id="19688" href="#19589" class="Bound">g</a> <a id="19690" href="#19597" class="Bound">x</a> <a id="19692" href="#13390" class="Function Operator">∪</a> <a id="19694" class="Symbol">((</a><a id="19696" href="#19601" class="Bound">xs</a> <a id="19699" href="#13390" class="Function Operator">∪</a> <a id="19701" href="#19586" class="Bound">ys</a><a id="19703" class="Symbol">)</a> <a id="19705" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19709" href="#19589" class="Bound">g</a><a id="19710" class="Symbol">)</a> <a id="19712" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="19715" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="19720" class="Symbol">(</a><a id="19721" href="#19593" class="Bound">p</a> <a id="19723" href="#14109" class="Function Operator">⋊</a> <a id="19725" href="#19589" class="Bound">g</a> <a id="19727" href="#19597" class="Bound">x</a> <a id="19729" href="#13390" class="Function Operator">∪_</a><a id="19731" class="Symbol">)</a> <a id="19733" href="#19606" class="Bound">P</a> <a id="19735" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="19741" href="#19593" class="Bound">p</a> <a id="19743" href="#14109" class="Function Operator">⋊</a> <a id="19745" href="#19589" class="Bound">g</a> <a id="19747" href="#19597" class="Bound">x</a> <a id="19749" href="#13390" class="Function Operator">∪</a> <a id="19751" class="Symbol">((</a><a id="19753" href="#19601" class="Bound">xs</a> <a id="19756" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19760" href="#19589" class="Bound">g</a><a id="19761" class="Symbol">)</a> <a id="19763" href="#13390" class="Function Operator">∪</a> <a id="19765" class="Symbol">(</a><a id="19766" href="#19586" class="Bound">ys</a> <a id="19769" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19773" href="#19589" class="Bound">g</a><a id="19774" class="Symbol">))</a> <a id="19777" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="19780" href="#13658" class="Function">∪-assoc</a> <a id="19788" class="Symbol">(</a><a id="19789" href="#19593" class="Bound">p</a> <a id="19791" href="#14109" class="Function Operator">⋊</a> <a id="19793" href="#19589" class="Bound">g</a> <a id="19795" href="#19597" class="Bound">x</a><a id="19796" class="Symbol">)</a> <a id="19798" class="Symbol">(</a><a id="19799" href="#19601" class="Bound">xs</a> <a id="19802" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19806" href="#19589" class="Bound">g</a><a id="19807" class="Symbol">)</a> <a id="19809" class="Symbol">(</a><a id="19810" href="#19586" class="Bound">ys</a> <a id="19813" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19817" href="#19589" class="Bound">g</a><a id="19818" class="Symbol">)</a> <a id="19820" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="19826" class="Symbol">(</a><a id="19827" href="#19593" class="Bound">p</a> <a id="19829" href="#14109" class="Function Operator">⋊</a> <a id="19831" href="#19589" class="Bound">g</a> <a id="19833" href="#19597" class="Bound">x</a> <a id="19835" href="#13390" class="Function Operator">∪</a> <a id="19837" class="Symbol">(</a><a id="19838" href="#19601" class="Bound">xs</a> <a id="19841" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19845" href="#19589" class="Bound">g</a><a id="19846" class="Symbol">))</a> <a id="19849" href="#13390" class="Function Operator">∪</a> <a id="19851" class="Symbol">(</a><a id="19852" href="#19586" class="Bound">ys</a> <a id="19855" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19859" href="#19589" class="Bound">g</a><a id="19860" class="Symbol">)</a> <a id="19862" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="19870" class="Symbol">((</a><a id="19872" href="#19593" class="Bound">p</a> <a id="19874" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="19876" href="#19597" class="Bound">x</a> <a id="19878" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="19880" href="#19601" class="Bound">xs</a><a id="19882" class="Symbol">)</a> <a id="19884" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19888" href="#19589" class="Bound">g</a><a id="19889" class="Symbol">)</a> <a id="19891" href="#13390" class="Function Operator">∪</a> <a id="19893" class="Symbol">(</a><a id="19894" href="#19586" class="Bound">ys</a> <a id="19897" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="19901" href="#19589" class="Bound">g</a><a id="19902" class="Symbol">)</a> <a id="19904" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="*-assoc-⋊"></a><a id="19907" href="#19907" class="Function">*-assoc-⋊</a> <a id="19917" class="Symbol">:</a> <a id="19919" class="Symbol">∀</a> <a id="19921" href="#19921" class="Bound">p</a> <a id="19923" href="#19923" class="Bound">q</a> <a id="19925" class="Symbol">(</a><a id="19926" href="#19926" class="Bound">xs</a> <a id="19929" class="Symbol">:</a> <a id="19931" href="#8679" class="Datatype">𝒫</a> <a id="19933" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="19934" class="Symbol">)</a> <a id="19936" class="Symbol">→</a> <a id="19938" class="Symbol">(</a><a id="19939" href="#19921" class="Bound">p</a> <a id="19941" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="19943" href="#19923" class="Bound">q</a><a id="19944" class="Symbol">)</a> <a id="19946" href="#14109" class="Function Operator">⋊</a> <a id="19948" href="#19926" class="Bound">xs</a> <a id="19951" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="19953" href="#19921" class="Bound">p</a> <a id="19955" href="#14109" class="Function Operator">⋊</a> <a id="19957" class="Symbol">(</a><a id="19958" href="#19923" class="Bound">q</a> <a id="19960" href="#14109" class="Function Operator">⋊</a> <a id="19962" href="#19926" class="Bound">xs</a><a id="19964" class="Symbol">)</a>
<a id="19966" href="#19907" class="Function">*-assoc-⋊</a> <a id="19976" class="Symbol">=</a> <a id="19978" class="Symbol">λ</a> <a id="19980" href="#19980" class="Bound">p</a> <a id="19982" href="#19982" class="Bound">q</a> <a id="19984" class="Symbol">→</a> <a id="19986" href="#12103" class="Function Operator">⟦</a> <a id="19988" href="#20031" class="Function">*-assoc-⋊′</a> <a id="19999" href="#19980" class="Bound">p</a> <a id="20001" href="#19982" class="Bound">q</a> <a id="20003" href="#12103" class="Function Operator">⟧⇓</a>
  <a id="20008" class="Keyword">module</a> <a id="MAssocJ"></a><a id="20015" href="#20015" class="Module">MAssocJ</a> <a id="20023" class="Keyword">where</a>
  <a id="MAssocJ.*-assoc-⋊′"></a><a id="20031" href="#20031" class="Function">*-assoc-⋊′</a> <a id="20042" class="Symbol">:</a> <a id="20044" class="Symbol">∀</a> <a id="20046" href="#20046" class="Bound">p</a> <a id="20048" href="#20048" class="Bound">q</a> <a id="20050" class="Symbol">→</a> <a id="20052" href="#12139" class="Function">⟦</a> <a id="20054" href="#20054" class="Bound">xs</a> <a id="20057" href="#12139" class="Function">∈𝒫</a> <a id="20060" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="20062" href="#12139" class="Function">⇒</a> <a id="20064" class="Symbol">(</a><a id="20065" href="#20046" class="Bound">p</a> <a id="20067" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20069" href="#20048" class="Bound">q</a><a id="20070" class="Symbol">)</a> <a id="20072" href="#14109" class="Function Operator">⋊</a> <a id="20074" href="#20054" class="Bound">xs</a> <a id="20077" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="20079" href="#20046" class="Bound">p</a> <a id="20081" href="#14109" class="Function Operator">⋊</a> <a id="20083" class="Symbol">(</a><a id="20084" href="#20048" class="Bound">q</a> <a id="20086" href="#14109" class="Function Operator">⋊</a> <a id="20088" href="#20054" class="Bound">xs</a><a id="20090" class="Symbol">)</a> <a id="20092" href="#12139" class="Function">⟧</a>
  <a id="20096" href="#11443" class="Field Operator">⟦</a> <a id="20098" href="#20031" class="Function">*-assoc-⋊′</a> <a id="20109" href="#20109" class="Bound">p</a> <a id="20111" href="#20111" class="Bound">q</a> <a id="20113" href="#11443" class="Field Operator">⟧-prop</a> <a id="20120" class="Symbol">=</a> <a id="20122" href="#8921" class="InductiveConstructor">trunc</a> <a id="20128" class="Symbol">_</a> <a id="20130" class="Symbol">_</a>
  <a id="20134" href="#11481" class="Field Operator">⟦</a> <a id="20136" href="#20031" class="Function">*-assoc-⋊′</a> <a id="20147" href="#20147" class="Bound">p</a> <a id="20149" href="#20149" class="Bound">q</a> <a id="20151" href="#11481" class="Field Operator">⟧[]</a> <a id="20155" class="Symbol">=</a> <a id="20157" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="20164" href="#11498" class="Field Operator">⟦</a> <a id="20166" href="#20031" class="Function">*-assoc-⋊′</a> <a id="20177" href="#20177" class="Bound">p</a> <a id="20179" href="#20179" class="Bound">q</a> <a id="20181" href="#11498" class="Field Operator">⟧</a> <a id="20183" href="#20183" class="Bound">r</a> <a id="20185" href="#11498" class="Field Operator">&amp;</a> <a id="20187" href="#20187" class="Bound">x</a> <a id="20189" href="#11498" class="Field Operator">∷</a> <a id="20191" href="#20191" class="Bound">xs</a> <a id="20194" href="#11498" class="Field Operator">⟨</a> <a id="20196" href="#20196" class="Bound">P</a> <a id="20198" href="#11498" class="Field Operator">⟩</a> <a id="20200" class="Symbol">=</a>
    <a id="20206" href="#20177" class="Bound">p</a> <a id="20208" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20210" href="#20179" class="Bound">q</a> <a id="20212" href="#14109" class="Function Operator">⋊</a> <a id="20214" class="Symbol">(</a><a id="20215" href="#20183" class="Bound">r</a> <a id="20217" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20219" href="#20187" class="Bound">x</a> <a id="20221" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20223" href="#20191" class="Bound">xs</a><a id="20225" class="Symbol">)</a> <a id="20227" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="20235" href="#20177" class="Bound">p</a> <a id="20237" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20239" href="#20179" class="Bound">q</a> <a id="20241" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20243" href="#20183" class="Bound">r</a> <a id="20245" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20247" href="#20187" class="Bound">x</a> <a id="20249" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20251" class="Symbol">(</a><a id="20252" href="#20177" class="Bound">p</a> <a id="20254" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20256" href="#20179" class="Bound">q</a> <a id="20258" href="#14109" class="Function Operator">⋊</a> <a id="20260" href="#20191" class="Bound">xs</a><a id="20262" class="Symbol">)</a> <a id="20264" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="20267" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="20272" class="Symbol">(</a><a id="20273" href="#8727" class="InductiveConstructor Operator">_&amp;</a> <a id="20276" href="#20187" class="Bound">x</a> <a id="20278" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20280" class="Symbol">(</a><a id="20281" href="#20177" class="Bound">p</a> <a id="20283" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20285" href="#20179" class="Bound">q</a> <a id="20287" href="#14109" class="Function Operator">⋊</a> <a id="20289" href="#20191" class="Bound">xs</a><a id="20291" class="Symbol">))</a> <a id="20294" class="Symbol">(</a><a id="20295" href="../code/probability/ProbabilityModule.Semirings.html#326" class="Field">*-assoc</a> <a id="20303" href="#20177" class="Bound">p</a> <a id="20305" href="#20179" class="Bound">q</a> <a id="20307" href="#20183" class="Bound">r</a><a id="20308" class="Symbol">)</a> <a id="20310" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="20316" href="#20177" class="Bound">p</a> <a id="20318" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20320" class="Symbol">(</a><a id="20321" href="#20179" class="Bound">q</a> <a id="20323" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20325" href="#20183" class="Bound">r</a><a id="20326" class="Symbol">)</a> <a id="20328" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20330" href="#20187" class="Bound">x</a> <a id="20332" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20334" class="Symbol">(</a><a id="20335" href="#20177" class="Bound">p</a> <a id="20337" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20339" href="#20179" class="Bound">q</a> <a id="20341" href="#14109" class="Function Operator">⋊</a> <a id="20343" href="#20191" class="Bound">xs</a><a id="20345" class="Symbol">)</a> <a id="20347" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="20350" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="20355" class="Symbol">(</a><a id="20356" href="#20177" class="Bound">p</a> <a id="20358" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20360" class="Symbol">(</a><a id="20361" href="#20179" class="Bound">q</a> <a id="20363" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20365" href="#20183" class="Bound">r</a><a id="20366" class="Symbol">)</a> <a id="20368" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20370" href="#20187" class="Bound">x</a> <a id="20372" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="20374" class="Symbol">)</a> <a id="20376" href="#20196" class="Bound">P</a> <a id="20378" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="20384" href="#20177" class="Bound">p</a> <a id="20386" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20388" class="Symbol">(</a><a id="20389" href="#20179" class="Bound">q</a> <a id="20391" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20393" href="#20183" class="Bound">r</a><a id="20394" class="Symbol">)</a> <a id="20396" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20398" href="#20187" class="Bound">x</a> <a id="20400" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20402" class="Symbol">(</a><a id="20403" href="#20177" class="Bound">p</a> <a id="20405" href="#14109" class="Function Operator">⋊</a> <a id="20407" class="Symbol">(</a><a id="20408" href="#20179" class="Bound">q</a> <a id="20410" href="#14109" class="Function Operator">⋊</a> <a id="20412" href="#20191" class="Bound">xs</a><a id="20414" class="Symbol">))</a> <a id="20417" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="20425" href="#20177" class="Bound">p</a> <a id="20427" href="#14109" class="Function Operator">⋊</a> <a id="20429" class="Symbol">(</a><a id="20430" href="#20179" class="Bound">q</a> <a id="20432" href="#14109" class="Function Operator">⋊</a> <a id="20434" class="Symbol">(</a><a id="20435" href="#20183" class="Bound">r</a> <a id="20437" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20439" href="#20187" class="Bound">x</a> <a id="20441" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20443" href="#20191" class="Bound">xs</a><a id="20445" class="Symbol">))</a> <a id="20448" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="⋊-assoc-&gt;&gt;="></a><a id="20451" href="#20451" class="Function">⋊-assoc-&gt;&gt;=</a> <a id="20463" class="Symbol">:</a> <a id="20465" class="Symbol">∀</a> <a id="20467" href="#20467" class="Bound">p</a> <a id="20469" class="Symbol">(</a><a id="20470" href="#20470" class="Bound">xs</a> <a id="20473" class="Symbol">:</a> <a id="20475" href="#8679" class="Datatype">𝒫</a> <a id="20477" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="20478" class="Symbol">)</a> <a id="20480" class="Symbol">(</a><a id="20481" href="#20481" class="Bound">f</a> <a id="20483" class="Symbol">:</a> <a id="20485" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="20487" class="Symbol">→</a> <a id="20489" href="#8679" class="Datatype">𝒫</a> <a id="20491" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="20492" class="Symbol">)</a> <a id="20494" class="Symbol">→</a> <a id="20496" class="Symbol">(</a><a id="20497" href="#20467" class="Bound">p</a> <a id="20499" href="#14109" class="Function Operator">⋊</a> <a id="20501" href="#20470" class="Bound">xs</a><a id="20503" class="Symbol">)</a> <a id="20505" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20509" href="#20481" class="Bound">f</a> <a id="20511" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="20513" href="#20467" class="Bound">p</a> <a id="20515" href="#14109" class="Function Operator">⋊</a> <a id="20517" class="Symbol">(</a><a id="20518" href="#20470" class="Bound">xs</a> <a id="20521" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20525" href="#20481" class="Bound">f</a><a id="20526" class="Symbol">)</a>
<a id="20528" href="#20451" class="Function">⋊-assoc-&gt;&gt;=</a> <a id="20540" class="Symbol">=</a> <a id="20542" class="Symbol">λ</a> <a id="20544" href="#20544" class="Bound">p</a> <a id="20546" href="#20546" class="Bound">xs</a> <a id="20549" href="#20549" class="Bound">f</a> <a id="20551" class="Symbol">→</a> <a id="20553" href="#12103" class="Function Operator">⟦</a> <a id="20555" href="#20605" class="Function">⋊-assoc-&gt;&gt;=′</a> <a id="20568" href="#20544" class="Bound">p</a> <a id="20570" href="#20549" class="Bound">f</a> <a id="20572" href="#12103" class="Function Operator">⟧⇓</a> <a id="20575" href="#20546" class="Bound">xs</a>
  <a id="20580" class="Keyword">module</a> <a id="JDistribB"></a><a id="20587" href="#20587" class="Module">JDistribB</a> <a id="20597" class="Keyword">where</a>
  <a id="JDistribB.⋊-assoc-&gt;&gt;=′"></a><a id="20605" href="#20605" class="Function">⋊-assoc-&gt;&gt;=′</a> <a id="20618" class="Symbol">:</a> <a id="20620" class="Symbol">∀</a> <a id="20622" href="#20622" class="Bound">p</a> <a id="20624" class="Symbol">(</a><a id="20625" href="#20625" class="Bound">f</a> <a id="20627" class="Symbol">:</a> <a id="20629" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="20631" class="Symbol">→</a> <a id="20633" href="#8679" class="Datatype">𝒫</a> <a id="20635" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="20636" class="Symbol">)</a> <a id="20638" class="Symbol">→</a> <a id="20640" href="#12139" class="Function">⟦</a> <a id="20642" href="#20642" class="Bound">xs</a> <a id="20645" href="#12139" class="Function">∈𝒫</a> <a id="20648" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="20650" href="#12139" class="Function">⇒</a> <a id="20652" class="Symbol">(</a><a id="20653" href="#20622" class="Bound">p</a> <a id="20655" href="#14109" class="Function Operator">⋊</a> <a id="20657" href="#20642" class="Bound">xs</a><a id="20659" class="Symbol">)</a> <a id="20661" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20665" href="#20625" class="Bound">f</a> <a id="20667" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="20669" href="#20622" class="Bound">p</a> <a id="20671" href="#14109" class="Function Operator">⋊</a> <a id="20673" class="Symbol">(</a><a id="20674" href="#20642" class="Bound">xs</a> <a id="20677" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20681" href="#20625" class="Bound">f</a><a id="20682" class="Symbol">)</a> <a id="20684" href="#12139" class="Function">⟧</a>
  <a id="20688" href="#11443" class="Field Operator">⟦</a> <a id="20690" href="#20605" class="Function">⋊-assoc-&gt;&gt;=′</a> <a id="20703" href="#20703" class="Bound">p</a> <a id="20705" href="#20705" class="Bound">f</a> <a id="20707" href="#11443" class="Field Operator">⟧-prop</a> <a id="20714" class="Symbol">=</a> <a id="20716" href="#8921" class="InductiveConstructor">trunc</a> <a id="20722" class="Symbol">_</a> <a id="20724" class="Symbol">_</a>
  <a id="20728" href="#11481" class="Field Operator">⟦</a> <a id="20730" href="#20605" class="Function">⋊-assoc-&gt;&gt;=′</a> <a id="20743" href="#20743" class="Bound">p</a> <a id="20745" href="#20745" class="Bound">f</a> <a id="20747" href="#11481" class="Field Operator">⟧[]</a> <a id="20751" class="Symbol">=</a> <a id="20753" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="20760" href="#11498" class="Field Operator">⟦</a> <a id="20762" href="#20605" class="Function">⋊-assoc-&gt;&gt;=′</a> <a id="20775" href="#20775" class="Bound">p</a> <a id="20777" href="#20777" class="Bound">f</a> <a id="20779" href="#11498" class="Field Operator">⟧</a> <a id="20781" href="#20781" class="Bound">q</a> <a id="20783" href="#11498" class="Field Operator">&amp;</a> <a id="20785" href="#20785" class="Bound">x</a> <a id="20787" href="#11498" class="Field Operator">∷</a> <a id="20789" href="#20789" class="Bound">xs</a> <a id="20792" href="#11498" class="Field Operator">⟨</a> <a id="20794" href="#20794" class="Bound">P</a> <a id="20796" href="#11498" class="Field Operator">⟩</a> <a id="20798" class="Symbol">=</a>
    <a id="20804" class="Symbol">(</a><a id="20805" href="#20775" class="Bound">p</a> <a id="20807" href="#14109" class="Function Operator">⋊</a> <a id="20809" class="Symbol">(</a><a id="20810" href="#20781" class="Bound">q</a> <a id="20812" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20814" href="#20785" class="Bound">x</a> <a id="20816" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20818" href="#20789" class="Bound">xs</a><a id="20820" class="Symbol">))</a> <a id="20823" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20827" href="#20777" class="Bound">f</a> <a id="20829" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="20837" class="Symbol">(</a><a id="20838" href="#20775" class="Bound">p</a> <a id="20840" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20842" href="#20781" class="Bound">q</a> <a id="20844" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="20846" href="#20785" class="Bound">x</a> <a id="20848" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="20850" href="#20775" class="Bound">p</a> <a id="20852" href="#14109" class="Function Operator">⋊</a> <a id="20854" href="#20789" class="Bound">xs</a><a id="20856" class="Symbol">)</a> <a id="20858" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20862" href="#20777" class="Bound">f</a> <a id="20864" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="20872" class="Symbol">((</a><a id="20874" href="#20775" class="Bound">p</a> <a id="20876" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20878" href="#20781" class="Bound">q</a><a id="20879" class="Symbol">)</a> <a id="20881" href="#14109" class="Function Operator">⋊</a> <a id="20883" href="#20777" class="Bound">f</a> <a id="20885" href="#20785" class="Bound">x</a><a id="20886" class="Symbol">)</a> <a id="20888" href="#13390" class="Function Operator">∪</a> <a id="20890" class="Symbol">((</a><a id="20892" href="#20775" class="Bound">p</a> <a id="20894" href="#14109" class="Function Operator">⋊</a> <a id="20896" href="#20789" class="Bound">xs</a><a id="20898" class="Symbol">)</a> <a id="20900" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20904" href="#20777" class="Bound">f</a><a id="20905" class="Symbol">)</a> <a id="20907" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="20910" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="20915" class="Symbol">(((</a><a id="20918" href="#20775" class="Bound">p</a> <a id="20920" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20922" href="#20781" class="Bound">q</a><a id="20923" class="Symbol">)</a> <a id="20925" href="#14109" class="Function Operator">⋊</a> <a id="20927" href="#20777" class="Bound">f</a> <a id="20929" href="#20785" class="Bound">x</a><a id="20930" class="Symbol">)</a> <a id="20932" href="#13390" class="Function Operator">∪_</a><a id="20934" class="Symbol">)</a> <a id="20936" href="#20794" class="Bound">P</a> <a id="20938" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="20944" class="Symbol">((</a><a id="20946" href="#20775" class="Bound">p</a> <a id="20948" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="20950" href="#20781" class="Bound">q</a><a id="20951" class="Symbol">)</a> <a id="20953" href="#14109" class="Function Operator">⋊</a> <a id="20955" href="#20777" class="Bound">f</a> <a id="20957" href="#20785" class="Bound">x</a><a id="20958" class="Symbol">)</a> <a id="20960" href="#13390" class="Function Operator">∪</a> <a id="20962" class="Symbol">(</a><a id="20963" href="#20775" class="Bound">p</a> <a id="20965" href="#14109" class="Function Operator">⋊</a> <a id="20967" class="Symbol">(</a><a id="20968" href="#20789" class="Bound">xs</a> <a id="20971" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="20975" href="#20777" class="Bound">f</a><a id="20976" class="Symbol">))</a> <a id="20979" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="20982" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="20987" class="Symbol">(</a><a id="20988" href="#13390" class="Function Operator">_∪</a> <a id="20991" class="Symbol">(</a><a id="20992" href="#20775" class="Bound">p</a> <a id="20994" href="#14109" class="Function Operator">⋊</a> <a id="20996" class="Symbol">(</a><a id="20997" href="#20789" class="Bound">xs</a> <a id="21000" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21004" href="#20777" class="Bound">f</a><a id="21005" class="Symbol">)))</a> <a id="21009" class="Symbol">(</a><a id="21010" href="#19907" class="Function">*-assoc-⋊</a> <a id="21020" href="#20775" class="Bound">p</a> <a id="21022" href="#20781" class="Bound">q</a> <a id="21024" class="Symbol">(</a><a id="21025" href="#20777" class="Bound">f</a> <a id="21027" href="#20785" class="Bound">x</a><a id="21028" class="Symbol">))</a> <a id="21031" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="21037" class="Symbol">(</a><a id="21038" href="#20775" class="Bound">p</a> <a id="21040" href="#14109" class="Function Operator">⋊</a> <a id="21042" class="Symbol">(</a><a id="21043" href="#20781" class="Bound">q</a> <a id="21045" href="#14109" class="Function Operator">⋊</a> <a id="21047" href="#20777" class="Bound">f</a> <a id="21049" href="#20785" class="Bound">x</a><a id="21050" class="Symbol">))</a> <a id="21053" href="#13390" class="Function Operator">∪</a> <a id="21055" class="Symbol">(</a><a id="21056" href="#20775" class="Bound">p</a> <a id="21058" href="#14109" class="Function Operator">⋊</a> <a id="21060" class="Symbol">(</a><a id="21061" href="#20789" class="Bound">xs</a> <a id="21064" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21068" href="#20777" class="Bound">f</a><a id="21069" class="Symbol">))</a> <a id="21072" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="21075" href="#16654" class="Function">⋊-distribˡ</a> <a id="21086" href="#20775" class="Bound">p</a> <a id="21088" class="Symbol">(</a><a id="21089" href="#20781" class="Bound">q</a> <a id="21091" href="#14109" class="Function Operator">⋊</a> <a id="21093" href="#20777" class="Bound">f</a> <a id="21095" href="#20785" class="Bound">x</a><a id="21096" class="Symbol">)</a> <a id="21098" class="Symbol">(</a><a id="21099" href="#20789" class="Bound">xs</a> <a id="21102" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21106" href="#20777" class="Bound">f</a><a id="21107" class="Symbol">)</a> <a id="21109" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="21115" href="#20775" class="Bound">p</a> <a id="21117" href="#14109" class="Function Operator">⋊</a> <a id="21119" class="Symbol">((</a><a id="21121" href="#20781" class="Bound">q</a> <a id="21123" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21125" href="#20785" class="Bound">x</a> <a id="21127" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21129" href="#20789" class="Bound">xs</a><a id="21131" class="Symbol">)</a> <a id="21133" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21137" href="#20777" class="Bound">f</a><a id="21138" class="Symbol">)</a> <a id="21140" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="&gt;&gt;=-idˡ"></a><a id="21143" href="#21143" class="Function">&gt;&gt;=-idˡ</a> <a id="21151" class="Symbol">:</a> <a id="21153" class="Symbol">(</a><a id="21154" href="#21154" class="Bound">x</a> <a id="21156" class="Symbol">:</a> <a id="21158" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="21159" class="Symbol">)</a> <a id="21161" class="Symbol">→</a> <a id="21163" class="Symbol">(</a><a id="21164" href="#21164" class="Bound">f</a> <a id="21166" class="Symbol">:</a> <a id="21168" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="21170" class="Symbol">→</a> <a id="21172" href="#8679" class="Datatype">𝒫</a> <a id="21174" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="21175" class="Symbol">)</a>
      <a id="21183" class="Symbol">→</a> <a id="21185" class="Symbol">(</a><a id="21186" href="#15418" class="Function">pure</a> <a id="21191" href="#21154" class="Bound">x</a> <a id="21193" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21197" href="#21164" class="Bound">f</a><a id="21198" class="Symbol">)</a> <a id="21200" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="21202" href="#21164" class="Bound">f</a> <a id="21204" href="#21154" class="Bound">x</a>
<a id="21206" href="#21143" class="Function">&gt;&gt;=-idˡ</a> <a id="21214" href="#21214" class="Bound">x</a> <a id="21216" href="#21216" class="Bound">f</a> <a id="21218" class="Symbol">=</a>
  <a id="21222" href="#15418" class="Function">pure</a> <a id="21227" href="#21214" class="Bound">x</a> <a id="21229" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21233" href="#21216" class="Bound">f</a> <a id="21235" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
  <a id="21241" class="Symbol">(</a><a id="21242" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21245" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21247" href="#21214" class="Bound">x</a> <a id="21249" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21251" href="#8715" class="InductiveConstructor">[]</a><a id="21253" class="Symbol">)</a> <a id="21255" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21259" href="#21216" class="Bound">f</a> <a id="21261" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
  <a id="21267" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21270" href="#14109" class="Function Operator">⋊</a> <a id="21272" href="#21216" class="Bound">f</a> <a id="21274" href="#21214" class="Bound">x</a> <a id="21276" href="#13390" class="Function Operator">∪</a> <a id="21278" href="#8715" class="InductiveConstructor">[]</a> <a id="21281" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21285" href="#21216" class="Bound">f</a> <a id="21287" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
  <a id="21293" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21296" href="#14109" class="Function Operator">⋊</a> <a id="21298" href="#21216" class="Bound">f</a> <a id="21300" href="#21214" class="Bound">x</a> <a id="21302" href="#13390" class="Function Operator">∪</a> <a id="21304" href="#8715" class="InductiveConstructor">[]</a> <a id="21307" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="21310" href="#17140" class="Function">∪-idʳ</a> <a id="21316" class="Symbol">(</a><a id="21317" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21320" href="#14109" class="Function Operator">⋊</a> <a id="21322" href="#21216" class="Bound">f</a> <a id="21324" href="#21214" class="Bound">x</a><a id="21325" class="Symbol">)</a> <a id="21327" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
  <a id="21331" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21334" href="#14109" class="Function Operator">⋊</a> <a id="21336" href="#21216" class="Bound">f</a> <a id="21338" href="#21214" class="Bound">x</a> <a id="21340" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="21343" href="#18904" class="Function">1⋊</a> <a id="21346" class="Symbol">(</a><a id="21347" href="#21216" class="Bound">f</a> <a id="21349" href="#21214" class="Bound">x</a><a id="21350" class="Symbol">)</a> <a id="21352" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
  <a id="21356" href="#21216" class="Bound">f</a> <a id="21358" href="#21214" class="Bound">x</a> <a id="21360" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="&gt;&gt;=-idʳ"></a><a id="21363" href="#21363" class="Function">&gt;&gt;=-idʳ</a> <a id="21371" class="Symbol">:</a> <a id="21373" class="Symbol">(</a><a id="21374" href="#21374" class="Bound">xs</a> <a id="21377" class="Symbol">:</a> <a id="21379" href="#8679" class="Datatype">𝒫</a> <a id="21381" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="21382" class="Symbol">)</a> <a id="21384" class="Symbol">→</a> <a id="21386" href="#21374" class="Bound">xs</a> <a id="21389" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21393" href="#15418" class="Function">pure</a> <a id="21398" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="21400" href="#21374" class="Bound">xs</a>
<a id="21403" href="#21363" class="Function">&gt;&gt;=-idʳ</a> <a id="21411" class="Symbol">=</a> <a id="21413" href="#12103" class="Function Operator">⟦</a> <a id="21415" href="#21449" class="Function">&gt;&gt;=-idʳ′</a> <a id="21424" href="#12103" class="Function Operator">⟧⇓</a>
  <a id="21429" class="Keyword">module</a> <a id="Law1"></a><a id="21436" href="#21436" class="Module">Law1</a> <a id="21441" class="Keyword">where</a>
  <a id="Law1.&gt;&gt;=-idʳ′"></a><a id="21449" href="#21449" class="Function">&gt;&gt;=-idʳ′</a> <a id="21458" class="Symbol">:</a> <a id="21460" href="#12139" class="Function">⟦</a> <a id="21462" href="#21462" class="Bound">xs</a> <a id="21465" href="#12139" class="Function">∈𝒫</a> <a id="21468" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="21470" href="#12139" class="Function">⇒</a> <a id="21472" href="#21462" class="Bound">xs</a> <a id="21475" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21479" href="#15418" class="Function">pure</a> <a id="21484" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="21486" href="#21462" class="Bound">xs</a> <a id="21489" href="#12139" class="Function">⟧</a>
  <a id="21493" href="#11443" class="Field Operator">⟦</a> <a id="21495" href="#21449" class="Function">&gt;&gt;=-idʳ′</a> <a id="21504" href="#11443" class="Field Operator">⟧-prop</a> <a id="21511" class="Symbol">=</a> <a id="21513" href="#8921" class="InductiveConstructor">trunc</a> <a id="21519" class="Symbol">_</a> <a id="21521" class="Symbol">_</a>
  <a id="21525" href="#11481" class="Field Operator">⟦</a> <a id="21527" href="#21449" class="Function">&gt;&gt;=-idʳ′</a> <a id="21536" href="#11481" class="Field Operator">⟧[]</a> <a id="21540" class="Symbol">=</a> <a id="21542" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="21549" href="#11498" class="Field Operator">⟦</a> <a id="21551" href="#21449" class="Function">&gt;&gt;=-idʳ′</a> <a id="21560" href="#11498" class="Field Operator">⟧</a> <a id="21562" href="#21562" class="Bound">p</a> <a id="21564" href="#11498" class="Field Operator">&amp;</a> <a id="21566" href="#21566" class="Bound">x</a> <a id="21568" href="#11498" class="Field Operator">∷</a> <a id="21570" href="#21570" class="Bound">xs</a> <a id="21573" href="#11498" class="Field Operator">⟨</a> <a id="21575" href="#21575" class="Bound">P</a> <a id="21577" href="#11498" class="Field Operator">⟩</a> <a id="21579" class="Symbol">=</a>
    <a id="21585" class="Symbol">((</a><a id="21587" href="#21562" class="Bound">p</a> <a id="21589" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21591" href="#21566" class="Bound">x</a> <a id="21593" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21595" href="#21570" class="Bound">xs</a><a id="21597" class="Symbol">)</a> <a id="21599" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21603" href="#15418" class="Function">pure</a><a id="21607" class="Symbol">)</a> <a id="21609" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="21617" href="#21562" class="Bound">p</a> <a id="21619" href="#14109" class="Function Operator">⋊</a> <a id="21621" class="Symbol">(</a><a id="21622" href="#15418" class="Function">pure</a> <a id="21627" href="#21566" class="Bound">x</a><a id="21628" class="Symbol">)</a> <a id="21630" href="#13390" class="Function Operator">∪</a> <a id="21632" class="Symbol">(</a><a id="21633" href="#21570" class="Bound">xs</a> <a id="21636" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21640" href="#15418" class="Function">pure</a><a id="21644" class="Symbol">)</a> <a id="21646" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="21654" href="#21562" class="Bound">p</a> <a id="21656" href="#14109" class="Function Operator">⋊</a> <a id="21658" class="Symbol">(</a><a id="21659" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21662" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21664" href="#21566" class="Bound">x</a> <a id="21666" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21668" href="#8715" class="InductiveConstructor">[]</a><a id="21670" class="Symbol">)</a> <a id="21672" href="#13390" class="Function Operator">∪</a> <a id="21674" class="Symbol">(</a><a id="21675" href="#21570" class="Bound">xs</a> <a id="21678" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21682" href="#15418" class="Function">pure</a><a id="21686" class="Symbol">)</a> <a id="21688" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="21696" href="#21562" class="Bound">p</a> <a id="21698" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="21700" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21703" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21705" href="#21566" class="Bound">x</a> <a id="21707" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21709" href="#8715" class="InductiveConstructor">[]</a> <a id="21712" href="#13390" class="Function Operator">∪</a> <a id="21714" class="Symbol">(</a><a id="21715" href="#21570" class="Bound">xs</a> <a id="21718" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21722" href="#15418" class="Function">pure</a><a id="21726" class="Symbol">)</a> <a id="21728" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="21736" href="#21562" class="Bound">p</a> <a id="21738" href="../code/probability/ProbabilityModule.Semirings.html#234" class="Field Operator">*</a> <a id="21740" href="../code/probability/ProbabilityModule.Semirings.html#265" class="Field">1#</a> <a id="21743" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21745" href="#21566" class="Bound">x</a> <a id="21747" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21749" class="Symbol">(</a><a id="21750" href="#21570" class="Bound">xs</a> <a id="21753" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21757" href="#15418" class="Function">pure</a><a id="21761" class="Symbol">)</a> <a id="21763" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="21766" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="21771" class="Symbol">(</a><a id="21772" href="#8727" class="InductiveConstructor Operator">_&amp;</a> <a id="21775" href="#21566" class="Bound">x</a> <a id="21777" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21779" class="Symbol">(</a><a id="21780" href="#21570" class="Bound">xs</a> <a id="21783" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21787" href="#15418" class="Function">pure</a><a id="21791" class="Symbol">))</a> <a id="21794" class="Symbol">(</a><a id="21795" href="../code/probability/ProbabilityModule.Semirings.html#456" class="Field">*1</a> <a id="21798" href="#21562" class="Bound">p</a><a id="21799" class="Symbol">)</a> <a id="21801" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="21807" href="#21562" class="Bound">p</a> <a id="21809" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21811" href="#21566" class="Bound">x</a> <a id="21813" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21815" href="#21570" class="Bound">xs</a> <a id="21818" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21822" href="#15418" class="Function">pure</a> <a id="21827" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="21830" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="21835" class="Symbol">(</a><a id="21836" href="#21562" class="Bound">p</a> <a id="21838" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21840" href="#21566" class="Bound">x</a> <a id="21842" href="#8727" class="InductiveConstructor Operator">∷_</a><a id="21844" class="Symbol">)</a> <a id="21846" href="#21575" class="Bound">P</a> <a id="21848" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="21854" href="#21562" class="Bound">p</a> <a id="21856" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="21858" href="#21566" class="Bound">x</a> <a id="21860" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="21862" href="#21570" class="Bound">xs</a> <a id="21865" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>

<a id="&gt;&gt;=-assoc"></a><a id="21868" href="#21868" class="Function">&gt;&gt;=-assoc</a> <a id="21878" class="Symbol">:</a> <a id="21880" class="Symbol">(</a><a id="21881" href="#21881" class="Bound">xs</a> <a id="21884" class="Symbol">:</a> <a id="21886" href="#8679" class="Datatype">𝒫</a> <a id="21888" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a><a id="21889" class="Symbol">)</a> <a id="21891" class="Symbol">→</a> <a id="21893" class="Symbol">(</a><a id="21894" href="#21894" class="Bound">f</a> <a id="21896" class="Symbol">:</a> <a id="21898" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="21900" class="Symbol">→</a> <a id="21902" href="#8679" class="Datatype">𝒫</a> <a id="21904" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="21905" class="Symbol">)</a> <a id="21907" class="Symbol">→</a> <a id="21909" class="Symbol">(</a><a id="21910" href="#21910" class="Bound">g</a> <a id="21912" class="Symbol">:</a> <a id="21914" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a> <a id="21916" class="Symbol">→</a> <a id="21918" href="#8679" class="Datatype">𝒫</a> <a id="21920" href="../code/probability/ProbabilityModule.Utils.html#218" class="Generalizable">C</a><a id="21921" class="Symbol">)</a>
      <a id="21929" class="Symbol">→</a> <a id="21931" class="Symbol">((</a><a id="21933" href="#21881" class="Bound">xs</a> <a id="21936" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21940" href="#21894" class="Bound">f</a><a id="21941" class="Symbol">)</a> <a id="21943" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21947" href="#21910" class="Bound">g</a><a id="21948" class="Symbol">)</a> <a id="21950" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="21952" href="#21881" class="Bound">xs</a> <a id="21955" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21959" class="Symbol">(λ</a> <a id="21962" href="#21962" class="Bound">x</a> <a id="21964" class="Symbol">→</a> <a id="21966" href="#21894" class="Bound">f</a> <a id="21968" href="#21962" class="Bound">x</a> <a id="21970" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="21974" href="#21910" class="Bound">g</a><a id="21975" class="Symbol">)</a>
<a id="21977" href="#21868" class="Function">&gt;&gt;=-assoc</a> <a id="21987" class="Symbol">=</a> <a id="21989" class="Symbol">λ</a> <a id="21991" href="#21991" class="Bound">xs</a> <a id="21994" href="#21994" class="Bound">f</a> <a id="21996" href="#21996" class="Bound">g</a> <a id="21998" class="Symbol">→</a> <a id="22000" href="#12103" class="Function Operator">⟦</a> <a id="22002" href="#22045" class="Function">&gt;&gt;=-assoc′</a> <a id="22013" href="#21994" class="Bound">f</a> <a id="22015" href="#21996" class="Bound">g</a> <a id="22017" href="#12103" class="Function Operator">⟧⇓</a> <a id="22020" href="#21991" class="Bound">xs</a>
  <a id="22025" class="Keyword">module</a> <a id="Law3"></a><a id="22032" href="#22032" class="Module">Law3</a> <a id="22037" class="Keyword">where</a>
  <a id="Law3.&gt;&gt;=-assoc′"></a><a id="22045" href="#22045" class="Function">&gt;&gt;=-assoc′</a> <a id="22056" class="Symbol">:</a> <a id="22058" class="Symbol">(</a><a id="22059" href="#22059" class="Bound">f</a> <a id="22061" class="Symbol">:</a> <a id="22063" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="22065" class="Symbol">→</a> <a id="22067" href="#8679" class="Datatype">𝒫</a> <a id="22069" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a><a id="22070" class="Symbol">)</a> <a id="22072" class="Symbol">→</a> <a id="22074" class="Symbol">(</a><a id="22075" href="#22075" class="Bound">g</a> <a id="22077" class="Symbol">:</a> <a id="22079" href="../code/probability/ProbabilityModule.Utils.html#206" class="Generalizable">B</a> <a id="22081" class="Symbol">→</a> <a id="22083" href="#8679" class="Datatype">𝒫</a> <a id="22085" href="../code/probability/ProbabilityModule.Utils.html#218" class="Generalizable">C</a><a id="22086" class="Symbol">)</a> <a id="22088" class="Symbol">→</a> <a id="22090" href="#12139" class="Function">⟦</a> <a id="22092" href="#22092" class="Bound">xs</a> <a id="22095" href="#12139" class="Function">∈𝒫</a> <a id="22098" href="../code/probability/ProbabilityModule.Utils.html#194" class="Generalizable">A</a> <a id="22100" href="#12139" class="Function">⇒</a> <a id="22102" class="Symbol">((</a><a id="22104" href="#22092" class="Bound">xs</a> <a id="22107" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22111" href="#22059" class="Bound">f</a><a id="22112" class="Symbol">)</a> <a id="22114" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22118" href="#22075" class="Bound">g</a><a id="22119" class="Symbol">)</a> <a id="22121" href="Agda.Builtin.Cubical.Path.html#353" class="Function Operator">≡</a> <a id="22123" href="#22092" class="Bound">xs</a> <a id="22126" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22130" class="Symbol">(λ</a> <a id="22133" href="#22133" class="Bound">x</a> <a id="22135" class="Symbol">→</a> <a id="22137" href="#22059" class="Bound">f</a> <a id="22139" href="#22133" class="Bound">x</a> <a id="22141" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22145" href="#22075" class="Bound">g</a><a id="22146" class="Symbol">)</a> <a id="22148" href="#12139" class="Function">⟧</a>
  <a id="22152" href="#11443" class="Field Operator">⟦</a> <a id="22154" href="#22045" class="Function">&gt;&gt;=-assoc′</a> <a id="22165" href="#22165" class="Bound">f</a> <a id="22167" href="#22167" class="Bound">g</a> <a id="22169" href="#11443" class="Field Operator">⟧-prop</a> <a id="22176" class="Symbol">=</a> <a id="22178" href="#8921" class="InductiveConstructor">trunc</a> <a id="22184" class="Symbol">_</a> <a id="22186" class="Symbol">_</a>
  <a id="22190" href="#11481" class="Field Operator">⟦</a> <a id="22192" href="#22045" class="Function">&gt;&gt;=-assoc′</a> <a id="22203" href="#22203" class="Bound">f</a> <a id="22205" href="#22205" class="Bound">g</a> <a id="22207" href="#11481" class="Field Operator">⟧[]</a> <a id="22211" class="Symbol">=</a> <a id="22213" href="../code/probability/Cubical.Foundations.Prelude.html#827" class="Function">refl</a>
  <a id="22220" href="#11498" class="Field Operator">⟦</a> <a id="22222" href="#22045" class="Function">&gt;&gt;=-assoc′</a> <a id="22233" href="#22233" class="Bound">f</a> <a id="22235" href="#22235" class="Bound">g</a> <a id="22237" href="#11498" class="Field Operator">⟧</a> <a id="22239" href="#22239" class="Bound">p</a> <a id="22241" href="#11498" class="Field Operator">&amp;</a> <a id="22243" href="#22243" class="Bound">x</a> <a id="22245" href="#11498" class="Field Operator">∷</a> <a id="22247" href="#22247" class="Bound">xs</a> <a id="22250" href="#11498" class="Field Operator">⟨</a> <a id="22252" href="#22252" class="Bound">P</a> <a id="22254" href="#11498" class="Field Operator">⟩</a> <a id="22256" class="Symbol">=</a>
    <a id="22262" class="Symbol">(((</a><a id="22265" href="#22239" class="Bound">p</a> <a id="22267" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="22269" href="#22243" class="Bound">x</a> <a id="22271" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="22273" href="#22247" class="Bound">xs</a><a id="22275" class="Symbol">)</a> <a id="22277" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22281" href="#22233" class="Bound">f</a><a id="22282" class="Symbol">)</a> <a id="22284" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22288" href="#22235" class="Bound">g</a><a id="22289" class="Symbol">)</a> <a id="22291" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="22299" class="Symbol">((</a><a id="22301" href="#22239" class="Bound">p</a> <a id="22303" href="#14109" class="Function Operator">⋊</a> <a id="22305" href="#22233" class="Bound">f</a> <a id="22307" href="#22243" class="Bound">x</a> <a id="22309" href="#13390" class="Function Operator">∪</a> <a id="22311" class="Symbol">(</a><a id="22312" href="#22247" class="Bound">xs</a> <a id="22315" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22319" href="#22233" class="Bound">f</a><a id="22320" class="Symbol">))</a> <a id="22323" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22327" href="#22235" class="Bound">g</a><a id="22328" class="Symbol">)</a> <a id="22330" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="22333" href="#19228" class="Function">&gt;&gt;=-distrib</a> <a id="22345" class="Symbol">(</a><a id="22346" href="#22239" class="Bound">p</a> <a id="22348" href="#14109" class="Function Operator">⋊</a> <a id="22350" href="#22233" class="Bound">f</a> <a id="22352" href="#22243" class="Bound">x</a><a id="22353" class="Symbol">)</a> <a id="22355" class="Symbol">(</a><a id="22356" href="#22247" class="Bound">xs</a> <a id="22359" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22363" href="#22233" class="Bound">f</a><a id="22364" class="Symbol">)</a> <a id="22366" href="#22235" class="Bound">g</a> <a id="22368" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="22374" class="Symbol">((</a><a id="22376" href="#22239" class="Bound">p</a> <a id="22378" href="#14109" class="Function Operator">⋊</a> <a id="22380" href="#22233" class="Bound">f</a> <a id="22382" href="#22243" class="Bound">x</a><a id="22383" class="Symbol">)</a> <a id="22385" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22389" href="#22235" class="Bound">g</a><a id="22390" class="Symbol">)</a> <a id="22392" href="#13390" class="Function Operator">∪</a> <a id="22394" class="Symbol">((</a><a id="22396" href="#22247" class="Bound">xs</a> <a id="22399" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22403" href="#22233" class="Bound">f</a><a id="22404" class="Symbol">)</a> <a id="22406" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22410" href="#22235" class="Bound">g</a><a id="22411" class="Symbol">)</a> <a id="22413" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="22416" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="22421" class="Symbol">((</a><a id="22423" href="#22239" class="Bound">p</a> <a id="22425" href="#14109" class="Function Operator">⋊</a> <a id="22427" href="#22233" class="Bound">f</a> <a id="22429" href="#22243" class="Bound">x</a><a id="22430" class="Symbol">)</a> <a id="22432" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22436" href="#22235" class="Bound">g</a> <a id="22438" href="#13390" class="Function Operator">∪_</a><a id="22440" class="Symbol">)</a> <a id="22442" href="#22252" class="Bound">P</a> <a id="22444" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="22450" class="Symbol">((</a><a id="22452" href="#22239" class="Bound">p</a> <a id="22454" href="#14109" class="Function Operator">⋊</a> <a id="22456" href="#22233" class="Bound">f</a> <a id="22458" href="#22243" class="Bound">x</a><a id="22459" class="Symbol">)</a> <a id="22461" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22465" href="#22235" class="Bound">g</a><a id="22466" class="Symbol">)</a> <a id="22468" href="#13390" class="Function Operator">∪</a> <a id="22470" class="Symbol">(</a><a id="22471" href="#22247" class="Bound">xs</a> <a id="22474" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22478" class="Symbol">(λ</a> <a id="22481" href="#22481" class="Bound">y</a> <a id="22483" class="Symbol">→</a> <a id="22485" href="#22233" class="Bound">f</a> <a id="22487" href="#22481" class="Bound">y</a> <a id="22489" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22493" href="#22235" class="Bound">g</a><a id="22494" class="Symbol">))</a> <a id="22497" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">≡⟨</a> <a id="22500" href="../code/probability/Cubical.Foundations.Prelude.html#1027" class="Function">cong</a> <a id="22505" class="Symbol">(</a><a id="22506" href="#13390" class="Function Operator">_∪</a> <a id="22509" class="Symbol">(</a><a id="22510" href="#22247" class="Bound">xs</a> <a id="22513" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22517" class="Symbol">(λ</a> <a id="22520" href="#22520" class="Bound">y</a> <a id="22522" class="Symbol">→</a> <a id="22524" href="#22233" class="Bound">f</a> <a id="22526" href="#22520" class="Bound">y</a> <a id="22528" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22532" href="#22235" class="Bound">g</a><a id="22533" class="Symbol">)))</a> <a id="22537" class="Symbol">(</a><a id="22538" href="#20451" class="Function">⋊-assoc-&gt;&gt;=</a> <a id="22550" href="#22239" class="Bound">p</a> <a id="22552" class="Symbol">(</a><a id="22553" href="#22233" class="Bound">f</a> <a id="22555" href="#22243" class="Bound">x</a><a id="22556" class="Symbol">)</a> <a id="22558" href="#22235" class="Bound">g</a><a id="22559" class="Symbol">)</a> <a id="22561" href="../code/probability/ProbabilityModule.Utils.html#436" class="Function">⟩</a>
    <a id="22567" href="#22239" class="Bound">p</a> <a id="22569" href="#14109" class="Function Operator">⋊</a> <a id="22571" class="Symbol">(</a><a id="22572" href="#22233" class="Bound">f</a> <a id="22574" href="#22243" class="Bound">x</a> <a id="22576" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22580" href="#22235" class="Bound">g</a><a id="22581" class="Symbol">)</a> <a id="22583" href="#13390" class="Function Operator">∪</a> <a id="22585" class="Symbol">(</a><a id="22586" href="#22247" class="Bound">xs</a> <a id="22589" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22593" class="Symbol">(λ</a> <a id="22596" href="#22596" class="Bound">y</a> <a id="22598" class="Symbol">→</a> <a id="22600" href="#22233" class="Bound">f</a> <a id="22602" href="#22596" class="Bound">y</a> <a id="22604" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22608" href="#22235" class="Bound">g</a><a id="22609" class="Symbol">))</a> <a id="22612" href="../code/probability/ProbabilityModule.Utils.html#572" class="Function Operator">≡⟨⟩</a>
    <a id="22620" class="Symbol">((</a><a id="22622" href="#22239" class="Bound">p</a> <a id="22624" href="#8727" class="InductiveConstructor Operator">&amp;</a> <a id="22626" href="#22243" class="Bound">x</a> <a id="22628" href="#8727" class="InductiveConstructor Operator">∷</a> <a id="22630" href="#22247" class="Bound">xs</a><a id="22632" class="Symbol">)</a> <a id="22634" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22638" class="Symbol">(λ</a> <a id="22641" href="#22641" class="Bound">y</a> <a id="22643" class="Symbol">→</a> <a id="22645" href="#22233" class="Bound">f</a> <a id="22647" href="#22641" class="Bound">y</a> <a id="22649" href="#18081" class="Function Operator">&gt;&gt;=</a> <a id="22653" href="#22235" class="Bound">g</a><a id="22654" class="Symbol">))</a> <a id="22657" href="../code/probability/Cubical.Foundations.Prelude.html#2745" class="Function Operator">∎</a>
</pre>
</details>
<h1 id="conclusion">Conclusion</h1>
<p>I’ve really enjoyed working with cubical Agda so far, and the proofs
above were a pleasure to write. I think I can use the above definition
to get a workable differential privacy monad, also.</p>
<p>Anyway, all the code is available <a
href="https://oisdk.github.io/agda-cubical-probability/Probability.html">here</a>.</p>
]]></description>
    <pubDate>Wed, 17 Apr 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-04-17-cubical-probability.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Permutations By Sorting</title>
    <link>https://doisinkidney.com/posts/2019-03-24-permutations-by-sorting.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 24, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>A naive—and wrong—way to shuffle a list is to assign each element in
the list a random number, and then sort it. It might not be immediately
obvious why: <span class="citation"
data-cites="kiselyov_provably_2002">Kiselyov (<a
href="#ref-kiselyov_provably_2002" role="doc-biblioref">2002</a>)</span>
has a good explanation as to the problem. One way to think about it is
like this: choosing
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
random numbers each in the range
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">[</mo><mn>0</mn><mo>,</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">[0,n)</annotation></semantics></math>
has
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mi>n</mi><mi>n</mi></msup><annotation encoding="application/x-tex">n^n</annotation></semantics></math>
possible outcomes, whereas there are
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>!</mi></mrow><annotation encoding="application/x-tex">n!</annotation></semantics></math>
permutations. Since these don’t necessarily divide evenly into each
other, you’re going to have some bias.</p>
<h1 id="factorial-numbers">Factorial Numbers</h1>
<p>The first part of the fix is to figure out a way to get some random
data that has only
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>!</mi></mrow><annotation encoding="application/x-tex">n!</annotation></semantics></math>
possible values. The trick here will be to mimic the structure of a
factorial itself: taking
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>5</mn></mrow><annotation encoding="application/x-tex">n =
5</annotation></semantics></math>, the previous technique would have
yielded:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><mo>×</mo><mn>5</mn><mo>×</mo><mn>5</mn><mo>×</mo><mn>5</mn><mo>×</mo><mn>5</mn><mo>=</mo><msup><mn>5</mn><mn>5</mn></msup></mrow><annotation encoding="application/x-tex">5 \times 5 \times 5 \times 5 \times 5 = 5^5</annotation></semantics></math></p>
<p>possible values. But we want:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>5</mn><mo>×</mo><mn>4</mn><mo>×</mo><mn>3</mn><mo>×</mo><mn>2</mn><mo>×</mo><mn>1</mn><mo>=</mo><mn>5</mn><mi>!</mi></mrow><annotation encoding="application/x-tex">5 \times 4 \times 3 \times 2 \times 1 = 5!</annotation></semantics></math></p>
<p>The solution is simple, then! Simply decrement the range by one for
each position in the output list. In Haskell:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">nums ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> [<span class="dt">Int</span>]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>nums <span class="dv">0</span> <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>nums n <span class="ot">=</span> (<span class="op">:</span>) <span class="op">&lt;$&gt;</span> randomR (<span class="dv">0</span>,n) <span class="op">&lt;*&gt;</span> nums (n<span class="op">-</span><span class="dv">1</span>)</span></code></pre></div>
<p>As an aside, what we’ve done here is constructed a list of digits in
the <a
href="https://en.wikipedia.org/wiki/Factorial_number_system">factorial
number system</a>.</p>
<h1 id="sorts">Sorts</h1>
<p>Unfortunately, while we’ve figured out a way to get properly
distributed random data, we can’t yet sort it to shuffle our list. If we
look at the 6 factorial numbers generated for
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>=</mo><mn>5</mn></mrow><annotation encoding="application/x-tex">n = 5</annotation></semantics></math>,
we can see the problem:</p>
<pre><code>000
010
100
110
200
210</code></pre>
<p>Different values in the list will produce the same sort:
<code>100</code> and <code>200</code>, for instance.</p>
<h1 id="lehmer-codes">Lehmer Codes</h1>
<p>We need a way to map the numbers above to a particular permutation:
that’s precisely the problem solved by <a
href="https://en.wikipedia.org/wiki/Lehmer_code">Lehmer codes</a>. For
the numbers <code>110</code>, we can think of each digit as the relative
position to put that item from the string into. Some Haskell code might
make it clear:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>insert <span class="dv">0</span> x xs <span class="ot">=</span> x <span class="op">:</span> xs</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>insert i x (y<span class="op">:</span>ys) <span class="ot">=</span> y <span class="op">:</span> insert (i<span class="op">-</span><span class="dv">1</span>) x ys</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="ot">shuffle ::</span> [a] <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [a]</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>shuffle xs ys <span class="ot">=</span> <span class="fu">foldr</span> (<span class="fu">uncurry</span> insert) [] (<span class="fu">zip</span> ys xs)</span></code></pre></div>
<p>And we can step through its execution:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>shuffle <span class="st">&quot;abc&quot;</span> [<span class="dv">1</span>,<span class="dv">1</span>,<span class="dv">0</span>]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="fu">foldr</span> (<span class="fu">uncurry</span> insert) [] [(<span class="dv">1</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">1</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">0</span>,<span class="ch">&#39;c&#39;</span>)]</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>insert <span class="dv">1</span> <span class="ch">&#39;a&#39;</span> (insert <span class="dv">1</span> <span class="ch">&#39;b&#39;</span> (insert <span class="dv">0</span> <span class="ch">&#39;c&#39;</span> []))</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>insert <span class="dv">1</span> <span class="ch">&#39;a&#39;</span> (insert <span class="dv">1</span> <span class="ch">&#39;b&#39;</span> <span class="st">&quot;c&quot;</span>)</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>insert <span class="dv">1</span> <span class="ch">&#39;a&#39;</span> <span class="st">&quot;cb&quot;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="ch">&#39;c&#39;</span> <span class="op">:</span> insert <span class="dv">0</span> <span class="ch">&#39;a&#39;</span> <span class="st">&quot;b&quot;</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;cab&quot;</span></span></code></pre></div>
<h1 id="dualities-of-sorts">Dualities of Sorts</h1>
<p>Notice the similarity of the function above to a standard insertion
sort:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>insert x [] <span class="ot">=</span> x <span class="op">:</span> []</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>insert x (y<span class="op">:</span>ys)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> x <span class="op">&lt;=</span> y <span class="ot">=</span> x <span class="op">:</span> y <span class="op">:</span> ys</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> y <span class="op">:</span> insert x ys</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ot">insertSort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>insertSort <span class="ot">=</span> <span class="fu">foldr</span> insert []</span></code></pre></div>
<p>The “comparison” is a little strange—we have to take into account
relative position—but the shape is almost identical. Once I spot
something like that, my first thought is to see if the relationship
extends to a better
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>
sort, but there’s something else I’d like to look at first.</p>
<p>“A Duality of Sorts” <span class="citation"
data-cites="hinze_duality_2013">(<a href="#ref-hinze_duality_2013"
role="doc-biblioref">Hinze, Magalhães, and Wu 2013</a>)</span> is a
paper based on the interesting symmetry between insertion sort and
selection sort [There’s also a video of Graham Hutton explaining the
idea; <span class="citation" data-cites="haran_sorting_2016">Haran (<a
href="#ref-haran_sorting_2016"
role="doc-biblioref">2016</a>)</span>].</p>
<p>With that paper in mind, can we rewrite <code>shuffle</code> as a
selection-based algorithm? We can indeed!</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">pop ::</span> [(<span class="dt">Int</span>,a)] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (a, [(<span class="dt">Int</span>,a)])</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>pop [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>pop ((<span class="dv">0</span>,x)<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Just</span> (x, xs)</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>pop ((i,x)<span class="op">:</span>xs) <span class="ot">=</span> (<span class="fu">fmap</span><span class="op">.</span><span class="fu">fmap</span>) ((i<span class="op">-</span><span class="dv">1</span>,x)<span class="op">:</span>) (pop xs)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="ot">shuffle ::</span> [a] <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [a]</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>shuffle xs ys <span class="ot">=</span> unfoldr pop (<span class="fu">zip</span> ys xs)</span></code></pre></div>
<p>While the symmetry is pleasing, the paper details how to make the
relationship explicit, using the same function for both selection and
insertion sort:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>swop <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>swop (<span class="dt">Cons</span> a (x , <span class="dt">Nil</span>)) <span class="ot">=</span> <span class="dt">Cons</span> a (<span class="dt">Left</span> x)</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>swop (<span class="dt">Cons</span> a (x , <span class="dt">Cons</span> b x&#39;))</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">fst</span> a <span class="op">==</span> <span class="dv">0</span> <span class="ot">=</span> <span class="dt">Cons</span> a (<span class="dt">Left</span> x)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span>  <span class="ot">=</span> <span class="dt">Cons</span> b (<span class="dt">Right</span> (<span class="dt">Cons</span> (first <span class="fu">pred</span> a) x&#39;))</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="ot">ishuffle ::</span> [(<span class="dt">Int</span>,a)] <span class="ot">-&gt;</span> [(<span class="dt">Int</span>,a)]</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>ishuffle <span class="ot">=</span> cata (apo (swop <span class="op">.</span> <span class="fu">fmap</span> (<span class="fu">id</span> <span class="op">&amp;&amp;&amp;</span> project)))</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="ot">sshuffle ::</span> [(<span class="dt">Int</span>,a)] <span class="ot">-&gt;</span> [(<span class="dt">Int</span>,a)]</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>sshuffle <span class="ot">=</span> ana (para (<span class="fu">fmap</span> (<span class="fu">id</span> <span class="op">|||</span> embed) <span class="op">.</span> swop))</span></code></pre></div>
<h1 id="improved-efficiency">Improved Efficiency</h1>
<p>So now we have to upgrade our sorts: in the paper, merge sort is the
more efficient sort chosen, similarly to what I chose <a
href="2018-12-21-balancing-scans.html#random-shuffles">previously</a>.</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>merge [] ys <span class="ot">=</span> ys</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>merge xs [] <span class="ot">=</span> xs</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>merge ((x,i)<span class="op">:</span>xs) ((y,j)<span class="op">:</span>ys)</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> i <span class="op">&lt;=</span> j    <span class="ot">=</span> (x,i) <span class="op">:</span> merge xs ((y,j<span class="op">-</span>i)<span class="op">:</span>ys)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (y,j) <span class="op">:</span> merge ((x,i<span class="op">-</span>j<span class="op">-</span><span class="dv">1</span>)<span class="op">:</span>xs) ys</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>treeFold f <span class="ot">=</span> go</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>    go x [] <span class="ot">=</span> x</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    go a (b<span class="op">:</span>l) <span class="ot">=</span> go (f a b) (pairMap l)</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>    pairMap (x<span class="op">:</span>y<span class="op">:</span>rest) <span class="ot">=</span> f x y <span class="op">:</span> pairMap rest</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>    pairMap xs <span class="ot">=</span> xs</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>shuffle xs inds <span class="ot">=</span> <span class="fu">map</span> <span class="fu">fst</span> <span class="op">$</span> treeFold merge [] <span class="op">$</span> <span class="fu">map</span> <span class="fu">pure</span> <span class="op">$</span> <span class="fu">zip</span> xs inds</span></code></pre></div>
<p>However, I feel like merge sort is an upgrade of <em>insertion</em>
sort, not selection sort. Indeed, if you do the “split” step of merge
sort badly, i.e. by splitting very unevenly, merge sort in fact
<em>becomes</em> insertion sort!</p>
<p>So there’s a missing bit of this table:</p>
<table>
<thead>
<tr>
<th></th>
<th style="text-align: center;">Insertion</th>
<th style="text-align: center;">Selection</th>
</tr>
</thead>
<tbody>
<tr>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math></td>
<td style="text-align: center;">Insertion sort</td>
<td style="text-align: center;">Selection sort</td>
</tr>
<tr>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math></td>
<td style="text-align: center;">Merge sort</td>
<td style="text-align: center;">???</td>
</tr>
</tbody>
</table>
<p>I think it’s clear that quicksort is the algorithm that fits in
there: again, done badly it degrades to selection sort (if you
intentionally pick the pivot to be the worst element possible, i.e. the
smallest element).</p>
<p>There are more symmetries: merge sort splits the lists using their
structure, and merges them using the ordering of the elements. Quicksort
is the opposite, merging by concatenation, but splitting using order.
Finally, in merge sort adjacent elements are in the correct order after
the recursive call, but the two sides of the split are not. Again,
quicksort is precisely the opposite: adjacent elements have not been
compared (<em>before</em> the recursive call), but the two sides of the
split are correctly ordered.</p>
<p>Anyway, I haven’t yet formalised this duality (and I don’t know if I
can), but we <em>can</em> use it to produce a quicksort-based shuffle
algorithm:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>partition <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="fu">const</span> ([],[]))</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    f (y,j) ys i</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> i <span class="op">&lt;=</span> j    <span class="ot">=</span> <span class="fu">fmap</span>  ((y,j<span class="op">-</span>i)<span class="op">:</span>) (ys i)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> first ((y,j)<span class="op">:</span>) (ys (i<span class="op">-</span><span class="dv">1</span>))</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="ot">shuffle ::</span> [a] <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [a]</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>shuffle xs ys <span class="ot">=</span> go (<span class="fu">zip</span> xs ys)</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> []</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>    go ((x,i)<span class="op">:</span>xs) <span class="ot">=</span> <span class="kw">case</span> partition xs i <span class="kw">of</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>        (ls,rs) <span class="ot">-&gt;</span> go ls <span class="op">++</span> [x] <span class="op">++</span> go rs</span></code></pre></div>
<p>That’s all for this post! The algorithms can all be translated into
Agda or Idris: I’m currently working on a way to represent permutations
that isn’t
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>
using them. If I figure out a way to properly dualise quicksort and
merge sort I’ll do a small write up as well <span class="citation"
data-cites="hinze_sorting_2012">(I’m currently working my way through <a
href="#ref-hinze_sorting_2012" role="doc-biblioref">Hinze et al.
2012</a> for ideas)</span>. Finally, I’d like to explore some other
sorting algorithms as permutation algorithms: sorting networks seem
especially related to “permutations by swapping”.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-haran_sorting_2016" class="csl-entry" role="listitem">
Haran, Brady. 2016. <span>“Sorting <span>Secret</span>.”</span> <a
href="https://www.youtube.com/watch?v=pcJHkWwjNl4"
class="uri">https://www.youtube.com/watch?v=pcJHkWwjNl4</a>.
</div>
<div id="ref-hinze_sorting_2012" class="csl-entry" role="listitem">
Hinze, Ralf, Daniel W. H. James, Thomas Harper, Nicolas Wu, and José
Pedro Magalhães. 2012. <span>“Sorting with bialgebras and distributive
laws.”</span> In <em>Proceedings of the 8th <span>ACM SIGPLAN</span>
workshop on <span>Generic</span> programming - <span>WGP</span>
’12</em>, 69. Copenhagen, Denmark: <span>ACM Press</span>. doi:<a
href="https://doi.org/10.1145/2364394.2364405">10.1145/2364394.2364405</a>.
</div>
<div id="ref-hinze_duality_2013" class="csl-entry" role="listitem">
Hinze, Ralf, José Pedro Magalhães, and Nicolas Wu. 2013. <span>“A
<span>Duality</span> of <span>Sorts</span>.”</span> In <em>The
<span>Beauty</span> of <span>Functional Code</span>: <span>Essays
Dedicated</span> to <span>Rinus Plasmeijer</span> on the
<span>Occasion</span> of <span>His</span> 61st
<span>Birthday</span></em>, ed by. Peter Achten and Pieter Koopman,
151–167. Lecture <span>Notes</span> in <span>Computer Science</span>.
Berlin, Heidelberg: <span>Springer Berlin Heidelberg</span>. doi:<a
href="https://doi.org/10.1007/978-3-642-40355-2_11">10.1007/978-3-642-40355-2_11</a>.
</div>
<div id="ref-kiselyov_provably_2002" class="csl-entry" role="listitem">
Kiselyov, Oleg. 2002. <span>“Provably perfect random shuffling and its
pure functional implementations.”</span> <em>http://okmij.org</em>. <a
href="http://okmij.org/ftp/Haskell/AlgorithmsH.html#perfect-shuffle"
class="uri">http://okmij.org/ftp/Haskell/AlgorithmsH.html#perfect-shuffle</a>.
</div>
</div>
]]></description>
    <pubDate>Sun, 24 Mar 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-03-24-permutations-by-sorting.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Lazy Binary Numbers</title>
    <link>https://doisinkidney.com/posts/2019-03-21-binary-logic-search.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 21, 2019
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Binary%20Numbers.html">1-part series on Binary Numbers</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>, <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<h1 id="number-representations">Number Representations</h1>
<p>When working with numbers in Agda, we usually use the following
definition:</p>
<style>
.column {
    float: left;
    width: 50%;
}
.row:after {
    content: "";
    display: table;
    clear: both;
}
</style>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">N</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">N</span> <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>)</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">N</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Z</span> <span class="op">+</span> n <span class="ot">=</span> n</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">S</span> n <span class="op">+</span> m <span class="ot">=</span> <span class="dt">S</span> (n <span class="op">+</span> m)</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Z</span> <span class="op">*</span> m <span class="ot">=</span> <span class="dt">Z</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">S</span> n <span class="op">*</span> m <span class="ot">=</span> m <span class="op">+</span> n <span class="op">*</span> m</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb2"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ℕ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">:</span> ℕ</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  suc <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>+<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>zero  + y <span class="ot">=</span> y</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>suc x + y <span class="ot">=</span> suc <span class="ot">(</span>x + y<span class="ot">)</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>*<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>zero  * y <span class="ot">=</span> zero</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>suc x * y <span class="ot">=</span> y + <span class="ot">(</span>x * y<span class="ot">)</span></span></code></pre></div>
</div>
</div>
<div class="row">
<div class="column">
<p>Haskell</p>
</div>
<div class="column">
<p>Agda</p>
</div>
</div>
<p>In Haskell it’s less common, for obvious reasons:</p>
<table>
<thead>
<tr>
<th>Operation</th>
<th>Complexity</th>
</tr>
</thead>
<tbody>
<tr>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>+</mo><mi>m</mi></mrow><annotation encoding="application/x-tex">n + m</annotation></semantics></math></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math></td>
</tr>
<tr>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>×</mo><mi>m</mi></mrow><annotation encoding="application/x-tex">n \times m</annotation></semantics></math></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mi>m</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(nm)</annotation></semantics></math></td>
</tr>
</tbody>
</table>
<p>Why use them at all, then? Well, in Agda, we need them so we can
<em>prove</em> things about the natural numbers. Machine-level integers
are fast, but they’re opaque: their implementation isn’t written in
Agda, and therefore it’s not available for the compiler to reason
about.</p>
<p>In Haskell, they occasionally find uses due to their
<em>laziness</em>. This can help in Agda as well. By lazy here I mean
that operations on them don’t have to inspect the full structure before
giving some output.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="dt">Z</span> <span class="op">&lt;</span> <span class="dt">S</span> <span class="fu">undefined</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="dt">True</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb4"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>*-zeroˡ <span class="ot">:</span> <span class="ot">∀</span> x <span class="ot">→</span> zero * x ≡ zero</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>*-zeroˡ x <span class="ot">=</span> refl</span></code></pre></div>
</div>
</div>
<p>In Haskell, as we can see, this lets us run computations without
scrutinising some arguments. Agda benefits similarly: here it lets the
compiler see more “obvious” facts that it may have missed otherwise.</p>
<p>It’s not <em>completely</em> lazy, though. In particular, it tends to
be left-biased:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">undefined</span> <span class="op">*</span> <span class="dt">Z</span> <span class="op">==</span> <span class="dt">Z</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="op">**</span> <span class="dt">Exception</span><span class="op">:</span> Prelude.undefined</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>*-zeroʳ <span class="ot">:</span> <span class="ot">∀</span> x <span class="ot">→</span> x * zero ≡ zero</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>*-zeroʳ x <span class="ot">=</span> refl</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- x * zero != zero of type ℕ</span></span></code></pre></div>
</div>
</div>
<p>Like Boolean short-circuiting operators, operations on Peano numbers
will usually have to scrutinise the left-hand-side argument quite a bit
before giving an output.</p>
<p>So, Peano numbers are good because:</p>
<ol>
<li>We can prove things about them.</li>
<li>They’re lazy.</li>
</ol>
<p>In this post, I’m going to look at some other number representations
that maintain these two desirable properties, while improving on the
efficiency somewhat.</p>
<h2 id="list-of-bits-binary">List-of-Bits-Binary</h2>
<p>The first option for an improved representation is binary numbers. We
can represent binary numbers as a list of bits:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Bit</span> <span class="ot">=</span> <span class="dt">O</span> <span class="op">|</span> <span class="dt">I</span> <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Show</span>, <span class="dt">Ord</span>)</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">B</span> <span class="ot">=</span> [<span class="dt">Bit</span>]</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Bit <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span> O I <span class="ot">:</span> Bit</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">:</span> <span class="dt">Set</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">=</span> List Bit</span></code></pre></div>
</div>
</div>
<p>As we’re using these to represent natural numbers, we’ll need to
define a way to convert between them:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">eval ::</span> <span class="dt">B</span> <span class="ot">-&gt;</span> <span class="dt">N</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>eval <span class="ot">=</span> <span class="fu">foldr</span> f <span class="dt">Z</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">O</span> xs <span class="ot">=</span> xs <span class="op">+</span> xs</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    f <span class="dt">I</span> xs <span class="ot">=</span> <span class="dt">S</span> (xs <span class="op">+</span> xs)</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a><span class="ot">inc ::</span> <span class="dt">B</span> <span class="ot">-&gt;</span> <span class="dt">B</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>inc [] <span class="ot">=</span> [<span class="dt">I</span>]</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>inc (<span class="dt">O</span><span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> xs</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>inc (<span class="dt">I</span><span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">O</span> <span class="op">:</span> inc xs</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a><span class="ot">fromN ::</span> <span class="dt">N</span> <span class="ot">-&gt;</span> <span class="dt">B</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>fromN <span class="dt">Z</span> <span class="ot">=</span> []</span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>fromN (<span class="dt">S</span> n) <span class="ot">=</span> inc (fromN n)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb10"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>⟦<span class="ot">_</span>⇓⟧ <span class="ot">:</span> 𝔹 <span class="ot">→</span> ℕ</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>⟦<span class="ot">_</span>⇓⟧ <span class="ot">=</span> foldr <span class="ot">(λ</span> <span class="ot">{</span> O xs <span class="ot">→</span> xs + xs</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>                <span class="ot">;</span> I xs <span class="ot">→</span> suc <span class="ot">(</span>xs + xs<span class="ot">)</span> <span class="ot">})</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>             zero</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>inc [] <span class="ot">=</span> I ∷ []</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">(</span>O ∷ xs<span class="ot">)</span> <span class="ot">=</span> I ∷ xs</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">(</span>I ∷ xs<span class="ot">)</span> <span class="ot">=</span> O ∷ inc xs</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>⟦<span class="ot">_</span>⇑⟧ <span class="ot">:</span> ℕ <span class="ot">→</span> 𝔹</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>⟦ zero  ⇑⟧ <span class="ot">=</span> []</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>⟦ suc n ⇑⟧ <span class="ot">=</span> inc ⟦ n ⇑⟧</span></code></pre></div>
</div>
</div>
<p>And here we run into our first problem: redundancy. There are
multiple ways to represent the same number according to the semantics
defined above. We can actually prove this in Agda:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>redundant <span class="ot">:</span> ∃₂ <span class="ot">λ</span> x y <span class="ot">→</span> x ≢ y × ⟦ x ⇓⟧ ≡ ⟦ y ⇓⟧</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>redundant <span class="ot">=</span> [] , O ∷ [] , <span class="ot">(λ</span> <span class="ot">())</span> , refl</span></code></pre></div>
<p>In English: “There are two binary numbers which are not the same, but
which do evaluate to the same natural number”. (This proof was actually
automatically filled in for me after writing the signature)</p>
<p>This represents a huge problem for proofs. It means that even simple
things like
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>×</mo><mn>0</mn><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">x \times 0 = 0</annotation></semantics></math>
aren’t true, depending on how multiplication is implemented. On to our
next option:</p>
<h2 id="list-of-gaps-binary">List-of-Gaps-Binary</h2>
<p>Instead of looking at the bits directly, let’s think about a binary
number as a list of chunks of 0s, each followed by a 1. In this way, we
simply <em>can’t</em> have trailing zeroes, because the definition
implies that every number other than 0 ends in 1.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Gap</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Gap</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">B</span> <span class="ot">=</span> [<span class="dt">Gap</span>]</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb13"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">:</span> <span class="dt">Set</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">=</span> List ℕ</span></code></pre></div>
</div>
</div>
<p>This guarantees a unique representation. As in the representation
above, it has much improved time complexities for the familiar
operations:</p>
<table>
<thead>
<tr>
<th>Operation</th>
<th>Complexity</th>
</tr>
</thead>
<tbody>
<tr>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>+</mo><mi>m</mi></mrow><annotation encoding="application/x-tex">n + m</annotation></semantics></math></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msub><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mn>2</mn></msub><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log_2 n)</annotation></semantics></math></td>
</tr>
<tr>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>×</mo><mi>m</mi></mrow><annotation encoding="application/x-tex">n \times m</annotation></semantics></math></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msub><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mn>2</mn></msub><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo>+</mo><mi>m</mi><mo stretchy="false" form="postfix">)</mo><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log_2 (n + m))</annotation></semantics></math></td>
</tr>
</tbody>
</table>
<p>Encoding the zeroes as gaps also makes multiplication much faster in
certain cases: multiplying by a high power of 2 is a constant-time
operation, for instance.</p>
<p>It does have one disadvantage, and it’s to do with the increment
function:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">inc ::</span> <span class="dt">B</span> <span class="ot">-&gt;</span> <span class="dt">B</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">=</span> <span class="fu">uncurry</span> (<span class="fu">flip</span> (<span class="op">:</span>)) <span class="op">.</span> inc&#39;</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    inc&#39; [] <span class="ot">=</span> ([], <span class="dt">Z</span>)</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    inc&#39; (x<span class="op">:</span>xs) <span class="ot">=</span> inc&#39;&#39; x xs</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    inc&#39;&#39; <span class="dt">Z</span> ns <span class="ot">=</span> <span class="fu">fmap</span> <span class="dt">S</span> (inc&#39; ns)</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    inc&#39;&#39; (<span class="dt">S</span> n) ns <span class="ot">=</span> (n<span class="op">:</span>ns,<span class="dt">Z</span>)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb15"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>𝔹⁺ <span class="ot">:</span> <span class="dt">Set</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>𝔹⁺ <span class="ot">=</span> ℕ × 𝔹</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">=</span> uncurry <span class="ot">_</span>∷<span class="ot">_</span> ∘ inc′</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">module</span> Inc <span class="kw">where</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">mutual</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>    inc′ <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹⁺</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>    inc′ [] <span class="ot">=</span> <span class="dv">0</span> , []</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    inc′ <span class="ot">(</span>x ∷ xs<span class="ot">)</span> <span class="ot">=</span> inc″ x xs</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>    inc″ <span class="ot">:</span> ℕ <span class="ot">→</span> 𝔹 <span class="ot">→</span> 𝔹⁺</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>    inc″ zero ns <span class="ot">=</span> map₁ suc <span class="ot">(</span>inc′ ns<span class="ot">)</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>    inc″ <span class="ot">(</span>suc n<span class="ot">)</span> ns <span class="ot">=</span> <span class="dv">0</span> , n ∷ ns</span></code></pre></div>
</div>
</div>
<p>With all of their problems, Peano numbers performed this operation in
constant time. The above implementation is only <em>amortised</em>
constant-time, though, with a worst case of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msub><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mn>2</mn></msub><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log_2 n)</annotation></semantics></math>
(same as the list-of-bits version). There are a number of ways to remedy
this, the most famous being:</p>
<h2 id="skew-binary">Skew Binary</h2>
<p>This encoding has three digits: 0, 1, and 2. To guarantee a unique
representation, we add the condition that there can be at most one 2 in
the number, which must be the first non-zero digit if it’s present.</p>
<p>To represent this we’ll encode “gaps”, as before, with the condition
that if the second gap is 0 it <em>actually</em> represents a 2 digit in
the preceding position. That weirdness out of the way, we are rewarded
with an <code>inc</code> implementation which is clearly
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">inc ::</span> <span class="dt">B</span> <span class="ot">-&gt;</span> <span class="dt">B</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>inc [] <span class="ot">=</span> <span class="dt">Z</span> <span class="op">:</span> []</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>inc (x<span class="op">:</span>[]) <span class="ot">=</span> <span class="dt">Z</span> <span class="op">:</span> x <span class="op">:</span> []</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>inc (x  <span class="op">:</span> <span class="dt">Z</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">S</span> x <span class="op">:</span> xs</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>inc (x1 <span class="op">:</span> <span class="dt">S</span> x2 <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">Z</span> <span class="op">:</span> x1 <span class="op">:</span> x2 <span class="op">:</span> xs</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb17"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>inc [] <span class="ot">=</span> <span class="dv">0</span> ∷ []</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">(</span>x ∷ []<span class="ot">)</span> <span class="ot">=</span> <span class="dv">0</span> ∷ x ∷ []</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">(</span>x₁ ∷ zero ∷ xs<span class="ot">)</span> <span class="ot">=</span> suc x₁ ∷ xs</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">(</span>x₁ ∷ suc x₂ ∷ xs<span class="ot">)</span> <span class="ot">=</span> <span class="dv">0</span> ∷ x₁ ∷ x₂ ∷ xs</span></code></pre></div>
</div>
</div>
<p>Unfortunately, though, we’ve lost the other efficiencies! Addition
and multiplication have no easy or direct encoding in this system, so we
have to convert back and forth between this and regular binary to
perform them.</p>
<h2 id="list-of-segments-binary">List-of-Segments-Binary</h2>
<p>The key problem with incrementing in the normal binary system is that
it can cascade: when we hit a long string of 1s, all the 1s become 0
followed by a single 1. We can turn this problem to our advantage if we
use a representation which encodes both 1s and 0s as strings of gaps.
We’ll have to use a couple more tricks to ensure a unique
representation, but all in all this is what we have (switching to just
Agda now):</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> 0≤<span class="ot">_</span> <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span><span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  0₂  <span class="ot">:</span> 0≤ A</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  0&lt;<span class="ot">_</span> <span class="ot">:</span> A <span class="ot">→</span> 0≤ A</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="kw">mutual</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">record</span> 𝔹₀ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constructor</span> <span class="ot">_</span>0&amp;<span class="ot">_</span></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">inductive</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">field</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>      H₀ <span class="ot">:</span> ℕ</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>      T₀ <span class="ot">:</span> 𝔹₁</span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">record</span> 𝔹₁ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">constructor</span> <span class="ot">_</span>1&amp;<span class="ot">_</span></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">inductive</span></span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">field</span></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>      H₁ <span class="ot">:</span> ℕ</span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a>      T₁ <span class="ot">:</span> 0≤  𝔹₀</span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> 𝔹₀ <span class="kw">public</span></span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> 𝔹₁ <span class="kw">public</span></span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> 𝔹⁺ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a>  B₀<span class="ot">_</span> <span class="ot">:</span> 𝔹₀ <span class="ot">→</span> 𝔹⁺</span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a>  B₁<span class="ot">_</span> <span class="ot">:</span> 𝔹₁ <span class="ot">→</span> 𝔹⁺</span>
<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">:</span> <span class="dt">Set</span></span>
<span id="cb18-27"><a href="#cb18-27" aria-hidden="true" tabindex="-1"></a>𝔹 <span class="ot">=</span> 0≤ 𝔹⁺</span>
<span id="cb18-28"><a href="#cb18-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-29"><a href="#cb18-29" aria-hidden="true" tabindex="-1"></a>inc⁺ <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹⁺</span>
<span id="cb18-30"><a href="#cb18-30" aria-hidden="true" tabindex="-1"></a>inc⁺ 0₂                               <span class="ot">=</span>      B₁ <span class="dv">0</span>     1&amp; 0₂</span>
<span id="cb18-31"><a href="#cb18-31" aria-hidden="true" tabindex="-1"></a>inc⁺ <span class="ot">(</span>0&lt; B₀ zero  0&amp; y 1&amp; xs        <span class="ot">)</span> <span class="ot">=</span>      B₁ suc y 1&amp; xs</span>
<span id="cb18-32"><a href="#cb18-32" aria-hidden="true" tabindex="-1"></a>inc⁺ <span class="ot">(</span>0&lt; B₀ suc x 0&amp; y 1&amp; xs        <span class="ot">)</span> <span class="ot">=</span>      B₁ <span class="dv">0</span>     1&amp; 0&lt; x 0&amp; y 1&amp; xs</span>
<span id="cb18-33"><a href="#cb18-33" aria-hidden="true" tabindex="-1"></a>inc⁺ <span class="ot">(</span>0&lt; B₁ x 1&amp; 0₂                 <span class="ot">)</span> <span class="ot">=</span> B₀ x 0&amp; <span class="dv">0</span>     1&amp; 0₂</span>
<span id="cb18-34"><a href="#cb18-34" aria-hidden="true" tabindex="-1"></a>inc⁺ <span class="ot">(</span>0&lt; B₁ x 1&amp; 0&lt; zero  0&amp; z 1&amp; xs<span class="ot">)</span> <span class="ot">=</span> B₀ x 0&amp; suc z 1&amp; xs</span>
<span id="cb18-35"><a href="#cb18-35" aria-hidden="true" tabindex="-1"></a>inc⁺ <span class="ot">(</span>0&lt; B₁ x 1&amp; 0&lt; suc y 0&amp; z 1&amp; xs<span class="ot">)</span> <span class="ot">=</span> B₀ x 0&amp; <span class="dv">0</span>     1&amp; 0&lt; y 0&amp; z 1&amp; xs</span>
<span id="cb18-36"><a href="#cb18-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-37"><a href="#cb18-37" aria-hidden="true" tabindex="-1"></a>inc <span class="ot">:</span> 𝔹 <span class="ot">→</span> 𝔹</span>
<span id="cb18-38"><a href="#cb18-38" aria-hidden="true" tabindex="-1"></a>inc x <span class="ot">=</span> 0&lt; inc⁺ x</span></code></pre></div>
<p>Perfect! Increments are obviously
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>,
and we’ve guaranteed a unique representation.</p>
<p>I’ve been working on this type for a couple of days, and you can see
my code <a href="https://github.com/oisdk/agda-binary/">here</a>. So
far, I’ve done the following:</p>
<dl>
<dt>Defined <code>inc</code>, addition, and multiplication</dt>
<dd>
<p>These were a little tricky to get right (<a
href="https://github.com/oisdk/agda-binary/blob/master/Data/Binary/Operations/Addition.agda#L9">addition
is particularly hairy</a>), but they’re all there, and maximally
lazy.</p>
</dd>
<dt>Proved Homomorphism</dt>
<dd>
<p>For each one of the functions, you want them to correspond precisely
to the equivalent functions on Peano numbers. Proving that fact amounts
to filling in definitions for the following:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>inc-homo <span class="ot">:</span> <span class="ot">∀</span> x <span class="ot">→</span> ⟦ inc x ⇓⟧ ≡ suc ⟦ x ⇓⟧</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>+-homo <span class="ot">:</span> <span class="ot">∀</span> x y <span class="ot">→</span> ⟦ x + y ⇓⟧ ≡ ⟦ x ⇓⟧ + ⟦ y ⇓⟧</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>*-homo <span class="ot">:</span> <span class="ot">∀</span> x y <span class="ot">→</span> ⟦ x * y ⇓⟧ ≡ ⟦ x ⇓⟧ * ⟦ y ⇓⟧</span></code></pre></div>
</dd>
<dt>Proved Bijection</dt>
<dd>
<p>As we went to so much trouble, it’s important to prove that these
numbers form a one-to-one correspondence with the Peano numbers. As well
as that, once done, we can use it to prove facts about the homomorphic
functions above, by reusing any proofs about the same functions on Peano
numbers. For instance, here is a proof of commutativity of addition:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>+-comm <span class="ot">:</span> <span class="ot">∀</span> x y <span class="ot">→</span> x + y ≡ y + x</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>+-comm x y <span class="ot">=</span> injective <span class="ot">(</span>+-homo x y ⟨ trans ⟩</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>                        ℕ<span class="ot">.</span>+-comm ⟦ x ⇓⟧ ⟦ y ⇓⟧ ⟨ trans ⟩</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>                        sym <span class="ot">(</span>+-homo y x<span class="ot">))</span></span></code></pre></div>
</dd>
</dl>
<h1 id="applications">Applications</h1>
<p>So now that we have our nice number representation, what can we do
with it? One use is as a general-purpose number type in Agda: it
represents a good balance between speed and “proofiness”, and Coq uses a
similar type in its standard library.</p>
<p>There are other, more unusual uses of such a type, though.</p>
<h2 id="data-structures">Data Structures</h2>
<p>It’s a well-known technique to build a data structure out of some
number representation <span class="citation"
data-cites="hinze_numerical_1998">(<a href="#ref-hinze_numerical_1998"
role="doc-biblioref">Hinze 1998</a>)</span>: in fact, all of the
representations above are explored in Okasaki <span class="citation"
data-cites="okasaki_purely_1999">(<a href="#ref-okasaki_purely_1999"
role="doc-biblioref">1999, chap. 9.2</a>)</span>.</p>
<h2 id="logic-programming">Logic Programming</h2>
<p>Logic programming languages like Prolog let us write programs in a
backwards kind of way. We say what the output looks like, and the
unifier will figure out the set of inputs that generates it.</p>
<p>In Haskell, we have a very rough approximation of a similar system:
the list monad.</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">pyth ::</span> [(<span class="dt">Int</span>,<span class="dt">Int</span>,<span class="dt">Int</span>)]</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>pyth <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>]</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>]</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>  z <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">10</span>]</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>  guard (x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y <span class="op">==</span> z<span class="op">*</span>z)</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">return</span> (x,y,z)</span></code></pre></div>
<p>There are tons of inefficiencies in the above code: for us, though,
we can look at one: the number representation. In the equation:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><msup><mi>y</mi><mn>2</mn></msup><mo>=</mo><msup><mi>z</mi><mn>2</mn></msup></mrow><annotation encoding="application/x-tex">x^2 + y^2 = z^2</annotation></semantics></math></p>
<p>If we know that
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>y</mi><annotation encoding="application/x-tex">y</annotation></semantics></math>
are both odd, then
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>z</mi><annotation encoding="application/x-tex">z</annotation></semantics></math>
must be even. If the calculation of the equation is expensive, this is
precisely the kind of shortcut we’d want to take advantage of. Luckily,
our binary numbers do just that: it is enough to scrutinise just the
first bits of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>y</mi><annotation encoding="application/x-tex">y</annotation></semantics></math>
in order to determine the first bit of the output.</p>
<p>After seeing that example, you may be thinking that lazy evaluation
is a perfect fit for logic programming. You’re not alone! Curry <span
class="citation" data-cites="Hanus16Curry">(<a href="#ref-Hanus16Curry"
role="doc-biblioref">Hanus (ed.) 2016</a>)</span> is a lazy, functional
logic programming language, with a similar syntax to Haskell. It also
uses lazy binary numbers to optimise testing.</p>
<h2 id="lazy-predicates">Lazy Predicates</h2>
<p>In order for queries to be performed efficiently on binary numbers,
we will also need a way to describe lazy <em>predicates</em> on them. A
lot of these predicates are more easily expressible on the list-of-bits
representation above, so we’ll be working with that representation for
this bit. Not to worry, though: we can convert from the segmented
representation into the list-of-bits, and <a
href="https://github.com/oisdk/agda-binary/blob/fb89ba5ae3b2aa0cb95301da42c8dbf27048181b/Data/Binary/Bits.agda#L52">we
can prove that the conversion is injective</a>:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>toBits-injective <span class="ot">:</span> <span class="ot">∀</span> xs ys <span class="ot">→</span> toBits xs ≡ toBits ys <span class="ot">→</span> xs ≡ ys</span></code></pre></div>
<p>Here’s the curious problem: since our binary numbers are expressed
least-significant-bit-first, we have to go to the end before knowing
which is bigger. Luckily, we can use one of my favourite Haskell tricks,
involving the ordering monoid:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Ordering <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  lt eq gt <span class="ot">:</span> Ordering</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>∙<span class="ot">_</span> <span class="ot">:</span> Ordering <span class="ot">→</span> Ordering <span class="ot">→</span> Ordering</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>lt ∙ y <span class="ot">=</span> lt</span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>eq ∙ y <span class="ot">=</span> y</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>gt ∙ y <span class="ot">=</span> gt</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>cmpBit <span class="ot">:</span> Bit <span class="ot">→</span> Bit <span class="ot">→</span> Ordering</span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>cmpBit O O <span class="ot">=</span> eq</span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>cmpBit O I <span class="ot">=</span> lt</span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a>cmpBit I O <span class="ot">=</span> gt</span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a>cmpBit I I <span class="ot">=</span> eq</span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a>compare <span class="ot">:</span> Bits <span class="ot">→</span> Bits <span class="ot">→</span> Ordering</span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a>compare [] [] <span class="ot">=</span> eq</span>
<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a>compare [] <span class="ot">(_</span> ∷ <span class="ot">_)</span> <span class="ot">=</span> lt</span>
<span id="cb23-18"><a href="#cb23-18" aria-hidden="true" tabindex="-1"></a>compare <span class="ot">(_</span> ∷ <span class="ot">_)</span> [] <span class="ot">=</span> gt</span>
<span id="cb23-19"><a href="#cb23-19" aria-hidden="true" tabindex="-1"></a>compare <span class="ot">(</span>x ∷ xs<span class="ot">)</span> <span class="ot">(</span>y ∷ ys<span class="ot">)</span> <span class="ot">=</span> compare xs ys ∙ cmpBit x y</span></code></pre></div>
<p>Thanks to laziness, this function first compares the length of the
lists, and then does a lexicographical comparison in reverse only if the
lengths are the same. This is exactly what we want for our numbers.</p>
<h1 id="future-posts">Future Posts</h1>
<p>That’s all I have for now, but I’m interested to formalise the
laziness of these numbers in Agda. Usually that’s done with coinduction:
I would also like to see the relationship with exact real
arithmetic.</p>
<p>I wonder if it can be combined with <span class="citation"
data-cites="oconnor_applications_2016">O’Connor (<a
href="#ref-oconnor_applications_2016"
role="doc-biblioref">2016</a>)</span> to get some efficient proof search
algorithms, or with <span class="citation"
data-cites="escardo_seemingly_2014">Escardo (<a
href="#ref-escardo_seemingly_2014" role="doc-biblioref">2014</a>)</span>
to get more efficient exhaustive search.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-escardo_seemingly_2014" class="csl-entry" role="listitem">
Escardo, Martin. 2014. <span>“Seemingly impossible constructive proofs |
<span>Mathematics</span> and <span>Computation</span>.”</span>
<em>Mathematics and Computation</em>. <a
href="http://math.andrej.com/2014/05/08/seemingly-impossible-proofs/">http://math.andrej.com/2014/05/08/seemingly-impossible-proofs/</a>.
</div>
<div id="ref-Hanus16Curry" class="csl-entry" role="listitem">
Hanus (ed.), M. 2016. <em>Curry: <span>An Integrated Functional Logic
Language</span> (<span>Vers</span>. 0.9.0)</em>. Available at
http://www.curry-language.org. <a
href="https://www-ps.informatik.uni-kiel.de/currywiki/">https://www-ps.informatik.uni-kiel.de/currywiki/</a>.
</div>
<div id="ref-hinze_numerical_1998" class="csl-entry" role="listitem">
Hinze, Ralf. 1998. <em>Numerical <span>Representations</span> as
<span>Higher</span>-<span>Order Nested Datatypes</span></em>.
<span>Institut für Informatik III, Universität Bonn</span>. <a
href="http://www.cs.ox.ac.uk/ralf.hinze/publications/\#R5">http://www.cs.ox.ac.uk/ralf.hinze/publications/\#R5</a>.
</div>
<div id="ref-oconnor_applications_2016" class="csl-entry"
role="listitem">
O’Connor, Liam. 2016. <span>“Applications of <span>Applicative Proof
Search</span>.”</span> In <em>Proceedings of the 1st <span>International
Workshop</span> on <span>Type</span>-<span>Driven
Development</span></em>, 43–55. <span>TyDe</span> 2016. New York, NY,
USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2976022.2976030">10.1145/2976022.2976030</a>.
<a
href="http://doi.acm.org/10.1145/2976022.2976030">http://doi.acm.org/10.1145/2976022.2976030</a>.
</div>
<div id="ref-okasaki_purely_1999" class="csl-entry" role="listitem">
Okasaki, Chris. 1999. <em>Purely <span>Functional Data
Structures</span></em>. <span>Cambridge University Press</span>.
</div>
</div>
]]></description>
    <pubDate>Thu, 21 Mar 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-03-21-binary-logic-search.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>More Agda Tips</title>
    <link>https://doisinkidney.com/posts/2019-03-14-more-agda-tips.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 14, 2019
</div>
<div class="info">
    
        Part 2 of a <a href="/series/Agda%20Tips.html">2-part series on Agda Tips</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<h1 id="literate-agda">Literate Agda</h1>
<p>For including Agda code in LaTeX files, Agda’s built-in literate
programming support is a great tool. It typesets code well, and ensures
that it typechecks which can help avoid typos.</p>
<h3 id="embedding-agda-code-in-latex">Embedding Agda Code in LaTeX</h3>
<p>I write the LaTeX document in one file, and the Agda code in another
<code>.lagda</code> file. Using the <a
href="https://ctan.org/pkg/catchfilebetweentags?lang=en">catchfilebetweentags</a>
LaTeX package, I can then embed snippets of the Agda code into the LaTeX
document. For instance, in a file named <code>Lists.lagda</code> I can
have the following:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>%&lt;*head-type&gt;</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">\</span>begin<span class="ot">{</span>code<span class="ot">}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>head <span class="ot">:</span> List A <span class="ot">→</span> Maybe A</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">\</span>end<span class="ot">{</span>code<span class="ot">}</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>%&lt;/head-type&gt;</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="ot">\</span>begin<span class="ot">{</span>code<span class="ot">}</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>head [] <span class="ot">=</span> nothing</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>x ∷ xs<span class="ot">)</span> <span class="ot">=</span> just x</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="ot">\</span>end<span class="ot">{</span>code<span class="ot">}</span></span></code></pre></div>
<p>Then, after compiling the Agda file with
<code>agda --latex --output-dir=. Lists.lagda</code>, I can embed the
snippet <code>head : List A → Maybe A</code> into the TeX file like
so:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode latex"><code class="sourceCode latex"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">\ExecuteMetaData</span>[Lists.tex]{head-type}</span></code></pre></div>
<h3 id="dealing-with-unicode">Dealing with Unicode</h3>
<p>Most Agda source code will be Unicode-heavy, which doesn’t work well
in LaTeX. There are a few different ways to deal with this: you could
use XeTeX, which handles Unicode better, for instance. I found it easier
to use the <a href="https://ctan.org/pkg/ucs?lang=en">ucs</a> package,
and write a declaration for each Unicode character as I came across it.
For the <code>∷</code> character above, for instance, you can write:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode latex"><code class="sourceCode latex"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="bu">\usepackage</span>{<span class="ex">ucs</span>}</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="fu">\DeclareUnicodeCharacter</span>{8759}{<span class="ss">\ensuremath{</span><span class="sc">\squaredots</span><span class="ss">}</span>}</span></code></pre></div>
<h3 id="live-reloading">Live Reloading</h3>
<p>For plain LaTeX code, I use <a
href="http://spacemacs.org/">Spacemacs</a> and <a
href="https://skim-app.sourceforge.io/">Skim</a> to get live reloading.
When I save the LaTeX source code, the Skim window refreshes and jumps
to the point my editing cursor is at. I use elisp code from <a
href="https://mssun.me/blog/spacemacs-and-latex.html">this</a> blog
post.</p>
<p>For Agda code, live reloading gets a little trickier. If I edit an
Agda source file, the LaTeX won’t automatically recompile it. However,
based on <a
href="https://tex.stackexchange.com/questions/142540/configuring-latexmk-to-use-a-preprocessor-lhs2tex">this</a>
stack exchange answer, you can put the following <code>.latexmkrc</code>
file in the same directory as your <code>.lagda</code> files and your
<code>.tex</code> file:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode perl"><code class="sourceCode perl"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>add_cus_dep(<span class="ot">&#39;</span><span class="ss">lagda</span><span class="ot">&#39;</span>,<span class="ot">&#39;</span><span class="ss">tex</span><span class="ot">&#39;</span>,<span class="dv">0</span>,<span class="ot">&#39;</span><span class="ss">lagda2tex</span><span class="ot">&#39;</span>);</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">sub </span><span class="fu">lagda2tex</span> {</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">my</span> <span class="dt">$base</span> = <span class="fu">shift</span> <span class="dt">@_</span>;</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">system</span>(<span class="ot">&#39;</span><span class="ss">agda</span><span class="ot">&#39;</span>, <span class="ot">&#39;</span><span class="ss">--latex</span><span class="ot">&#39;</span>, <span class="ot">&#39;</span><span class="ss">--latex-dir=.</span><span class="ot">&#39;</span>, <span class="ot">&quot;</span><span class="dt">$base</span><span class="st">.lagda</span><span class="ot">&quot;</span>);</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>This will recompile the literate Agda files whenever they’re changed.
Unfortunately, it doesn’t automate it the <em>first</em> time you do it:
it needs to see the <code>.tex</code> files to see the dependency. You
can fix this yourself, by running
<code>agda --latex --output-dir=.</code> when you add a new
<code>.lagda</code> file (just once, after that the automation will take
over), or you can use a script like the following:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="co">#!/bin/bash</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">find</span> . <span class="at">-type</span> f <span class="at">-name</span> <span class="st">&#39;*.lagda&#39;</span> <span class="kw">|</span> <span class="cf">while</span> <span class="bu">read</span> <span class="at">-r</span> <span class="va">code</span> <span class="kw">;</span> <span class="cf">do</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="va">dir</span><span class="op">=</span><span class="va">$(</span><span class="fu">dirname</span> <span class="st">&quot;</span><span class="va">$code</span><span class="st">&quot;</span><span class="va">)</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="va">file</span><span class="op">=</span><span class="va">$(</span><span class="fu">basename</span> <span class="st">&quot;</span><span class="va">$code</span><span class="st">&quot;</span> .lagda<span class="va">)</span>.tex</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="bu">[</span> <span class="ot">!</span> <span class="ot">-e</span> <span class="st">&quot;</span><span class="va">$dir</span><span class="st">/</span><span class="va">$file</span><span class="st">&quot;</span> <span class="bu">]</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">then</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>        <span class="ex">agda</span> <span class="at">--latex</span> <span class="at">--latex-dir</span><span class="op">=</span>. <span class="st">&quot;</span><span class="va">$code</span><span class="st">&quot;</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">fi</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="cf">done</span></span></code></pre></div>
<p>This will compile any <code>.lagda</code> file it finds that
<em>doesn’t</em> have a corresponding <code>.tex</code> file (so it
won’t slow things down). Then call that script on the first line of your
<code>.latexmkrc</code>, like so:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode perl"><code class="sourceCode perl"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">system</span>(<span class="ot">&quot;</span><span class="st">bash ./init-missing-lagda.sh</span><span class="ot">&quot;</span>);</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>add_cus_dep(<span class="ot">&#39;</span><span class="ss">lagda</span><span class="ot">&#39;</span>,<span class="ot">&#39;</span><span class="ss">tex</span><span class="ot">&#39;</span>,<span class="dv">0</span>,<span class="ot">&#39;</span><span class="ss">lagda2tex</span><span class="ot">&#39;</span>);</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="kw">sub </span><span class="fu">lagda2tex</span> {</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">my</span> <span class="dt">$base</span> = <span class="fu">shift</span> <span class="dt">@_</span>;</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">system</span>(<span class="ot">&#39;</span><span class="ss">agda</span><span class="ot">&#39;</span>, <span class="ot">&#39;</span><span class="ss">--latex</span><span class="ot">&#39;</span>, <span class="ot">&#39;</span><span class="ss">--latex-dir=.</span><span class="ot">&#39;</span>, <span class="ot">&quot;</span><span class="dt">$base</span><span class="st">.lagda</span><span class="ot">&quot;</span>);</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<h1 id="flags-for-debugging">Flags for Debugging</h1>
<p>There are a number of undocumented flags you can pass to Agda which
are absolutely invaluable when it comes to debugging. One of them <a
href="http://oleg.fi/gists/posts/2018-08-29-agda-termination-checker.html">can
tell you more about termination checking</a>, another reports on type
checking (<code>tc</code>), another for profiling
(<code>profile</code>), and so on. Set the verbosity level
(<code>agda -v 100</code>) to get more or less info.</p>
<h1 id="type-checking-order">Type Checking Order</h1>
<p>Agda does type checking from left to right. This isn’t always
desired: as an example, if we want to annotate a value with its type, we
can use the following function:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>the <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">→</span> A <span class="ot">→</span> A</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>the <span class="ot">_</span> x <span class="ot">=</span> x</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>example <span class="ot">:</span> <span class="ot">_</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>example <span class="ot">=</span> the ℕ <span class="dv">3</span></span></code></pre></div>
<p>Coming from Haskell, though, this is the wrong way around. We usually
prefer to write something like <code>3 :: Int</code>. We can’t write
that as a simple function in Agda, though, so we instead use a syntax
declaration:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">syntax</span> the ty x <span class="ot">=</span> x ∷ ty</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>example <span class="ot">:</span> <span class="ot">_</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>example <span class="ot">=</span> <span class="dv">3</span> ∷ ℕ</span></code></pre></div>
<p>Changing the order of type checking can also <a
href="https://github.com/agda/agda-stdlib/issues/622#issue-411010875">speed
up typechecking in some cases</a>. There’s more information about syntax
declarations in <a
href="https://agda.readthedocs.io/en/latest/language/syntax-declarations.html">Agda’s
documentation</a>.</p>
]]></description>
    <pubDate>Thu, 14 Mar 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-03-14-more-agda-tips.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Finger Trees in Agda</title>
    <link>https://doisinkidney.com/posts/2019-02-25-agda-fingertrees.html</link>
    <description><![CDATA[<div class="info">
    Posted on February 25, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<hr />
<h2 id="this-post-is-available-with-clickable-code-here"><a
href="https://oisdk.github.io/agda-indexed-fingertree/Data.FingerTree.html">This
Post is Available With Clickable Code Here</a></h2>
<p>This whole post is written with clickable identifiers and ascii art
at the above link. I also provide the normal version below in case there
are any problems rendering.</p>
<hr />
<p>As I have talked about <a
href="/posts/2019-01-15-binomial-urn.html">previously</a>, a large class
of divide-and conquer algorithms rely on “good” partitioning for the
divide step. If you then want to make the algorithms incremental, you
keep all of those partitions (with their summaries) in some “good”
arrangement <span class="citation" data-cites="mu_queueing_2016">(<a
href="#ref-mu_queueing_2016" role="doc-biblioref">Mu, Chiang, and Lyu
2016</a>)</span>. Several common data structures are designed around
this principle: binomial heaps, for instance, store partitions of size
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mn>2</mn><mi>n</mi></msup><annotation encoding="application/x-tex">2^n</annotation></semantics></math>.
Different ways of storing partitions favours different use cases: switch
from a binomial heap to a skew binomial, for instance, and you get
constant-time <code>cons</code>.</p>
<p>The standout data structure in this area is Hinze and Paterson’s
finger tree <span class="citation"
data-cites="Hinze-Paterson:FingerTree">(<a
href="#ref-Hinze-Paterson:FingerTree" role="doc-biblioref">Hinze and
Paterson 2006</a>)</span>. It caches summaries in a pretty amazing way,
allowing for (amortised)
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
<code>cons</code> and <code>snoc</code> and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
<code>split</code> and <code>append</code>. These features allow it to
be used for a huge variety of things: <a
href="http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Sequence.html">Data.Sequence</a>
uses it as a random-access sequence, but it can also work as a priority
queue, a search tree, a priority search tree <span class="citation"
data-cites="hinze_simple_2001">(<a href="#ref-hinze_simple_2001"
role="doc-biblioref">Hinze 2001</a>)</span>, an interval tree, an order
statistic tree…</p>
<p>All of these applications solely rely on an underlying monoid. As a
result, I thought it would be a great data structure to implement in
Agda, so that you’d get all of the other data structures with minimal
effort [similar thinking motivated a Coq implementation; <span
class="citation" data-cites="sozeau_program-ing_2007">Sozeau (<a
href="#ref-sozeau_program-ing_2007"
role="doc-biblioref">2007</a>)</span>].</p>
<h1 id="scope-of-the-verification">Scope of the Verification</h1>
<p>There would be no real point to implementing a finger tree in Agda if
we didn’t also prove some things about it. The scope of the proofs I’ve
done so far are intrinsic proofs of the summaries in the tree. In other
words, the type of <code>cons</code> is as follows:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>cons <span class="ot">:</span> <span class="ot">∀</span> x <span class="ot">{</span>xs<span class="ot">}</span> <span class="ot">→</span> Tree xs <span class="ot">→</span> Tree <span class="ot">(</span>μ x ∙ xs<span class="ot">)</span></span></code></pre></div>
<p>This is enough to prove things about the derived data structures
(like the correctness of sorting if it’s used as a priority queue), but
it’s worth pointing out what I <em>haven’t</em> proved (yet):</p>
<ol>
<li>Invariants on the structure (“safe” and “unsafe” digits and so
on).</li>
<li>The time complexity or performance of any operations.</li>
</ol>
<p>To be honest, I’m not even sure that my current implementation is
correct in these regards! I’ll probably have a go at proving them in the
future <span class="citation"
data-cites="danielsson_lightweight_2008">(possibly using <a
href="#ref-danielsson_lightweight_2008" role="doc-biblioref">Danielsson
2008</a>)</span>.</p>
<h1 id="monoids-and-proofs">Monoids and Proofs</h1>
<p>The bad news is that finger trees are a relatively complex data
structure, and we’re going to need a <em>lot</em> of proofs to write a
verified version. The good news is that monoids (in contrast to rings)
are extremely easy to prove automatically. In this project, I used
reflection to do so, but I think it should be possible to do with
instance resolution also.</p>
<h1 id="measures">Measures</h1>
<p>First things first, we need a way to talk about the summaries of
elements we’re interested in. This is captured by the following record
type:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> σ <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>Σ <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="ot">(</span>a ⊔ r<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    μ <span class="ot">:</span> Σ <span class="ot">→</span> 𝓡</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> σ ⦃ <span class="ot">...</span> ⦄</span></code></pre></div>
<p><code>𝓡</code> is the type of the summaries, and <code>μ</code> means
“summarise”. The silly symbols are used for brevity: we’re going to be
using this thing everywhere, so it’s important to keep it short. Here’s
an example instance for lists:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  σ-List <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">{</span>Σ <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> σ Σ ⦄ <span class="ot">→</span> σ <span class="ot">(</span>List Σ<span class="ot">)</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  μ ⦃ σ-List ⦄ <span class="ot">=</span> List<span class="ot">.</span>foldr <span class="ot">(_</span>∙<span class="ot">_</span> ∘ μ<span class="ot">)</span> ε</span></code></pre></div>
<h1 id="working-with-setoids">Working With Setoids</h1>
<p>As I mentioned, the tree is going to be verified intrinsically. In
other words its type will look something like this:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>Tree <span class="ot">:</span> 𝓡 <span class="ot">→</span> <span class="dt">Set</span></span></code></pre></div>
<p>But before running off to define that the obvious way, I should
mention that I made the annoying decision to use a setoid (rather than
propositional equality) based monoid. This means that we don’t get
substitution, making the obvious definition untenable.</p>
<p>I figured out a solution to the problem, but I’m not sure if I’m
happy with it. That’s actually the main motivation for writing this
post: I’m curious if other people have better techniques for this kind
of thing.</p>
<p>To clarify: “this kind of thing” is writing intrinsic
(correct-by-construction) proofs when a setoid is involved. Intrinsic
proofs usually lend themselves to elegance: to prove that
<code>map</code> preserves a vector’s length, for instance, basically
requires no proof at all:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>map <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a b n<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">{</span>B <span class="ot">:</span> <span class="dt">Set</span> b<span class="ot">}</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">→</span> <span class="ot">(</span>A <span class="ot">→</span> B<span class="ot">)</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">→</span> Vec A n</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">→</span> Vec B n</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>map f [] <span class="ot">=</span> []</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>map f <span class="ot">(</span>x ∷ xs<span class="ot">)</span> <span class="ot">=</span> f x ∷ map f xs</span></code></pre></div>
<p>But that’s because pattern matching works well with propositional
equality: in the first clause, <code>n</code> is set to <code>0</code>
automatically. If we were working with setoid equality, we’d instead
maybe get a proof that <code>n ≈ 0</code>, and we’d have to figure a way
to work that into the types.</p>
<h1 id="fibres">Fibres</h1>
<p>The first part of the solution is to define a wrapper type which
stores information about the size of the thing it contains:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> μ⟨<span class="ot">_</span>⟩≈<span class="ot">_</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>Σ <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> σ Σ ⦄ <span class="ot">(</span>𝓂 <span class="ot">:</span> 𝓡<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="ot">(</span>a ⊔ r ⊔ m<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>⇑[<span class="ot">_</span>]</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    𝓢 <span class="ot">:</span> Σ</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    𝒻 <span class="ot">:</span> μ 𝓢 ≈ 𝓂</span></code></pre></div>
<p>Technically speaking, I think this is known as a “fibre”.
<code>μ⟨ Σ ⟩≈ 𝓂</code> means “There exists a <code>Σ</code> such that
<code>μ Σ ≈ 𝓂</code>”. Next, we’ll need some combinators to work
with:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">2</span> <span class="ot">_</span>≈[<span class="ot">_</span>]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>≈[<span class="ot">_</span>] <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">{</span>Σ <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> σ Σ ⦄ <span class="ot">{</span>x <span class="ot">:</span> 𝓡<span class="ot">}</span> <span class="ot">→</span> μ⟨ Σ ⟩≈ x <span class="ot">→</span> <span class="ot">∀</span> <span class="ot">{</span>y<span class="ot">}</span> <span class="ot">→</span> x ≈ y <span class="ot">→</span> μ⟨ Σ ⟩≈ y</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>𝓢 <span class="ot">(</span>xs ≈[ y≈z ]<span class="ot">)</span> <span class="ot">=</span> 𝓢 xs</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>𝒻 <span class="ot">(</span>xs ≈[ y≈z ]<span class="ot">)</span> <span class="ot">=</span> trans <span class="ot">(</span>𝒻 xs<span class="ot">)</span> y≈z</span></code></pre></div>
<p>This makes it possible to “rewrite” the summary, given a proof of
equivalence.</p>
<h1 id="do-notation">Do Notation</h1>
<p>The wrapper on its own isn’t enough to save us from hundreds of lines
of proofs. Once you do computation on its contents, you still need to
join it up with its original proof of equivalence. In other words,
you’ll need to drill into the return type of a function, find the place
you used the relevant type variable, and apply the relevant proof from
the type above. This can really clutter proofs. Instead, we can use
Agda’s new support for do notation to try and get a cleaner notation for
everything. Here’s a big block of code:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">2</span> arg-syntax</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Arg <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>Σ <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> σ Σ ⦄ <span class="ot">(</span>𝓂 <span class="ot">:</span> 𝓡<span class="ot">)</span> <span class="ot">(</span>f <span class="ot">:</span> 𝓡 <span class="ot">→</span> 𝓡<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="ot">(</span>m ⊔ r ⊔ a<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> arg-syntax</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    ⟨f⟩ <span class="ot">:</span> Congruent₁ f</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    arg <span class="ot">:</span> μ⟨ Σ ⟩≈ 𝓂</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> Arg</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="kw">syntax</span> arg-syntax <span class="ot">(λ</span> sz <span class="ot">→</span> e₁<span class="ot">)</span> xs <span class="ot">=</span> xs [ e₁ ⟿ sz ]</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">1</span> <span class="ot">_</span>&gt;&gt;=<span class="ot">_</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&gt;&gt;=<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a b<span class="ot">}</span> <span class="ot">{</span>Σ₁ <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">{</span>Σ₂ <span class="ot">:</span> <span class="dt">Set</span> b<span class="ot">}</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> σ Σ₁ ⦄ ⦃ <span class="ot">_</span> <span class="ot">:</span> σ Σ₂ ⦄ <span class="ot">{</span>𝓂 f<span class="ot">}</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> Arg Σ₁ 𝓂 f</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> <span class="ot">((</span>x <span class="ot">:</span> Σ₁<span class="ot">)</span> <span class="ot">→</span> ⦃ x≈ <span class="ot">:</span> μ x ≈ 𝓂 ⦄ <span class="ot">→</span> μ⟨ Σ₂ ⟩≈ f <span class="ot">(</span>μ x<span class="ot">))</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> μ⟨ Σ₂ ⟩≈ f 𝓂</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>arg-syntax cng xs &gt;&gt;= k <span class="ot">=</span> k <span class="ot">(</span>𝓢 xs<span class="ot">)</span> ⦃ 𝒻 xs ⦄ ≈[ cng <span class="ot">(</span>𝒻 xs<span class="ot">)</span> ]</span></code></pre></div>
<p>First, we define a wrapper for types parameterised by their summary,
with a way to lift an underlying equality up into some expression
<code>f</code>. The <code>&gt;&gt;=</code> operator just connects up all
of the relevant bits. An example is what’s needed:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>listToTree <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">{</span>Σ <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> σ Σ ⦄ <span class="ot">→</span> <span class="ot">(</span>xs <span class="ot">:</span> List Σ<span class="ot">)</span> <span class="ot">→</span> μ⟨ Tree Σ ⟩≈ μ xs</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>listToTree [] <span class="ot">=</span> empty ⇑</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>listToTree <span class="ot">(</span>x ∷ xs<span class="ot">)</span> <span class="ot">=</span> [ ℳ ↯ ]≈ <span class="kw">do</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  ys ← listToTree xs [ μ x ∙&gt; s ⟿ s ]</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  x ◂ ys</span></code></pre></div>
<p>The first line is the base case, nothing interesting going on there.
The second line begins the do-notation, but first applies
<code>[ ℳ ↯ ]≈</code>: this calls the automated solver. The second line
makes the recursive call, and with the syntax:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>[ μ x ∙&gt; s ⟿ s ]</span></code></pre></div>
<p>It tells us where the size of the bound variable will end up in the
outer expression.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-danielsson_lightweight_2008" class="csl-entry"
role="listitem">
Danielsson, Nils Anders. 2008. <span>“Lightweight <span>Semiformal Time
Complexity Analysis</span> for <span>Purely Functional Data
Structures</span>.”</span> In <em>Proceedings of the 35th <span>Annual
ACM SIGPLAN</span>-<span>SIGACT Symposium</span> on
<span>Principles</span> of <span>Programming Languages</span></em>,
133–144. <span>POPL</span> ’08. New York, NY, USA: <span>ACM</span>.
doi:<a
href="https://doi.org/10.1145/1328438.1328457">10.1145/1328438.1328457</a>.
</div>
<div id="ref-hinze_simple_2001" class="csl-entry" role="listitem">
Hinze, Ralf. 2001. <span>“A <span>Simple Implementation Technique</span>
for <span>Priority Search Queues</span>.”</span> In <em>Proceedings of
the 2001 <span>International Conference</span> on <span>Functional
Programming</span></em>, 110–121. <span>ACM Press</span>. doi:<a
href="https://doi.org/10.1145/507635.507650">10.1145/507635.507650</a>.
</div>
<div id="ref-Hinze-Paterson:FingerTree" class="csl-entry"
role="listitem">
Hinze, Ralf, and Ross Paterson. 2006. <span>“Finger <span>Trees</span>:
<span>A Simple General</span>-purpose <span>Data
Structure</span>.”</span> <em>Journal of Functional Programming</em> 16
(2): 197–217.
</div>
<div id="ref-mu_queueing_2016" class="csl-entry" role="listitem">
Mu, Shin-Cheng, Yu-Hsi Chiang, and Yu-Han Lyu. 2016. <span>“Queueing and
<span>Glueing</span> for <span>Optimal Partitioning</span>
(<span>Functional Pearl</span>).”</span> In <em>Proceedings of the 21st
<span>ACM SIGPLAN International Conference</span> on <span>Functional
Programming</span></em>, 158–167. <span>ICFP</span> 2016. New York, NY,
USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2951913.2951923">10.1145/2951913.2951923</a>.
</div>
<div id="ref-sozeau_program-ing_2007" class="csl-entry" role="listitem">
Sozeau, Matthieu. 2007. <span>“Program-ing <span>Finger Trees</span> in
<span>Coq</span>.”</span> In <em>Proceedings of the 12th <span>ACM
SIGPLAN International Conference</span> on <span>Functional
Programming</span></em>, 13–24. <span>ICFP</span> ’07. New York, NY,
USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/1291151.1291156">10.1145/1291151.1291156</a>.
</div>
</div>
]]></description>
    <pubDate>Mon, 25 Feb 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-02-25-agda-fingertrees.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A New Ring Solver for Agda</title>
    <link>https://doisinkidney.com/posts/2019-01-25-agda-ring-solver.html</link>
    <description><![CDATA[<div class="info">
    Posted on January 25, 2019
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>I’m finally at the point where I feel like I can make the project
I’ve been working on for the past few months public: <a
href="https://oisdk.github.io/agda-ring-solver/README.html">A Ring
Solver for Agda</a>. The focus of the project is ergonomics and
ease-of-use: hopefully the interface to the solver is simpler and more
friendly than the one that’s already there. It can do step-by-step
solutions (like Wolfram Alpha). It’s also asymptotically faster than the
old solver (and actually faster! The usual optimizations you might apply
don’t actually work here, so this bit definitely took the most
work).</p>
<p>Anyway, this work is all for my undergrad final year project, but I’m
hoping to submit it to a conference or something in the next few
weeks.</p>
]]></description>
    <pubDate>Fri, 25 Jan 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-01-25-agda-ring-solver.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Binomial Urn</title>
    <link>https://doisinkidney.com/posts/2019-01-15-binomial-urn.html</link>
    <description><![CDATA[<div class="info">
    Posted on January 15, 2019
</div>
<div class="info">
    
        Part 3 of a <a href="/series/Balanced%20Folds.html">3-part series on Balanced Folds</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>When we started the series, we wanted to find a “better” fold: one
that was more balanced than either <code>foldl</code> or
<code>foldr</code> (in its placement of parentheses). Both of these are
about as unbalanced as you can get:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> (<span class="dv">2</span> <span class="op">+</span> (<span class="dv">3</span> <span class="op">+</span> <span class="dv">0</span>))</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">foldl</span> (<span class="op">+</span>) <span class="dv">0</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>((<span class="dv">0</span> <span class="op">+</span> <span class="dv">1</span>) <span class="op">+</span> <span class="dv">2</span>) <span class="op">+</span> <span class="dv">3</span></span></code></pre></div>
<p>The first better fold I found was Jon Fairbairn’s simple
<code>treeFold</code>:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>treeFold f <span class="ot">=</span> go</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    go x [] <span class="ot">=</span> x</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    go a  (b<span class="op">:</span>l) <span class="ot">=</span> go (f a b) (pairMap l)</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    pairMap (x<span class="op">:</span>y<span class="op">:</span>rest) <span class="ot">=</span> f x y <span class="op">:</span> pairMap rest</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    pairMap xs <span class="ot">=</span> xs</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> treeFold (<span class="op">+</span>) <span class="dv">0</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>(<span class="dv">0</span> <span class="op">+</span> <span class="dv">1</span>) <span class="op">+</span> (<span class="dv">2</span> <span class="op">+</span> <span class="dv">3</span>)</span></code></pre></div>
<p>Already this function was kind of magical: if your binary operator
merges two sorted lists, <code>foldr</code> will give you insertion
sort, whereas <code>treeFold</code> will give you merge sort; for
summing floats, <code>treeFold</code> has a lower error growth than
<code>sum</code>. By dividing up the work better, we were able to
improve the characteristics of many algorithms automatically. We also
saw that it could easily be made parallel:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">parseq ::</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>parseq a b <span class="ot">=</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    runST</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>        (bool (par a b) (<span class="fu">seq</span> a b) <span class="op">&lt;$&gt;</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>         unsafeIOToST (liftA2 (<span class="op">&gt;</span>) numSparks getNumCapabilities))</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFoldParallel ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>treeFoldParallel f <span class="ot">=</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    treeFold</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>        (\l r <span class="ot">-&gt;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>              r <span class="ot">`parseq`</span> (l <span class="ot">`parseq`</span> f l r))</span></code></pre></div>
<p>In the next post, we saw how we could make the fold incremental, by
using binary number representations for data structures. This let us do
2 things: it meant the fold was structurally terminating, so it would
pass the termination checker (efficiently) in languages like Agda or
Idris, and it meant we could write <code>scanl</code> using the fold.
The <code>scanl</code> was also efficient: you could run the fold at any
point in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
time, and work would be shared between subsequent runs. Effectively,
this let us use it to solve greedy optimization problems. We also saw
how it was effectively constructing an implicit binomial priority queue
under the hood, and how it exploited laziness to get sharing.</p>
<p>I’ve gotten huge mileage out of this fold and the general ideas about
it, and today I’m going to show one more use of it. We’re going to
improve some of the asymptotics of the data structure presented in <span
class="citation" data-cites="lampropoulos_ode_2017">Lampropoulos,
Spector-Zabusky, and Foner (<a href="#ref-lampropoulos_ode_2017"
role="doc-biblioref">2017</a>)</span>.</p>
<h1 id="a-random-urn">A Random Urn</h1>
<p>The paper opens with the problem:</p>
<blockquote>
<p>Suppose you have an urn containing two red balls, four green balls,
and three blue balls. If you take three balls out of the urn, what is
the probability that two of them are green?</p>
</blockquote>
<p>If you were to take just <em>one</em> ball out of the urn,
calculating the associated probabilities would be easy. Once you get to
the second, though, you have to update the previous probability
<em>based on what ball was removed</em>. In other words, we need to be
able to dynamically update the distribution.</p>
<p>Using lists, this would obviously become an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
operation. In the paper, an almost-perfect binary tree is used. This
turns the operation into one that’s
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>.
The rest of the operations have the following complexities:</p>
<table>
<thead>
<tr>
<th style="text-align: left;">Operation</th>
<th>Complexity</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;"><code>insert</code></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math></td>
</tr>
<tr>
<td style="text-align: left;"><code>remove</code></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math></td>
</tr>
<tr>
<td style="text-align: left;"><code>fromList</code></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math></td>
</tr>
</tbody>
</table>
<p>As a quick spoiler, the improved version presented here has these
complexities:</p>
<table>
<thead>
<tr>
<th>Operation</th>
<th>Complexity</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>insert</code></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math></td>
</tr>
<tr>
<td><code>remove</code></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math></td>
</tr>
<tr>
<td><code>merge</code></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math></td>
</tr>
<tr>
<td><code>fromList</code></td>
<td><math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math></td>
</tr>
</tbody>
</table>
<p>We add another operation (<code>merge</code>), which means that the
new structure is viable as an instance of <code>Alternative</code>,
<code>Monad</code>, and so on, making it an efficient monad for weighted
backtracking search.</p>
<h1 id="priority-queues">Priority Queues</h1>
<p>The key thing to notice in the paper which will let us improve the
structure is that what they’re designing is actually a <em>priority
queue</em>. Well, a weird looking priority queue, but a priority queue
nonetheless.</p>
<p>Think about it like a max-priority queue (pop returns the largest
element first), with a degree of “randomization”. In other words, when
you go to do a pop, all of the comparisons between the ordering keys
(the weights in this case) sprinkles some randomness into the equation,
meaning that instead of <code>1 &lt; 2</code> returning
<code>True</code>, it returns <code>True</code>
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>2</mn><mn>3</mn></mfrac><annotation encoding="application/x-tex">\frac{2}{3}</annotation></semantics></math>
of the time, and <code>False</code> the other
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mn>1</mn><mn>3</mn></mfrac><annotation encoding="application/x-tex">\frac{1}{3}</annotation></semantics></math>.</p>
<p>This way of doing things means that not every priority queue is
suitable: we want to run comparisons at <code>pop</code> time (not
<code>insert</code>), so a binary heap (for instance) won’t do. At
branches (non-leaves), the queue will only be allowed to store
<em>summaries</em> of the data, not the “max element”.</p>
<p>The one presented in the paper is something like a Braun priority
queue: the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
<code>fromList</code> implementation is reminiscent of the one in <span
class="citation" data-cites="okasaki_three_1997">Okasaki (<a
href="#ref-okasaki_three_1997"
role="doc-biblioref">1997</a>)</span>.</p>
<p>So what priority queue can we choose to get us the desired
efficiency? Why, a binomial one of course!</p>
<h1 id="the-data-structure">The Data Structure</h1>
<p>The urn structure itself looks a lot like a binomial heap:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Tree</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> weight ::</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Word</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> branch ::</span> <span class="dt">Node</span> a</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Node</span> a</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Leaf</span> a</span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Branch</span> (<span class="dt">Tree</span> a) (<span class="dt">Node</span> a)</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heap</span> a</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Cons</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Word</span> (<span class="dt">Tree</span> a) (<span class="dt">Heap</span> a)</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Urn</span> a <span class="ot">=</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Urn</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Word</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>        <span class="op">!</span>(<span class="dt">Heap</span> a)</span></code></pre></div>
<p>By avoiding the usual <code>Skip</code> constructors you often see in
a binomial heap we save a huge amount of space. Instead, we store the
“number of zeroes before this bit”. Another thing to point out is that
only left branches in the trees store their weight: the same
optimization is made in the paper.</p>
<p>Insertion is not much different from insertion for a usual binomial
priority queue, although we don’t need to do anything to merge the
trees:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insertHeap ::</span> <span class="dt">Word</span> <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Heap</span> a <span class="ot">-&gt;</span> <span class="dt">Heap</span> a</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>insertHeap i&#39; x&#39; <span class="ot">=</span> go <span class="dv">0</span> (<span class="dt">Tree</span> i&#39; (<span class="dt">Leaf</span> x&#39;))</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    go <span class="op">!</span>i x <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Cons</span> i x <span class="dt">Nil</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    go <span class="op">!</span>i x (<span class="dt">Cons</span> <span class="dv">0</span> y ys) <span class="ot">=</span> go (i<span class="op">+</span><span class="dv">1</span>) (mergeTree x y) ys</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    go <span class="op">!</span>i x (<span class="dt">Cons</span> j y ys) <span class="ot">=</span> <span class="dt">Cons</span> i x (<span class="dt">Cons</span> (j<span class="op">-</span><span class="dv">1</span>) y ys)</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeTree ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>mergeTree xs ys <span class="ot">=</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Tree</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    (weight xs <span class="op">+</span> weight ys)</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Branch</span> xs (branch ys))</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Word</span> <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Urn</span> a <span class="ot">-&gt;</span> <span class="dt">Urn</span> a</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>insert i x (<span class="dt">Urn</span> w xs) <span class="ot">=</span> <span class="dt">Urn</span> (w<span class="op">+</span>i) (insertHeap i x xs)</span></code></pre></div>
<p>We <em>could</em> potentially get insertion from amortized
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
to worst-case
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
by using skew binary instead of binary (in fact I am almost sure it’s
possible), but then I think we’d lose the efficient merge. I’ll leave
exploring that for another day.</p>
<p>To get randomness, we’ll write a very simple class that encapsulates
only what we need:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Sample</span> m <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- | Inclusive range</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ot">    inRange ::</span> <span class="dt">Word</span> <span class="ot">-&gt;</span> <span class="dt">Word</span> <span class="ot">-&gt;</span> m <span class="dt">Word</span></span></code></pre></div>
<p>You can later instantiate this to whatever random monad you end up
using. (The same approach was taken in the paper, although we only
require <code>Functor</code> here, not <code>Monad</code>).</p>
<p>Sampling (with replacement) first randomly chooses a tree from the
top-level list, and then we drill down into that tree with binary
search.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">sample ::</span> (<span class="dt">Functor</span> m, <span class="dt">Sample</span> m) <span class="ot">=&gt;</span> <span class="dt">Urn</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (m a)</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>sample (<span class="dt">Urn</span> _ <span class="dt">Nil</span>) <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>sample (<span class="dt">Urn</span> w&#39; (<span class="dt">Cons</span> _ x&#39; xs&#39;)) <span class="ot">=</span> <span class="dt">Just</span> (<span class="fu">fmap</span> (go x&#39; xs&#39;) (<span class="fu">inRange</span> <span class="dv">0</span> (w&#39; <span class="op">-</span> <span class="dv">1</span>)))</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    go x <span class="dt">Nil</span> <span class="op">!</span>w <span class="ot">=</span> go&#39; w (branch x)</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    go x (<span class="dt">Cons</span> _ y ys) <span class="op">!</span>w</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> w <span class="op">&lt;</span> weight x <span class="ot">=</span> go&#39; w (branch x)</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span>    <span class="ot">=</span> go y ys (w <span class="op">-</span> weight x)</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>    go&#39; <span class="op">!</span>_ (<span class="dt">Leaf</span> x) <span class="ot">=</span> x</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    go&#39; <span class="op">!</span>i (<span class="dt">Branch</span> xs ys)</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> i <span class="op">&lt;</span> weight xs <span class="ot">=</span> go&#39; i (branch xs)</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> go&#39; (i <span class="op">-</span> weight xs) ys</span></code></pre></div>
<p>So we’re off to a good start, but <code>remove</code> is a complex
operation. We take the same route taken in the paper: first, we perform
an “uncons”-like operation, which pops out the last inserted element.
Then, we randomly choose a point in the tree (using the same logic as in
<code>sample</code>), and replace it with the popped element<a
href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a>.</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">remove ::</span> (<span class="dt">Functor</span> m, <span class="dt">Sample</span> m) <span class="ot">=&gt;</span> <span class="dt">Urn</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (m ((a, <span class="dt">Word</span>), <span class="dt">Urn</span> a))</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>remove (<span class="dt">Urn</span> w hp) <span class="ot">=</span> <span class="fu">fmap</span> go&#39; (Heap.uninsert hp)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    go&#39; (vw,v,hp&#39;) <span class="ot">=</span> <span class="fu">fmap</span> (<span class="ot">`go`</span> hp&#39;) (<span class="fu">inRange</span> <span class="dv">0</span> (w<span class="op">-</span><span class="dv">1</span>))</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        go <span class="op">!</span>_  <span class="dt">Nil</span> <span class="ot">=</span> ((v, vw), <span class="dt">Urn</span> <span class="dv">0</span> <span class="dt">Nil</span>)</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        go <span class="op">!</span>rw vs<span class="op">@</span>(<span class="dt">Cons</span> i&#39; x&#39; xs&#39;)</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> rw <span class="op">&lt;</span> vw <span class="ot">=</span> ((v, vw), <span class="dt">Urn</span> (w <span class="op">-</span> vw) vs)</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> replace (rw <span class="op">-</span> vw) i&#39; x&#39; xs&#39;</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>            (\ys yw y <span class="ot">-&gt;</span> ((y, yw), <span class="dt">Urn</span> (w <span class="op">-</span> yw) ys))</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>        replace <span class="op">!</span>rw i x <span class="dt">Nil</span> k <span class="ot">=</span> replaceTree rw x (\t <span class="ot">-&gt;</span> k (<span class="dt">Cons</span> i t <span class="dt">Nil</span>))</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>        replace <span class="op">!</span>rw i x xs<span class="op">@</span>(<span class="dt">Cons</span> j y ys) k</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> rw <span class="op">&lt;</span> weight x <span class="ot">=</span> replaceTree rw x (\t <span class="ot">-&gt;</span> k (<span class="dt">Cons</span> i t xs))</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> replace (rw <span class="op">-</span> weight x) j y ys (k <span class="op">.</span> <span class="dt">Cons</span> i x)</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>        replaceTree <span class="op">!</span>_  (<span class="dt">Tree</span> tw (<span class="dt">Leaf</span> x)) k <span class="ot">=</span> k (<span class="dt">Tree</span> vw (<span class="dt">Leaf</span> v)) tw x</span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>        replaceTree <span class="op">!</span>rw (<span class="dt">Tree</span> tw (<span class="dt">Branch</span> xs ys)) k</span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> rw <span class="op">&lt;</span> weight xs <span class="ot">=</span> replaceTree rw xs</span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>            (\t <span class="ot">-&gt;</span> k (<span class="dt">Tree</span> (tw <span class="op">+</span> (weight t <span class="op">-</span> weight xs)) (<span class="dt">Branch</span> t ys)))</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> replaceTree (rw <span class="op">-</span> weight xs)</span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Tree</span> (tw <span class="op">-</span> weight xs) ys)</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>            (\t <span class="ot">-&gt;</span> k (<span class="dt">Tree</span> (weight xs <span class="op">+</span> weight t) (<span class="dt">Branch</span> xs (branch t))))</span></code></pre></div>
<p>Merge is the same as on binomial heaps:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeHeap ::</span> <span class="dt">Heap</span> a <span class="ot">-&gt;</span> <span class="dt">Heap</span> a <span class="ot">-&gt;</span> <span class="dt">Heap</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>mergeHeap <span class="dt">Nil</span> <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>mergeHeap (<span class="dt">Cons</span> i&#39; x&#39; xs&#39;) <span class="ot">=</span> merger i&#39; x&#39; xs&#39;</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    merger <span class="op">!</span>i x xs <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Cons</span> i x xs</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    merger <span class="op">!</span>i x xs (<span class="dt">Cons</span> j y ys) <span class="ot">=</span> merge&#39; i x xs j y ys</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>    merge&#39; <span class="op">!</span>i x xs <span class="op">!</span>j y ys <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> i j <span class="kw">of</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>        <span class="dt">LT</span> <span class="ot">-&gt;</span> <span class="dt">Cons</span> i x (merger (j<span class="op">-</span>i<span class="op">-</span><span class="dv">1</span>) y ys xs)</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>        <span class="dt">GT</span> <span class="ot">-&gt;</span> <span class="dt">Cons</span> j y (merger (i<span class="op">-</span>j<span class="op">-</span><span class="dv">1</span>) x xs ys)</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>        <span class="dt">EQ</span> <span class="ot">-&gt;</span> mergec (<span class="fu">succ</span> i) (mergeTree x y) xs ys</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>    mergec <span class="op">!</span>p <span class="op">!</span>t <span class="dt">Nil</span> <span class="ot">=</span> carryLonger p t</span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>    mergec <span class="op">!</span>p <span class="op">!</span>t (<span class="dt">Cons</span> i x xs) <span class="ot">=</span> mergecr p t i x xs</span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>    mergecr <span class="op">!</span>p <span class="op">!</span>t <span class="op">!</span>i x xs <span class="dt">Nil</span> <span class="ot">=</span> carryLonger&#39; p t i x xs</span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>    mergecr <span class="op">!</span>p <span class="op">!</span>t <span class="op">!</span>i x xs (<span class="dt">Cons</span> j y ys) <span class="ot">=</span> mergec&#39; p t i x xs j y ys</span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>    mergec&#39; <span class="op">!</span>p t <span class="op">!</span>i x xs <span class="op">!</span>j y ys <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> i j <span class="kw">of</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>      <span class="dt">LT</span> <span class="ot">-&gt;</span> mergecr&#39;&#39; p t i x xs (j<span class="op">-</span>i<span class="op">-</span><span class="dv">1</span>) y ys</span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>      <span class="dt">GT</span> <span class="ot">-&gt;</span> mergecr&#39;&#39; p t j y ys (i<span class="op">-</span>j<span class="op">-</span><span class="dv">1</span>) x xs</span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>      <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dt">Cons</span> p t (mergec i (mergeTree x y) xs ys)</span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>    mergecr&#39;&#39; <span class="op">!</span>p <span class="op">!</span>t  <span class="dv">0</span> x xs <span class="op">!</span>j y ys <span class="ot">=</span> mergecr (p<span class="op">+</span><span class="dv">1</span>) (mergeTree t x) j y ys xs</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>    mergecr&#39;&#39; <span class="op">!</span>p <span class="op">!</span>t <span class="op">!</span>i x xs <span class="op">!</span>j y ys <span class="ot">=</span> <span class="dt">Cons</span> p t (<span class="dt">Cons</span> (i<span class="op">-</span><span class="dv">1</span>) x (merger j y ys xs))</span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>    carryLonger <span class="op">!</span>i <span class="op">!</span>t <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Cons</span> i t <span class="dt">Nil</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a>    carryLonger <span class="op">!</span>i <span class="op">!</span>t (<span class="dt">Cons</span> j y ys) <span class="ot">=</span> carryLonger&#39; i t j y ys</span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a>    carryLonger&#39; <span class="op">!</span>i <span class="op">!</span>t  <span class="dv">0</span> y ys <span class="ot">=</span> carryLonger (<span class="fu">succ</span> i) (mergeTree t y) ys</span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true" tabindex="-1"></a>    carryLonger&#39; <span class="op">!</span>i <span class="op">!</span>t <span class="op">!</span>j y ys <span class="ot">=</span> <span class="dt">Cons</span> i t (<span class="dt">Cons</span> (j<span class="op">-</span><span class="dv">1</span>) y ys)</span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> <span class="dt">Urn</span> a <span class="ot">-&gt;</span> <span class="dt">Urn</span> a <span class="ot">-&gt;</span> <span class="dt">Urn</span> a</span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true" tabindex="-1"></a>merge (<span class="dt">Urn</span> i xs) (<span class="dt">Urn</span> j ys) <span class="ot">=</span> <span class="dt">Urn</span> (i<span class="op">+</span>j) (mergeHeap xs ys)</span></code></pre></div>
<h1 id="finger-trees">Finger Trees</h1>
<p>Again, the cleverness of all the tree folds is that they
intelligently batch summarizing operations, allowing you to efficiently
do prefix-scan-like operations that exploit sharing.</p>
<p>The bare-bones version just uses binary numbers: you can upgrade the
<code>cons</code> operation to worst-case constant-time if you use
<em>skew</em> binary. Are there other optimizations? Yes! What if we
wanted to stick something on to the <em>other</em> end, for instance?
What if we wanted to reverse?</p>
<p>If you figure out a way to do <em>all</em> these optimizations, and
put them into one big data structure, you get the mother-of-all
“batching” data structures: the finger tree. This is the basis for
Haskell’s Data.Sequence, but it can also implement priority queues, urns
(I’d imagine), fenwick-tree-like structures, and more.</p>
<h1 id="uses-and-further-work">Uses and Further Work</h1>
<p>First and foremost, I should test the above implementations! I’m
pretty confident the asymptotics are correct, but I’m certain the
implementations have bugs.</p>
<p>The efficient <code>merge</code> is intriguing: it means that
<code>Urn</code> could conceivably be <code>Alternative</code>,
<code>MonadPlus</code>, etc. I have yet to see a use for that, but it’s
interesting nonetheless! I’m constantly looking for a way to express
something like Dijkstra’s algorithm algebraically, using the usual
<code>Alternative</code> combinators; I don’t know if this is
related.</p>
<p>The other interesting point is that, for this to be an instance of
<code>Applicative</code>, it would need some analogue for multiplication
for the weights. I’m not sure what that should be.</p>
<p>This is inherently <em>max</em>-priority. It’s not obvious how to
translate what we have into a min-priority queue version.</p>
<p>Finally, it might be worth trying out different priority queues (a
pairing heap is very similar in structure to this). Also, we could
rearrange the weights so that larger ones are higher in each tree: this
might give a performance boost.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-lampropoulos_ode_2017" class="csl-entry" role="listitem">
Lampropoulos, Leonidas, Antal Spector-Zabusky, and Kenneth Foner. 2017.
<span>“Ode on a random urn (functional pearl).”</span> In, 26–37.
<span>ACM Press</span>. doi:<a
href="https://doi.org/10.1145/3122955.3122959">10.1145/3122955.3122959</a>.
</div>
<div id="ref-okasaki_three_1997" class="csl-entry" role="listitem">
Okasaki, Chris. 1997. <span>“Three <span>Algorithms</span> on
<span>Braun Trees</span>.”</span> <em>Journal of Functional
Programming</em> 7 (6) (November): 661–666. doi:<a
href="https://doi.org/10.1017/S0956796897002876">10.1017/S0956796897002876</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>There’s one extra step I haven’t mentioned: we also must
allow the first element (the last inserted) to be chosen, so we run the
random-number generator once to check if that’s the element we want to
choose.<a href="#fnref1" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Tue, 15 Jan 2019 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2019-01-15-binomial-urn.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Drawing Trees</title>
    <link>https://doisinkidney.com/posts/2018-12-30-drawing-trees-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 30, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>For a bunch of algorithms it’s handy to get a quick-and-dirty
visualization of a tree. <a
href="http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Tree.html#v:drawTree">Data.Tree</a>
has a tree-drawing function, but its output is too noisy for my taste,
and so doesn’t really illustrate the underlying structure in a way I
find helpful. This version uses the unicode box-drawing characters to
give an output that’s midway between what is provided in <a
href="http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Tree.html#v:drawTree">Data.Tree</a>
and a full-blown SVG diagram. This makes it perfect for debugging
tree-based algorithms while you’re writing them.</p>
<p>For the <a
href="https://en.wikipedia.org/wiki/Breadth-first_search">example tree
in Wikipedia’s article on breadth-first search</a>, it gives the
following output:</p>
<pre><code>     ┌─9
   ┌5┤
 ┌2┤ └10
 │ └6
1┼3
 │   ┌11
 │ ┌7┤
 └4┤ └12
   └8</code></pre>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">TreeDrawing</span> <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Tree</span> (<span class="dt">Tree</span>(..))</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List</span> (intercalate)</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="ot">drawTree ::</span> <span class="dt">Tree</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>drawTree tr <span class="ot">=</span> (<span class="fu">unlines</span> <span class="op">.</span> <span class="fu">filter</span> content <span class="op">.</span> flatten) (<span class="fu">foldr</span> go <span class="fu">undefined</span> maxLengths withLength)</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    withLength <span class="ot">=</span> <span class="fu">fmap</span> (\x <span class="ot">-&gt;</span> (<span class="fu">length</span> x, x)) tr</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    maxLengths <span class="ot">=</span> lwe withLength (<span class="fu">repeat</span> <span class="dv">0</span>)</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    lwe (<span class="dt">Node</span> x xs) (q<span class="op">:</span>qs) <span class="ot">=</span> <span class="fu">max</span> (<span class="fu">fst</span> x) q <span class="op">:</span> <span class="fu">foldr</span> lwe qs xs</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    content <span class="ot">=</span> <span class="fu">any</span> (<span class="ot">`notElem`</span> <span class="st">&quot; │&quot;</span>)</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    flatten (ls,x,rs) <span class="ot">=</span> ls <span class="op">++</span> [x] <span class="op">++</span> rs</span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    mapZipper lf f rf (ls,x,rs) <span class="ot">=</span> (<span class="fu">map</span> lf ls, f x, <span class="fu">map</span> rf rs)</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    toZipper xs <span class="ot">=</span> <span class="kw">case</span> <span class="fu">splitAt</span> (<span class="fu">length</span> xs <span class="ot">`div`</span> <span class="dv">2</span>) xs <span class="kw">of</span> (ls,x<span class="op">:</span>rs) <span class="ot">-&gt;</span> (ls,x,rs)</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    go m ls (<span class="dt">Node</span> (l,x) []) <span class="ot">=</span> ([],<span class="fu">replicate</span> (m<span class="op">-</span>l) <span class="ch">&#39;─&#39;</span> <span class="op">++</span> x,[])</span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>    go m ls (<span class="dt">Node</span> (l,x) [y]) <span class="ot">=</span> mapZipper pad link pad (ls y)</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>        padding <span class="ot">=</span> m <span class="op">+</span> <span class="dv">1</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>        pad <span class="ot">=</span> (<span class="op">++</span>) (<span class="fu">replicate</span> padding <span class="ch">&#39; &#39;</span>)</span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>        link z <span class="ot">=</span> <span class="fu">replicate</span> (m<span class="op">-</span>l) <span class="ch">&#39;─&#39;</span> <span class="op">++</span> x <span class="op">++</span> <span class="st">&quot;─&quot;</span> <span class="op">++</span> z</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>    go m ls (<span class="dt">Node</span> (l,x&#39;) xs) <span class="ot">=</span> mapZipper pad link pad (toZipper (intercalate [<span class="st">&quot;│&quot;</span>] ([ysh] <span class="op">++</span> ysm <span class="op">++</span> [ysl])))</span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>        x <span class="ot">=</span> <span class="fu">replicate</span> (m<span class="op">-</span>l) <span class="ch">&#39;─&#39;</span> <span class="op">++</span> x&#39;</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a>        ys <span class="ot">=</span> <span class="fu">map</span> ls xs</span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>        ysh <span class="ot">=</span> flatten (mapZipper (<span class="ch">&#39; &#39;</span><span class="op">:</span>) (<span class="ch">&#39;┌&#39;</span> <span class="op">:</span>) (<span class="ch">&#39;│&#39;</span><span class="op">:</span>) (<span class="fu">head</span> ys))</span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>        ysl <span class="ot">=</span> flatten (mapZipper (<span class="ch">&#39;│&#39;</span><span class="op">:</span>) (<span class="ch">&#39;└&#39;</span> <span class="op">:</span>) (<span class="ch">&#39; &#39;</span><span class="op">:</span>) (<span class="fu">last</span> ys))</span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a>        ysm <span class="ot">=</span> <span class="fu">map</span> (flatten <span class="op">.</span> mapZipper (<span class="ch">&#39;│&#39;</span><span class="op">:</span>) (<span class="ch">&#39;├&#39;</span><span class="op">:</span>) (<span class="ch">&#39;│&#39;</span><span class="op">:</span>)) (<span class="fu">init</span> (<span class="fu">tail</span> ys))</span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a>        pad <span class="ot">=</span> (<span class="op">++</span>) (<span class="fu">replicate</span> m <span class="ch">&#39; &#39;</span>)</span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a>        link (<span class="ch">&#39;│&#39;</span><span class="op">:</span>zs) <span class="ot">=</span> x <span class="op">++</span> <span class="st">&quot;┤&quot;</span> <span class="op">++</span> zs</span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>        link (<span class="ch">&#39;├&#39;</span><span class="op">:</span>zs) <span class="ot">=</span> x <span class="op">++</span> <span class="st">&quot;┼&quot;</span> <span class="op">++</span> zs</span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>        link (<span class="ch">&#39;┌&#39;</span><span class="op">:</span>zs) <span class="ot">=</span> x <span class="op">++</span> <span class="st">&quot;┬&quot;</span> <span class="op">++</span> zs</span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a>        link (<span class="ch">&#39;└&#39;</span><span class="op">:</span>zs) <span class="ot">=</span> x <span class="op">++</span> <span class="st">&quot;┴&quot;</span> <span class="op">++</span> zs</span></code></pre></div>
]]></description>
    <pubDate>Sun, 30 Dec 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-12-30-drawing-trees-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>liftAN</title>
    <link>https://doisinkidney.com/posts/2018-12-29-nary-uncurry-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 29, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>This function is now available <a
href="http://hackage.haskell.org/package/arity-generic-liftA">on
hackage</a>.</p>
<p>There’s a family of functions in <a
href="https://hackage.haskell.org/package/base-4.11.0.0/docs/Control-Applicative.html">Control.Applicative</a>
which follow the pattern <code class="sourceCode haskell">liftA2</code>,
<code class="sourceCode haskell">liftA3</code>, etc. Using some tricks
from Richard Eisenberg’s thesis we can write them all at once.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DataKinds             #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeFamilies          #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE MultiParamTypeClasses #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleInstances     #-}</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleContexts      #-}</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Apply</span> <span class="kw">where</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">N</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">N</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">AppFunc</span> f n a <span class="kw">where</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">AppFunc</span> f <span class="dt">Z</span> a <span class="ot">=</span> f a</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">AppFunc</span> f (<span class="dt">S</span> n) (a <span class="ot">-&gt;</span> b) <span class="ot">=</span> f a <span class="ot">-&gt;</span> <span class="dt">AppFunc</span> f n b</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">CountArgs</span> f <span class="kw">where</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>  <span class="dt">CountArgs</span> (_ <span class="ot">-&gt;</span> b) <span class="ot">=</span> <span class="dt">S</span> (<span class="dt">CountArgs</span> b)</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>  <span class="dt">CountArgs</span> _ <span class="ot">=</span> <span class="dt">Z</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (<span class="dt">CountArgs</span> a <span class="op">~</span> n) <span class="ot">=&gt;</span> <span class="dt">Applyable</span> a n <span class="kw">where</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="ot">  apply ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">AppFunc</span> f (<span class="dt">CountArgs</span> a) a</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">CountArgs</span> a <span class="op">~</span> <span class="dt">Z</span>) <span class="ot">=&gt;</span> <span class="dt">Applyable</span> a <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  apply <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE apply #-}</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applyable</span> b n <span class="ot">=&gt;</span> <span class="dt">Applyable</span> (a <span class="ot">-&gt;</span> b) (<span class="dt">S</span> n) <span class="kw">where</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>  apply f x <span class="ot">=</span> apply (f <span class="op">&lt;*&gt;</span> x)</span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE apply #-}</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a><span class="co">-- | &gt;&gt;&gt; lift (\x y z -&gt; x ++ y ++ z) (Just &quot;a&quot;) (Just &quot;b&quot;) (Just &quot;c&quot;)</span></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a><span class="co">-- Just &quot;abc&quot;</span></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a><span class="ot">lift ::</span> (<span class="dt">Applyable</span> a n, <span class="dt">Applicative</span> f) <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (f b <span class="ot">-&gt;</span> <span class="dt">AppFunc</span> f n a)</span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>lift f x <span class="ot">=</span> apply (<span class="fu">fmap</span> f x)</span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE lift #-}</span></span></code></pre></div>
<p><a
href="https://github.com/goldfirere/thesis/raw/master/built/thesis.pdf">Eisenberg,
Richard A. “Dependent Types in Haskell: Theory and Practice.” University
of Pennsylvania, 2016.</a></p>
]]></description>
    <pubDate>Sat, 29 Dec 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-12-29-nary-uncurry-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Balancing Scans</title>
    <link>https://doisinkidney.com/posts/2018-12-21-balancing-scans.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 21, 2018
</div>
<div class="info">
    
        Part 2 of a <a href="/series/Balanced%20Folds.html">3-part series on Balanced Folds</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p><a href="2017-10-30-balancing-folds.html">Previously</a> I tried to
figure out a way to fold lists in a more balanced way. Usually, when
folding lists, you’ve got two choices for your folds, both of which are
extremely unbalanced in one direction or another. Jon Fairbairn <a
href="https://www.mail-archive.com/haskell@haskell.org/msg01788.html">wrote</a>
a more balanced version, which looked something like this:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>treeFold f <span class="ot">=</span> go</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    go x [] <span class="ot">=</span> x</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    go a (b<span class="op">:</span>l) <span class="ot">=</span> go (f a b) (pairMap l)</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    pairMap (x<span class="op">:</span>y<span class="op">:</span>rest) <span class="ot">=</span> f x y <span class="op">:</span> pairMap rest</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    pairMap xs <span class="ot">=</span> xs</span></code></pre></div>
<h1 id="magical-speedups">Magical Speedups</h1>
<p>The fold above is kind of magical: for a huge class of algorithms, it
kind of “automatically” improves some factor of theirs from
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>.
For instance: to sum a list of floats, <code
class="sourceCode haskell">foldl&#39; (<span class="op">+</span>) <span class="dv">0</span></code>
will have an error growth of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>;
<code>treeFold (+) 0</code>, though, has an error rate of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>.
Similarly, using the following function to merge two sorted lists:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>merge [] ys <span class="ot">=</span> ys</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>merge (x<span class="op">:</span>xs) ys <span class="ot">=</span> go x xs ys</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    go x xs [] <span class="ot">=</span> x <span class="op">:</span> xs</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    go x xs (y<span class="op">:</span>ys)</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> x <span class="op">:</span> go y ys xs</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> y <span class="op">:</span> go x xs ys</span></code></pre></div>
<p>We get either insertion sort
(<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>)
or merge sort
(<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n
\log n)</annotation></semantics></math>) just depending on which fold
you use.</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldr</span>    merge [] <span class="op">.</span> <span class="fu">map</span> <span class="fu">pure</span> <span class="co">-- n^2</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>treeFold merge [] <span class="op">.</span> <span class="fu">map</span> <span class="fu">pure</span> <span class="co">-- n log(n)</span></span></code></pre></div>
<p>I’ll give some more examples later, but effectively it gives us a
better “divide” step in many divide and conquer algorithms.</p>
<h1 id="termination">Termination</h1>
<p>As it was such a useful fold, and so integral to many tricky
algorithms, I really wanted to have it available in Agda. Unfortunately,
though, the functions (as defined above) aren’t structurally
terminating, and there doesn’t <em>look</em> like there’s an obvious way
to make it so. I tried to make well founded recursion work, but the
proofs were ugly and slow.</p>
<p>However, we can use some structures from a <a
href="2018-11-20-fast-verified-structures.html">previous post</a>: the
nested binary sequence, for instance. It has some extra nice properties:
instead of nesting the types, we can just apply the combining
function.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">mutual</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">data</span> Tree <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    2^<span class="ot">_</span>×<span class="ot">_</span>+<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> A <span class="ot">→</span> Node A <span class="ot">→</span> Tree A</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">data</span> Node <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    ⟨⟩  <span class="ot">:</span> Node A</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    ⟨<span class="ot">_</span>⟩ <span class="ot">:</span> Tree A <span class="ot">→</span> Node A</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> TreeFold <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">(_</span>*<span class="ot">_</span> <span class="ot">:</span> A <span class="ot">→</span> A <span class="ot">→</span> A<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">infixr</span> <span class="dv">5</span> <span class="ot">_</span>⊛<span class="ot">_</span> 2^<span class="ot">_</span>×<span class="ot">_</span>⊛<span class="ot">_</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  2^<span class="ot">_</span>×<span class="ot">_</span>⊛<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> A <span class="ot">→</span> Tree A <span class="ot">→</span> Tree A</span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>  2^ n × x ⊛ 2^ suc m × y + ys <span class="ot">=</span> 2^ n × x + ⟨ 2^ m × y + ys ⟩</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>  2^ n × x ⊛ 2^ zero  × y + ⟨⟩ <span class="ot">=</span> 2^ suc n × <span class="ot">(</span>x * y<span class="ot">)</span> + ⟨⟩</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>  2^ n × x ⊛ 2^ zero  × y + ⟨ ys ⟩ <span class="ot">=</span> 2^ suc n × <span class="ot">(</span>x * y<span class="ot">)</span> ⊛ ys</span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>⊛<span class="ot">_</span> <span class="ot">:</span> A <span class="ot">→</span> Tree A <span class="ot">→</span> Tree A</span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>⊛<span class="ot">_</span> <span class="ot">=</span> 2^ <span class="dv">0</span> ×<span class="ot">_</span>⊛<span class="ot">_</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>  ⟦<span class="ot">_</span>⟧↓ <span class="ot">:</span> Tree A <span class="ot">→</span> A</span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>  ⟦ 2^ <span class="ot">_</span> × x + ⟨⟩ ⟧↓ <span class="ot">=</span> x</span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a>  ⟦ 2^ <span class="ot">_</span> × x + ⟨ xs ⟩ ⟧↓ <span class="ot">=</span> x * ⟦ xs ⟧↓</span>
<span id="cb4-23"><a href="#cb4-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-24"><a href="#cb4-24" aria-hidden="true" tabindex="-1"></a>  ⟦<span class="ot">_</span>⟧↑ <span class="ot">:</span> A <span class="ot">→</span> Tree A</span>
<span id="cb4-25"><a href="#cb4-25" aria-hidden="true" tabindex="-1"></a>  ⟦ x ⟧↑ <span class="ot">=</span> 2^ <span class="dv">0</span> × x + ⟨⟩</span>
<span id="cb4-26"><a href="#cb4-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-27"><a href="#cb4-27" aria-hidden="true" tabindex="-1"></a>  ⦅<span class="ot">_</span>,<span class="ot">_</span>⦆ <span class="ot">:</span> A <span class="ot">→</span> List A <span class="ot">→</span> A</span>
<span id="cb4-28"><a href="#cb4-28" aria-hidden="true" tabindex="-1"></a>  ⦅ x , xs ⦆ <span class="ot">=</span> ⟦ foldr <span class="ot">_</span>⊛<span class="ot">_</span> ⟦ x ⟧↑ xs ⟧↓</span></code></pre></div>
<p>Alternatively, we can get
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
cons with the skew array:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="ot">_</span>⊛<span class="ot">_</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>⊛<span class="ot">_</span> <span class="ot">:</span> A <span class="ot">→</span> Tree A <span class="ot">→</span> Tree A</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>x ⊛ 2^ n × y  + ⟨⟩ <span class="ot">=</span> 2^ <span class="dv">0</span> × x + ⟨ 2^ n × y + ⟨⟩ ⟩</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>x ⊛ 2^ n × y₁ + ⟨ 2^ <span class="dv">0</span>     × y₂ + ys ⟩ <span class="ot">=</span> 2^ suc n × <span class="ot">(</span>x * <span class="ot">(</span>y₁ * y₂<span class="ot">))</span> + ys</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>x ⊛ 2^ n × y₁ + ⟨ 2^ suc m × y₂ + ys ⟩ <span class="ot">=</span> 2^ <span class="dv">0</span> × x + ⟨ 2^ n × y₁ + ⟨ 2^ m × y₂ + ys ⟩ ⟩</span></code></pre></div>
<p>Using this, a proper and efficient merge sort is very
straightforward:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Total <span class="ot">{</span>a r<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">(_</span>≤<span class="ot">_</span> <span class="ot">:</span> A <span class="ot">→</span> A <span class="ot">→</span> <span class="dt">Set</span> r<span class="ot">)</span> <span class="ot">(</span>x y <span class="ot">:</span> A<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="ot">(</span>a ⊔ r<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  x≤y <span class="ot">:</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> x ≤ y ⦄ <span class="ot">→</span> Total <span class="ot">_</span>≤<span class="ot">_</span> x y</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  y≤x <span class="ot">:</span> ⦃ <span class="ot">_</span> <span class="ot">:</span> y ≤ x ⦄ <span class="ot">→</span> Total <span class="ot">_</span>≤<span class="ot">_</span> x y</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> Sorting <span class="ot">{</span>a r<span class="ot">}</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>               <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>               <span class="ot">{_</span>≤<span class="ot">_</span> <span class="ot">:</span> A <span class="ot">→</span> A <span class="ot">→</span> <span class="dt">Set</span> r<span class="ot">}</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>               <span class="ot">(_</span>≤?<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> x y <span class="ot">→</span> Total <span class="ot">_</span>≤<span class="ot">_</span> x y<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">data</span> [∙] <span class="ot">:</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>    ⊥   <span class="ot">:</span> [∙]</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>    [<span class="ot">_</span>] <span class="ot">:</span> A <span class="ot">→</span> [∙]</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">data</span> <span class="ot">_</span>≥<span class="ot">_</span> <span class="ot">(</span>x <span class="ot">:</span> A<span class="ot">)</span> <span class="ot">:</span> [∙] <span class="ot">→</span> <span class="dt">Set</span> <span class="ot">(</span>a ⊔ r<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>    <span class="kw">instance</span> ⌈<span class="ot">_</span>⌉ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>y<span class="ot">}</span> <span class="ot">→</span> y ≤ x <span class="ot">→</span> x ≥ [ y ]</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">instance</span> ⌊⊥⌋ <span class="ot">:</span> x ≥ ⊥</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>  <span class="kw">infixr</span> <span class="dv">5</span> <span class="ot">_</span>∷<span class="ot">_</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">data</span> Ordered <span class="ot">(</span>b <span class="ot">:</span> [∙]<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="ot">(</span>a ⊔ r<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>    []  <span class="ot">:</span> Ordered b</span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>    <span class="ot">_</span>∷<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> x <span class="ot">→</span> ⦃ x≥b <span class="ot">:</span> x ≥ b ⦄ <span class="ot">→</span> <span class="ot">(</span>xs <span class="ot">:</span> Ordered [ x ]<span class="ot">)</span> <span class="ot">→</span> Ordered b</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>∪<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>b<span class="ot">}</span> <span class="ot">→</span> Ordered b <span class="ot">→</span> Ordered b <span class="ot">→</span> Ordered b</span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true" tabindex="-1"></a>  [] ∪ ys <span class="ot">=</span> ys</span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true" tabindex="-1"></a>  <span class="ot">(</span>x ∷ xs<span class="ot">)</span> ∪ ys <span class="ot">=</span> ⟅ x ∹ xs ∪ ys ⟆</span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true" tabindex="-1"></a>    ⟅<span class="ot">_</span>∹<span class="ot">_</span>∪<span class="ot">_</span>⟆ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>b<span class="ot">}</span> <span class="ot">→</span> <span class="ot">∀</span> x ⦃ <span class="ot">_</span> <span class="ot">:</span> x ≥ b ⦄ <span class="ot">→</span> Ordered [ x ] <span class="ot">→</span> Ordered b <span class="ot">→</span> Ordered b</span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true" tabindex="-1"></a>    ⟅<span class="ot">_</span>∪<span class="ot">_</span>∹<span class="ot">_</span>⟆ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>b<span class="ot">}</span> <span class="ot">→</span> Ordered b <span class="ot">→</span> <span class="ot">∀</span> y ⦃ <span class="ot">_</span> <span class="ot">:</span> y ≥ b ⦄ <span class="ot">→</span> Ordered [ y ] <span class="ot">→</span> Ordered b</span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true" tabindex="-1"></a>    merge <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>b<span class="ot">}</span> x y ⦃ <span class="ot">_</span> <span class="ot">:</span> x ≥ b ⦄ ⦃ <span class="ot">_</span> <span class="ot">:</span> y ≥ b ⦄</span>
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span> Total <span class="ot">_</span>≤<span class="ot">_</span> x y</span>
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span> Ordered [ x ]</span>
<span id="cb6-31"><a href="#cb6-31" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span> Ordered [ y ]</span>
<span id="cb6-32"><a href="#cb6-32" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span> Ordered b</span>
<span id="cb6-33"><a href="#cb6-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-34"><a href="#cb6-34" aria-hidden="true" tabindex="-1"></a>    ⟅ x ∹ xs ∪ [] ⟆ <span class="ot">=</span> x ∷ xs</span>
<span id="cb6-35"><a href="#cb6-35" aria-hidden="true" tabindex="-1"></a>    ⟅ x ∹ xs ∪ y ∷ ys ⟆ <span class="ot">=</span> merge x y <span class="ot">(</span>x ≤? y<span class="ot">)</span> xs ys</span>
<span id="cb6-36"><a href="#cb6-36" aria-hidden="true" tabindex="-1"></a>    ⟅ [] ∪ y ∹ ys ⟆ <span class="ot">=</span> y ∷ ys</span>
<span id="cb6-37"><a href="#cb6-37" aria-hidden="true" tabindex="-1"></a>    ⟅ x ∷ xs ∪ y ∹ ys ⟆ <span class="ot">=</span> merge x y <span class="ot">(</span>x ≤? y<span class="ot">)</span> xs ys</span>
<span id="cb6-38"><a href="#cb6-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-39"><a href="#cb6-39" aria-hidden="true" tabindex="-1"></a>    merge x y x≤y xs ys <span class="ot">=</span> x ∷ ⟅ xs ∪ y ∹ ys ⟆</span>
<span id="cb6-40"><a href="#cb6-40" aria-hidden="true" tabindex="-1"></a>    merge x y y≤x xs ys <span class="ot">=</span> y ∷ ⟅ x ∹ xs ∪ ys ⟆</span>
<span id="cb6-41"><a href="#cb6-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-42"><a href="#cb6-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-43"><a href="#cb6-43" aria-hidden="true" tabindex="-1"></a>  <span class="kw">open</span> TreeFold</span>
<span id="cb6-44"><a href="#cb6-44" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-45"><a href="#cb6-45" aria-hidden="true" tabindex="-1"></a>  sort <span class="ot">:</span> List A <span class="ot">→</span> Ordered ⊥</span>
<span id="cb6-46"><a href="#cb6-46" aria-hidden="true" tabindex="-1"></a>  sort <span class="ot">=</span> ⦅ <span class="ot">_</span>∪<span class="ot">_</span> , [] ⦆ ∘ map <span class="ot">(_</span>∷ []<span class="ot">)</span></span></code></pre></div>
<h1 id="validity">Validity</h1>
<p>It would be nice if we could verify these optimized versions of
folds. Luckily, by writing them using <code>foldr</code>, we’ve stumbled
into well-trodden ground: the <em>foldr fusion law</em>. It states that
if you have some transformation
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>f</mi><annotation encoding="application/x-tex">f</annotation></semantics></math>,
and two binary operators
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>⊕</mi><annotation encoding="application/x-tex">\oplus</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>⊗</mi><annotation encoding="application/x-tex">\otimes</annotation></semantics></math>,
then:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mtable><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mi>f</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>⊕</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"></mtd><mtd columnalign="right" style="text-align: right; padding-right: 0"><mo>=</mo><mspace width="0.278em"></mspace></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mi>x</mi><mo>⊗</mo><mi>f</mi><mi>y</mi></mtd></mtr><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mo>⟹</mo><mi>f</mi><mo>∘</mo><mtext mathvariant="normal">foldr</mtext><mo>⊕</mo><mi>e</mi></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"></mtd><mtd columnalign="right" style="text-align: right; padding-right: 0"><mo>=</mo><mspace width="0.278em"></mspace></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mtext mathvariant="normal">foldr</mtext><mo>⊗</mo><mo stretchy="false" form="prefix">(</mo><mi>f</mi><mi>e</mi><mo stretchy="false" form="postfix">)</mo></mtd></mtr></mtable><annotation encoding="application/x-tex">\begin{align}
   f (x \oplus y)                         &amp;&amp;=\;&amp; x \otimes f y \\
   \implies f \circ \text{foldr} \oplus e &amp;&amp;=\;&amp; \text{foldr} \otimes (f e)
\end{align}</annotation></semantics></math></p>
<p>This fits right in with the function we used above.
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>f</mi><annotation encoding="application/x-tex">f</annotation></semantics></math>
is <code>⟦_⟧↓</code>,
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>⊕</mi><annotation encoding="application/x-tex">\oplus</annotation></semantics></math>
is <code>_⊛_</code>, and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>⊗</mi><annotation encoding="application/x-tex">\otimes</annotation></semantics></math>
is whatever combining function was passed in. Let’s prove the foldr
fusion law, then, before we go any further.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> Proofs</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{</span>a r<span class="ot">}</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{</span>R <span class="ot">:</span> Rel A r<span class="ot">}</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">infix</span> <span class="dv">4</span> <span class="ot">_</span>≈<span class="ot">_</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>≈<span class="ot">_</span> <span class="ot">=</span> R</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">open</span> <span class="kw">import</span> Algebra<span class="ot">.</span>FunctionProperties <span class="ot">_</span>≈<span class="ot">_</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>  foldr-universal <span class="ot">:</span> Transitive <span class="ot">_</span>≈<span class="ot">_</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>                  <span class="ot">→</span> <span class="ot">∀</span> <span class="ot">{</span>b<span class="ot">}</span> <span class="ot">{</span>B <span class="ot">:</span> <span class="dt">Set</span> b<span class="ot">}</span> <span class="ot">(</span>h <span class="ot">:</span> List B <span class="ot">→</span> A<span class="ot">)</span> f e</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>                  <span class="ot">→</span> ∀[ f ⊢ Congruent₁ ]</span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>                  <span class="ot">→</span> <span class="ot">(</span>h [] ≈ e<span class="ot">)</span></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>                  <span class="ot">→</span> <span class="ot">(∀</span> x xs <span class="ot">→</span> h <span class="ot">(</span>x ∷ xs<span class="ot">)</span> ≈ f x <span class="ot">(</span>h xs<span class="ot">))</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a>                  <span class="ot">→</span> <span class="ot">∀</span> xs <span class="ot">→</span> h xs ≈ foldr f e xs</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>  foldr-universal <span class="ot">_</span>○<span class="ot">_</span> h f e f⟨<span class="ot">_</span>⟩ ⇒[] ⇒<span class="ot">_</span>∷<span class="ot">_</span> [] <span class="ot">=</span> ⇒[]</span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>  foldr-universal <span class="ot">_</span>○<span class="ot">_</span> h f e f⟨<span class="ot">_</span>⟩ ⇒[] ⇒<span class="ot">_</span>∷<span class="ot">_</span> <span class="ot">(</span>x ∷ xs<span class="ot">)</span> <span class="ot">=</span></span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>    <span class="ot">(</span>⇒ x ∷ xs<span class="ot">)</span> ○ f⟨ foldr-universal <span class="ot">_</span>○<span class="ot">_</span> h f e f⟨<span class="ot">_</span>⟩ ⇒[] ⇒<span class="ot">_</span>∷<span class="ot">_</span> xs ⟩</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>  foldr-fusion <span class="ot">:</span> Transitive <span class="ot">_</span>≈<span class="ot">_</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>               <span class="ot">→</span> Reflexive <span class="ot">_</span>≈<span class="ot">_</span></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>               <span class="ot">→</span> <span class="ot">∀</span> <span class="ot">{</span>b c<span class="ot">}</span> <span class="ot">{</span>B <span class="ot">:</span> <span class="dt">Set</span> b<span class="ot">}</span> <span class="ot">{</span>C <span class="ot">:</span> <span class="dt">Set</span> c<span class="ot">}</span> <span class="ot">(</span>f <span class="ot">:</span> C <span class="ot">→</span> A<span class="ot">)</span> <span class="ot">{_</span>⊕<span class="ot">_</span> <span class="ot">:</span> B <span class="ot">→</span> C <span class="ot">→</span> C<span class="ot">}</span> <span class="ot">{_</span>⊗<span class="ot">_</span> <span class="ot">:</span> B <span class="ot">→</span> A <span class="ot">→</span> A<span class="ot">}</span> e</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>               <span class="ot">→</span> ∀[ <span class="ot">_</span>⊗<span class="ot">_</span> ⊢ Congruent₁ ]</span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>               <span class="ot">→</span> <span class="ot">(∀</span> x y <span class="ot">→</span> f <span class="ot">(</span>x ⊕ y<span class="ot">)</span> ≈ x ⊗ f y<span class="ot">)</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>               <span class="ot">→</span> <span class="ot">∀</span> xs <span class="ot">→</span> f <span class="ot">(</span>foldr <span class="ot">_</span>⊕<span class="ot">_</span> e xs<span class="ot">)</span> ≈ foldr <span class="ot">_</span>⊗<span class="ot">_</span> <span class="ot">(</span>f e<span class="ot">)</span> xs</span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>  foldr-fusion <span class="ot">_</span>○<span class="ot">_</span> ∎ h <span class="ot">{</span>f<span class="ot">}</span> <span class="ot">{</span>g<span class="ot">}</span> e g⟨<span class="ot">_</span>⟩ fuse <span class="ot">=</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a>    foldr-universal <span class="ot">_</span>○<span class="ot">_</span> <span class="ot">(</span>h ∘ foldr f e<span class="ot">)</span> g <span class="ot">(</span>h e<span class="ot">)</span> g⟨<span class="ot">_</span>⟩ ∎ <span class="ot">(λ</span> x xs <span class="ot">→</span> fuse x <span class="ot">(</span>foldr f e xs<span class="ot">))</span></span></code></pre></div>
<p>We’re not using the proofs in Agda’s standard library because these
are tied to propositional equality. In other words, instead of using an
abstract binary relation, they prove things over <em>actual</em>
equality. That’s all well and good, but as you can see above, we don’t
need propositional equality: we don’t even need the relation to be an
equivalence, we just need transitivity and reflexivity.</p>
<p>After that, we can state precisely what correspondence the tree fold
has, and under what conditions it does the same things as a fold:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="ot">_</span> <span class="ot">{_</span>*<span class="ot">_</span> <span class="ot">:</span> A <span class="ot">→</span> A <span class="ot">→</span> A<span class="ot">}</span> <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">open</span> TreeFold <span class="ot">_</span>*<span class="ot">_</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  treeFoldHom <span class="ot">:</span> Transitive <span class="ot">_</span>≈<span class="ot">_</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> Reflexive <span class="ot">_</span>≈<span class="ot">_</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> Associative <span class="ot">_</span>*<span class="ot">_</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> RightCongruent <span class="ot">_</span>*<span class="ot">_</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> <span class="ot">∀</span> x xs</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> ⦅ x , xs ⦆ ≈ foldr <span class="ot">_</span>*<span class="ot">_</span> x xs</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>  treeFoldHom <span class="ot">_</span>○<span class="ot">_</span> ∎ assoc *⟨<span class="ot">_</span>⟩ b <span class="ot">=</span> foldr-fusion <span class="ot">_</span>○<span class="ot">_</span> ∎ ⟦<span class="ot">_</span>⟧↓ ⟦ b ⟧↑ *⟨<span class="ot">_</span>⟩ <span class="ot">(</span>⊛-hom zero<span class="ot">)</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>    ⊛-hom <span class="ot">:</span> <span class="ot">∀</span> n x xs <span class="ot">→</span> ⟦ 2^ n × x ⊛ xs ⟧↓ ≈ x * ⟦ xs ⟧↓</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>    ⊛-hom n x <span class="ot">(</span>2^ suc m × y + ⟨⟩    <span class="ot">)</span> <span class="ot">=</span> ∎</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>    ⊛-hom n x <span class="ot">(</span>2^ suc m × y + ⟨ ys ⟩<span class="ot">)</span> <span class="ot">=</span> ∎</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>    ⊛-hom n x <span class="ot">(</span>2^ zero  × y + ⟨⟩    <span class="ot">)</span> <span class="ot">=</span> ∎</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>    ⊛-hom n x <span class="ot">(</span>2^ zero  × y + ⟨ ys ⟩<span class="ot">)</span> <span class="ot">=</span> ⊛-hom <span class="ot">(</span>suc n<span class="ot">)</span> <span class="ot">(</span>x * y<span class="ot">)</span> ys ○ assoc x y ⟦ ys ⟧↓</span></code></pre></div>
<h1 id="implicit-data-structures">“Implicit” Data Structures</h1>
<p>Consider the following implementation of the tree above in
Haskell:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Tree</span> a <span class="ot">=</span> [(<span class="dt">Int</span>,a)]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>cons (<span class="op">*</span>) <span class="ot">=</span> cons&#39; <span class="dv">0</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    cons&#39; n x [] <span class="ot">=</span> [(n,x)]</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    cons&#39; n x ((<span class="dv">0</span>,y)<span class="op">:</span>ys) <span class="ot">=</span> cons&#39; (n<span class="op">+</span><span class="dv">1</span>) (x <span class="op">*</span> y) ys</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>    cons&#39; n x ((m,y)<span class="op">:</span>ys) <span class="ot">=</span> (n,x) <span class="op">:</span> (m<span class="op">-</span><span class="dv">1</span>,y) <span class="op">:</span> ys</span></code></pre></div>
<p>The <code>cons</code> function “increments” that list as if it were
the bits of a binary number. Now, consider using the <code>merge</code>
function from above, in a pattern like this:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>f <span class="ot">=</span> <span class="fu">foldr</span> (cons merge <span class="op">.</span> <span class="fu">pure</span>) []</span></code></pre></div>
<p>What does <code>f</code> build? A list of lists, right?</p>
<p>Kind of. That’s what’s built in terms of the observable, but what’s
actually stored in memory is a bunch of thunks. The shape of
<em>those</em> is what I’m interested in. We can try and see what they
look like by using a data structure that doesn’t force on merge:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> <span class="dt">Leaf</span> a <span class="op">|</span> <span class="dt">Tree</span> a <span class="op">:*:</span> <span class="dt">Tree</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>f <span class="ot">=</span> <span class="fu">foldr</span> (cons (<span class="op">:*:</span>) <span class="op">.</span> <span class="dt">Leaf</span>) []</span></code></pre></div>
<p>Using a handy tree-drawing function, we can see what
<code>f [1..13]</code> looks like:</p>
<pre><code>[(0,*),(1,*),(0,*)]
    └1    │ ┌2  │  ┌6
          │┌┤   │ ┌┤
          ││└3  │ │└7
          └┤    │┌┤
           │┌4  │││┌8
           └┤   ││└┤
            └5  ││ └9
                └┤
                 │ ┌10
                 │┌┤
                 ││└11
                 └┤
                  │┌12
                  └┤
                   └13</code></pre>
<p>It’s a binomial heap! It’s a list of trees, each one contains
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mn>2</mn><mi>n</mi></msup><annotation encoding="application/x-tex">2^n</annotation></semantics></math>
elements. But they’re not in heap order, you say? Well, as a matter of
fact, they <em>are</em>. It just hasn’t been evaluated yet. Once we
force—say—the first element, the rest will shuffle themselves into a
tree of thunks.</p>
<p>This illustrates a pretty interesting similarity between binomial
heaps and merge sort. Performance-wise, though, there’s another
interesting property: the thunks <em>stay thunked</em>. In other words,
if we do a merge sort via:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="fu">sort</span> <span class="ot">=</span> <span class="fu">foldr</span> (merge <span class="op">.</span> <span class="fu">snd</span>) [] <span class="op">.</span> <span class="fu">foldr</span> (cons merge <span class="op">.</span> <span class="fu">pure</span>) []</span></code></pre></div>
<p>We could instead freeze the fold, and look at it at every point:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>sortPrefixes <span class="ot">=</span> <span class="fu">map</span> (<span class="fu">foldr</span> (merge <span class="op">.</span> <span class="fu">snd</span>) []) <span class="op">.</span> <span class="fu">scanl</span> (<span class="fu">flip</span> (cons merge <span class="op">.</span> <span class="fu">pure</span>)) []</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> [[],[<span class="dv">1</span>],[<span class="dv">1</span>,<span class="dv">4</span>],[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">4</span>],[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>],[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>]]</span></code></pre></div>
<p>And <code>sortPrefixes</code> is only
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>
(rather than
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2 \log
n)</annotation></semantics></math>). I confess I don’t know of a use for
sorted prefixes, but it should illustrate the general idea: we get a
pretty decent batching of operations, with the ability to freeze at any
point in time. The other nice property (which I mentioned in the last
post) is that any of the tree folds are extremely parallel.</p>
<h1 id="random-shuffles">Random Shuffles</h1>
<p><a
href="http://okmij.org/ftp/Haskell/AlgorithmsH.html#perfect-shuffle">There’s
a great article on shuffling in Haskell</a> which provides an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>
implementation of a perfect random shuffle. Unfortunately, the <a
href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">Fisher-Yates
shuffle</a> isn’t applicable in a pure functional setting, so you have
to be a little cleverer.</p>
<p>The first implementation most people jump to (certainly the one I
thought of) is to assign everything in the sequence a random number, and
then sort according to that number. Perhaps surprisingly, this
<em>isn’t</em> perfectly random! It’s a little weird, but the example in
the article explains it well: basically, for
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
elements, your random numbers will have
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mi>n</mi><mi>n</mi></msup><annotation encoding="application/x-tex">n^n</annotation></semantics></math>
possible values, but the output of the sort will have
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>!</mi></mrow><annotation encoding="application/x-tex">n!</annotation></semantics></math>
possible values. Since they don’t divide into each other evenly, you’re
going to have some extra weight on some permutations, and less on
others.</p>
<p>Instead, we can generate a random <a
href="https://en.wikipedia.org/wiki/Factorial_number_system"><em>factoradic</em></a>
number. A factoradic number is one where the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>th
digit is in base
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>.
Because of this, a factoradic number with
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
digits has
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mi>!</mi></mrow><annotation encoding="application/x-tex">n!</annotation></semantics></math>
possible values: exactly what we want.</p>
<p>In the article, the digits of the number are used to pop values from
a binary tree. Because the last digit will have
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
possible values, and the second last
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">n-1</annotation></semantics></math>,
and so on, you can keep popping without hitting an empty tree.</p>
<p>This has the correct time
complexity—<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n \log n)</annotation></semantics></math>—but
there’s a lot of overhead. Building the tree, then indexing into it, the
rebuilding after each pop, etc.</p>
<p>We’d <em>like</em> to just sort the list, according to the indices.
The problem is that the indices are relative: if you want to
<code>cons</code> something onto the list, you have to increment the
rest of the indices, as they’ve all shifted right by one.</p>
<p>What we’ll do instead is use the indices as <em>gaps</em>. Our merge
function looks like the following:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>merge [] ys <span class="ot">=</span> ys</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>merge xs [] <span class="ot">=</span> xs</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>merge ((x,i)<span class="op">:</span>xs) ((y,j)<span class="op">:</span>ys)</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> i <span class="op">&lt;=</span> j    <span class="ot">=</span> (x,i) <span class="op">:</span> merge xs ((y,j<span class="op">-</span>i)<span class="op">:</span>ys)</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (y,j) <span class="op">:</span> merge ((x,i<span class="op">-</span>j<span class="op">-</span><span class="dv">1</span>)<span class="op">:</span>xs) ys</span></code></pre></div>
<p>With that, and the same <code>cons</code> as above, we get a very
simple random shuffle algorithm:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>shuffle xs <span class="ot">=</span> <span class="fu">map</span> <span class="fu">fst</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>           <span class="op">.</span> <span class="fu">foldr</span> (merge <span class="op">.</span> <span class="fu">snd</span>) []</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>           <span class="op">.</span> <span class="fu">foldr</span> f (<span class="fu">const</span> []) xs</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>    f x xs (i<span class="op">:</span>is) <span class="ot">=</span> cons merge [(x,i)] (xs is)</span></code></pre></div>
<p>The other interesting thing about this algorithm is that it can use
Peano numbers without taking too much of a performance hit:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>merge <span class="op">:</span> ∀ {a} {<span class="dt">A</span> <span class="op">:</span> <span class="dt">Set</span> a} → <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">List</span> (<span class="dt">A</span> × ℕ)</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>merge xs [] <span class="ot">=</span> xs</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>merge {<span class="dt">A</span> <span class="ot">=</span> <span class="dt">A</span>} xs ((y , j) ∷ ys) <span class="ot">=</span> go<span class="op">-</span>r xs y j ys</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  go<span class="op">-</span>l <span class="op">:</span> <span class="dt">A</span> → ℕ → <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">List</span> (<span class="dt">A</span> × ℕ)</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>  go<span class="op">-</span>r <span class="op">:</span> <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">A</span> → ℕ → <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">List</span> (<span class="dt">A</span> × ℕ)</span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>  go <span class="op">:</span> ℕ → ℕ → <span class="dt">A</span> → ℕ → <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">A</span> → ℕ → <span class="dt">List</span> (<span class="dt">A</span> × ℕ) → <span class="dt">List</span> (<span class="dt">A</span> × ℕ)</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>  go i     zero   x i′ xs y j′ ys <span class="ot">=</span> (y , j′) ∷ go<span class="op">-</span>l x i xs ys</span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a>  go zero (suc j) x i′ xs y j′ ys <span class="ot">=</span> (x , i′) ∷ go<span class="op">-</span>r xs y j ys</span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a>  go (suc i) (suc j) <span class="ot">=</span> go i j</span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a>  go<span class="op">-</span>l x i xs [] <span class="ot">=</span> (x , i) ∷ xs</span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a>  go<span class="op">-</span>l x i xs ((y , j) ∷ ys) <span class="ot">=</span> go i j x i xs y j ys</span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a>  go<span class="op">-</span>r [] y j ys <span class="ot">=</span> (y , j) ∷ ys</span>
<span id="cb17-17"><a href="#cb17-17" aria-hidden="true" tabindex="-1"></a>  go<span class="op">-</span>r ((x , i) ∷ xs) y j ys <span class="ot">=</span> go i j x i xs y j ys</span>
<span id="cb17-18"><a href="#cb17-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-19"><a href="#cb17-19" aria-hidden="true" tabindex="-1"></a>shuffle <span class="op">:</span> ∀ {a} {<span class="dt">A</span> <span class="op">:</span> <span class="dt">Set</span> a} → <span class="dt">List</span> <span class="dt">A</span> → <span class="dt">List</span> ℕ → <span class="dt">List</span> <span class="dt">A</span></span>
<span id="cb17-20"><a href="#cb17-20" aria-hidden="true" tabindex="-1"></a>shuffle {a} {<span class="dt">A</span>} xs i <span class="ot">=</span> <span class="fu">map</span> proj₁ (⦅ [] , <span class="fu">zip</span><span class="op">-</span>inds xs i ⦆)</span>
<span id="cb17-21"><a href="#cb17-21" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb17-22"><a href="#cb17-22" aria-hidden="true" tabindex="-1"></a>  open <span class="dt">TreeFold</span> {a} {<span class="dt">List</span> (<span class="dt">A</span> × ℕ)} merge</span>
<span id="cb17-23"><a href="#cb17-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-24"><a href="#cb17-24" aria-hidden="true" tabindex="-1"></a>  <span class="fu">zip</span><span class="op">-</span>inds <span class="op">:</span> <span class="dt">List</span> <span class="dt">A</span> → <span class="dt">List</span> ℕ → <span class="dt">List</span> (<span class="dt">List</span> (<span class="dt">A</span> × ℕ))</span>
<span id="cb17-25"><a href="#cb17-25" aria-hidden="true" tabindex="-1"></a>  <span class="fu">zip</span><span class="op">-</span>inds [] inds <span class="ot">=</span> []</span>
<span id="cb17-26"><a href="#cb17-26" aria-hidden="true" tabindex="-1"></a>  <span class="fu">zip</span><span class="op">-</span>inds (x ∷ xs) [] <span class="ot">=</span> ((x , <span class="dv">0</span>) ∷ []) ∷ <span class="fu">zip</span><span class="op">-</span>inds xs []</span>
<span id="cb17-27"><a href="#cb17-27" aria-hidden="true" tabindex="-1"></a>  <span class="fu">zip</span><span class="op">-</span>inds (x ∷ xs) (i ∷ inds) <span class="ot">=</span> ((x , i) ∷ []) ∷ <span class="fu">zip</span><span class="op">-</span>inds xs inds</span></code></pre></div>
<p>I don’t know exactly what the complexity of this is, but I
<em>think</em> it should be better than the usual approach of popping
from a vector.</p>
<h1 id="future-stuff">Future Stuff</h1>
<p>This is just a collection of random thoughts for now, but I intend to
work on using these folds to see if there are any other algorithms they
can be useful for. In particular, I think I can write a version of
Data.List.permutations which benefits from sharing. And I’m interested
in using the implicit binomial heap for some search problems.</p>
]]></description>
    <pubDate>Fri, 21 Dec 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-12-21-balancing-scans.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Pure and Lazy Breadth-First Traversals of Graphs in Haskell</title>
    <link>https://doisinkidney.com/posts/2018-12-18-traversing-graphs.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 18, 2018
</div>
<div class="info">
    
        Part 5 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Today, I’m going to look at extending the previous breadth-first
traversal algorithms to arbitrary graphs (rather than just trees).
Graphs with cycles are notoriously cumbersome in functional languages,
so this actually proves to be a little trickier than I thought it would
be. First, a quick recap.</p>
<h1 id="ways-to-breadth-first-search">3 Ways to Breadth-First
Search</h1>
<p>So far, we have three major ways to traverse a tree in breadth-first
order. The first is the simplest, and the fastest:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfe ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>bfe r <span class="ot">=</span> f r b []</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (xs <span class="op">:</span> bw)</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b qs []</span></code></pre></div>
<p>Given a tree like the following:</p>
<pre><code>   ┌4
 ┌2┤
 │ │ ┌8
 │ └5┤
 │   └9
1┤
 │   ┌10
 │ ┌6┘
 └3┤
   └7</code></pre>
<p>We get:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> bfe tree</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">10</span>]</span></code></pre></div>
<p>It also demonstrates a theme that will run through this post: lists
are the only <em>visible</em> data structure (other than the tree, of
course). However, we are carefully batching the operations on those
lists (the <code>foldl</code> is effectively a reverse) so that they
have the same complexity as if we had used a queue. In actual fact, when
lists are used this way, they <em>are</em> queues: “corecursive” ones
<span class="citation"
data-cites="allison_circular_2006 smith_lloyd_2009">(<a
href="#ref-allison_circular_2006" role="doc-biblioref">Allison 2006</a>;
<a href="#ref-smith_lloyd_2009" role="doc-biblioref">Smith
2009</a>)</span>.</p>
<p>The next two functions perform a breadth-first traversal
“level-wise”: instead of just returning all the nodes of the tree, we
get them delimited by how far they are from the root.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lwe ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>lwe r <span class="ot">=</span> f b r [] []</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    f k (<span class="dt">Node</span> x xs) ls qs <span class="ot">=</span> k (x <span class="op">:</span> ls) (xs <span class="op">:</span> qs)</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    b _ [] <span class="ot">=</span> []</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    b k qs <span class="ot">=</span> k <span class="op">:</span> <span class="fu">foldl</span> (<span class="fu">foldl</span> f) b qs [] []</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> lwe tree</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">3</span>],[<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>,<span class="dv">7</span>],[<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">10</span>]]</span></code></pre></div>
<p>The above function is very clearly related to the <code>bfe</code>
function: we just add another queue (representing the current level),
and work from there.</p>
<p>The third of these functions also does level-wise enumeration, but in
a direct style (without continuations).</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lwe ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>lwe r <span class="ot">=</span> f r []</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) (q<span class="op">:</span>qs) <span class="ot">=</span> (x<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) []     <span class="ot">=</span> [x]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>There are more techniques out there than just these three (including
the one in <a
href="http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Tree.html#v:levels">Data.Tree</a>),
but these are my favorite, and they’re what I’ll be looking at
today.</p>
<h1 id="graphs-and-purity">Graphs and Purity</h1>
<p>Functional programming in general excels at working with trees and
similar data structures. Graphs, though, are trickier. There’s been a
lot of recent work in improving the situation <span class="citation"
data-cites="mokhov_algebraic_2017">(<a href="#ref-mokhov_algebraic_2017"
role="doc-biblioref">Mokhov 2017</a>)</span>, but I’m going to keep it
simple today: a graph is just a function.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Graph</span> a <span class="ot">=</span> a <span class="ot">-&gt;</span> [a]</span></code></pre></div>
<p>So the tree from above could be represented as:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">1</span> <span class="ot">=</span> [<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">2</span> <span class="ot">=</span> [<span class="dv">4</span>,<span class="dv">5</span>]</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">3</span> <span class="ot">=</span> [<span class="dv">6</span>,<span class="dv">7</span>]</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">5</span> <span class="ot">=</span> [<span class="dv">8</span>,<span class="dv">9</span>]</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">6</span> <span class="ot">=</span> [<span class="dv">10</span>]</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>graph _ <span class="ot">=</span> []</span></code></pre></div>
<p>As it happens, all of the algorithms that follow will work on graphs
represented as rose trees (or represented any way, really).</p>
<p>So let’s fire up our first traversal!</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfs ::</span> <span class="dt">Graph</span> a <span class="ot">-&gt;</span> <span class="dt">Graph</span> a</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>bfs g r <span class="ot">=</span> f r b []</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    f x fw bw <span class="ot">=</span> x <span class="op">:</span> fw (g x <span class="op">:</span> bw)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b qs []</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> bfs graph <span class="dv">1</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">10</span>]</span></code></pre></div>
<p>Unfortunately, this won’t handle cycles properly:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">1</span> <span class="ot">=</span> [<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">2</span> <span class="ot">=</span> [<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">1</span>]</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">3</span> <span class="ot">=</span> [<span class="dv">6</span>,<span class="dv">7</span>]</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">5</span> <span class="ot">=</span> [<span class="dv">8</span>,<span class="dv">9</span>]</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>graph <span class="dv">6</span> <span class="ot">=</span> [<span class="dv">10</span>]</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>graph _ <span class="ot">=</span> []</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> bfs graph <span class="dv">1</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">1</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">10</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">1</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">10</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">1</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">10</span>,<span class="dv">4</span>,<span class="dv">5</span><span class="op">...</span></span></code></pre></div>
<p>We need a way to mark off what we’ve already seen. The following
isn’t good enough, also:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> nub (bfs graph <span class="dv">1</span>)</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">10</span><span class="op">...</span></span></code></pre></div>
<p>It will hang without finishing the list. The solution is to mark off
nodes as we find them, with some set structure:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bfs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Graph</span> a <span class="ot">-&gt;</span> <span class="dt">Graph</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>bfs g ts <span class="ot">=</span> f ts b [] Set.empty</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    f x fw bw s</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> Set.member x s <span class="ot">=</span> fw bw s</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span>      <span class="ot">=</span> x <span class="op">:</span> fw (g x <span class="op">:</span> bw) (Set.insert x s)</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>    b [] _ <span class="ot">=</span> []</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>    b qs s <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b qs [] s</span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> bfs graph <span class="dv">1</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>,<span class="dv">9</span>,<span class="dv">10</span>]</span></code></pre></div>
<p>The levelwise algorithm is similar:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lws ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Graph</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>lws g r <span class="ot">=</span> f b r [] [] Set.empty</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    f k x ls qs s</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> Set.member x s <span class="ot">=</span> k ls qs s</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> k (x <span class="op">:</span> ls) (g x <span class="op">:</span> qs) (Set.insert x s)</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>    b _ [] _ <span class="ot">=</span> []</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>    b k qs s <span class="ot">=</span> k <span class="op">:</span> <span class="fu">foldl</span> (<span class="fu">foldl</span> f) b qs [] [] s</span></code></pre></div>
<h1 id="tying-the-knot">Tying the Knot</h1>
<p>The other levelwise algorithm <em>doesn’t</em> translate across so
easily. To see why, let’s look at the version without cycle
detection:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lws ::</span> <span class="dt">Graph</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>lws g r <span class="ot">=</span> f r []</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    f x (q<span class="op">:</span>qs) <span class="ot">=</span> (x<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs (g x)</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    f x []     <span class="ot">=</span> [x]   <span class="op">:</span> <span class="fu">foldr</span> f [] (g x)</span></code></pre></div>
<p>The recursive call is being made <em>depth</em>-first, not
breadth-first. The result, of course, is breadth-first, but that’s only
because the recursive call zips as it goes.</p>
<p>Just looking at the fourth line for now:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>f x (q<span class="op">:</span>qs) <span class="ot">=</span> (x<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs (g x)</span></code></pre></div>
<p>We want whatever process built up that <code>q</code> to be denied
access to <code>x</code>. The following doesn’t work:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>f x (q<span class="op">:</span>qs) <span class="ot">=</span> (x<span class="op">:</span><span class="fu">filter</span> (x<span class="op">/=</span>) q) <span class="op">:</span> <span class="fu">foldr</span> f qs (g x)</span></code></pre></div>
<p>As well as being terribly slow, the later computation can diverge
when it finds a cycle, and filtering won’t do anything to help that.</p>
<p>The solution is to “tie the knot”. We basically do two passes over
the data: one to build up the “seen so far” list, and then another to do
the actual search. The trick is to do both of these passes at once, and
feed the result back into the demanding computation.</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>lws g r <span class="ot">=</span> <span class="fu">takeWhile</span> (<span class="fu">not</span><span class="op">.</span><span class="fu">null</span>) (<span class="fu">map</span> <span class="fu">fst</span> (fix (f r <span class="op">.</span> push)))</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    push xs <span class="ot">=</span> ([],Set.empty) <span class="op">:</span> [ ([],seen) <span class="op">|</span> (_,seen) <span class="ot">&lt;-</span> xs ]</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    f x q<span class="op">@</span>((l,s)<span class="op">:</span>qs)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> Set.member x s <span class="ot">=</span> q</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (x<span class="op">:</span>l, Set.insert x s) <span class="op">:</span> <span class="fu">foldr</span> f qs (g x)</span></code></pre></div>
<p>And it works!</p>
<p>I got the idea for this trick from the appendix of <span
class="citation" data-cites="okasaki_breadth-first_2000">Okasaki (<a
href="#ref-okasaki_breadth-first_2000"
role="doc-biblioref">2000</a>)</span>. There’s something similar in
<span class="citation"
data-cites="kiselyov_pure-functional_2002">Kiselyov (<a
href="#ref-kiselyov_pure-functional_2002"
role="doc-biblioref">2002</a>)</span>.</p>
<hr />
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-allison_circular_2006" class="csl-entry" role="listitem">
Allison, Lloyd. 2006. <span>“Circular <span>Programs</span> and
<span>Self</span>-<span>Referential Structures</span>.”</span>
<em>Software: Practice and Experience</em> 19 (2) (October): 99–109.
doi:<a
href="https://doi.org/10.1002/spe.4380190202">10.1002/spe.4380190202</a>.
</div>
<div id="ref-kiselyov_pure-functional_2002" class="csl-entry"
role="listitem">
Kiselyov, Oleg. 2002. <span>“Pure-functional transformations of cyclic
graphs and the <span>Credit Card Transform</span>.”</span> <a
href="http://okmij.org/ftp/Haskell/AlgorithmsH.html#ccard-transform"
class="uri">http://okmij.org/ftp/Haskell/AlgorithmsH.html#ccard-transform</a>.
</div>
<div id="ref-mokhov_algebraic_2017" class="csl-entry" role="listitem">
Mokhov, Andrey. 2017. <span>“Algebraic <span>Graphs</span> with
<span>Class</span> (<span>Functional Pearl</span>).”</span> In
<em>Proceedings of the 10th <span>ACM SIGPLAN International
Symposium</span> on <span>Haskell</span></em>, 2–13. Haskell 2017. New
York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/3122955.3122956">10.1145/3122955.3122956</a>.
</div>
<div id="ref-okasaki_breadth-first_2000" class="csl-entry"
role="listitem">
Okasaki, Chris. 2000. <span>“Breadth-first <span>Numbering</span>:
<span>Lessons</span> from a <span>Small Exercise</span> in
<span>Algorithm Design</span>.”</span> In <em>Proceedings of the
<span>Fifth ACM SIGPLAN International Conference</span> on
<span>Functional Programming</span></em>, 131–136. <span>ICFP</span>
’00. New York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/351240.351253">10.1145/351240.351253</a>.
</div>
<div id="ref-smith_lloyd_2009" class="csl-entry" role="listitem">
Smith, Leon P. 2009. <span>“Lloyd <span>Allison</span>’s
<span>Corecursive Queues</span>: <span>Why Continuations
Matter</span>.”</span> <em>The Monad.Reader</em> 14 (14) (July): 28.
</div>
</div>
]]></description>
    <pubDate>Tue, 18 Dec 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-12-18-traversing-graphs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Prime Sieves in Agda</title>
    <link>https://doisinkidney.com/posts/2018-12-14-primes-in-agda.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 14, 2018
</div>
<div class="info">
    
        Part 2 of a <a href="/series/Prime%20Sieves.html">2-part series on Prime Sieves</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>Prime numbers in Agda are <em>slow</em>. First, they’re Peano-based,
so a huge chunk of optimizations we might make in other languages are
out of the window. Second, we really often want to <em>prove</em> that
they’re prime, so the generation code has to carry verification logic
with it (I won’t do that today, though). And third, as always in Agda,
you have to convince the compiler of termination. With all of that in
mind, let’s try and write a (very slow, very basic) prime sieve in
Agda.</p>
<p>First, we can make an “array” of numbers that we cross off as we
go.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">:</span> <span class="ot">∀</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin n<span class="ot">)</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>primes zero <span class="ot">=</span> []</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc zero<span class="ot">)</span> <span class="ot">=</span> []</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc <span class="ot">(</span>suc zero<span class="ot">))</span> <span class="ot">=</span> []</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc <span class="ot">(</span>suc <span class="ot">(</span>suc m<span class="ot">)))</span> <span class="ot">=</span> sieve <span class="ot">(</span>tabulate <span class="ot">(</span>just ∘ Fin<span class="ot">.</span>suc<span class="ot">))</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  cross-off <span class="ot">:</span> Fin <span class="ot">_</span> <span class="ot">→</span> List <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">_))</span> <span class="ot">→</span> List <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">_))</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">:</span> List <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">_))</span> <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">_)</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>  sieve [] <span class="ot">=</span> []</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">(</span>nothing ∷ xs<span class="ot">)</span> <span class="ot">=</span>         sieve xs</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">(</span>just x  ∷ xs<span class="ot">)</span> <span class="ot">=</span> suc x ∷ sieve <span class="ot">(</span>cross-off x xs<span class="ot">)</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>  cross-off p fs <span class="ot">=</span> foldr f <span class="ot">(</span>const []<span class="ot">)</span> fs p</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>    B <span class="ot">=</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">→</span> Fin i <span class="ot">→</span> List <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>    f <span class="ot">:</span> Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">))</span> <span class="ot">→</span> B <span class="ot">→</span> B</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>    f <span class="ot">_</span> xs zero    <span class="ot">=</span> nothing ∷ xs p</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>    f x xs <span class="ot">(</span>suc y<span class="ot">)</span> <span class="ot">=</span> x       ∷ xs y</span></code></pre></div>
<p>Very simple so far: we run through the list, filtering out the
multiples of each prime as we see it. Unfortunately, this won’t pass the
termination checker. This recursive call to <code>sieve</code> is the
problem:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>sieve <span class="ot">(</span>just x ∷ xs<span class="ot">)</span> <span class="ot">=</span> suc x ∷ sieve <span class="ot">(</span>cross-off x xs<span class="ot">)</span></span></code></pre></div>
<p>Agda finds if a function is terminating by checking that at least one
argument gets (structurally) smaller on every recursive call.
<code>sieve</code> only takes one argument (the input list), so that’s
the one that needs to get smaller. In the line above, if we replaced it
with the following:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>sieve <span class="ot">(</span>just x ∷ xs<span class="ot">)</span> <span class="ot">=</span> suc x ∷ sieve xs</span></code></pre></div>
<p>We’d be good to go: <code>xs</code> is definitely smaller than
<code>(just x ∷ xs)</code>. <code>cross-off x xs</code>, though? The
thing is, <code>cross-off</code> returns a list of the same length that
it’s given. But the function call is opaque: Agda can’t automatically
see the fact that the length stays the same. Reaching for a proof here
is the wrong move, though: you can get all of the same benefit by
switching out the list for a length-indexed vector.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">:</span> <span class="ot">∀</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin n<span class="ot">)</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>primes zero <span class="ot">=</span> []</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc zero<span class="ot">)</span> <span class="ot">=</span> []</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc <span class="ot">(</span>suc zero<span class="ot">))</span> <span class="ot">=</span> []</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc <span class="ot">(</span>suc <span class="ot">(</span>suc m<span class="ot">)))</span> <span class="ot">=</span> sieve <span class="ot">(</span>tabulate <span class="ot">(</span>just ∘ Fin<span class="ot">.</span>suc<span class="ot">))</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>  cross-off <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Fin <span class="ot">_</span> <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">_)</span> n <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">_)</span> n</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span>  Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>  sieve [] <span class="ot">=</span> []</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">(</span>nothing ∷ xs<span class="ot">)</span> <span class="ot">=</span>         sieve xs</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">(</span>just x  ∷ xs<span class="ot">)</span> <span class="ot">=</span> suc x ∷ sieve <span class="ot">(</span>cross-off x xs<span class="ot">)</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>  cross-off p fs <span class="ot">=</span> foldr B f <span class="ot">(</span>const []<span class="ot">)</span> fs p</span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>    B <span class="ot">=</span> <span class="ot">λ</span> n <span class="ot">→</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">→</span> Fin i <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> n</span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>    f <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">))</span> <span class="ot">→</span> B n <span class="ot">→</span> B <span class="ot">(</span>suc n<span class="ot">)</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>    f <span class="ot">_</span> xs zero    <span class="ot">=</span> nothing ∷ xs p</span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>    f x xs <span class="ot">(</span>suc y<span class="ot">)</span> <span class="ot">=</span> x       ∷ xs y</span></code></pre></div>
<p>Actually, my explanation above is a little bit of a lie. Often, the
way I think about dependently-typed programs has a lot to do with my
intuition for “proofs” and so on. But this leads you down the wrong path
(and it’s why writing a proof that <code>cross-off</code> returns a list
of the same length is the wrong move).</p>
<p>The actual termination checking algorithm is very simple, albeit
strict: the argument passed recursively must be <em>structurally</em>
smaller. That’s it. Basically, the recursive argument has to be
contained in one of the arguments passed. It has nothing to do with Agda
“seeing” inside the function <code>cross-off</code> or anything like
that. What we’ve done above (to make it terminate) is add another
argument to the function: the length of the vector. The argument is
implicit, but if we were to make it explicit in the recursive call:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>sieve <span class="ot">{</span>suc n<span class="ot">}</span> <span class="ot">(</span>just x  ∷ xs<span class="ot">)</span> <span class="ot">=</span> suc x ∷ sieve <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">(</span>cross-off x xs<span class="ot">)</span></span></code></pre></div>
<p>We can see that it does indeed get structurally smaller.</p>
<h1 id="adding-the-squaring-optimization">Adding the Squaring
Optimization</h1>
<p>A simple improvement we should be able to make is stopping once we
hit the square root of the limit. Since we don’t want to be squaring as
we go, we’ll use the following identity:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo>+</mo><mn>1</mn><msup><mo stretchy="false" form="postfix">)</mo><mn>2</mn></msup><mo>=</mo><msup><mi>n</mi><mn>2</mn></msup><mo>+</mo><mn>2</mn><mi>n</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">(n + 1)^2 = n^2 + 2n + 1</annotation></semantics></math></p>
<p>to figure out the square of the next number from the previous. In
fact, we’ll just pass in the limit, and reduce it by
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>2</mn><mi>n</mi><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">2n + 1</annotation></semantics></math>
each time, until it reaches zero:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">:</span> <span class="ot">∀</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin n<span class="ot">)</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>primes zero <span class="ot">=</span> []</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc zero<span class="ot">)</span> <span class="ot">=</span> []</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc <span class="ot">(</span>suc zero<span class="ot">))</span> <span class="ot">=</span> []</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">(</span>suc <span class="ot">(</span>suc <span class="ot">(</span>suc m<span class="ot">)))</span> <span class="ot">=</span> sieve <span class="dv">1</span> m <span class="ot">(</span>Vec<span class="ot">.</span>tabulate <span class="ot">(</span>just ∘ Fin<span class="ot">.</span>suc ∘ Fin<span class="ot">.</span>suc<span class="ot">))</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  cross-off <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> ℕ <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">_)</span> n <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">_)</span> n</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">)))</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">_</span> zero <span class="ot">=</span> List<span class="ot">.</span>mapMaybe id ∘ Vec<span class="ot">.</span>toList</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">_</span> <span class="ot">(</span>suc <span class="ot">_)</span> [] <span class="ot">=</span> []</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>  sieve i <span class="ot">(</span>suc l<span class="ot">)</span> <span class="ot">(</span>nothing ∷ xs<span class="ot">)</span> <span class="ot">=</span>     sieve <span class="ot">(</span>suc i<span class="ot">)</span> <span class="ot">(</span>l ∸ i ∸ i<span class="ot">)</span> xs</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>  sieve i <span class="ot">(</span>suc l<span class="ot">)</span> <span class="ot">(</span>just x  ∷ xs<span class="ot">)</span> <span class="ot">=</span> x ∷ sieve <span class="ot">(</span>suc i<span class="ot">)</span> <span class="ot">(</span>l ∸ i ∸ i<span class="ot">)</span> <span class="ot">(</span>cross-off i xs<span class="ot">)</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>  cross-off p fs <span class="ot">=</span> Vec<span class="ot">.</span>foldr B f <span class="ot">(</span>const []<span class="ot">)</span> fs p</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>      B <span class="ot">=</span> <span class="ot">λ</span> n <span class="ot">→</span> ℕ <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">)))</span> n</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>      f <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">→</span> Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span> <span class="ot">→</span> B i <span class="ot">→</span> B <span class="ot">(</span>suc i<span class="ot">)</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>      f <span class="ot">_</span> xs zero    <span class="ot">=</span> nothing ∷ xs p</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a>      f x xs <span class="ot">(</span>suc y<span class="ot">)</span> <span class="ot">=</span> x       ∷ xs y</span></code></pre></div>
<h1 id="finding-prime-factors">Finding Prime Factors</h1>
<p>A slight variation on the code above (the first version) will give us
the prime factors of a number:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">:</span> <span class="ot">∀</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin n<span class="ot">)</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>primeFactors zero <span class="ot">=</span> []</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">(</span>suc zero<span class="ot">)</span> <span class="ot">=</span> []</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">(</span>suc <span class="ot">(</span>suc zero<span class="ot">))</span> <span class="ot">=</span> []</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">(</span>suc <span class="ot">(</span>suc <span class="ot">(</span>suc m<span class="ot">)))</span> <span class="ot">=</span> sieve <span class="ot">(</span>Vec<span class="ot">.</span>tabulate <span class="ot">(</span>just ∘ Fin<span class="ot">.</span>suc<span class="ot">))</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  sieve [] <span class="ot">=</span> []</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">(</span>nothing ∷ xs<span class="ot">)</span> <span class="ot">=</span> sieve xs</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">(</span>just x  ∷ xs<span class="ot">)</span> <span class="ot">=</span> Vec<span class="ot">.</span>foldr B remove b xs sieve x</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>    B <span class="ot">=</span> <span class="ot">λ</span> n <span class="ot">→</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>            <span class="ot">→</span> <span class="ot">(</span>Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> n</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>            <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">)))</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>            <span class="ot">→</span> Fin i</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a>            <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>    b <span class="ot">:</span> B <span class="dv">0</span></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>    b k zero    <span class="ot">=</span> suc x ∷ k []</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>    b k <span class="ot">(</span>suc <span class="ot">_)</span> <span class="ot">=</span>         k []</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>    remove <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">))</span> <span class="ot">→</span> B n <span class="ot">→</span> B <span class="ot">(</span>suc n<span class="ot">)</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a>    remove y ys k zero    <span class="ot">=</span> ys <span class="ot">(</span>k ∘ <span class="ot">(</span>nothing ∷<span class="ot">_))</span> x</span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a>    remove y ys k <span class="ot">(</span>suc j<span class="ot">)</span> <span class="ot">=</span> ys <span class="ot">(</span>k ∘ <span class="ot">(</span>y ∷<span class="ot">_))</span> j</span></code></pre></div>
<p>Adding the squaring optimization complicates things
significantly:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">:</span> <span class="ot">∀</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin n<span class="ot">)</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>primeFactors zero <span class="ot">=</span> []</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">(</span>suc zero<span class="ot">)</span> <span class="ot">=</span> []</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">(</span>suc <span class="ot">(</span>suc zero<span class="ot">))</span> <span class="ot">=</span> []</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>primeFactors <span class="ot">(</span>suc <span class="ot">(</span>suc <span class="ot">(</span>suc m<span class="ot">)))</span> <span class="ot">=</span> sqr <span class="ot">(</span>suc m<span class="ot">)</span> m suc sieve</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>2F-<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> ℕ <span class="ot">→</span> Fin n <span class="ot">→</span> ℕ</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>  x           2F- zero <span class="ot">=</span> x</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  zero        2F- suc y <span class="ot">=</span> zero</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>  suc zero    2F- suc y <span class="ot">=</span> zero</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>  suc <span class="ot">(</span>suc x<span class="ot">)</span> 2F- suc y <span class="ot">=</span> x 2F- y</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>  sqr <span class="ot">:</span> <span class="ot">∀</span> n</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> ℕ</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> <span class="ot">(</span>Fin n <span class="ot">→</span> Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">))</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> <span class="ot">(∀</span> <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> i <span class="ot">→</span> ℕ <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">)))</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>  sqr n       zero    f k <span class="ot">=</span> k [] n</span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>  sqr zero    <span class="ot">(</span>suc l<span class="ot">)</span> f k <span class="ot">=</span> k [] zero</span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>  sqr <span class="ot">(</span>suc n<span class="ot">)</span> <span class="ot">(</span>suc l<span class="ot">)</span> f k <span class="ot">=</span></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> x <span class="ot">=</span> f zero</span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>    <span class="kw">in</span> sqr n <span class="ot">(</span>l 2F- x<span class="ot">)</span> <span class="ot">(</span>f ∘ suc<span class="ot">)</span> <span class="ot">(</span>k ∘ <span class="ot">(</span>just x ∷<span class="ot">_))</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> n <span class="ot">→</span> ℕ <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>  sieve xs′ i <span class="ot">=</span> go xs′</span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a>    go <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> []</span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a>    go <span class="ot">(</span>nothing ∷ xs<span class="ot">)</span> <span class="ot">=</span> go xs</span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a>    go <span class="ot">(</span>just x  ∷ xs<span class="ot">)</span> <span class="ot">=</span> Vec<span class="ot">.</span>foldr B remove <span class="ot">(</span>b i<span class="ot">)</span> xs x go</span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a>      B <span class="ot">=</span> <span class="ot">λ</span> n <span class="ot">→</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span></span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> Fin i</span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> <span class="ot">(</span>Vec <span class="ot">(</span>Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">)))</span> n <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">)))</span></span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a>              <span class="ot">→</span> List <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">3</span> + m<span class="ot">))</span></span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a>      b <span class="ot">:</span> ℕ <span class="ot">→</span> B <span class="dv">0</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a>      b zero    zero    k <span class="ot">=</span> suc x ∷ k []</span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a>      b zero    <span class="ot">(</span>suc y<span class="ot">)</span> k <span class="ot">=</span> k []</span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true" tabindex="-1"></a>      b <span class="ot">(</span>suc n<span class="ot">)</span> zero    k <span class="ot">=</span> b n x k</span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true" tabindex="-1"></a>      b <span class="ot">(</span>suc n<span class="ot">)</span> <span class="ot">(</span>suc y<span class="ot">)</span> k <span class="ot">=</span> b n y k</span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-43"><a href="#cb8-43" aria-hidden="true" tabindex="-1"></a>      remove <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Maybe <span class="ot">(</span>Fin <span class="ot">(</span><span class="dv">2</span> + m<span class="ot">))</span> <span class="ot">→</span> B n <span class="ot">→</span> B <span class="ot">(</span>suc n<span class="ot">)</span></span>
<span id="cb8-44"><a href="#cb8-44" aria-hidden="true" tabindex="-1"></a>      remove y ys zero    k <span class="ot">=</span> ys x <span class="ot">(</span>k ∘ <span class="ot">(</span>nothing ∷<span class="ot">_))</span></span>
<span id="cb8-45"><a href="#cb8-45" aria-hidden="true" tabindex="-1"></a>      remove y ys <span class="ot">(</span>suc j<span class="ot">)</span> k <span class="ot">=</span> ys j <span class="ot">(</span>k ∘ <span class="ot">(</span>y ∷<span class="ot">_))</span></span></code></pre></div>
<h1 id="infinitude">Infinitude</h1>
<p>The above sieves aren’t “true” in that each <code>remove</code> is
linear, so the performance is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><msup><mi>n</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n^2)</annotation></semantics></math>
overall. This is the same problem we ran into with the naive infinite
sieve in Haskell.</p>
<p>Since it bears such a similarity to the infinite sieve, we have to
ask: can <em>this</em> sieve be infinite? Agda supports a notion of
infinite data, so it would seem like it:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="ot">_</span>◂<span class="ot">_</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Stream <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span><span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>◂<span class="ot">_</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">coinductive</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    head <span class="ot">:</span> A</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    tail <span class="ot">:</span> Stream A</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> Stream</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">:</span> Stream ℕ</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">=</span> sieve <span class="dv">1</span> nats</span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>  nats <span class="ot">:</span> Stream ℕ</span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>  head nats <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>  tail nats <span class="ot">=</span> nats</span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>  sieve <span class="ot">:</span> ℕ <span class="ot">→</span> Stream ℕ <span class="ot">→</span> Stream ℕ</span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>  head <span class="ot">(</span>sieve i xs<span class="ot">)</span> <span class="ot">=</span> suc i</span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>  tail <span class="ot">(</span>sieve i xs<span class="ot">)</span> <span class="ot">=</span> remove i <span class="ot">(</span>head xs<span class="ot">)</span> <span class="ot">(</span>tail xs<span class="ot">)</span> <span class="ot">(</span>sieve ∘ suc ∘ <span class="ot">(_</span>+ i<span class="ot">))</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>    remove <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> Stream ℕ <span class="ot">→</span> <span class="ot">(</span>ℕ <span class="ot">→</span> Stream ℕ <span class="ot">→</span> Stream ℕ<span class="ot">)</span> <span class="ot">→</span> Stream ℕ</span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>    remove zero zero zs       k <span class="ot">=</span> remove i <span class="ot">(</span>head zs<span class="ot">)</span> <span class="ot">(</span>tail zs<span class="ot">)</span> <span class="ot">(</span>k ∘ suc<span class="ot">)</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a>    remove zero <span class="ot">(</span>suc z<span class="ot">)</span> zs    k <span class="ot">=</span> remove i z zs <span class="ot">(</span>k ∘ suc<span class="ot">)</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a>    remove <span class="ot">(</span>suc y<span class="ot">)</span> zero zs    k <span class="ot">=</span> k zero <span class="ot">(</span>remove y <span class="ot">(</span>head zs<span class="ot">)</span> <span class="ot">(</span>tail zs<span class="ot">)</span> <span class="ot">_</span>◂<span class="ot">_)</span></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>    remove <span class="ot">(</span>suc y<span class="ot">)</span> <span class="ot">(</span>suc z<span class="ot">)</span> zs k <span class="ot">=</span> remove y z zs <span class="ot">(</span>k ∘ suc<span class="ot">)</span></span></code></pre></div>
<p>But this won’t pass the termination checker. What we actually need to
prove to do so is that there are infinitely many primes: <a
href="https://gist.github.com/copumpkin/1286093">a nontrivial task in
Agda</a>.</p>
]]></description>
    <pubDate>Fri, 14 Dec 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-12-14-primes-in-agda.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Keeping Formal Verification in Bounds</title>
    <link>https://doisinkidney.com/posts/2018-11-20-fast-verified-structures.html</link>
    <description><![CDATA[<div class="info">
    Posted on November 20, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>One of the favorite pastimes of both Haskell and Agda programmers
alike is verifying data structures. Among my favorite examples are
Red-Black trees <span class="citation"
data-cites="might_missing_2015 weirich_depending_2014">(<a
href="#ref-might_missing_2015" role="doc-biblioref">Might 2015</a>; <a
href="#ref-weirich_depending_2014" role="doc-biblioref">Weirich
2014</a>, verified for balance)</span>, perfect binary trees <span
class="citation" data-cites="hinze_perfect_1999">(<a
href="#ref-hinze_perfect_1999" role="doc-biblioref">Hinze
1999</a>)</span>, square matrices <span class="citation"
data-cites="okasaki_fast_1999">(<a href="#ref-okasaki_fast_1999"
role="doc-biblioref">Okasaki 1999a</a>)</span>, search trees <span
class="citation" data-cites="mcbride_how_2014">(<a
href="#ref-mcbride_how_2014" role="doc-biblioref">McBride 2014</a>,
verified for balance and order)</span>, and binomial heaps <span
class="citation" data-cites="hinze_numerical_1998">(<a
href="#ref-hinze_numerical_1998" role="doc-biblioref">Hinze 1998</a>,
verified for structure)</span>.</p>
<p>There are many ways to verify data structures. One technique which
has had recent massive success is to convert Haskell code to Coq, and
then verify the Coq translation: this was the route taken by <span
class="citation" data-cites="breitner_ready_2018-1">Breitner et al. (<a
href="#ref-breitner_ready_2018-1" role="doc-biblioref">2018</a>)</span>
to verify <code>Set</code> and <code>IntSet</code> in containers (a
mammoth achievement, in my opinion).</p>
<p>This approach has some obvious advantages: you separate
implementation from testing (which is usually a good idea), and your
verification language can be different from your implementation
language, with each tailored towards its particular domain.</p>
<p>LiquidHaskell <span class="citation"
data-cites="bakst_liquidhaskell_2018">(<a
href="#ref-bakst_liquidhaskell_2018" role="doc-biblioref">Bakst et al.
2018</a>)</span> (and other tools like it) adds an extra type system to
Haskell tailor-made for verification. The added type system (refinement
types) is more automated (the typechecker uses Z3), more suited for
“invariant”-like things (it supports subtyping), and has a bunch of
domain-specific built-ins (reasoning about sets, equations, etc.). I’d
encourage anyone who hasn’t used it to give it a try: especially if
you’re experienced writing any kind of proof in a language like Agda or
Idris, LiquidHaskell proofs are <em>shockingly</em> simple and easy.</p>
<p>What I’m going to focus on today, though, is writing
<em>correct-by-construction</em> data structures, using Haskell and
Agda’s own type systems. In particular, I’m going to look at how to
write <em>fast</em> verification. In the other two approaches, we don’t
really care about the “speed” of the proofs: sure, it’s nice to speed up
compilation and so on, but we don’t have to worry about our
implementation suffering at runtime because of some complex proof. When
writing correct-by-construction code, though, our task is doubly hard:
we now have to worry about the time complexity of both the
implementation <em>and the proofs</em>.</p>
<p>In this post, I’m going to demonstrate some techniques to write
proofs that stay within the complexity bounds of the algorithms they’re
verifying (without cheating!). Along the way I’m going to verify some
data structures I haven’t seen verified before (a skew-binary
random-access list).</p>
<h1
id="technique-1-start-with-an-unverified-implementation-then-index">Technique
1: Start With an Unverified Implementation, then Index</h1>
<p>To demonstrate the first two techniques, we’re going to write a type
for modular arithmetic. For a more tactile metaphor, think of the flip
clock:</p>
<p><img
src="https://upload.wikimedia.org/wikipedia/commons/c/c3/Split-flap_display.jpg" /></p>
<p>Each digit can be incremented
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
times, where
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
is whatever base you’re using (12 for our flip-clock above). Once you
hit the limit, it flips the next digit along. We’ll start with just one
digit, and then just string them together to get our full type. That in
mind, our “digit” type has two requirements:</p>
<ol>
<li>It should be incrementable.</li>
<li>Once it hits its limit, it should flip back to zero, and let us know
that a flip was performed.</li>
</ol>
<p>Anyone who’s used a little Agda or Idris will be familiar with the
<code>Fin</code> type:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Fin <span class="ot">:</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">:</span> <span class="ot">{</span>n <span class="ot">:</span> ℕ<span class="ot">}</span> <span class="ot">→</span> Fin <span class="ot">(</span>suc n<span class="ot">)</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  suc  <span class="ot">:</span> <span class="ot">{</span>n <span class="ot">:</span> ℕ<span class="ot">}</span> <span class="ot">→</span> Fin n <span class="ot">→</span> Fin <span class="ot">(</span>suc n<span class="ot">)</span></span></code></pre></div>
<p><code>Fin n</code> is the standard way to encode “numbers smaller
than <code>n</code>”. However, for digits they’re entirely unsuitable:
since the limit parameter changes on successor, the kind of increment we
want is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>try-suc <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Fin n <span class="ot">→</span> Maybe <span class="ot">(</span>Fin n<span class="ot">)</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>try-suc <span class="ot">(</span>suc x<span class="ot">)</span> <span class="ot">=</span> Maybe<span class="ot">.</span>map suc <span class="ot">(</span>try-suc x<span class="ot">)</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>try-suc <span class="ot">{</span>suc n<span class="ot">}</span> zero <span class="kw">with</span> n</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> zero <span class="ot">=</span> nothing</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> suc <span class="ot">_</span> <span class="ot">=</span> just <span class="ot">(</span>suc zero<span class="ot">)</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Fin n <span class="ot">→</span> Fin n × Bool</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">{</span>suc n<span class="ot">}</span> x <span class="ot">=</span> maybe <span class="ot">(_</span>, false<span class="ot">)</span> <span class="ot">(</span>zero , true<span class="ot">)</span> <span class="ot">(</span>try-suc x<span class="ot">)</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">{</span>zero<span class="ot">}</span> <span class="ot">()</span></span></code></pre></div>
<p>If we keep going down this path with proofs in mind, we might next
look at the various
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mo>≤</mo><annotation encoding="application/x-tex">\leq</annotation></semantics></math>
proofs in the Agda standard library (<a
href="https://github.com/agda/agda-stdlib/blob/18b45b151f44cee2114fa4b3c1ad9ea532baf919/src/Data/Nat/Base.agda#L28">here</a>,
<a
href="https://github.com/agda/agda-stdlib/blob/18b45b151f44cee2114fa4b3c1ad9ea532baf919/src/Data/Nat/Base.agda#L117">here</a>,
and <a
href="https://github.com/agda/agda-stdlib/blob/18b45b151f44cee2114fa4b3c1ad9ea532baf919/src/Data/Nat/Base.agda#L133">here</a>),
and see if we can wrangle them into doing what we want.</p>
<p>For me, though, this wasn’t a fruitful approach. Instead, we’ll try
and think of how we’d do this without proving anything, and then see if
there’s any place in the resulting data structure we can hang some
proof.</p>
<p>So, in an unproven way, let’s start with some numbers. Since we’re
going to be incrementing, they’d better be unary:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ℕ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">:</span> ℕ</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  suc <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ</span></code></pre></div>
<p>And then, for the “flippable” type, we’ll just store the limit
alongside the value:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Flipper <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>&amp;<span class="ot">_</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    val <span class="ot">:</span> ℕ</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    lim <span class="ot">:</span> ℕ</span></code></pre></div>
<p>We’re not there yet: to check if we’ve gone over the limit, we’ll
still have to compare <code>val</code> and <code>lim</code>. Hopefully
you can guess the optimization we’ll make: instead of storing the limit,
we’ll store the space left:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Flipper <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>&amp;<span class="ot">_</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    space <span class="ot">:</span> ℕ</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    val   <span class="ot">:</span> ℕ</span></code></pre></div>
<p>And we get our flip function:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">:</span> Flipper <span class="ot">→</span> Flipper × Bool</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">(</span>zero  &amp; n<span class="ot">)</span> <span class="ot">=</span> <span class="ot">(</span>suc n &amp; zero <span class="ot">)</span>, true</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">(</span>suc m &amp; n<span class="ot">)</span> <span class="ot">=</span> <span class="ot">(</span>m     &amp; suc n<span class="ot">)</span>, false</span></code></pre></div>
<p>When there’s no space left, the digit must be maximal (9 in decimal,
for instance), so it’ll be one less than the base. That lets us stick it
in for the base, rather than recalculating. In the other case, we just
take one from the space left, and add it to the value.</p>
<p>So, to “prove” this implementation, we might first reach for an
equality proof that <code>val + space</code> is equal to your base.
Don’t! Both <code>val</code> and <code>space</code> are inductive
structures, which could be giving us information on every application of
<code>suc</code>! Let’s set our sights on <code>val</code> and see how
we can hang our proofs off of it.</p>
<p>We’re going to upgrade our Peano number with some information, which
means that our resulting type is going to look an awful lot like a Peano
number. In other words, two cases: <code>zero</code> and
<code>suc</code>.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Val <span class="ot">_</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  zero-case <span class="ot">:</span> Val <span class="ot">_</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  suc-case  <span class="ot">:</span> Val <span class="ot">_</span> <span class="ot">→</span> Val <span class="ot">_</span></span></code></pre></div>
<p>For the <code>suc-case</code>, remember we only want to be allowed to
increment it when the space left is more than zero. So let’s encode
it:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Val <span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  zero-case <span class="ot">:</span> Val <span class="ot">_</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  suc-case  <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>space<span class="ot">}</span> <span class="ot">→</span> Val <span class="ot">_</span> <span class="ot">(</span>suc space<span class="ot">)</span> <span class="ot">→</span> Val <span class="ot">_</span> space</span></code></pre></div>
<p>And for the <code>zero-case</code>, the space left is just the base.
So let’s stick the base into the type as well:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Val <span class="ot">(</span>base <span class="ot">:</span> ℕ<span class="ot">)</span> <span class="ot">:</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  zero-case <span class="ot">:</span> Val base base</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  suc-case  <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>space<span class="ot">}</span> <span class="ot">→</span> Val base <span class="ot">(</span>suc space<span class="ot">)</span> <span class="ot">→</span> Val base space</span></code></pre></div>
<p>(We’ve changed around the way “base” works: it’s now one smaller. So
to encode base-10 you’d have <code>Val 9 space</code>. You can get back
to the other encoding with a simple wrapper, this way just makes things
slightly easier from now on).</p>
<p>Finally, our flipper:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Flipper <span class="ot">(</span>base <span class="ot">:</span> ℕ<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>&amp;<span class="ot">_</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>    space <span class="ot">:</span> ℕ</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    val <span class="ot">:</span> Val base space</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Flipper n <span class="ot">→</span> Flipper n × Bool</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">(</span>zero  &amp; m<span class="ot">)</span> <span class="ot">=</span> <span class="ot">(_</span> &amp;  zero-case<span class="ot">)</span> , true</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">(</span>suc n &amp; m<span class="ot">)</span> <span class="ot">=</span> <span class="ot">(</span>n &amp; suc-case m<span class="ot">)</span> , false</span></code></pre></div>
<p>Great! Everything works.</p>
<p>You may have noticed that the <code>Val</code> type is actually a
proof for
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mo>≥</mo><annotation encoding="application/x-tex">\geq</annotation></semantics></math>
in disguise:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="ot">_</span>≥<span class="ot">_</span> <span class="ot">(</span>m <span class="ot">:</span> ℕ<span class="ot">)</span> <span class="ot">:</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  m≥m <span class="ot">:</span> m ≥ m</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  m≥p <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> m ≥ suc n <span class="ot">→</span> m ≥ n</span></code></pre></div>
<p>And the flipper itself is just an existential in disguise:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>Flipper <span class="ot">:</span> ℕ <span class="ot">→</span> <span class="dt">Set</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>Flipper n <span class="ot">=</span> ∃ <span class="ot">(</span>n ≥<span class="ot">_)</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> Flipper n <span class="ot">→</span> Flipper n × Bool</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">(</span>zero  , m<span class="ot">)</span> <span class="ot">=</span> <span class="ot">(_</span> , m≥m  <span class="ot">)</span>, true</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>suc-flip <span class="ot">(</span>suc n , m<span class="ot">)</span> <span class="ot">=</span> <span class="ot">(</span>n , m≥p m<span class="ot">)</span>, false</span></code></pre></div>
<p>Hopefully this explanation will help you understand how to get from
the specification to those 8 lines. This technique is going to come in
especially handy later when we base data structures off of number
systems.</p>
<h1
id="technique-2-once-you-eliminate-the-impossible-whatever-remains-no-matter-how-improbable-must-be-the-truth.">Technique
2: Once you eliminate the impossible, whatever remains, no matter how
improbable, must be the truth.</h1>
<p>For this next trick, we’ll add an extra operation to the flipper type
above: conversion from a natural number. We want to be able to do it in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>
time, and we won’t allow ourselves to change the original type
definition. Here’s the type we’re aiming for:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>fromNat <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>m<span class="ot">}</span> <span class="ot">(</span>n <span class="ot">:</span> ℕ<span class="ot">)</span> <span class="ot">→</span> <span class="ot">(</span>m≥n <span class="ot">:</span> m ≥ n<span class="ot">)</span> <span class="ot">→</span> Flipper m</span></code></pre></div>
<p>We pass in a proof that the natural number we’re converting from is
indeed in range (it’s marked irrelevant so we don’t pay for it). Here’s
a non-answer:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>fromNat <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>m<span class="ot">}</span> <span class="ot">(</span>n <span class="ot">:</span> ℕ<span class="ot">)</span> <span class="ot">→</span> <span class="ot">{</span>m≥n <span class="ot">:</span> m ≥ n<span class="ot">}</span> <span class="ot">→</span> Flipper m</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>fromNat n <span class="ot">{</span>m≥n<span class="ot">}</span> <span class="ot">=</span> n , m≥n</span></code></pre></div>
<p>While this looks fine, it’s actually the <em>inverse</em> of what we
want. We defined the inductive structure to be indicated by the
inequality proof itself. Let’s make the desired output explicit:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>toNat <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n m<span class="ot">}</span> <span class="ot">→</span> n ≥ m <span class="ot">→</span> ℕ</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>toNat m≥m <span class="ot">=</span> zero</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>toNat <span class="ot">(</span>m≥p n≥m<span class="ot">)</span> <span class="ot">=</span> suc <span class="ot">(</span>toNat n≥m<span class="ot">)</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>fromNat-≡ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> m</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span> <span class="ot">.(</span>n≥m <span class="ot">:</span> n ≥ m<span class="ot">)</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span>  Σ[ n-m ∈ Flipper n ] toNat <span class="ot">(</span>proj₂ n-m<span class="ot">)</span> ≡ m</span></code></pre></div>
<p>And finally we can try an implementation:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>fromNat-≡ zero    <span class="ot">_</span>   <span class="ot">=</span> <span class="ot">(_</span> , m≥m<span class="ot">)</span> , refl</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>fromNat-≡ <span class="ot">(</span>suc m<span class="ot">)</span> n≥m <span class="ot">=</span> ??? <span class="ot">(</span>fromNat-≡ m <span class="ot">(</span>m≥p n≥m<span class="ot">))</span></span></code></pre></div>
<p>In the <code>???</code> there, we want some kind of successor
function. The problem is that we would also need to prove that we
<em>can</em> do a successor call. Except we don’t want to do that:
proving that there’s space left is an expensive operation, and one we
can avoid with another trick: first, we <em>assume</em> that there’s
space left.</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>fromNat-≡ zero    n≥m <span class="ot">=</span> <span class="ot">(</span> <span class="ot">_</span> , m≥m<span class="ot">)</span> , refl</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>fromNat-≡ <span class="ot">(</span>suc n<span class="ot">)</span> n≥m <span class="kw">with</span> fromNat-≡ n <span class="ot">(</span>m≥p n≥m<span class="ot">)</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> <span class="ot">(</span>suc space , n-1<span class="ot">)</span>, x≡m  <span class="ot">=</span> <span class="ot">(</span>space , m≥p n-1<span class="ot">)</span>, cong suc x≡m</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> <span class="ot">(</span>zero      , n-1<span class="ot">)</span>, refl <span class="ot">=</span> ???</span></code></pre></div>
<p>But what about the second case? Well, we have to prove this
impossible. What if it’s an extremely complex, expensive proof? It
doesn’t matter! It will never be run! In contrast to proving the “happy
path” correct, if we can confine all of the ugly complex cases to the
unhappy paths, we can spend as long as we want proving them impossible
without having to worry about runtime cost. Here’s the full
function.</p>
<details>
<summary>
<code>fromNat</code> implementation
</summary>
<div class="sourceCode" id="cb18"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>fromNat-≡ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> m</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span> <span class="ot">.(</span>n≥m <span class="ot">:</span> n ≥ m<span class="ot">)</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>          <span class="ot">→</span>  Σ[ n-m ∈ Flipper n ] toNat <span class="ot">(</span>proj₂ n-m<span class="ot">)</span> ≡ m</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>fromNat-≡ zero    n≥m <span class="ot">=</span> <span class="ot">(</span> <span class="ot">_</span> , m≥m<span class="ot">)</span> , refl</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>fromNat-≡ <span class="ot">(</span>suc n<span class="ot">)</span> n≥m <span class="kw">with</span> fromNat-≡ n <span class="ot">(</span>m≥p n≥m<span class="ot">)</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> <span class="ot">(</span>suc space , n-1<span class="ot">)</span>, x≡m  <span class="ot">=</span> <span class="ot">(</span>space , m≥p n-1<span class="ot">)</span>, cong suc x≡m</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> <span class="ot">(</span>zero      , n≥0<span class="ot">)</span>, refl <span class="ot">=</span> Irrel<span class="ot">.</span>⊥-elim <span class="ot">(</span>contra <span class="ot">_</span> zero n≥0 n≥m<span class="ot">)</span></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">import</span> Data<span class="ot">.</span>Nat<span class="ot">.</span>Properties as <span class="dt">Prop</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>  n≱sk+n <span class="ot">:</span> <span class="ot">∀</span> n k <span class="ot">{</span>sk+n<span class="ot">}</span> <span class="ot">→</span> sk+n ≡ suc k ℕ<span class="ot">.</span>+ n <span class="ot">→</span> n ≥ sk+n <span class="ot">→</span> ⊥</span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>  n≱sk+n n k wit <span class="ot">(</span>m≥p n≥sk+n<span class="ot">)</span> <span class="ot">=</span> n≱sk+n n <span class="ot">(</span>suc k<span class="ot">)</span> <span class="ot">(</span>cong suc wit<span class="ot">)</span> n≥sk+n</span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>  n≱sk+n n k wit m≥m <span class="kw">with</span> <span class="dt">Prop</span><span class="ot">.</span>+-cancelʳ-≡ <span class="dv">0</span> <span class="ot">(</span>suc k<span class="ot">)</span> wit</span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>  <span class="ot">...</span> <span class="ot">|</span> <span class="ot">()</span></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>  contra <span class="ot">:</span> <span class="ot">∀</span> n m <span class="ot">→</span> <span class="ot">(</span>n≥m <span class="ot">:</span> n ≥ m<span class="ot">)</span> <span class="ot">→</span> n ≥ suc <span class="ot">(</span>m ℕ<span class="ot">.</span>+ toNat n≥m<span class="ot">)</span> <span class="ot">→</span> ⊥</span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>  contra n m m≥m n≥st <span class="ot">=</span> n≱sk+n n zero <span class="ot">(</span>cong suc <span class="ot">(</span><span class="dt">Prop</span><span class="ot">.</span>+-identityʳ n<span class="ot">))</span> n≥st</span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a>  contra n m <span class="ot">(</span>m≥p n≥m<span class="ot">)</span> n≥st <span class="ot">=</span></span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a>    contra</span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a>      n</span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a>      <span class="ot">(</span>suc m<span class="ot">)</span></span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a>      n≥m</span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a>      <span class="ot">(</span>subst <span class="ot">(λ</span> x <span class="ot">→</span> n ≥ suc x<span class="ot">)</span> <span class="ot">(</span><span class="dt">Prop</span><span class="ot">.</span>+-suc m <span class="ot">(</span>toNat n≥m<span class="ot">))</span> n≥st<span class="ot">)</span></span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a>fromNat <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> m <span class="ot">→</span> <span class="ot">.(</span>n≥m <span class="ot">:</span> n ≥ m<span class="ot">)</span> <span class="ot">→</span> Flipper n</span>
<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a>fromNat m n≥m <span class="ot">=</span> proj₁ <span class="ot">(</span>fromNat-≡ m n≥m<span class="ot">)</span></span></code></pre></div>
</details>
<h1 id="technique-3-make-indices-correct-by-construction">Technique 3:
Make Indices Correct-By-Construction</h1>
<p>We’re going to switch into Haskell now, and in particular to
functional arrays. These are data structures which aren’t real arrays,
but they offer you the kind of interface you’d want from an array in a
functional setting. You can’t get better than
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
indexing, unfortunately <span class="citation"
data-cites="ben-amram_pointers_1992">(<a
href="#ref-ben-amram_pointers_1992" role="doc-biblioref">Ben-Amram and
Galil 1992</a>)</span>, but often it’s enough.</p>
<p>The first “functional array” we’re going to be looking at is nested
binary random-access lists. It has
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>
indexing, as you might expect, and amortized single-threaded
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
<code>cons</code>.</p>
<p>It starts out like a binary random-access list (“random-access list”
is another name for “functional array”). You can find a full explanation
of the structure in your nearest copy of Purely Functional Data
Structures <span class="citation" data-cites="okasaki_purely_1999">(<a
href="#ref-okasaki_purely_1999" role="doc-biblioref">Okasaki
1999b</a>)</span>, but briefly: the structure mimics a binary number, in
that it’s a list of “bits”. At each set bit, it stores a tree with
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mn>2</mn><mi>i</mi></msup><annotation encoding="application/x-tex">2^i</annotation></semantics></math>
elements, where
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>i</mi><annotation encoding="application/x-tex">i</annotation></semantics></math>
is the position in the list. In this way, every binary number
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
has an analogous list of “bits” which contains, in total,
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
elements.</p>
<p>The “nested” part refers to how we’re going to implement the trees.
It works a little like this:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> <span class="dt">Leaf</span> a <span class="op">|</span> <span class="dt">Node</span> (<span class="dt">Tree</span> (a,a))</span></code></pre></div>
<p>You might have to squint at that definition for a second to
understand it: instead of storing two trees at the <code>Node</code>
constructor (which is what you’d usually do), we store a tree with
double the elements. This has two advantages: all of the children have
the same number of elements (this tree, for instance, is always some
power of 2), and it also cuts down on memory use.</p>
<p>For the binary random-access list, we’ll use the nested encoding of
trees to encode the contents of each bit. There’s an implementation of
this very thing on Hackage <span class="citation"
data-cites="komuves_nested-sequence_2016">(<a
href="#ref-komuves_nested-sequence_2016" role="doc-biblioref">Komuves
and Divianszky 2016</a>)</span>, and Okasaki himself wrote something
very similar to it <span class="citation"
data-cites="okasaki_fast_1999">(<a href="#ref-okasaki_fast_1999"
role="doc-biblioref">1999a</a>)</span>, but we’re going to go a little
further than both of those by indexing the type by its size. Here it
is:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Bit</span> <span class="ot">=</span> <span class="dt">O</span> <span class="op">|</span> <span class="dt">I</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Seq</span> ns a <span class="kw">where</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span><span class="ot">  ::</span>                      <span class="dt">Seq</span> &#39;[]      a</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Even</span><span class="ot"> ::</span>      <span class="dt">Seq</span> xs (a,a) <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">O</span> <span class="op">:</span> xs) a</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Odd</span><span class="ot">  ::</span> a <span class="ot">-&gt;</span> <span class="dt">Seq</span> xs (a,a) <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">I</span> <span class="op">:</span> xs) a</span></code></pre></div>
<p>The operations we’re interested will be <code>cons</code> and
<code>uncons</code>: for the indices, they correspond to incrementing
and decrementing the numbers, respectively. As such, we’ll need
type-level functions for those:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Inc</span> (<span class="ot">ns ::</span> [<span class="dt">Bit</span>])<span class="ot"> ::</span> [<span class="dt">Bit</span>] <span class="kw">where</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> &#39;[] <span class="ot">=</span> &#39;[<span class="dt">I</span>]</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (<span class="dt">O</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> xs</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (<span class="dt">I</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">O</span> <span class="op">:</span> <span class="dt">Inc</span> xs</span></code></pre></div>
<p>And now the <code>cons</code> function:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> a <span class="ot">-&gt;</span> <span class="dt">Seq</span> ns a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">Inc</span> ns) a</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>cons x <span class="dt">Nil</span>        <span class="ot">=</span> <span class="dt">Odd</span> x <span class="dt">Nil</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Even</span>  xs) <span class="ot">=</span> <span class="dt">Odd</span> x xs</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Odd</span> y ys) <span class="ot">=</span> <span class="dt">Even</span> (cons (x,y) ys)</span></code></pre></div>
<p>However, we’re going to run into trouble if we try to write
<code>uncons</code>:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Dec</span> (<span class="ot">ns ::</span> [<span class="dt">Bit</span>])<span class="ot"> ::</span> [<span class="dt">Bit</span>] <span class="kw">where</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> (<span class="dt">I</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">O</span> <span class="op">:</span> xs</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> (<span class="dt">O</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">I</span> <span class="op">:</span> <span class="dt">Dec</span> xs</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> &#39;[] <span class="ot">=</span> <span class="op">???</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a><span class="ot">uncons ::</span> <span class="dt">Seq</span> ns a <span class="ot">-&gt;</span> (a, <span class="dt">Seq</span> (<span class="dt">Dec</span> ns) a)</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>uncons (<span class="dt">Odd</span> x xs) <span class="ot">=</span> (x, <span class="dt">Even</span> xs)</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>uncons (<span class="dt">Even</span>  xs) <span class="ot">=</span> <span class="kw">case</span> uncons xs <span class="kw">of</span></span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>    ((x,y),ys) <span class="ot">-&gt;</span> (x, <span class="dt">Odd</span> y ys)</span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>uncons <span class="dt">Nil</span> <span class="ot">=</span> <span class="op">???</span></span></code></pre></div>
<p>We <em>should</em> be able to write this function without returning a
<code>Maybe</code>. Because we statically know the size, we can encode
“only nonempty sequences”. The problem is that <code>Seq [] a</code>
isn’t the only non-empty sequence: there’s also <code>Seq [O] a</code>
and <code>Seq [O,O] a</code>, and so on. Our binary number system is
redundant, because it contains trailing zeroes.</p>
<p>We could add some kind of proof into the data structure, but that
would (again) be expensive. Instead, we can make the index
<em>itself</em> correct-by-construction, by choosing a non-redundant
representation of binary numbers.</p>
<p>Here’s the trick: instead of having a list of bits, we’re going to
have a list of “the distance to the next one”. This eliminates the
redundancy, and translates into our data structure like so:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">N</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">N</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Nest</span> n ns a <span class="kw">where</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Odd</span><span class="ot">  ::</span> a <span class="ot">-&gt;</span> (<span class="dt">Seq</span>    ns (a,a)) <span class="ot">-&gt;</span> <span class="dt">Nest</span> <span class="dt">Z</span>     ns a</span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Even</span><span class="ot"> ::</span>      (<span class="dt">Nest</span> n ns (a,a)) <span class="ot">-&gt;</span> <span class="dt">Nest</span> (<span class="dt">S</span> n) ns a</span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Seq</span> ns a <span class="kw">where</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">Seq</span> &#39;[] a</span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Cons</span><span class="ot"> ::</span> <span class="dt">Nest</span> n ns a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (n <span class="op">:</span> ns) a</span></code></pre></div>
<p>Lovely! Crucially for our <code>uncons</code>, we now know that any
non-empty list of bits is a non-zero list of bits, so we can type
“nonempty sequence” easily:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Dec</span> (<span class="ot">n ::</span> <span class="dt">N</span>) (<span class="ot">ns ::</span> [<span class="dt">N</span>]) <span class="ot">=</span> (<span class="ot">r ::</span> [<span class="dt">N</span>]) <span class="op">|</span> r <span class="ot">-&gt;</span> n ns <span class="kw">where</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> (<span class="dt">S</span> n) ns       <span class="ot">=</span> <span class="dt">Z</span> <span class="op">:</span> <span class="dt">Dec</span> n ns</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> <span class="dt">Z</span>     &#39;[]      <span class="ot">=</span> &#39;[]</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> <span class="dt">Z</span>     (n <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">S</span> n <span class="op">:</span> ns</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a><span class="ot">uncons ::</span> <span class="dt">Seq</span> (n <span class="op">:</span> ns) a <span class="ot">-&gt;</span> (a, <span class="dt">Seq</span> (<span class="dt">Dec</span> n ns) a)</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>uncons (<span class="dt">Cons</span> xs&#39;) <span class="ot">=</span> go xs&#39;</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">Nest</span> n ns a <span class="ot">-&gt;</span> (a, <span class="dt">Seq</span> (<span class="dt">Dec</span> n ns) a)</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> x <span class="dt">Nil</span>) <span class="ot">=</span> (x, <span class="dt">Nil</span>)</span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> x (<span class="dt">Cons</span> xs)) <span class="ot">=</span> (x, <span class="dt">Cons</span> (<span class="dt">Even</span> xs))</span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Even</span> xs) <span class="ot">=</span> <span class="kw">case</span> go xs <span class="kw">of</span> ((x,y),ys) <span class="ot">-&gt;</span> (x, <span class="dt">Cons</span> (<span class="dt">Odd</span> y ys))</span></code></pre></div>
<p>We’re still not done, though: here’s our new type family for
incrementing things.</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Inc</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>])<span class="ot"> ::</span> [<span class="dt">N</span>] <span class="kw">where</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> &#39;[] <span class="ot">=</span> &#39;[<span class="dt">Z</span>]</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (<span class="dt">S</span> n <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">Z</span> <span class="op">:</span> n <span class="op">:</span> ns</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (<span class="dt">Z</span>   <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">Carry</span> (<span class="dt">Inc</span> ns)</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Carry</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>])<span class="ot"> ::</span> [<span class="dt">N</span>] <span class="kw">where</span></span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Carry</span> &#39;[] <span class="ot">=</span> &#39;[]</span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Carry</span> (n <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">S</span> n <span class="op">:</span> ns</span></code></pre></div>
<p>The <code>Carry</code> there is ugly, and that ugliness carries into
the <code>cons</code> function:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> a <span class="ot">-&gt;</span> <span class="dt">Seq</span> ns a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">Inc</span> ns) a</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>cons x <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Cons</span> (<span class="dt">Odd</span> x <span class="dt">Nil</span>)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>cons x&#39; (<span class="dt">Cons</span> xs&#39;) <span class="ot">=</span> go x&#39; xs&#39;</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> a <span class="ot">-&gt;</span> <span class="dt">Nest</span> n ns a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">Inc</span> (n<span class="op">:</span>ns)) a</span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a>    go x (<span class="dt">Even</span>  xs) <span class="ot">=</span> <span class="dt">Cons</span> (<span class="dt">Odd</span> x (<span class="dt">Cons</span> xs))</span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>    go x (<span class="dt">Odd</span> y <span class="dt">Nil</span>) <span class="ot">=</span> <span class="dt">Cons</span> (<span class="dt">Even</span> (<span class="dt">Odd</span> (x,y) <span class="dt">Nil</span>))</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>    go x (<span class="dt">Odd</span> y (<span class="dt">Cons</span> ys)) <span class="ot">=</span> carry (go (x,y) ys)</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a><span class="ot">    carry ::</span> <span class="dt">Seq</span> ns (a,a) <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">Carry</span> ns) a</span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a>    carry <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a>    carry (<span class="dt">Cons</span> xs) <span class="ot">=</span> <span class="dt">Cons</span> (<span class="dt">Even</span> xs)</span></code></pre></div>
<p>To clean it up, we’re going to use another technique.</p>
<h1
id="technique-4-provide-information-on-indices-as-early-as-possible">Technique
4: Provide Information on Indices as Early as Possible</h1>
<p>You occasionally see people wonder about the usual definition of
addition on Peano numbers:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>+<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>zero  + m <span class="ot">=</span> m</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>suc n + m <span class="ot">=</span> suc <span class="ot">(</span>n + m<span class="ot">)</span></span></code></pre></div>
<p>It’s very simple, with only two equations. When someone sees the
following error, then:</p>
<blockquote>
<p><code>couldn't match type n with n + 0</code></p>
</blockquote>
<p>They might be tempted to add it as an equation to the function:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>+<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>zero  + m    <span class="ot">=</span> m</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>n     + zero <span class="ot">=</span> n</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>suc n + m    <span class="ot">=</span> suc <span class="ot">(</span>n + m<span class="ot">)</span></span></code></pre></div>
<p>Similarly, when someone sees the other error commonly found with
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>+</mi><annotation encoding="application/x-tex">+</annotation></semantics></math>:</p>
<blockquote>
<p><code>couldn't match type S n + m with n + S m</code></p>
</blockquote>
<p>They’ll add that equation in too! In fact, that particular equation
will provide a valid definition of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>+</mi><annotation encoding="application/x-tex">+</annotation></semantics></math>:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>+<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>zero  + m <span class="ot">=</span> m</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>suc n + m <span class="ot">=</span> n + suc m</span></code></pre></div>
<p>So why is the first definition of + the one almost always used?
Because it <em>maximizes output information from minimal input</em>.
Take the second implementation above, the one with the zero on the
right. In this function, we have to look at the second argument in the
second clause: in other words, we don’t get to find out about the output
until we’ve looked at both <code>n</code> and <code>m</code>. In the
usual definition, if you know the first argument is <code>suc</code>
something, you also know the <em>output</em> must be <code>suc</code>
something.</p>
<p>Similarly with the third implementation: we have to examine the first
argument in its <em>entirety</em> before we wrap the output in a
constructor. Yes, we can of course prove that they’re all equivalent,
but remember: proofs are expensive, and we’re looking for speed here. So
the first definition of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>+</mi><annotation encoding="application/x-tex">+</annotation></semantics></math>
is our best bet, since it tells us the most without having to prove
anything.</p>
<p>Looking back at our definition of <code>Inc</code>, we can actually
provide more information a little sooner:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Inc</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>])<span class="ot"> ::</span> [<span class="dt">N</span>] <span class="kw">where</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> &#39;[] <span class="ot">=</span> &#39;[<span class="dt">Z</span>]</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (<span class="dt">S</span> n <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">Z</span> <span class="op">:</span> n <span class="op">:</span> ns</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (<span class="dt">Z</span>   <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">Carry</span> (<span class="dt">Inc</span> ns)</span></code></pre></div>
<p>In all of the outputs, the list is non-empty. We can encode that, by
having two different functions for the head and tail of the list:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">IncHead</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>])<span class="ot"> ::</span> <span class="dt">N</span> <span class="kw">where</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncHead</span> &#39;[] <span class="ot">=</span> <span class="dt">Z</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncHead</span> (n <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">IncHead&#39;</span> n ns</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">IncHead&#39;</span> (<span class="ot">n ::</span> <span class="dt">N</span>) (<span class="ot">ns ::</span> [<span class="dt">N</span>])<span class="ot"> ::</span> <span class="dt">N</span> <span class="kw">where</span></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncHead&#39;</span> (<span class="dt">S</span> n) ns <span class="ot">=</span> <span class="dt">Z</span></span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncHead&#39;</span> <span class="dt">Z</span> ns <span class="ot">=</span> <span class="dt">S</span> (<span class="dt">IncHead</span> ns)</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">IncTail</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>])<span class="ot"> ::</span> [<span class="dt">N</span>] <span class="kw">where</span></span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncTail</span> &#39;[] <span class="ot">=</span> &#39;[]</span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncTail</span> (n <span class="op">:</span> ns) <span class="ot">=</span> <span class="dt">IncTail&#39;</span> n ns</span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">IncTail&#39;</span> (<span class="ot">n ::</span> <span class="dt">N</span>) (<span class="ot">ns ::</span> [<span class="dt">N</span>])<span class="ot"> ::</span> [<span class="dt">N</span>] <span class="kw">where</span></span>
<span id="cb32-14"><a href="#cb32-14" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncTail&#39;</span> (<span class="dt">S</span> n) ns <span class="ot">=</span> n <span class="op">:</span> ns</span>
<span id="cb32-15"><a href="#cb32-15" aria-hidden="true" tabindex="-1"></a>    <span class="dt">IncTail&#39;</span> <span class="dt">Z</span> ns <span class="ot">=</span> <span class="dt">IncTail</span> ns</span>
<span id="cb32-16"><a href="#cb32-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-17"><a href="#cb32-17" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Inc</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>]) <span class="ot">=</span> <span class="dt">IncHead</span> ns <span class="op">:</span> <span class="dt">IncTail</span> ns</span></code></pre></div>
<p>This tells the typechecker that we’re not returning an empty sequence
right away, so we don’t have to pattern-match to prove it later, giving
us a more efficient function.</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> a <span class="ot">-&gt;</span> <span class="dt">Seq</span> ns a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">Inc</span> ns) a</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>cons x&#39; xs&#39; <span class="ot">=</span> <span class="dt">Cons</span> (go x&#39; xs&#39;)</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> a <span class="ot">-&gt;</span> <span class="dt">Seq</span> ns a <span class="ot">-&gt;</span> <span class="dt">Nest</span> (<span class="dt">IncHead</span> ns) (<span class="dt">IncTail</span> ns) a</span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a>    go x <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Odd</span> x <span class="dt">Nil</span></span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>    go x (<span class="dt">Cons</span> (<span class="dt">Even</span>  xs)) <span class="ot">=</span> <span class="dt">Odd</span> x (<span class="dt">Cons</span> xs)</span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>    go x (<span class="dt">Cons</span> (<span class="dt">Odd</span> y ys)) <span class="ot">=</span> <span class="dt">Even</span> (go (x,y) ys)</span></code></pre></div>
<h1 id="technique-5-lazy-proofs">Technique 5: Lazy Proofs</h1>
<p>Briefly after introducing the binary random-access list, Okasaki
describes the <em>skew-binary</em> random-access list. As well as having
the same indexing cost as the type above, it supports
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
<code>cons</code>. But wait—didn’t the previous structure have
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
<code>cons</code>? Not really. Unfortunately, in a pure functional
setting, imperative-style amortization measurements aren’t always valid.
Say we perform a <code>cons</code> in the worst case, and it takes
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">\log n</annotation></semantics></math>
time. In an imperative setting, that’s no problem, because all of the
rest of the operations are not going to be on the worst-case. In a pure
setting, though, the old structure is still sitting around. You can
still access it, and you can still get that awful worst-case time.</p>
<p>This is where the skew binary tree comes in. It’s based on the <a
href="https://en.wikipedia.org/wiki/Skew_binary_number_system">skew
binary numbers</a>: these work similarly to binary, but you’re allowed
have (at most) a single 2 digit before any ones. This gives you
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
incrementing and decrementing, which is what we need here. Let’s get
started.</p>
<p>First, our type-level numbers. We’re going to use the sparse encoding
as above, but we need some way to encode “you’re only allowed one 2”.
The most lightweight way to do it I can think of is by implicitly
assuming the second number in the list of gaps is one less than the
others. In other words, we encode a 2 with <code>[n, 0, m]</code>. That
<code>0</code> means that at position <code>n</code> there’s a 2, not a
1.</p>
<p>The corresponding type families for increment and decrement are
clearly
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Inc</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>]) <span class="ot">=</span> (<span class="ot">ms ::</span> [<span class="dt">N</span>]) <span class="op">|</span> ms <span class="ot">-&gt;</span> ns <span class="kw">where</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> &#39;[]              <span class="ot">=</span> <span class="dt">Z</span>   <span class="op">:</span> &#39;[]</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (x  <span class="op">:</span> &#39;[])       <span class="ot">=</span> <span class="dt">Z</span>   <span class="op">:</span> x  <span class="op">:</span> &#39;[]</span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (x  <span class="op">:</span> <span class="dt">Z</span>    <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">S</span> x <span class="op">:</span> xs</span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Inc</span> (x1 <span class="op">:</span> <span class="dt">S</span> x2 <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">Z</span>   <span class="op">:</span> x1 <span class="op">:</span> x2 <span class="op">:</span> xs</span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Dec</span> (<span class="ot">n ::</span> <span class="dt">N</span>) (<span class="ot">ns ::</span> [<span class="dt">N</span>]) <span class="ot">=</span> (<span class="ot">ms ::</span> [<span class="dt">N</span>]) <span class="op">|</span> ms <span class="ot">-&gt;</span> n ns <span class="kw">where</span></span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> (<span class="dt">S</span> x)  xs            <span class="ot">=</span> x  <span class="op">:</span> <span class="dt">Z</span> <span class="op">:</span> xs</span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> <span class="dt">Z</span>     &#39;[]            <span class="ot">=</span> &#39;[]</span>
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> <span class="dt">Z</span>     (x  <span class="op">:</span> &#39;[])     <span class="ot">=</span> x  <span class="op">:</span> &#39;[]</span>
<span id="cb34-11"><a href="#cb34-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Dec</span> <span class="dt">Z</span>     (x1 <span class="op">:</span> x2 <span class="op">:</span> xs) <span class="ot">=</span> x1 <span class="op">:</span> <span class="dt">S</span> x2 <span class="op">:</span> xs</span></code></pre></div>
<p>We don’t need to split this into head and tail families as we did
before because there’s no recursive call: we know all we’re ever going
to know about the output following <em>any</em> match on the input.</p>
<p>There’s another problem before we write the implementation: we can’t
use the <code>Nest</code> construction that we had before, because then
the head would be buried in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">\log n</annotation></semantics></math>
constructors (or thereabouts). Instead, we’re going to have to use GADTs
to encode the “gap” type, alongside the relevant tree. This gap type is
going to be very similar to the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mo>≥</mo><annotation encoding="application/x-tex">\geq</annotation></semantics></math>
proof we had for the modular counters, but with an extra parameter:</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Gap</span> (<span class="ot">n ::</span> <span class="dt">N</span>) (<span class="ot">g ::</span> <span class="dt">N</span>) (<span class="ot">m ::</span> <span class="dt">N</span>) <span class="kw">where</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Zy</span><span class="ot"> ::</span> <span class="dt">Gap</span> n <span class="dt">Z</span> n</span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Sy</span><span class="ot"> ::</span> <span class="dt">Gap</span> n g m <span class="ot">-&gt;</span> <span class="dt">Gap</span> n (<span class="dt">S</span> g) (<span class="dt">S</span> m)</span></code></pre></div>
<p><code>Gap n g m</code> means there is a gap of <code>g</code> between
<code>n</code> and <code>m</code>. Or, stated another way, it means
<code>n + g = m</code>. Its inductive structure mimics the
<code>g</code> parameter (it’s basically the <code>g</code> parameter
itself with some added information).</p>
<p>With all of that together, here’s the definition of the array
itself:</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Tree</span> (<span class="ot">n ::</span> <span class="dt">N</span>) (<span class="ot">a ::</span> <span class="dt">Type</span>) <span class="kw">where</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Tree</span> <span class="dt">Z</span> a <span class="ot">=</span> a</span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Tree</span> (<span class="dt">S</span> n) a <span class="ot">=</span> <span class="dt">Node</span> n a</span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Node</span> n a <span class="ot">=</span> <span class="dt">Node</span> a (<span class="dt">Tree</span> n a) (<span class="dt">Tree</span> n a)</span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">SeqTail</span> (<span class="ot">n ::</span> <span class="dt">N</span>) (<span class="ot">ns ::</span> [<span class="dt">N</span>]) (<span class="ot">a ::</span> <span class="dt">Type</span>) <span class="kw">where</span></span>
<span id="cb36-8"><a href="#cb36-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">NilT</span><span class="ot">  ::</span> <span class="dt">SeqTail</span> n &#39;[] a</span>
<span id="cb36-9"><a href="#cb36-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">ConsT</span><span class="ot"> ::</span> <span class="dt">Gap</span> n g m</span>
<span id="cb36-10"><a href="#cb36-10" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">Tree</span> m a</span>
<span id="cb36-11"><a href="#cb36-11" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">SeqTail</span> (<span class="dt">S</span> m) ms a</span>
<span id="cb36-12"><a href="#cb36-12" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">SeqTail</span> n (g <span class="op">:</span> ms) a</span>
<span id="cb36-13"><a href="#cb36-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb36-14"><a href="#cb36-14" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Seq</span> (<span class="ot">ns ::</span> [<span class="dt">N</span>]) (<span class="ot">a ::</span> <span class="dt">Type</span>) <span class="kw">where</span></span>
<span id="cb36-15"><a href="#cb36-15" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">Seq</span> &#39;[] a</span>
<span id="cb36-16"><a href="#cb36-16" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Cons</span><span class="ot"> ::</span> <span class="dt">Gap</span> <span class="dt">Z</span> g n</span>
<span id="cb36-17"><a href="#cb36-17" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="dt">Tree</span> n a</span>
<span id="cb36-18"><a href="#cb36-18" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="dt">SeqTail</span> n ns a</span>
<span id="cb36-19"><a href="#cb36-19" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="dt">Seq</span> (g <span class="op">:</span> ns) a</span></code></pre></div>
<p>The <code>cons</code> operation again mimics the increment function,
but there’s one final snag before it’ll typecheck:</p>
<div class="sourceCode" id="cb37"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> a <span class="ot">-&gt;</span> <span class="dt">Seq</span> ns a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">Inc</span> ns) a</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>cons x <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Cons</span> <span class="dt">Zy</span> x <span class="dt">NilT</span></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Cons</span> zn y <span class="dt">NilT</span>) <span class="ot">=</span> <span class="dt">Cons</span> <span class="dt">Zy</span> x (<span class="dt">ConsT</span> zn y <span class="dt">NilT</span>)</span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Cons</span> zn y1 (<span class="dt">ConsT</span> <span class="dt">Zy</span> y2 ys)) <span class="ot">=</span> <span class="dt">Cons</span>(<span class="dt">Sy</span> zn) (<span class="dt">Node</span> x y1 y2) ys</span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Cons</span> zn y1 (<span class="dt">ConsT</span> (<span class="dt">Sy</span> nm) y2 ys)) <span class="ot">=</span></span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Cons</span> <span class="dt">Zy</span> x (<span class="dt">ConsT</span> zn y1 (<span class="dt">ConsT</span> <span class="op">???</span> y2 ys))</span></code></pre></div>
<p>On the final line, the <code>???</code> is missing. In the unverified
version, <code>nm</code> would slot right in there. Here, though, if we
try it we get an error, which basically amounts to:</p>
<div class="sourceCode" id="cb38"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Gap</span> n g m <span class="op">/=</span> <span class="dt">Gap</span> (<span class="dt">S</span> n) g (<span class="dt">S</span> m)</span></code></pre></div>
<p>At this point, I’d usually throw out the inductive-style proof, and
replace it with a proof of equality, which I’d aggressively erase in all
of the functions. I said at the beginning I wouldn’t cheat, though, so
here’s what I’ll do instead:</p>
<div class="sourceCode" id="cb39"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="ot">gapr ::</span> <span class="dt">Gap</span> n g m <span class="ot">-&gt;</span> <span class="dt">Gap</span> (<span class="dt">S</span> n) g (<span class="dt">S</span> m)</span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>gapr <span class="dt">Zy</span>       <span class="ot">=</span> <span class="dt">Zy</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>gapr (<span class="dt">Sy</span> pnm) <span class="ot">=</span> <span class="dt">Sy</span> (gapr pnm)</span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> a <span class="ot">-&gt;</span> <span class="dt">Seq</span> ns a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (<span class="dt">Inc</span> ns) a</span>
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a>cons x <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Cons</span> <span class="dt">Zy</span> x <span class="dt">NilT</span></span>
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Cons</span> zn y <span class="dt">NilT</span>) <span class="ot">=</span> <span class="dt">Cons</span> <span class="dt">Zy</span> x (<span class="dt">ConsT</span> zn y <span class="dt">NilT</span>)</span>
<span id="cb39-8"><a href="#cb39-8" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Cons</span> zn y1 (<span class="dt">ConsT</span> <span class="dt">Zy</span> y2 ys)) <span class="ot">=</span> <span class="dt">Cons</span> (<span class="dt">Sy</span> zn) (<span class="dt">Node</span> x y1 y2) ys</span>
<span id="cb39-9"><a href="#cb39-9" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">Cons</span> zn y1 (<span class="dt">ConsT</span> (<span class="dt">Sy</span> nm) y2 ys)) <span class="ot">=</span></span>
<span id="cb39-10"><a href="#cb39-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Cons</span> <span class="dt">Zy</span> x (<span class="dt">ConsT</span> zn y1 (<span class="dt">ConsT</span> (gapr nm) y2 ys))</span></code></pre></div>
<p>At first glance, we’ve lost the complexity bounds. That
<code>gapr</code> operation is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi></mrow><annotation encoding="application/x-tex">\log n</annotation></semantics></math>
(or something), and we’re performing it pretty frequently. We might keep
the amortized bounds, but isn’t that not really worthy in a pure
setting?</p>
<p>That would all be true, if it weren’t for laziness. Because we
<em>delay</em> the evaluation of <code>gapr</code>, we won’t have to pay
for it all in one big thunk. In fact, because it’s basically a unary
number, we only have to pay for one part of it at a time. I haven’t yet
fully worked out the proofs, but I’m pretty sure we’re guaranteed
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
worst-case time here too.</p>
<h1 id="technique-6-when-all-else-fails-prove-it-later">Technique 6:
When All Else Fails, Prove it Later</h1>
<p>About a year ago, I <a
href="/posts/2017-04-23-verifying-data-structures-in-haskell-lhs.html">tried</a>
to write a verified version of binomial heaps, which could then be used
for sorting traversable containers. Unfortunately, I couldn’t figure out
how to write delete-min, and gave up. I <em>did</em> recognize that the
redundancy of the binary representation was a problem, but I couldn’t
figure out much more than that.</p>
<p>Now, though, we have a new non-redundant representation of binary
numbers, and some handy techniques to go along with it.</p>
<p>Unfortunately, I ran into a similar roadblock in the implementation.
Here’s the point where I was stuck:</p>
<div class="sourceCode" id="cb40"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Zipper</span> a n xs <span class="ot">=</span> <span class="dt">Zipper</span> a (<span class="dt">Node</span> n a) (<span class="dt">Binomial</span> n xs a)</span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a><span class="ot">slideLeft ::</span> <span class="dt">Zipper</span> a (<span class="dt">S</span> n) xs <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a n (<span class="dt">Z</span> <span class="op">:</span> xs)</span>
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a>slideLeft (<span class="dt">Zipper</span> m (t <span class="op">:&lt;</span> ts) hs) <span class="ot">=</span> <span class="dt">Zipper</span> m ts (<span class="dt">Cons</span> (<span class="dt">Odd</span> t hs))</span>
<span id="cb40-5"><a href="#cb40-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-6"><a href="#cb40-6" aria-hidden="true" tabindex="-1"></a><span class="ot">minView ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Binomial</span> n (x <span class="op">:</span> xs) a <span class="ot">-&gt;</span> (a, <span class="dt">Binomial</span> n (<span class="dt">Decr</span> x xs) a)</span>
<span id="cb40-7"><a href="#cb40-7" aria-hidden="true" tabindex="-1"></a>minView (<span class="dt">Cons</span> xs&#39;) <span class="ot">=</span> unZipper (go xs&#39;)</span>
<span id="cb40-8"><a href="#cb40-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb40-9"><a href="#cb40-9" aria-hidden="true" tabindex="-1"></a>    unZipper (<span class="dt">Zipper</span> x _ xs) <span class="ot">=</span> (x, xs)</span>
<span id="cb40-10"><a href="#cb40-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-11"><a href="#cb40-11" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="kw">forall</span> a n x xs<span class="op">.</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Nest</span> n x xs a <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a n (<span class="dt">Decr</span> x xs)</span>
<span id="cb40-12"><a href="#cb40-12" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Even</span> xs) <span class="ot">=</span> slideLeft (go xs)</span>
<span id="cb40-13"><a href="#cb40-13" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> (<span class="dt">Root</span> x ts) <span class="dt">Empty</span>) <span class="ot">=</span> <span class="dt">Zipper</span> x ts <span class="dt">Empty</span></span>
<span id="cb40-14"><a href="#cb40-14" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> c<span class="op">@</span>(<span class="dt">Root</span> x ts) (<span class="dt">Cons</span> xs)) <span class="ot">=</span></span>
<span id="cb40-15"><a href="#cb40-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> go xs <span class="kw">of</span></span>
<span id="cb40-16"><a href="#cb40-16" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Zipper</span> m (t&#39; <span class="op">:&lt;</span> _) hs)</span>
<span id="cb40-17"><a href="#cb40-17" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> m <span class="op">&gt;=</span> x <span class="ot">-&gt;</span> <span class="dt">Zipper</span> x ts (<span class="dt">Cons</span> (<span class="dt">Even</span> xs))</span>
<span id="cb40-18"><a href="#cb40-18" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">-&gt;</span></span>
<span id="cb40-19"><a href="#cb40-19" aria-hidden="true" tabindex="-1"></a>                  <span class="dt">Zipper</span> m ts</span>
<span id="cb40-20"><a href="#cb40-20" aria-hidden="true" tabindex="-1"></a>                      (<span class="kw">case</span> hs <span class="kw">of</span></span>
<span id="cb40-21"><a href="#cb40-21" aria-hidden="true" tabindex="-1"></a>                           <span class="dt">Empty</span> <span class="ot">-&gt;</span> <span class="dt">Cons</span> (<span class="dt">Even</span> (<span class="dt">Odd</span> (mergeTree c t&#39;) <span class="dt">Empty</span>))</span>
<span id="cb40-22"><a href="#cb40-22" aria-hidden="true" tabindex="-1"></a>                           <span class="dt">Cons</span> hs&#39; <span class="ot">-&gt;</span> <span class="dt">Cons</span> (<span class="dt">Even</span> (carryOneNest (mergeTree c t&#39;) hs&#39;)))</span></code></pre></div>
<p>The last two lines don’t typecheck! The errors were complex, but
effectively they stated:</p>
<blockquote>
<p><code>Could not deduce</code></p>
<blockquote>
<p><code
class="sourceCode haskell">x <span class="op">:</span> xs <span class="op">~</span> [<span class="dt">Z</span>]</code></p>
</blockquote>
<p><code>from the context</code></p>
<blockquote>
<p><code
class="sourceCode haskell"><span class="dt">Decr</span> x xs <span class="op">~</span> []</code></p>
</blockquote>
</blockquote>
<p>and:</p>
<blockquote>
<p><code>Could not deduce</code></p>
<blockquote>
<p><code
class="sourceCode haskell">x <span class="op">:</span> xs <span class="op">~</span> <span class="dt">Inc</span> (y <span class="op">:</span> ys)</code></p>
</blockquote>
<p><code>from the context</code></p>
<blockquote>
<p><code
class="sourceCode haskell"><span class="dt">Decr</span> x xs <span class="op">~</span> y <span class="op">:</span> ys</code></p>
</blockquote>
</blockquote>
<p>The thing is, all of those look pretty provable. So, for this
technique, we first figure out what proofs we need, and <em>assume</em>
we have them. This means changing <code>minView</code> to the
following:</p>
<div class="sourceCode" id="cb41"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Zipper</span> a n xs <span class="ot">=</span> <span class="dt">Zipper</span> a (<span class="dt">Node</span> n a) (<span class="dt">Binomial</span> n xs a)</span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a><span class="ot">slideLeft ::</span> <span class="dt">Zipper</span> a (<span class="dt">S</span> n) xs <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a n (<span class="dt">Z</span> <span class="op">:</span> xs)</span>
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a>slideLeft (<span class="dt">Zipper</span> m (t <span class="op">:&lt;</span> ts) hs) <span class="ot">=</span> <span class="dt">Zipper</span> m ts (<span class="dt">Cons</span> (<span class="dt">Odd</span> t hs))</span>
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-6"><a href="#cb41-6" aria-hidden="true" tabindex="-1"></a><span class="ot">minView ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Binomial</span> n (x <span class="op">:</span> xs) a <span class="ot">-&gt;</span> (a, <span class="dt">Binomial</span> n (<span class="dt">Decr</span> x xs) a)</span>
<span id="cb41-7"><a href="#cb41-7" aria-hidden="true" tabindex="-1"></a>minView (<span class="dt">Cons</span> xs&#39;) <span class="ot">=</span> unZipper (go xs&#39;)</span>
<span id="cb41-8"><a href="#cb41-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb41-9"><a href="#cb41-9" aria-hidden="true" tabindex="-1"></a>    unZipper (<span class="dt">Zipper</span> x _ xs) <span class="ot">=</span> (x, xs)</span>
<span id="cb41-10"><a href="#cb41-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-11"><a href="#cb41-11" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="kw">forall</span> a n x xs<span class="op">.</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Nest</span> n x xs a <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a n (<span class="dt">Decr</span> x xs)</span>
<span id="cb41-12"><a href="#cb41-12" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Even</span> xs) <span class="ot">=</span> slideLeft (go xs)</span>
<span id="cb41-13"><a href="#cb41-13" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> (<span class="dt">Root</span> x ts) <span class="dt">Empty</span>) <span class="ot">=</span> <span class="dt">Zipper</span> x ts <span class="dt">Empty</span></span>
<span id="cb41-14"><a href="#cb41-14" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> c<span class="op">@</span>(<span class="dt">Root</span> x ts) (<span class="dt">Cons</span> xs)) <span class="ot">=</span></span>
<span id="cb41-15"><a href="#cb41-15" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> go xs <span class="kw">of</span></span>
<span id="cb41-16"><a href="#cb41-16" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Zipper</span> m (t&#39; <span class="op">:&lt;</span> _) (<span class="ot">hs ::</span> <span class="dt">Binomial</span> (<span class="dt">S</span> n) (<span class="dt">Decr</span> y ys) a))</span>
<span id="cb41-17"><a href="#cb41-17" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> m <span class="op">&gt;=</span> x <span class="ot">-&gt;</span> <span class="dt">Zipper</span> x ts (<span class="dt">Cons</span> (<span class="dt">Even</span> xs))</span>
<span id="cb41-18"><a href="#cb41-18" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">-&gt;</span></span>
<span id="cb41-19"><a href="#cb41-19" aria-hidden="true" tabindex="-1"></a>                  <span class="dt">Zipper</span> m ts</span>
<span id="cb41-20"><a href="#cb41-20" aria-hidden="true" tabindex="-1"></a>                      (<span class="kw">case</span> hs <span class="kw">of</span></span>
<span id="cb41-21"><a href="#cb41-21" aria-hidden="true" tabindex="-1"></a>                           <span class="dt">Empty</span> <span class="ot">-&gt;</span> gcastWith (lemma1 <span class="op">@</span>y <span class="op">@</span>ys <span class="dt">Refl</span>)</span>
<span id="cb41-22"><a href="#cb41-22" aria-hidden="true" tabindex="-1"></a>                               <span class="dt">Cons</span> (<span class="dt">Even</span> (<span class="dt">Odd</span> (mergeTree c t&#39;) <span class="dt">Empty</span>))</span>
<span id="cb41-23"><a href="#cb41-23" aria-hidden="true" tabindex="-1"></a>                           <span class="dt">Cons</span> hs&#39; <span class="ot">-&gt;</span> gcastWith (lemma2 <span class="op">@</span>y <span class="op">@</span>ys <span class="dt">Refl</span>)</span>
<span id="cb41-24"><a href="#cb41-24" aria-hidden="true" tabindex="-1"></a>                               <span class="dt">Cons</span> (<span class="dt">Even</span> (carryOneNest (mergeTree c t&#39;) hs&#39;)))</span></code></pre></div>
<p>And writing in the templates for our lemmas:</p>
<div class="sourceCode" id="cb42"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lemma1 ::</span> <span class="kw">forall</span> x xs<span class="op">.</span> <span class="dt">Decr</span> x xs <span class="op">:~:</span> &#39;[] <span class="ot">-&gt;</span> x <span class="op">:</span> xs <span class="op">:~:</span> <span class="dt">Z</span> <span class="op">:</span> &#39;[]</span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a>lemma1 <span class="ot">=</span> _</span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a><span class="ot">lemma2 ::</span> <span class="kw">forall</span> x xs y ys<span class="op">.</span> <span class="dt">Decr</span> x xs <span class="op">:~:</span> y <span class="op">:</span> ys <span class="ot">-&gt;</span> x <span class="op">:</span> xs <span class="op">:~:</span> <span class="dt">Inc</span> (y <span class="op">:</span> ys)</span>
<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a>lemma2 <span class="ot">=</span> _</span></code></pre></div>
<p>We now need to provide the <em>implementations</em> for
<code>lemma1</code> and <code>lemma2</code>. With this approach, even if
we fail to do the next steps, we can cop out here and sub in
<code>unsafeCoerce Refl</code> in place of the two proofs, maintaining
the efficiency. We won’t need to, though!</p>
<p>Unlike in Agda, the types for those proofs won’t be around at
runtime, so we won’t have anything to pattern match on. We’ll need to
look for things in the surrounding area which could act like singletons
for the lemmas.</p>
<p>It turns out that the <code>xs</code> and <code>hs'</code> floating
around can do exactly that: they tell us about the type-level
<code>y</code> and <code>x</code>. So we just pass them to the lemmas
(where they’re needed). This changes the last 4 lines of
<code>minView</code> to:</p>
<div class="sourceCode" id="cb43"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Empty</span> <span class="ot">-&gt;</span> gcastWith (lemma1 <span class="dt">Refl</span> xs)</span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Cons</span> (<span class="dt">Even</span> (<span class="dt">Odd</span> (mergeTree c t&#39;) <span class="dt">Empty</span>))</span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Cons</span> hs&#39; <span class="ot">-&gt;</span> gcastWith (lemma2 <span class="dt">Refl</span> xs hs&#39;)</span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Cons</span> (<span class="dt">Even</span> (carryOneNest (mergeTree c t&#39;) hs&#39;))</span></code></pre></div>
<p>Now, we just have to fill in the lemmas! If we were lucky, they’d
actually be constant-time.</p>
<div class="sourceCode" id="cb44"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lemma1 ::</span> <span class="kw">forall</span> x xs n a<span class="op">.</span> <span class="dt">Decr</span> x xs <span class="op">:~:</span> &#39;[]</span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span>  <span class="dt">Nest</span> n x xs a</span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> x <span class="op">:</span> xs <span class="op">:~:</span> <span class="dt">Z</span> <span class="op">:</span> &#39;[]</span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a>lemma1 <span class="dt">Refl</span> (<span class="dt">Odd</span> _ <span class="dt">Empty</span>) <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a><span class="ot">lemma2 ::</span> <span class="kw">forall</span> x xs y ys n a<span class="op">.</span></span>
<span id="cb44-7"><a href="#cb44-7" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Decr</span> x xs <span class="op">:~:</span> y <span class="op">:</span> ys</span>
<span id="cb44-8"><a href="#cb44-8" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Nest</span> n x xs a</span>
<span id="cb44-9"><a href="#cb44-9" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Nest</span> n y ys a</span>
<span id="cb44-10"><a href="#cb44-10" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> x <span class="op">:</span> xs <span class="op">:~:</span> <span class="dt">Inc</span> (y <span class="op">:</span> ys)</span>
<span id="cb44-11"><a href="#cb44-11" aria-hidden="true" tabindex="-1"></a>lemma2 <span class="dt">Refl</span> (<span class="dt">Even</span> (<span class="dt">Odd</span> _ <span class="dt">Empty</span>)) (<span class="dt">Odd</span> _ <span class="dt">Empty</span>) <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb44-12"><a href="#cb44-12" aria-hidden="true" tabindex="-1"></a>lemma2 <span class="dt">Refl</span> (<span class="dt">Odd</span> _ (<span class="dt">Cons</span> _)) (<span class="dt">Even</span> _) <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb44-13"><a href="#cb44-13" aria-hidden="true" tabindex="-1"></a>lemma2 <span class="dt">Refl</span> (<span class="dt">Even</span> xs) (<span class="dt">Odd</span> _ (<span class="dt">Cons</span> ys)) <span class="ot">=</span></span>
<span id="cb44-14"><a href="#cb44-14" aria-hidden="true" tabindex="-1"></a>  gcastWith (lemma2 <span class="dt">Refl</span> xs ys) <span class="dt">Refl</span></span></code></pre></div>
<p>If they <em>had</em> been constant-time, that would have let us throw
them out: each proof would essentially show you what cases needed to be
scrutinized to satisfy the typechecker. You then just scrutinize those
cases in the actual function, and it should all typecheck.</p>
<p>As it is, <code>lemma2</code> is actually ok. It does cost
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log n)</annotation></semantics></math>,
but so does <code>carryOneNest</code>: we’ve maintained the complexity!
We <em>could</em> stop here, satisfied.</p>
<p>There’s another option, though, one that I picked up from Stephanie
Weirich’s talk <span class="citation"
data-cites="weirich_dependent_2017">(<a
href="#ref-weirich_dependent_2017"
role="doc-biblioref">2017</a>)</span>: you thread the requirement
through the function as an equality constraint. It won’t always work,
but when your function’s call graph matches that of the proof, the
constraint will indeed be satisfied, with no runtime cost. In this case,
we can whittle down the proof obligation to the following:</p>
<div class="sourceCode" id="cb45"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Inc</span> (<span class="dt">Decr</span> x xs) <span class="op">~</span> (x <span class="op">:</span> xs)</span></code></pre></div>
<p>Now we change the recursive <code>go</code> into continuation-passing
style, and add that constraint to its signature, and everything
works!</p>
<div class="sourceCode" id="cb46"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="ot">minView ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Binomial</span> n (x <span class="op">:</span> xs) a <span class="ot">-&gt;</span> (a, <span class="dt">Binomial</span> n (<span class="dt">Decr</span> x xs) a)</span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a>minView (<span class="dt">Cons</span> xs&#39;) <span class="ot">=</span> go xs&#39; \(<span class="dt">Zipper</span> x _ xs) <span class="ot">-&gt;</span> (x,xs)</span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="dt">Ord</span> a</span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> <span class="dt">Nest</span> n x xs a</span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> (<span class="dt">Inc</span> (<span class="dt">Decr</span> x xs) <span class="op">~</span> (x <span class="op">:</span> xs) <span class="ot">=&gt;</span> <span class="dt">Zipper</span> a n (<span class="dt">Decr</span> x xs) <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b</span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Even</span> xs) k <span class="ot">=</span> go xs \(<span class="dt">Zipper</span> m (t <span class="op">:&lt;</span> ts) hs) <span class="ot">-&gt;</span> k (<span class="dt">Zipper</span> m ts (<span class="dt">Cons</span> (<span class="dt">Odd</span> t hs)))</span>
<span id="cb46-8"><a href="#cb46-8" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> (<span class="dt">Root</span> x ts) <span class="dt">Empty</span>) k <span class="ot">=</span> k (<span class="dt">Zipper</span> x ts <span class="dt">Empty</span>)</span>
<span id="cb46-9"><a href="#cb46-9" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Odd</span> c<span class="op">@</span>(<span class="dt">Root</span> x cs) (<span class="dt">Cons</span> xs)) k <span class="ot">=</span></span>
<span id="cb46-10"><a href="#cb46-10" aria-hidden="true" tabindex="-1"></a>        go xs</span>
<span id="cb46-11"><a href="#cb46-11" aria-hidden="true" tabindex="-1"></a>            \<span class="kw">case</span></span>
<span id="cb46-12"><a href="#cb46-12" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Zipper</span> m _ _ <span class="op">|</span> m <span class="op">&gt;=</span> x <span class="ot">-&gt;</span></span>
<span id="cb46-13"><a href="#cb46-13" aria-hidden="true" tabindex="-1"></a>                    k (<span class="dt">Zipper</span> x cs (<span class="dt">Cons</span> (<span class="dt">Even</span> xs)))</span>
<span id="cb46-14"><a href="#cb46-14" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Zipper</span> m (t <span class="op">:&lt;</span> ts) <span class="dt">Empty</span> <span class="ot">-&gt;</span></span>
<span id="cb46-15"><a href="#cb46-15" aria-hidden="true" tabindex="-1"></a>                    k (<span class="dt">Zipper</span> m ts (<span class="dt">Cons</span> (<span class="dt">Even</span> (<span class="dt">Odd</span> (mergeTree c t) <span class="dt">Empty</span>))))</span>
<span id="cb46-16"><a href="#cb46-16" aria-hidden="true" tabindex="-1"></a>                <span class="dt">Zipper</span> m (t <span class="op">:&lt;</span> ts) (<span class="dt">Cons</span> hs) <span class="ot">-&gt;</span></span>
<span id="cb46-17"><a href="#cb46-17" aria-hidden="true" tabindex="-1"></a>                    k (<span class="dt">Zipper</span> m ts (<span class="dt">Cons</span> (<span class="dt">Even</span> (carryOneNest (mergeTree c t) hs))))</span></code></pre></div>
<h1 id="conclusion">Conclusion</h1>
<p>As I mentioned in the beginning, a huge amount of this stuff is
<em>much</em> easier using other systems. On top of that, there’s
currently a lot of work being done on dependent type erasure, so that
proofs like the above don’t even exist at runtime. In other words,
there’s a chance that all of these techniques will soon be useless!</p>
<p>Efficient proof-carrying code makes for an interesting puzzle,
though, even if it is a bit of a hair shirt.</p>
<h1 id="code">Code</h1>
<p>Fuller implementations of the structures here are in <a
href="https://github.com/oisdk/pure-arrays">this</a> git repository.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-bakst_liquidhaskell_2018" class="csl-entry"
role="listitem">
Bakst, Alexander, Ranjit Jhala, Ming Kawaguchi, Patrick Rondon, Eric
Seidel, Michael Smith, Anish Tondwalkar, Chris Tetreault, and Niki
Vazou. 2018. <span>“<span>LiquidHaskell</span>: <span>Liquid Types For
Haskell</span>.”</span> ucsd-progsys. <a
href="https://github.com/ucsd-progsys/liquidhaskell">https://github.com/ucsd-progsys/liquidhaskell</a>.
</div>
<div id="ref-ben-amram_pointers_1992" class="csl-entry" role="listitem">
Ben-Amram, Amir M., and Zvi Galil. 1992. <span>“On <span>Pointers Versus
Addresses</span>.”</span> <em>J. ACM</em> 39 (3) (July): 617–648. doi:<a
href="https://doi.org/10.1145/146637.146666">10.1145/146637.146666</a>.
<a
href="http://doi.acm.org/10.1145/146637.146666">http://doi.acm.org/10.1145/146637.146666</a>.
</div>
<div id="ref-breitner_ready_2018-1" class="csl-entry" role="listitem">
Breitner, Joachim, Antal Spector-Zabusky, Yao Li, Christine Rizkallah,
John Wiegley, and Stephanie Weirich. 2018. <span>“Ready,
<span>Set</span>, <span>Verify</span>! <span>Applying Hs</span>-to-coq
to <span>Real</span>-world <span>Haskell Code</span> (<span>Experience
Report</span>).”</span> <em>Proc. ACM Program. Lang.</em> 2 (ICFP)
(July): 89:1–89:16. doi:<a
href="https://doi.org/10.1145/3236784">10.1145/3236784</a>. <a
href="http://doi.acm.org/10.1145/3236784">http://doi.acm.org/10.1145/3236784</a>.
</div>
<div id="ref-hinze_numerical_1998" class="csl-entry" role="listitem">
Hinze, Ralf. 1998. <em>Numerical <span>Representations</span> as
<span>Higher</span>-<span>Order Nested Datatypes</span></em>.
<span>Institut für Informatik III, Universität Bonn</span>. <a
href="http://www.cs.ox.ac.uk/ralf.hinze/publications/\#R5">http://www.cs.ox.ac.uk/ralf.hinze/publications/\#R5</a>.
</div>
<div id="ref-hinze_perfect_1999" class="csl-entry" role="listitem">
———. 1999. <em>Perfect <span>Trees</span> and <span>Bit</span>-reversal
<span>Permutations</span></em>.
</div>
<div id="ref-komuves_nested-sequence_2016" class="csl-entry"
role="listitem">
Komuves, Balazs, and Peter Divianszky. 2016. <span>“Nested-sequence:
<span>List</span>-like data structures with <span>O</span>(log(n))
random access.”</span> <a
href="http://hackage.haskell.org/package/nested-sequence">http://hackage.haskell.org/package/nested-sequence</a>.
</div>
<div id="ref-mcbride_how_2014" class="csl-entry" role="listitem">
McBride, Conor Thomas. 2014. <span>“How to <span>Keep Your
Neighbours</span> in <span>Order</span>.”</span> In <em>Proceedings of
the 19th <span>ACM SIGPLAN International Conference</span> on
<span>Functional Programming</span></em>, 297–309. <span>ICFP</span>
’14. New York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2628136.2628163">10.1145/2628136.2628163</a>.
<a
href="https://personal.cis.strath.ac.uk/conor.mcbride/pub/Pivotal.pdf">https://personal.cis.strath.ac.uk/conor.mcbride/pub/Pivotal.pdf</a>.
</div>
<div id="ref-might_missing_2015" class="csl-entry" role="listitem">
Might, Matthew. 2015. <span>“Missing method: <span>How</span> to delete
from <span>Okasaki</span>’s red-black trees.”</span>
<em>matt.might.net</em>. <a
href="http://matt.might.net/articles/red-black-delete/">http://matt.might.net/articles/red-black-delete/</a>.
</div>
<div id="ref-okasaki_fast_1999" class="csl-entry" role="listitem">
Okasaki, Chris. 1999a. <span>“From <span>Fast Exponentiation</span> to
<span>Square Matrices</span>: <span>An Adventure</span> in
<span>Types</span>.”</span> In <em>Proceedings of the <span>ACM SIGPLAN
International Conference</span> on <span>Functional Programming</span>
(<span>ICFP</span>’99), <span>Paris</span>, <span>France</span>,
<span>September</span> 27-29, 1999</em>, 34:28. <span>ACM</span>. <a
href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.456.357\&amp;rep=rep1\&amp;type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.456.357\&amp;rep=rep1\&amp;type=pdf</a>.
</div>
<div id="ref-okasaki_purely_1999" class="csl-entry" role="listitem">
———. 1999b. <em>Purely <span>Functional Data Structures</span></em>.
<span>Cambridge University Press</span>.
</div>
<div id="ref-weirich_depending_2014" class="csl-entry" role="listitem">
Weirich, Stephanie. 2014. <span>“Depending on
<span>Types</span>.”</span> In <em>Proceedings of the 19th <span>ACM
SIGPLAN International Conference</span> on <span>Functional
Programming</span></em>, 241–241. <span>ICFP</span> ’14. New York, NY,
USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2628136.2631168">10.1145/2628136.2631168</a>.
<a
href="https://www.cis.upenn.edu/~sweirich/talks/icfp14.pdf">https://www.cis.upenn.edu/~sweirich/talks/icfp14.pdf</a>.
</div>
<div id="ref-weirich_dependent_2017" class="csl-entry" role="listitem">
———. 2017. <span>“Dependent <span>Types</span> in
<span>Haskell</span>.”</span> St. Louis, MO, USA. <a
href="https://www.youtube.com/watch?v=wNa3MMbhwS4">https://www.youtube.com/watch?v=wNa3MMbhwS4</a>.
</div>
</div>
]]></description>
    <pubDate>Tue, 20 Nov 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-11-20-fast-verified-structures.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Very Simple Prime Sieve in Haskell</title>
    <link>https://doisinkidney.com/posts/2018-11-10-a-very-simple-prime-sieve.html</link>
    <description><![CDATA[<div class="info">
    Posted on November 10, 2018
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Prime%20Sieves.html">2-part series on Prime Sieves</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>A few days ago, the <a
href="https://www.youtube.com/user/Computerphile">Computerphile YouTube
channel</a> put up a video about infinite lists in Haskell <span
class="citation" data-cites="haran_infinity_2018">(<a
href="#ref-haran_infinity_2018" role="doc-biblioref">Haran
2018</a>)</span>. It’s pretty basic, but finishes up with a definition
of an infinite list of prime numbers. The definition was something like
this:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">=</span> sieve [<span class="dv">2</span><span class="op">..</span>]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>sieve (p<span class="op">:</span>ps) <span class="ot">=</span> p <span class="op">:</span> sieve [ x <span class="op">|</span> x <span class="ot">&lt;-</span> ps, <span class="fu">mod</span> x p <span class="op">/=</span> <span class="dv">0</span> ]</span></code></pre></div>
<p>This really demonstrates the elegance of list comprehensions coupled
with lazy evaluation. If we’re being totally pedantic, however, this
<em>isn’t</em> a genuine <a
href="https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes">sieve of
Eratosthenes</a>. And this makes sense: the “true” sieve of Eratosthenes
<span class="citation" data-cites="oneill_genuine_2009">(<a
href="#ref-oneill_genuine_2009" role="doc-biblioref">O’Neill
2009</a>)</span> is probably too complex to demonstrate in a video meant
to be an introduction to Haskell. This isn’t because Haskell is bad at
this particular problem, mind you: it’s because a lazy, infinite sieve
is something very hard to implement indeed.</p>
<p>Anyway, I’m going to try today to show a very simple prime sieve that
(hopefully) rivals the simplicity of the definition above.</p>
<h1 id="a-first-attempt">A First Attempt</h1>
<p>Visualizations of the sieve of Eratosthenes often rely on metaphors
of “crossing out” on some large table. Once you hit a prime, you cross
off all of its multiples in the rest of the table, and then you move to
the next uncrossed number.</p>
<figure>
<img
src="https://upload.wikimedia.org/wikipedia/commons/0/0b/Sieve_of_Eratosthenes_animation.svg"
alt="Sieve of Eratosthenes Animation. By Ricordisamoa, CC BY-SA 3.0, from Wikimedia Commons" />
<figcaption aria-hidden="true">Sieve of Eratosthenes Animation. By
Ricordisamoa, CC BY-SA 3.0, from Wikimedia Commons</figcaption>
</figure>
<p>Working with a finite array, it should be easy to see that this is
extremely efficient. You’re crossing off every non-prime exactly once,
only using addition and squaring.</p>
<p>To extend it to infinite lists, we will use the following
function:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>[] \\ ys <span class="ot">=</span> []</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>xs \\ [] <span class="ot">=</span> xs</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>(x<span class="op">:</span>xs) \\ (y<span class="op">:</span>ys) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">compare</span> x y <span class="kw">of</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">LT</span> <span class="ot">-&gt;</span> x <span class="op">:</span> xs \\ (y<span class="op">:</span>ys)</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">EQ</span> <span class="ot">-&gt;</span> xs \\ ys</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">GT</span> <span class="ot">-&gt;</span> (x<span class="op">:</span>xs) \\ ys</span></code></pre></div>
<p>We’re “subtracting” the right list from the left. Crucially, it works
with infinite lists:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">take</span> <span class="dv">10</span> ([<span class="dv">1</span><span class="op">..</span>] \\ [<span class="dv">2</span>,<span class="dv">4</span><span class="op">..</span>])</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">5</span>,<span class="dv">7</span>,<span class="dv">9</span>,<span class="dv">11</span>,<span class="dv">13</span>,<span class="dv">15</span>,<span class="dv">17</span>,<span class="dv">19</span>]</span></code></pre></div>
<p>Finally, it only works if both lists are ordered and don’t contain
duplicates, but our sieve does indeed satisfy that requirement. Using
this, we’ve already got a sieve:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>sieve (p<span class="op">:</span>ps) <span class="ot">=</span> p <span class="op">:</span> sieve (ps \\ [p<span class="op">*</span>p, p<span class="op">*</span>p<span class="op">+</span>p<span class="op">..</span>])</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">=</span> <span class="dv">2</span> <span class="op">:</span> sieve [<span class="dv">3</span>,<span class="dv">5</span><span class="op">..</span>]</span></code></pre></div>
<p>No division, just addition and squaring, as promised. Unfortunately,
though, this doesn’t have the time complexity we want. See, in the
<code>(\\)</code> operation, we have to test every entry in the sieve
against the prime factor: when we’re crossing off from an array, we just
jump to the next composite number.</p>
<h1 id="using-a-queue">Using a Queue</h1>
<p>The way we speed up the “crossing-off” section of the algorithms is
by using a priority queue: this was the optimization provided in <span
class="citation" data-cites="oneill_genuine_2009">O’Neill (<a
href="#ref-oneill_genuine_2009" role="doc-biblioref">2009</a>)</span>.
Before we go any further, then, let’s put one together:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Queue</span> a b <span class="ot">=</span> <span class="dt">Queue</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> minKey ::</span> <span class="op">!</span>a</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> minVal ::</span> b</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> rest   ::</span> <span class="dt">List</span> a b</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> a b</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> (<span class="op">:-</span>) <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span>(<span class="dt">Queue</span> a b)</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>           (<span class="dt">List</span> a b)</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;+&gt;) ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Queue</span> a b <span class="ot">-&gt;</span> <span class="dt">Queue</span> a b <span class="ot">-&gt;</span> <span class="dt">Queue</span> a b</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;+&gt;</span>) q1<span class="op">@</span>(<span class="dt">Queue</span> x1 y1 ts1) q2<span class="op">@</span>(<span class="dt">Queue</span> x2 y2 ts2)</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x1 <span class="op">&lt;=</span> x2 <span class="ot">=</span> <span class="dt">Queue</span> x1 y1 (q2 <span class="op">:-</span> ts1)</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Queue</span> x2 y2 (q1 <span class="op">:-</span> ts2)</span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeQs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">List</span> a b <span class="ot">-&gt;</span> <span class="dt">Queue</span> a b</span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a>mergeQs (t <span class="op">:-</span> ts) <span class="ot">=</span> mergeQs1 t ts</span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a>mergeQs <span class="dt">Nil</span>       <span class="ot">=</span> errorWithoutStackTrace <span class="st">&quot;tried to merge empty list&quot;</span></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeQs1 ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Queue</span> a b <span class="ot">-&gt;</span> <span class="dt">List</span> a b <span class="ot">-&gt;</span> <span class="dt">Queue</span> a b</span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true" tabindex="-1"></a>mergeQs1 t1 <span class="dt">Nil</span>              <span class="ot">=</span> t1</span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true" tabindex="-1"></a>mergeQs1 t1 (t2 <span class="op">:-</span> <span class="dt">Nil</span>)      <span class="ot">=</span> t1 <span class="op">&lt;+&gt;</span> t2</span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true" tabindex="-1"></a>mergeQs1 t1 (t2 <span class="op">:-</span> t3 <span class="op">:-</span> ts) <span class="ot">=</span> (t1 <span class="op">&lt;+&gt;</span> t2) <span class="op">&lt;+&gt;</span> mergeQs1 t3 ts</span>
<span id="cb5-27"><a href="#cb5-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-28"><a href="#cb5-28" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Queue</span> a b <span class="ot">-&gt;</span> <span class="dt">Queue</span> a b</span>
<span id="cb5-29"><a href="#cb5-29" aria-hidden="true" tabindex="-1"></a>insert <span class="op">!</span>k <span class="op">!</span>v <span class="ot">=</span> (<span class="op">&lt;+&gt;</span>) (singleton k v)</span>
<span id="cb5-30"><a href="#cb5-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-31"><a href="#cb5-31" aria-hidden="true" tabindex="-1"></a><span class="ot">singleton ::</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Queue</span> a b</span>
<span id="cb5-32"><a href="#cb5-32" aria-hidden="true" tabindex="-1"></a>singleton <span class="op">!</span>k <span class="op">!</span>v <span class="ot">=</span> <span class="dt">Queue</span> k v <span class="dt">Nil</span></span></code></pre></div>
<p>These are pairing heaps: I’m using them here because they’re
relatively simple and very fast. A lot of their speed comes from the
fact that the top-level constructor (<code>Queue</code>) is
<em>non-empty</em>. Since, in this algorithm, we’re only actually going
to be working with non-empty queues, this saves us a pattern match on
pretty much every function. They’re also what’s used in <a
href="https://github.com/haskell/containers/blob/30ccbaa201043109bf1ee905c66ccd0dbe24422f/containers/src/Data/Sequence/Internal/sorting.md">Data.Sequence
for sorting</a>.</p>
<p>With that, we can write our proper sieve:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>insertPrime x xs <span class="ot">=</span> insert (x<span class="op">*</span>x) (<span class="fu">map</span> (<span class="op">*</span>x) xs)</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>adjust x q<span class="op">@</span>(<span class="dt">Queue</span> y (z<span class="op">:</span>zs) qs)</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> y <span class="op">&lt;=</span> x <span class="ot">=</span> adjust x (insert z zs (mergeQs qs))</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> q</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>sieve (x<span class="op">:</span>xs) <span class="ot">=</span> x <span class="op">:</span> sieve&#39; xs (singleton (x<span class="op">*</span>x) (<span class="fu">map</span> (<span class="op">*</span>x) xs))</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>    sieve&#39; (x<span class="op">:</span>xs) table</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> minKey table <span class="op">&lt;=</span> x <span class="ot">=</span> sieve&#39; xs (adjust x table)</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> x <span class="op">:</span> sieve&#39; xs (insertPrime x xs table)</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">=</span> <span class="dv">2</span> <span class="op">:</span> sieve [<span class="dv">3</span>,<span class="dv">5</span><span class="op">..</span>]</span></code></pre></div>
<h1 id="simplifying">Simplifying</h1>
<p>The priority queue stores lists alongside their keys: what you might
notice is that those lists are simply sequences of the type
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">[</mo><mi>x</mi><mo>,</mo><mn>2</mn><mi>x</mi><mo>,</mo><mn>3</mn><mi>x</mi><mo>,</mo><mn>4</mn><mi>x</mi><mi>.</mi><mi>.</mi><mi>.</mi><mo stretchy="false" form="postfix">]</mo></mrow><annotation encoding="application/x-tex">[x, 2x, 3x, 4x...]</annotation></semantics></math>
and so on. Rather than storing the whole list, we can instead store just
the head and the step. This also simplifies (and greatly speeds up) the
expensive <code>map (*x)</code> operation to just <em>two</em>
multiplications. If you wanted, you could just sub in this
representation of streams for all the lists above:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Stepper</span> a <span class="ot">=</span> <span class="dt">Stepper</span> {<span class="ot"> start ::</span> a,<span class="ot"> step ::</span> a }</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ot">nextStep ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Stepper</span> a <span class="ot">-&gt;</span> (a, <span class="dt">Stepper</span> a)</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>nextStep (<span class="dt">Stepper</span> x y) <span class="ot">=</span> (x, <span class="dt">Stepper</span> (x<span class="op">+</span>y) y)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> x <span class="op">:-</span> xs <span class="ot">&lt;-</span> (nextStep <span class="ot">-&gt;</span> (x,xs))</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="ot">(^*) ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Stepper</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Stepper</span> a</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="dt">Stepper</span> x y <span class="op">^*</span> f <span class="ot">=</span> <span class="dt">Stepper</span> (x <span class="op">*</span> f) (y <span class="op">*</span> f)</span></code></pre></div>
<p>If you were so inclined, you could even make it conform to
<code>Foldable</code>:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Stepper</span> a <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Stepper</span><span class="ot"> ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Stepper</span> a</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>nextStep (<span class="dt">Stepper</span> x y) <span class="ot">=</span> (x, <span class="dt">Stepper</span> (x<span class="op">+</span>y) y)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> x <span class="op">:-</span> xs <span class="ot">&lt;-</span> (nextStep <span class="ot">-&gt;</span> (x,xs))</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Foldable</span> <span class="dt">Stepper</span> <span class="kw">where</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">foldr</span> f b (x <span class="op">:-</span> xs) <span class="ot">=</span> f x (<span class="fu">foldr</span> f b xs)</span></code></pre></div>
<p>But that’s overkill for what we need here.</p>
<p>Second observation is that if we remove the wheel (from 2), the
“start” is simply the <em>key</em> in the priority queue, again cutting
down on space.</p>
<p>Finally, we get the implementation:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>primes <span class="ot">=</span> <span class="dv">2</span> <span class="op">:</span> sieve <span class="dv">3</span> (singleton <span class="dv">4</span> <span class="dv">2</span>)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    adjust <span class="op">!</span>x q<span class="op">@</span>(<span class="dt">Queue</span> y z qs)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> x <span class="op">&lt;</span> y <span class="ot">=</span> q</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> adjust x (mergeQs1 (singleton (y <span class="op">+</span> z) z) qs)</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    sieve <span class="op">!</span>x q</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> x <span class="op">&lt;</span> minKey q <span class="ot">=</span> x <span class="op">:</span> sieve (x <span class="op">+</span> <span class="dv">1</span>) (insert (x <span class="op">*</span> x) x q)</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> sieve (x <span class="op">+</span> <span class="dv">1</span>) (adjust x q)</span></code></pre></div>
<p>8 lines for a lazy prime sieve isn’t bad!</p>
<p>I haven’t tried a huge amount to optimize the function, but it might
be worth looking in to how to add back the wheels. I noticed that for no
wheels, the queue contains only two elements per key; for one (the 2
wheel), we needed 3. I wonder if this pattern continues: possibly we
could represent wheels as finite lists at each key in the queue. Maybe
in a later post.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-haran_infinity_2018" class="csl-entry" role="listitem">
Haran, Brady. 2018. <span>“To <span>Infinity</span> &amp;
<span>Beyond</span> - <span>Computerphile</span>.”</span> <a
href="https://www.youtube.com/watch?v=bnRNiE_OVWA&amp;feature=youtu.be"
class="uri">https://www.youtube.com/watch?v=bnRNiE_OVWA&amp;feature=youtu.be</a>.
</div>
<div id="ref-oneill_genuine_2009" class="csl-entry" role="listitem">
O’Neill, Melissa E. 2009. <span>“The <span>Genuine Sieve</span> of
<span>Eratosthenes</span>.”</span> <em>Journal of Functional
Programming</em> 19 (01) (January): 95. doi:<a
href="https://doi.org/10.1017/S0956796808007004">10.1017/S0956796808007004</a>.
</div>
</div>
]]></description>
    <pubDate>Sat, 10 Nov 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-11-10-a-very-simple-prime-sieve.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Total Combinations</title>
    <link>https://doisinkidney.com/posts/2018-10-16-total-combinations.html</link>
    <description><![CDATA[<div class="info">
    Posted on October 16, 2018
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Total%20Combinatorics.html">1-part series on Total Combinatorics</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>, <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Here’s a quick puzzle: from a finite alphabet, produce an infinite
list of infinite strings, each of them unique.</p>
<p>It’s not a super hard problem, but here are some examples of what you
might get. Given the alphabet of <code>0</code> and <code>1</code>, for
instance, you could produce the following:</p>
<pre><code>0000000...
1000000...
0100000...
1100000...
0010000...
1010000...
0110000...
1110000...
0001000...</code></pre>
<p>In other words, the enumeration of the binary numbers
(least-significant-digit first). We’ll just deal with bits first:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Bit</span> <span class="ot">=</span> <span class="dt">O</span> <span class="op">|</span> <span class="dt">I</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> <span class="dt">Bit</span> <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">showsPrec</span> _ <span class="dt">O</span> <span class="ot">=</span> (<span class="op">:</span>) <span class="ch">&#39;0&#39;</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">showsPrec</span> _ <span class="dt">I</span> <span class="ot">=</span> (<span class="op">:</span>) <span class="ch">&#39;1&#39;</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">showList</span> xs s <span class="ot">=</span> <span class="fu">foldr</span> f s xs</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>        f <span class="dt">O</span> a <span class="ot">=</span> <span class="ch">&#39;0&#39;</span> <span class="op">:</span> a</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>        f <span class="dt">I</span> a <span class="ot">=</span> <span class="ch">&#39;1&#39;</span> <span class="op">:</span> a</span></code></pre></div>
<p>Thinking recursively, we can see that the tail of each list is
actually the original sequence, doubled-up:</p>
<p><code class="sourceCode"> 0<span class="er">000000</span>... <br/>
1<span class="er">000000</span>... <br/> 0<span
class="er">100000</span>... <br/> 1<span class="er">100000</span>...
<br/> 0<span class="er">010000</span>... <br/> 1<span
class="er">010000</span>... <br/> 0<span class="er">110000</span>...
<br/> 1<span class="er">110000</span>... <br/> 0<span
class="er">001000</span>... <br/> </code></p>
<p>As it happens, we get something like this pattern with the monad
instance for lists <em>anyway</em>:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (,) <span class="op">&lt;$&gt;</span> [<span class="dt">O</span>,<span class="dt">I</span>] <span class="op">&lt;*&gt;</span> <span class="st">&quot;abc&quot;</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">0</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">0</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">0</span>,<span class="ch">&#39;c&#39;</span>),(<span class="dv">1</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">1</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">1</span>,<span class="ch">&#39;c&#39;</span>)]</span></code></pre></div>
<p>Well, actually it’s the wrong way around. We want to loop through the
<em>first</em> list the quickest, incrementing the second slower. No
worries, we can just use a flipped version of
<code>&lt;*&gt;</code>:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">4</span> <span class="op">&lt;&lt;&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;&lt;&gt;) ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>fs <span class="op">&lt;&lt;&gt;</span> xs <span class="ot">=</span> <span class="fu">flip</span> (<span class="op">$</span>) <span class="op">&lt;$&gt;</span> xs <span class="op">&lt;*&gt;</span> fs</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (,) <span class="op">&lt;$&gt;</span> [<span class="dt">O</span>,<span class="dt">I</span>] <span class="op">&lt;&lt;&gt;</span> <span class="st">&quot;abc&quot;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">0</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">1</span>,<span class="ch">&#39;a&#39;</span>),(<span class="dv">0</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">1</span>,<span class="ch">&#39;b&#39;</span>),(<span class="dv">0</span>,<span class="ch">&#39;c&#39;</span>),(<span class="dv">1</span>,<span class="ch">&#39;c&#39;</span>)]</span></code></pre></div>
<p>Brilliant! So we can write our function now, yes?</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>bins <span class="ot">=</span> (<span class="op">:</span>) <span class="op">&lt;$&gt;</span> [<span class="dt">O</span>,<span class="dt">I</span>] <span class="op">&lt;&lt;&gt;</span> bins</span></code></pre></div>
<p>Nope! That won’t ever produce an answer, unfortunately.</p>
<h1 id="productivity">Productivity</h1>
<p>The issue with our definition above is that it’s not lazy enough: it
demands information that it hasn’t produced yet, so it gets caught in an
infinite loop before it can do anything!</p>
<p>We need to kick-start it a little, so it can produce output
<em>before</em> it asks itself for more. Because we know what the first
line is going to be, we can just tell it that:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>bins <span class="ot">=</span> (<span class="op">:</span>) <span class="op">&lt;$&gt;</span> [<span class="dt">O</span>,<span class="dt">I</span>] <span class="op">&lt;&lt;&gt;</span> (<span class="fu">repeat</span> <span class="dt">O</span> <span class="op">:</span> <span class="fu">tail</span> bins)</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">mapM_</span> <span class="fu">print</span> (<span class="fu">take</span> <span class="dv">8</span> (<span class="fu">map</span> (<span class="fu">take</span> <span class="dv">3</span>) bins))</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="dv">000</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="dv">100</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="dv">010</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="dv">110</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="dv">001</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="dv">101</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="dv">011</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="dv">111</span></span></code></pre></div>
<p>The property that this function has that the previous didn’t is
<em>productivity</em>: the dual of termination. See, we want to avoid a
<em>kind</em> of infinite loops in <code>bins</code>, but we don’t want
to avoid infinite things altogether: the list it produces is meant to be
infinite, for goodness’ sake. Instead, what it needs to do is produce
every new value in <em>finite</em> time.</p>
<h1 id="checking-productivity">Checking Productivity</h1>
<p>In total languages, like Agda, termination checking is a must. To
express computation like that above, though, you often also want a
<em>productivity</em> checker. Agda can do that, too.</p>
<p>Let’s get started then. First, a stream:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="ot">_</span>◂<span class="ot">_</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Stream <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">coinductive</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>◂<span class="ot">_</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    head <span class="ot">:</span> A</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    tail <span class="ot">:</span> Stream A</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> Stream</span></code></pre></div>
<p>In Haskell, there was no need to define a separate stream type: the
type of lists contains both finite and infinite lists.</p>
<p>Agda can get a little more specific: here, we’ve used the
<code>coinductive</code> keyword, which means we’re free to create
infinite <code>Stream</code>s. Rather than the usual termination
checking (which would kick in when we consume a recursive, inductive
type), we now get productivity checking: when creating a
<code>Stream</code>, the <code>tail</code> must always be available in
finite time. For a finite type, we’d have used the
<code>inductive</code> keyword instead; this wouldn’t be much use,
though, since there’s no way to create a finite <code>Stream</code>
without a nil constructor!<a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<p>One of the interesting things about working with infinite data (when
you’re forced to notice that it’s infinite, as you are in Agda) is that
<em>everything</em> gets flipped. So you have to prove productivity, not
totality; you use product types, rather than sums; and to define
functions, you use <em>co</em>patterns, rather than patterns.</p>
<h1 id="copatterns">Copatterns</h1>
<p>Copatterns are a handy syntactic construct for writing functions
about record types. Let’s start with an example, and then I’ll try
explain a little:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>pure <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> A <span class="ot">→</span> Stream A</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>pure x<span class="ot">)</span> <span class="ot">=</span> x</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>pure x<span class="ot">)</span> <span class="ot">=</span> pure x</span></code></pre></div>
<p>Here, we’re defining <code>pure</code> on streams:
<code>pure x</code> produces an infinite stream of <code>x</code>. Its
equivalent would be repeat in Haskell:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">repeat</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="fu">repeat</span> x <span class="ot">=</span> x <span class="op">:</span> <span class="fu">repeat</span> x</span></code></pre></div>
<p>Except instead of describing what it <em>is</em>, you describe how it
<em>acts</em> (it’s kind of an intensional vs. extensional thing). In
other words, if you want to make a stream <code>xs</code>, you have to
answer the questions “what’s the head of <code>xs</code>?” and “what’s
the tail of <code>xs</code>?”</p>
<p>Contrast this with pattern-matching: we’re producing (rather than
consuming) a value, and in pattern matching, you have to answer a
question for each <em>case</em>. If you want to consume a list
<code>xs</code>, you have to answer the questions “what do you do when
it’s nil?” and “what do you do when it’s cons?”</p>
<p>Anyway, I think the symmetry is kind of cool. Let’s get back to
writing our functions.</p>
<h1 id="sized-types">Sized Types</h1>
<p>Unfortunately, we don’t have enough to prove productivity yet. As an
explanation why, let’s first try produce the famous <code>fibs</code>
list. Written here in Haskell:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>fibs <span class="ot">=</span> <span class="dv">0</span> <span class="op">:</span> <span class="dv">1</span> <span class="op">:</span> <span class="fu">zipWith</span> (<span class="op">+</span>) fibs (<span class="fu">tail</span> fibs)</span></code></pre></div>
<p>Instead of <code>zipWith</code>, let’s define <code>&lt;*&gt;</code>.
That will let us use <a
href="https://agda.readthedocs.io/en/v2.5.4.1/language/syntactic-sugar.html#idiom-brackets">idiom
brackets</a>.</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;*&gt;<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a b<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">{</span>B <span class="ot">:</span> <span class="dt">Set</span> b<span class="ot">}</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> Stream <span class="ot">(</span>A <span class="ot">→</span> B<span class="ot">)</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> Stream A</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> Stream B</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>fs &lt;*&gt; xs<span class="ot">)</span> <span class="ot">=</span> head fs <span class="ot">(</span>head xs<span class="ot">)</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>fs &lt;*&gt; xs<span class="ot">)</span> <span class="ot">=</span> tail fs &lt;*&gt; tail xs</span></code></pre></div>
<p>And here’s <code>fibs</code>:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>fibs <span class="ot">:</span> Stream ℕ</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>head fibs <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>tail fibs<span class="ot">)</span> <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>tail fibs<span class="ot">)</span> <span class="ot">=</span> ⦇ fibs + tail fibs ⦈</span></code></pre></div>
<p>But it doesn’t pass the productivity checker! Because we use a
higher-order function (<code>&lt;*&gt;</code>), Agda won’t look at how
much it dips into the infinite supply of values. This is a problem: we
need it to know that <code>&lt;*&gt;</code> only needs the heads of its
arguments to produce a head, and so on. The solution? Encode this
information in the types.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="ot">_</span>◂<span class="ot">_</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="kw">record</span> Stream <span class="ot">{</span>i <span class="ot">:</span> Size<span class="ot">}</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">(</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">)</span> <span class="ot">:</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">coinductive</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">constructor</span> <span class="ot">_</span>◂<span class="ot">_</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">field</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    head <span class="ot">:</span> A</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    tail <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>j <span class="ot">:</span> Size&lt; i<span class="ot">}</span> <span class="ot">→</span> Stream <span class="ot">{</span>j<span class="ot">}</span> A</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a><span class="kw">open</span> Stream</span></code></pre></div>
<p>Now, <code>Stream</code> has an implicit <em>size</em> parameter.
Basically, <code>Stream {i} A</code> can produce <code>i</code> more
values. So <code>cons</code>, then, gives a stream one extra value to
produce:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>cons <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> A <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> A <span class="ot">→</span> Stream <span class="ot">{</span>↑ i<span class="ot">}</span> A</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>cons x xs<span class="ot">)</span> <span class="ot">=</span> x</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>cons x xs<span class="ot">)</span> <span class="ot">=</span> xs</span></code></pre></div>
<p>Conversely, we can write a different definition of <code>tail</code>
that consumes one value<a href="#fn2" class="footnote-ref" id="fnref2"
role="doc-noteref"><sup>2</sup></a>:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>tail′ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> Stream <span class="ot">{</span>↑ i<span class="ot">}</span> A <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> A</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>tail′ <span class="ot">{</span>i<span class="ot">}</span> xs <span class="ot">=</span> tail xs <span class="ot">{</span>i<span class="ot">}</span></span></code></pre></div>
<p>For <code>&lt;*&gt;</code>, we want to show that its result can
produce just as much values as its inputs can:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>&lt;*&gt;<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i a b<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">{</span>B <span class="ot">:</span> <span class="dt">Set</span> b<span class="ot">}</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">(</span>A <span class="ot">→</span> B<span class="ot">)</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> A</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> B</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>fs &lt;*&gt; xs<span class="ot">)</span> <span class="ot">=</span> head fs <span class="ot">(</span>head xs<span class="ot">)</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>fs &lt;*&gt; xs<span class="ot">)</span> <span class="ot">=</span> tail fs &lt;*&gt; tail xs</span></code></pre></div>
<p>How does this help the termination/productivity checker? Well, for
terminating functions, we have to keep giving the <code>tail</code>
field smaller and smaller sizes, meaning that we’ll eventually hit zero
(and terminate). For productivity, we now have a way to talk about
“definedness” in types, so we can make sure that a recursive call
doesn’t dip into a supply it hasn’t produced yet.</p>
<p>One more thing: <code>Size</code> types have strange typing rules,
mainly for ergonomic purposes (this is why we’re not just using an
<code>ℕ</code> parameter). One of them is that if you don’t specify the
size, it’s defaulted to <code>∞</code>, so functions written without
size annotations don’t have to be changed with this new definition:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>pure <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> A <span class="ot">→</span> Stream A</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>pure x<span class="ot">)</span> <span class="ot">=</span> x</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>pure x<span class="ot">)</span> <span class="ot">=</span> pure x</span></code></pre></div>
<p>Finally <code>fibs</code>:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>fibs <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> ℕ</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>head fibs <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>tail fibs<span class="ot">)</span> <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>tail fibs<span class="ot">)</span> <span class="ot">=</span> ⦇ fibs + tail fibs ⦈</span></code></pre></div>
<h1 id="bugs">Bugs!</h1>
<p>Before I show the Agda solution, I’d like to point out some bugs that
were revealed in the Haskell version by trying to implement it totally.
First of all, the function signature. “Takes an alphabet and produces
unique strings” seems like this:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">strings ::</span> [a] <span class="ot">-&gt;</span> [[a]]</span></code></pre></div>
<p>But what should you produce in this case:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>strings []</span></code></pre></div>
<p>So it must be a non-empty list, giving us the following type and
definition:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">strings ::</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>strings (x <span class="op">:|</span> xs) <span class="ot">=</span> (<span class="op">:</span>) <span class="op">&lt;$&gt;</span> (x<span class="op">:</span>xs) <span class="op">&lt;&lt;&gt;</span> (<span class="fu">repeat</span> x <span class="op">:</span> <span class="fu">tail</span> (strings (x <span class="op">:|</span> xs)))</span></code></pre></div>
<p>But this has a bug too! What happens if we pass in the following:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>strings (x <span class="op">:|</span> [])</span></code></pre></div>
<p>So this fails the specification: there is only one unique infinite
string from that alphabet (<code>pure x</code>). Interestingly, though,
our implementation above also won’t produce any output beyond the first
element. I suppose, in a way, these things cancel each other out: our
function does indeed produce all of the unique strings, it’s just a pity
that it goes into an infinite loop to do so!</p>
<h1 id="bringing-it-all-together">Bringing it all Together</h1>
<p>Finally, we have our function:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>strings <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> A × A × List A <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">(</span>Stream A<span class="ot">)</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>strings <span class="ot">(</span>x , <span class="ot">_</span> , <span class="ot">_))</span> <span class="ot">=</span> pure x</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>strings <span class="ot">{</span>A <span class="ot">=</span> A<span class="ot">}</span> xs<span class="ot">@(</span>x₁ , x₂ , xt<span class="ot">))</span> <span class="ot">=</span> go x₂ xt <span class="ot">(</span>strings xs<span class="ot">)</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>  go <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">→</span> A <span class="ot">→</span> List A <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">(</span>Stream A<span class="ot">)</span> <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">(</span>Stream A<span class="ot">)</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>  head <span class="ot">(</span>head <span class="ot">(</span>go y ys zs<span class="ot">))</span> <span class="ot">=</span> y</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>  tail <span class="ot">(</span>head <span class="ot">(</span>go y ys zs<span class="ot">))</span> <span class="ot">=</span> head zs</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>  tail <span class="ot">(</span>go <span class="ot">_</span> [] zs<span class="ot">)</span> <span class="ot">=</span> go x₁ <span class="ot">(</span>x₂ ∷ xt<span class="ot">)</span> <span class="ot">(</span>tail zs<span class="ot">)</span></span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>  tail <span class="ot">(</span>go <span class="ot">_</span> <span class="ot">(</span>y ∷ ys<span class="ot">)</span> zs<span class="ot">)</span> <span class="ot">=</span> go y ys zs</span></code></pre></div>
<p>As you can see, we do need to kick-start it without a recursive call
(the first line is <code>pure x</code>). Then, <code>go</code> takes as
a third argument the “tails” argument, and does the kind of backwards
Cartesian product we want. However, since we’re into the second element
of the stream now, we want to avoid repeating what we already said,
which is why we have to give <code>go</code> <code>x₂</code>, rather
than <code>x₁</code>. This is what forces us to take at least two
elements, rather than at least one, also: we can’t just take the tail of
the call to <code>go</code> (this is what we did in the Haskell version
of <code>strings</code> with the <code>NonEmpty</code> list), as the
recursive call to strings then doesn’t decrease in size:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>strings <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> A × List A <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">(</span>Stream A<span class="ot">)</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>head <span class="ot">(</span>strings <span class="ot">(</span>x , <span class="ot">_))</span> <span class="ot">=</span> pure x</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>tail <span class="ot">(</span>strings <span class="ot">{</span>A <span class="ot">=</span> A<span class="ot">}</span> xs<span class="ot">@(</span>x , xt<span class="ot">))</span> <span class="ot">=</span> tail <span class="ot">(</span>go x xt <span class="ot">(</span>strings xs<span class="ot">))</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>  go <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">→</span> A <span class="ot">→</span> List A <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">(</span>Stream A<span class="ot">)</span> <span class="ot">→</span> Stream <span class="ot">{</span>i<span class="ot">}</span> <span class="ot">(</span>Stream A<span class="ot">)</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>  head <span class="ot">(</span>head <span class="ot">(</span>go y ys zs<span class="ot">))</span> <span class="ot">=</span> y</span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  tail <span class="ot">(</span>head <span class="ot">(</span>go y ys zs<span class="ot">))</span> <span class="ot">=</span> head zs</span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>  tail <span class="ot">(</span>go <span class="ot">_</span> [] zs<span class="ot">)</span> <span class="ot">=</span> go x xt <span class="ot">(</span>tail zs<span class="ot">)</span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>  tail <span class="ot">(</span>go <span class="ot">_</span> <span class="ot">(</span>y ∷ ys<span class="ot">)</span> zs<span class="ot">)</span> <span class="ot">=</span> go y ys zs</span></code></pre></div>
<p>Agda will warn about termination on this function. Now, if you slap a
pragma on it, it <em>will</em> produce the correct results for enough
arguments, but give it one and you’ll get an infinite loop, just as you
were warned!</p>
<h1 id="further-work">Further Work</h1>
<p>I’m having a lot of fun with copatterns for various algorithms
(especially combinatorics). I’m planning on working on two particular
tasks with them for the next posts in this series:</p>
<dl>
<dt>Proving <code>strings</code></dt>
<dd>
<p>I’d like to prove that <code>strings</code> does indeed produce a
stream of unique values. Following from that, it would be cool to do a
Cantor diagonalisation on its output.</p>
</dd>
<dt>Permutations</dt>
<dd>
<p>Haskell’s <a
href="http://hackage.haskell.org/package/base-4.12.0.0/docs/src/Data.OldList.html#permutations">permutations
implementation in Data.List</a> does some interesting tricks to make it
as lazy as possible. It would be great to write an implementation that
is verified to be as lazy as possible: the pattern of “definedness” is
complex, though, so I don’t know if it’s possible with Agda’s current
sized types.</p>
</dd>
</dl>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Thanks to <a
href="http://gelisam.blogspot.com/">gelisam</a> for pointing out the
poor phrasing here. Updated on 2018/10/16<a href="#fnref1"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>You might wonder why the definition of <code>tail</code>
doesn’t have this signature to begin with. The reason is that our record
type must be <em>parameterized</em> (not indexed) over its size (as it’s
a record type), so we use a less-than proof instead.<a href="#fnref2"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Tue, 16 Oct 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-10-16-total-combinations.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Agda Beginner(-ish) Tips, Tricks, and Pitfalls</title>
    <link>https://doisinkidney.com/posts/2018-09-20-agda-tips.html</link>
    <description><![CDATA[<div class="info">
    Posted on September 20, 2018
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Agda%20Tips.html">2-part series on Agda Tips</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>I’m in the middle of quite a large Agda project at the moment, and
I’ve picked up a few tips and tricks in the past few weeks. I’d imagine
a lot of these are quite obvious once you get to grips with Agda, so I’m
writing them down before I forget that they were once confusing
stumbling blocks. Hopefully this helps other people trying to learn the
language!</p>
<h1 id="parameterized-modules-strangeness">Parameterized Modules
Strangeness</h1>
<p>Agda lets you parameterize modules, just as you can datatypes, with
types, values, etc. It’s extremely handy for those situations where you
want to be generic over some type, but that type won’t change inside the
generic code. The keys to dictionaries is a good example: you can start
the module with:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> Map <span class="ot">(</span>Key <span class="ot">:</span> <span class="dt">Set</span><span class="ot">)</span> <span class="ot">(</span>Ordering <span class="ot">:</span> Ord Key<span class="ot">)</span> <span class="kw">where</span></span></code></pre></div>
<p>And now, where in Haskell you’d have to write something like
<code>Ord a =&gt; Map a</code>… in pretty much any function signature,
you can just refer to <code>Key</code>, and you’re good to go. It’s kind
of like a dynamic type synonym, in that way.</p>
<p>Here’s the strangeness, though: what if you don’t supply one of the
arguments?</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> Map</span></code></pre></div>
<p>This won’t give you a type error, strange as it may seem. This will
perform <em>lambda lifting</em>, meaning that now, every function
exported by the module will have the type signature:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(</span>Key <span class="ot">:</span> <span class="dt">Set</span><span class="ot">)</span> <span class="ot">(</span>Ordering <span class="ot">:</span> Ord Key<span class="ot">)</span> <span class="ot">...</span></span></code></pre></div>
<p>Preceding its normal signature. In other words, it changes it into
what you would have had to write in Haskell.</p>
<p>This is a powerful feature, but it can also give you some confusing
errors if you don’t know about it (especially if the module has implicit
arguments).</p>
<h1 id="auto">Auto</h1>
<p>If you’ve got a hole in your program, you can put the cursor in it
and press <code>SPC-m-a</code> (in spacemacs), and Agda will try and
find the automatic solution to the problem. For a while, I didn’t think
much of this feature, as rare was the program which Agda could figure
out. Turns out I was just using it wrong! Into the hole you should type
the options for the proof search: enabling case-splitting
(<code>-c</code>), enabling the use of available definitions
(<code>-r</code>), and listing possible solutions (<code>-l</code>).</p>
<h1 id="well-founded-recursion">Well-Founded Recursion</h1>
<p>Often, a program will not be obviously terminating (according to
Agda’s termination checker). The first piece of advice is this:
<em>don’t</em> use well-founded recursion. It’s a huge hammer, and often
you can get away with fiddling with the function (try inlining
definitions, rewriting generic functions to monomorphic versions, or
replacing with-blocks with helper functions), or using one of the <a
href="https://gallais.github.io/blog/termination-tricks.html">more
lightweight techniques</a> out there.</p>
<p>However, sometimes it really is the best option, so you have to grit
your teeth and use it. What I expected (and what I used originally) was
a recursion combinator, with a type something like:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>wf-rec <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a b<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">{</span>B <span class="ot">:</span> <span class="dt">Set</span> b<span class="ot">}</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">→</span> <span class="ot">((</span>x <span class="ot">:</span> A<span class="ot">)</span> <span class="ot">→</span> <span class="ot">((</span>y <span class="ot">:</span> A<span class="ot">)</span> <span class="ot">→</span> y &lt; x <span class="ot">→</span> B<span class="ot">)</span> <span class="ot">→</span> B<span class="ot">)</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>       <span class="ot">→</span> A <span class="ot">→</span> B</span></code></pre></div>
<p>So we’re trying to generate a function of type <code>A → B</code>,
but there’s a hairy recursive call in there somewhere. Instead we use
this function, and pass it a version of our function that uses the
supplied function rather than making a recursive call:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>terminating <span class="ot">:</span> A <span class="ot">→</span> B</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>terminating <span class="ot">=</span> wf-rec <span class="ot">(λ</span> x recursive-call <span class="ot">→</span> <span class="ot">...)</span></span></code></pre></div>
<p>In other words, instead of calling the function itself, you call
<code>recursive-call</code> above. Along with the argument, you supply a
proof that it’s smaller than the outer argument (<code>y &lt; x</code>;
assume for now that the definition of <code>&lt;</code> is just some
relation like <a
href="https://github.com/agda/agda-stdlib/blob/442cd8a06b63f7e3550af55fb75c9d345c6ddb8f/src/Data/Nat/Base.agda#L31"><code>_&lt;_</code>
in Data.Nat</a>).</p>
<p>But wait! You don’t have to use it! Instead of all that, you can just
pass the <code>Acc _&lt;_ x</code> type as a parameter to your function.
In other words, if you have a dangerous function:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>f <span class="ot">:</span> A <span class="ot">→</span> B</span></code></pre></div>
<p>Instead write:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>f-step <span class="ot">:</span> <span class="ot">(</span>x <span class="ot">:</span> A<span class="ot">)</span> <span class="ot">→</span> Acc <span class="ot">_</span>&lt;<span class="ot">_</span> x <span class="ot">→</span> B</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>f-step <span class="ot">=</span> <span class="ot">...</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>f <span class="ot">:</span> A <span class="ot">→</span> B</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>f x <span class="ot">=</span> f-step x <span class="ot">...</span></span></code></pre></div>
<p>Once you pattern match on the accessibility relation, the termination
checker is satisfied. This is much easier to understand (for me anyway),
and made it <em>much</em> easier to write proofs about it.</p>
<p>Thanks to <a href="http://oleg.fi">Oleg Grenrus (phadej)</a> on irc
for helping me out with this! Funnily enough, he actually recommended
the <code>Acc</code> approach, and I instead originally went with the
recursion combinator. Would have saved a couple hours if I’d just
listened! Also worth mentioning is the approach recommended by <a
href="https://gallais.github.io">Guillaume Allais (gallais)</a>,
detailed <a
href="https://gallais.github.io/agdarsec/Induction.Nat.Strong.html">here</a>.
Haven’t had time to figure it out, so this article may be updated to
recommend it instead in the future.</p>
<h1 id="dont-touch-the-green-slime">Don’t Touch The Green Slime!</h1>
<p>This one is really important. If I hadn’t read the exact explanation
<a
href="https://twitter.com/pigworker/status/1013535783234473984">here</a>
I think I may have given up with Agda (or at the very least the project
I’m working on) out of frustration.</p>
<p>Basically the problem arises like this. Say you’re writing a function
to split a vector in two. You can specify the type pretty precisely:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>split <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>a n m<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span> <span class="ot">→</span> Vec A <span class="ot">(</span>n + m<span class="ot">)</span> <span class="ot">→</span> Vec A n × Vec A m</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>split xs <span class="ot">=</span> <span class="ot">{!!}</span></span></code></pre></div>
<p>Try to pattern-match on <code>xs</code>, though, and you’ll get the
following error:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>I&#39;m not sure if there should be a case for the <span class="kw">constructor</span> [],</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>because I get stuck when trying <span class="kw">to</span> solve the following unification</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>problems <span class="ot">(</span>inferred index ≟ expected index<span class="ot">):</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  zero ≟ n + m</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>when checking that the expression ? has type Vec <span class="ot">.</span>A <span class="ot">.</span>n × Vec <span class="ot">.</span>A <span class="ot">.</span>m</span></code></pre></div>
<p>What?! That’s weird. Anyway, you fiddle around with the function, end
up pattern matching on the <code>n</code> instead, and continue on with
your life.</p>
<p>What about this, though: you want to write a type for proofs that one
number is less than or equal to another. You go with something like
this:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infix</span> <span class="dv">4</span> <span class="ot">_</span>≤<span class="ot">_</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="ot">_</span>≤<span class="ot">_</span> <span class="ot">(</span>n <span class="ot">:</span> ℕ<span class="ot">)</span> <span class="ot">:</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  proof <span class="ot">:</span> <span class="ot">∀</span> k <span class="ot">→</span> n ≤ n + k</span></code></pre></div>
<p>And you want to use it in a proof. Here’s the example we’ll be using:
if two numbers are less than some limit <code>u</code>, then their
maximum is also less than that limit:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>max <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>max zero m <span class="ot">=</span> m</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>max <span class="ot">(</span>suc n<span class="ot">)</span> zero <span class="ot">=</span> suc n</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>max <span class="ot">(</span>suc n<span class="ot">)</span> <span class="ot">(</span>suc m<span class="ot">)</span> <span class="ot">=</span> suc <span class="ot">(</span>max n m<span class="ot">)</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>max-≤ <span class="ot">:</span> <span class="ot">∀</span> n m <span class="ot">{</span>u<span class="ot">}</span> <span class="ot">→</span> n ≤ u <span class="ot">→</span> m ≤ u <span class="ot">→</span> max n m ≤ u</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>max-≤ n m <span class="ot">(</span>proof k<span class="ot">)</span> m≤u <span class="ot">=</span> <span class="ot">{!!}</span></span></code></pre></div>
<p>It won’t let you match on <code>m≤u</code>! Here’s the error:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>I&#39;m not sure if there should be a case for the <span class="kw">constructor</span> proof,</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>because I get stuck when trying <span class="kw">to</span> solve the following unification</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>problems <span class="ot">(</span>inferred index ≟ expected index<span class="ot">):</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  m₁ + k₂ ≟ n₁ + k₁</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>when checking that the expression ? has type max n m ≤ n + k</span></code></pre></div>
<p>What do you <em>mean</em> you’re not sure if there’s a case for the
constructor <code>proof</code>: it’s the <em>only</em> case!</p>
<p>The problem is that Agda is trying to <em>unify</em> two types who
both have calls to user-defined functions in them, which is a hard
problem. As phrased by Conor McBride:</p>
<blockquote>
<p>When combining prescriptive and descriptive indices, ensure both are
in constructor form. Exclude defined functions which yield difficult
unification problems.</p>
</blockquote>
<p>So if you ever get the “I’m not sure if…” error, try either to:</p>
<ol>
<li>Redefine the indices so they use constructors, not functions.</li>
<li>Remove the index, instead having a proof inside the type of
equality. What does that mean? Basically, transform the definition of
<code>≤</code> above into <a
href="https://github.com/agda/agda-stdlib/blob/442cd8a06b63f7e3550af55fb75c9d345c6ddb8f/src/Data/Nat/Base.agda#L72-L76">the
one in Data.Nat</a>.</li>
</ol>
<h1 id="inspect">Inspect</h1>
<p>The use-case I had for this is a little long, I’m afraid (too long to
include here), but it <em>did</em> come in handy. Basically, if you’re
trying to prove something about a function, you may well want to
<em>run</em> that function and pattern match on the result.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>f-is-the-same-as-g <span class="ot">:</span> <span class="ot">∀</span> x <span class="ot">→</span> f x ≡ g x</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>f-is-the-same-as-g x <span class="kw">with</span> f x</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>f-is-the-same-as-g x <span class="ot">|</span> y <span class="ot">=</span> <span class="ot">{!!}</span></span></code></pre></div>
<p>This is a little different from the normal way of doing things, where
you’d pattern match on the argument. It is a pattern you’ll sometimes
need to write, though. And here’s the issue: that <code>y</code> has
nothing to do with <code>f x</code>, as far as Agda is concerned. All
you’ve done is introduced a new variable, and that’s that.</p>
<p>This is exactly the problem <a
href="https://github.com/agda/agda-stdlib/blob/442cd8a06b63f7e3550af55fb75c9d345c6ddb8f/src/Relation/Binary/PropositionalEquality.agda#L111-L113"><code>inspect</code></a>
solves: it runs your function, giving you a result, but <em>also</em>
giving you a proof that the result is equal to running the function. You
use it like this:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>f-is-the-same-as-g <span class="ot">:</span> <span class="ot">∀</span> x <span class="ot">→</span> f x ≡ g x</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>f-is-the-same-as-g x <span class="kw">with</span> f x <span class="ot">|</span> inspect f x</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>f-is-the-same-as-g x <span class="ot">|</span> y <span class="ot">|</span> [ fx≡y ] <span class="ot">=</span> <span class="ot">{!!}</span></span></code></pre></div>
<h1 id="spc-g-g">SPC-G-G</h1>
<p>Because the Agda standard library is a big fan of type synonyms
(<code>Op₂ A</code> instead of <code>A → A → A</code> for example), it’s
handy to know that pressing <code>SPC-G-G</code> (in spacemacs) over any
identifier will bring you to the definition. Also, you can normalize a
type with <code>SPC-m-n</code>.</p>
<h1 id="irrelevance">Irrelevance</h1>
<p>This one is a little confusing, because Agda’s notion of
“irrelevance” is different from Idris’, or Haskell’s. In all three
languages, irrelevance is used for performance: it means that a value
doesn’t need to be around at runtime, so the compiler can elide it.</p>
<p>That’s where the similarities stop though. In Haskell, <em>all</em>
types are irrelevant: they’re figments of the typechecker’s imagination.
You can’t get a type at runtime full stop.</p>
<p>In dependently typed languages, this isn’t a distinction we can rely
on. The line between runtime entities and compile-time entities is drawn
elsewhere, so quite often types <em>need</em> to exist at runtime. As
you might guess, though, they don’t always need to. The length of a
length-indexed vector, for instance, is completely determined by the
structure of the vector: why would you bother storing all of that
information at runtime? This is what Idris recognizes, and what it tries
to remedy: it analyses code for these kinds of opportunities for
elision, and does so when it can. Kind of like Haskell’s fusion, though,
it’s an invisible optimization, and there’s no way to make Idris throw a
type error when it can’t elide something you want it to elide.</p>
<p>Agda is totally different. Something is irrelevant in Agda if it’s
<em>unique</em>. Or, rather, it’s irrelevant if all you rely on is its
existence. It’s used for proofs that you carry around with you: in a
rational number type, you might use it to say that the numerator and
denominator have no common factors. The only information you want from
this proof is whether it holds or not, so it’s the perfect candidate for
irrelevance.</p>
<p>Weirdly, this means it’s useless for the length-indexed vector kind
of stuff mentioned above. In fact, it does exactly the opposite of what
you might expect: if the length parameter is marked as irrelevant, the
types <code>Vec A n</code> and <code>Vec A (suc n)</code> are the
same!</p>
<p>The way you <em>can</em> use it is to pattern-match if it’s
impossible. Again, it’s designed for eliding proofs that you may carry
with you otherwise.</p>
<h1 id="future-tips">Future Tips</h1>
<p>Once I’m finished the project, I’ll try write up a guide on how to do
literate Agda files. There were a couple of weird nuances that I had to
pick up on the way, mainly to do with getting unicode to work.</p>
]]></description>
    <pubDate>Thu, 20 Sep 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-09-20-agda-tips.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Verified AVL Trees in Haskell and Agda</title>
    <link>https://doisinkidney.com/posts/2018-07-30-verified-avl.html</link>
    <description><![CDATA[<div class="info">
    Posted on July 30, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Agda&#39;." href="/tags/Agda.html" rel="tag">Agda</a>
    
</div>

<p>I’ve been writing a lot of Agda recently, and had the occasion to
write a <a href="https://en.wikipedia.org/wiki/Fenwick_tree">Fenwick
tree</a> that did some rebalancing. I went with <a
href="https://en.wikipedia.org/wiki/AVL_tree">AVL</a>-style rebalancing
(rather than <a
href="https://en.wikipedia.org/wiki/Red–black_tree">red-black</a> or <a
href="https://en.wikipedia.org/wiki/Weight-balanced_tree">trees of
bounded balance</a>). I’d written pretty full implementations of the
other two before, and the Agda standard library <span class="citation"
data-cites="danielsson_agda_2018">(<a href="#ref-danielsson_agda_2018"
role="doc-biblioref">Danielsson 2018</a>)</span> has an implementation
already that I was able to use as a starting point. Also, apparently,
AVL trees seem to perform better than red-black trees in practice <span
class="citation" data-cites="pfaff_performance_2004">(<a
href="#ref-pfaff_performance_2004" role="doc-biblioref">Pfaff
2004</a>)</span>.</p>
<p>This post will be similar in style to Stephanie Weirich’s talk <span
class="citation" data-cites="weirich_depending_2014">(<a
href="#ref-weirich_depending_2014"
role="doc-biblioref">2014</a>)</span>, which compares an Agda
implementation of verified red-black trees to a Haskell one. When
there’s two columns of code side-by-side, the left-hand side is Haskell,
the right Agda.</p>
<p>The method of constructing the ordering proof is taken from “How to
Keep Your Neighbours in Order” <span class="citation"
data-cites="mcbride_how_2014">(<a href="#ref-mcbride_how_2014"
role="doc-biblioref">2014</a>)</span> by Conor McBride; the structural
proofs are somewhat inspired by the implementation in the Agda standard
library, but are mainly my own.</p>
<h1 id="height">Height</h1>
<p>AVL trees are more strictly balanced than red-black trees: the height
of neighboring subtrees can differ by at most one. To store the height,
we will start as every dependently-typed program does: with Peano
numbers.</p>
<style>
.column {
    float: left;
    width: 50%;
}
.row:after {
    content: "";
    display: table;
    clear: both;
}
</style>
<div class="row">
<div class="column">
<p>Haskell</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">N</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">N</span></span></code></pre></div>
</div>
<div class="column">
<p>Agda</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ℕ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">:</span> ℕ</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  suc  <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ</span></code></pre></div>
</div>
</div>
<p>The trees will be balanced one of three possible ways: left-heavy,
right-heavy, or even. We can represent these three cases in a GADT in
the case of Haskell, or an indexed datatype in the case of Agda:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Balance</span><span class="ot"> ::</span> <span class="dt">N</span> <span class="ot">-&gt;</span> <span class="dt">N</span> <span class="ot">-&gt;</span> <span class="dt">N</span> <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>      <span class="dt">L</span><span class="ot"> ::</span> <span class="dt">Balance</span> (<span class="dt">S</span> n) n    (<span class="dt">S</span> n)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>      <span class="dt">O</span><span class="ot"> ::</span> <span class="dt">Balance</span>  n    n     n</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>      <span class="dt">R</span><span class="ot"> ::</span> <span class="dt">Balance</span>  n   (<span class="dt">S</span> n) (<span class="dt">S</span> n)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb4"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ⟨<span class="ot">_</span>⊔<span class="ot">_</span>⟩≡<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  ◿  <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> ⟨ suc  n ⊔      n ⟩≡ suc  n</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  ▽  <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> ⟨      n ⊔      n ⟩≡      n</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  ◺  <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>n<span class="ot">}</span> <span class="ot">→</span> ⟨      n ⊔ suc  n ⟩≡ suc  n</span></code></pre></div>
</div>
</div>
<p>Those unfamiliar with Agda might be a little intimidated by the
mixfix operator in the balance definition: we’re using it here because
the type can be seen of a proof that:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mi>a</mi><mi>x</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>,</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo><mo>=</mo><mi>z</mi></mrow><annotation encoding="application/x-tex">max(x,y) = z</annotation></semantics></math></p>
<p>Or, using the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>⊔</mi><annotation encoding="application/x-tex">\sqcup</annotation></semantics></math>
operator:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>⊔</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo><mo>=</mo><mi>z</mi></mrow><annotation encoding="application/x-tex">(x \sqcup y) = z</annotation></semantics></math></p>
<p>We’ll use this proof in the tree itself, as we’ll need to know the
maximum of the height of a node’s two subtrees to find the height of the
node. Before we do that, we’ll need a couple helper functions for
manipulating the balance:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">balr ::</span> <span class="dt">Balance</span> x y z <span class="ot">-&gt;</span> <span class="dt">Balance</span> z x z</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>balr <span class="dt">L</span> <span class="ot">=</span> <span class="dt">O</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>balr <span class="dt">O</span> <span class="ot">=</span> <span class="dt">O</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>balr <span class="dt">R</span> <span class="ot">=</span> <span class="dt">L</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="ot">ball ::</span> <span class="dt">Balance</span> x y z <span class="ot">-&gt;</span> <span class="dt">Balance</span> y z z</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>ball <span class="dt">L</span> <span class="ot">=</span> <span class="dt">R</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>ball <span class="dt">O</span> <span class="ot">=</span> <span class="dt">O</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>ball <span class="dt">R</span> <span class="ot">=</span> <span class="dt">O</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb6"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>⃕ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>x y z<span class="ot">}</span> <span class="ot">→</span> ⟨ x ⊔ y ⟩≡ z <span class="ot">→</span> ⟨ z ⊔ x ⟩≡ z</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>⃕  ◿  <span class="ot">=</span> ▽</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>⃕  ▽  <span class="ot">=</span> ▽</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>⃕  ◺  <span class="ot">=</span> ◿</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>⃔ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>x y z<span class="ot">}</span> <span class="ot">→</span> ⟨ x ⊔ y ⟩≡ z <span class="ot">→</span> ⟨ y ⊔ z ⟩≡ z</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>⃔  ◿  <span class="ot">=</span> ◺</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>⃔  ▽  <span class="ot">=</span> ▽</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>⃔  ◺  <span class="ot">=</span> ▽</span></code></pre></div>
</div>
</div>
<h1 id="ordering">Ordering</h1>
<p>Along with the verification of the structure of the tree, we will
also want to verify that its contents are ordered correctly.
Unfortunately, this property is a little out of reach for Haskell, but
it’s 100% doable in Agda. First, we’ll need a way to describe orders on
a data type. In Haskell, we might write:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Ord</span> a <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  (==) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;)  ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span></code></pre></div>
</div>
<div class="column">
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>*</mi><mo>*</mo><mi>*</mi></mrow><annotation encoding="application/x-tex">***</annotation></semantics></math>
</div>
</div>
<p>That <code
class="sourceCode haskell"><span class="dt">Bool</span></code> throws
away any information gained in the comparison, though: we want to supply
a proof with the result of the comparison. First, equality:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>infix <span class="dv">4</span> <span class="op">==</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span><span class="ot"> (==) ::</span> <span class="dt">Type</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">Type</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Refl</span><span class="ot"> ::</span> x <span class="op">==</span> x</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb9"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infix</span> <span class="dv">4</span> <span class="ot">_</span>≡<span class="ot">_</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="ot">_</span>≡<span class="ot">_</span> <span class="ot">{</span>a<span class="ot">}</span> <span class="ot">{</span>A <span class="ot">:</span> <span class="dt">Set</span> a<span class="ot">}</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>         <span class="ot">(</span>x <span class="ot">:</span> A<span class="ot">)</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>         <span class="ot">:</span> A <span class="ot">→</span> <span class="dt">Set</span> a <span class="kw">where</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  refl <span class="ot">:</span> x ≡ x</span></code></pre></div>
</div>
</div>
<p>This is one of the many ways to describe equality in Agda. It’s a
type with only one constructor, and it can only be constructed when its
two arguments are the same. When we pattern match on the constructor,
then, we’re given a proof that whatever things those arguments refer to
must be the same.</p>
<p>Next, we need to describe an order. For this, we’ll need two types:
the empty type, and the unit type.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Void</span><span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Unit</span><span class="ot"> ::</span> <span class="dt">Type</span> <span class="kw">where</span> <span class="dt">Unit</span><span class="ot"> ::</span> <span class="dt">Unit</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb11"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ⊥ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ⊤ <span class="ot">:</span> <span class="dt">Set</span> <span class="kw">where</span> ⟨⟩ <span class="ot">:</span> ⊤</span></code></pre></div>
</div>
</div>
<p>These are kind of like type-level Bools, with one extra, powerful
addition: they keep their proof after construction. Because <code
class="sourceCode agda">⊥</code> has no constructors, if someone tells
you they’re going to give you one, you can be pretty sure they’re lying.
How do we use this? Well, first, on the numbers:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> (<span class="ot">n ::</span> <span class="dt">N</span>) <span class="op">&lt;</span> (<span class="ot">m ::</span> <span class="dt">N</span>)</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  x   <span class="op">&lt;</span> <span class="dt">Z</span>   <span class="ot">=</span> <span class="dt">Void</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span>   <span class="op">&lt;</span> <span class="dt">S</span> y <span class="ot">=</span> <span class="dt">Unit</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">S</span> x <span class="op">&lt;</span> <span class="dt">S</span> y <span class="ot">=</span> x <span class="op">&lt;</span> y</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb13"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>ℕ&lt;<span class="ot">_</span> <span class="ot">:</span> ℕ <span class="ot">→</span> ℕ <span class="ot">→</span> <span class="dt">Set</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>x     ℕ&lt; zero  <span class="ot">=</span> ⊥</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>zero  ℕ&lt; suc y <span class="ot">=</span> ⊤</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>suc x ℕ&lt; suc y <span class="ot">=</span> x ℕ&lt; y</span></code></pre></div>
</div>
</div>
<p>Therefore, if we ask for something of type <code
class="sourceCode agda">x ℕ&lt; y</code> (for some <code>x</code> and
<code>y</code>), we know that it only exists when <code>x</code> really
is less than <code>y</code> (according to the definition above).</p>
<p>For our actual code, we’ll parameterize the whole thing over some
abstract key type. We’ll do this using a module (a feature recently
added to Haskell, as it happens). That might look something like
this:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>signature <span class="dt">Key</span> <span class="kw">where</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">import</span> <span class="dt">Data.Kind</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">data</span> <span class="dt">Key</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> <span class="kw">family</span> (<span class="ot">n ::</span> <span class="dt">Key</span>) <span class="op">&lt;</span> (<span class="ot">m ::</span> <span class="dt">Key</span>)</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Type</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">AVL</span> <span class="kw">where</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">import</span> <span class="dt">Key</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb15"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> AVL</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{</span>k r<span class="ot">}</span> <span class="ot">(</span>Key <span class="ot">:</span> <span class="dt">Set</span> k<span class="ot">)</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{_</span>&lt;<span class="ot">_</span> <span class="ot">:</span> Rel Key r<span class="ot">}</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">(</span>isStrictTotalOrder</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>   <span class="ot">:</span> IsStrictTotalOrder <span class="ot">_</span>≡<span class="ot">_</span> <span class="ot">_</span>&lt;<span class="ot">_)</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">open</span> IsStrictTotalOrder isStrictTotalOrder</span></code></pre></div>
</div>
</div>
<p>(the <code class="sourceCode agda">k</code> and <code
class="sourceCode agda">r</code> here, as well as the <code
class="sourceCode agda">Lift</code>ing noise below, are to do with
Agda’s universe system, which I’ll try explain in a bit)</p>
<p>Now, the trick for the ordering is to keep a proof that two
neighboring values are ordered correctly in the tree at each leaf (as
there’s a leaf between every pair of nodes, this is exactly the place
you <em>should</em> store such a proof). A problem arises with the
extremal leaves in the tree (leftmost and rightmost): each leaf is
missing one neighboring value, so how can it store a proof of order? The
solution is to affix two elements to our key type which we define as the
greatest and least elements of the set.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Bound</span> <span class="ot">=</span> <span class="dt">LB</span> <span class="op">|</span> <span class="dt">IB</span> <span class="dt">Key</span> <span class="op">|</span> <span class="dt">UB</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>infix <span class="dv">4</span> <span class="op">&lt;:</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> (<span class="ot">x ::</span> <span class="dt">Bound</span>) <span class="op">&lt;:</span> (<span class="ot">y ::</span> <span class="dt">Bound</span>)</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LB</span>   <span class="op">&lt;:</span> <span class="dt">LB</span>   <span class="ot">=</span> <span class="dt">Void</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LB</span>   <span class="op">&lt;:</span> <span class="dt">UB</span>   <span class="ot">=</span> <span class="dt">Unit</span></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LB</span>   <span class="op">&lt;:</span> <span class="dt">IB</span> _ <span class="ot">=</span> <span class="dt">Unit</span></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">UB</span>   <span class="op">&lt;:</span> _    <span class="ot">=</span> <span class="dt">Void</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>  <span class="dt">IB</span> _ <span class="op">&lt;:</span> <span class="dt">LB</span>   <span class="ot">=</span> <span class="dt">Void</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>  <span class="dt">IB</span> _ <span class="op">&lt;:</span> <span class="dt">UB</span>   <span class="ot">=</span> <span class="dt">Unit</span></span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>  <span class="dt">IB</span> x <span class="op">&lt;:</span> <span class="dt">IB</span> y <span class="ot">=</span> x <span class="op">&lt;</span> y</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb17"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infix</span> <span class="dv">5</span> [<span class="ot">_</span>]</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> [∙] <span class="ot">:</span> <span class="dt">Set</span> k <span class="kw">where</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  ⌊⌋ ⌈⌉ <span class="ot">:</span> [∙]</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  [<span class="ot">_</span>]   <span class="ot">:</span> <span class="ot">(</span>k <span class="ot">:</span> Key<span class="ot">)</span> <span class="ot">→</span> [∙]</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a><span class="kw">infix</span> <span class="dv">4</span> <span class="ot">_</span>[&lt;]<span class="ot">_</span></span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>[&lt;]<span class="ot">_</span> <span class="ot">:</span> [∙] <span class="ot">→</span> [∙] <span class="ot">→</span> <span class="dt">Set</span> r</span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a>⌊⌋     [&lt;] ⌊⌋    <span class="ot">=</span> Lift r ⊥</span>
<span id="cb17-11"><a href="#cb17-11" aria-hidden="true" tabindex="-1"></a>⌊⌋     [&lt;] ⌈⌉    <span class="ot">=</span> Lift r ⊤</span>
<span id="cb17-12"><a href="#cb17-12" aria-hidden="true" tabindex="-1"></a>⌊⌋     [&lt;] [ <span class="ot">_</span> ] <span class="ot">=</span> Lift r ⊤</span>
<span id="cb17-13"><a href="#cb17-13" aria-hidden="true" tabindex="-1"></a>⌈⌉     [&lt;] <span class="ot">_</span>     <span class="ot">=</span> Lift r ⊥</span>
<span id="cb17-14"><a href="#cb17-14" aria-hidden="true" tabindex="-1"></a>[ <span class="ot">_</span> ]  [&lt;] ⌊⌋    <span class="ot">=</span> Lift r ⊥</span>
<span id="cb17-15"><a href="#cb17-15" aria-hidden="true" tabindex="-1"></a>[ <span class="ot">_</span> ]  [&lt;] ⌈⌉    <span class="ot">=</span> Lift r ⊤</span>
<span id="cb17-16"><a href="#cb17-16" aria-hidden="true" tabindex="-1"></a>[ x ]  [&lt;] [ y ] <span class="ot">=</span> x &lt; y</span></code></pre></div>
</div>
</div>
<h1 id="the-tree-type">The Tree Type</h1>
<p>After all that, we can bring back Haskell into the story, and define
our tree types:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span><span class="ot"> ::</span> <span class="dt">N</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">Type</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">Type</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Leaf</span><span class="ot"> ::</span> <span class="dt">Tree</span> <span class="dt">Z</span> k v</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Node</span><span class="ot"> ::</span> k</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> v</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Balance</span> lh rh h</span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Tree</span> lh k v</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Tree</span> rh k v</span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">Tree</span> (<span class="dt">S</span> h) k v</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb19"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> Tree <span class="ot">{</span>v<span class="ot">}</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>          <span class="ot">(</span>V <span class="ot">:</span> Key <span class="ot">→</span> <span class="dt">Set</span> v<span class="ot">)</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>          <span class="ot">(</span>l u <span class="ot">:</span> [∙]<span class="ot">)</span> <span class="ot">:</span> ℕ <span class="ot">→</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Set</span> <span class="ot">(</span>k ⊔ v ⊔ r<span class="ot">)</span> <span class="kw">where</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>  leaf  <span class="ot">:</span> <span class="ot">(</span>l&lt;u <span class="ot">:</span> l [&lt;] u<span class="ot">)</span> <span class="ot">→</span> Tree V l u <span class="dv">0</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>  node  <span class="ot">:</span> <span class="ot">∀</span>  <span class="ot">{</span>h lh rh<span class="ot">}</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>             <span class="ot">(</span>k <span class="ot">:</span> Key<span class="ot">)</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>             <span class="ot">(</span>v <span class="ot">:</span> V k<span class="ot">)</span></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>             <span class="ot">(</span>bl <span class="ot">:</span> ⟨ lh ⊔ rh ⟩≡ h<span class="ot">)</span></span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>             <span class="ot">(</span>lk <span class="ot">:</span> Tree V l [ k ] lh<span class="ot">)</span></span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a>             <span class="ot">(</span>ku <span class="ot">:</span> Tree V [ k ] u rh<span class="ot">)</span> <span class="ot">→</span></span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a>             Tree V l u <span class="ot">(</span>suc h<span class="ot">)</span></span></code></pre></div>
</div>
</div>
<p>The two definitions are similar, but have a few obvious differences.
The Agda version stores the ordering proof at the leaves, as well as the
bounds as indices. Its <a
href="https://pigworker.wordpress.com/2015/01/09/universe-hierarchies/"><em>universe</em></a>
is also different: briefly, universes are one of the ways to avoid
Russell’s paradox when you’re dealing with dependent types.</p>
<p>In normal, standard Haskell, we think of types as things that
describe values (how quaint!). When you’ve got a list, everything in the
list has the same type, and that is good and right.</p>
<p>These days, though, we’re not so constrained:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> xs <span class="kw">where</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">List</span> &#39;[]</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:-) ::</span> x</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">List</span> xs</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> <span class="dt">List</span> (x <span class="op">:</span> xs)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb21"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="ot">_</span>፦<span class="ot">_</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> List′ <span class="ot">:</span> List <span class="dt">Set</span> <span class="ot">→</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  nil <span class="ot">:</span> List′ []</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">_</span>፦<span class="ot">_</span> <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>x xs<span class="ot">}</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> x</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> List′ xs</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>      <span class="ot">→</span> List′ <span class="ot">(</span>x ∷ xs<span class="ot">)</span></span></code></pre></div>
</div>
</div>
<p>This can quite happily store elements of different types:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">example ::</span> <span class="dt">List</span> [<span class="dt">Bool</span>, <span class="dt">String</span>, <span class="dt">Integer</span>]</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>example <span class="ot">=</span> <span class="dt">True</span> <span class="op">:-</span> <span class="st">&quot;true&quot;</span> <span class="op">:-</span> <span class="dv">1</span> <span class="op">:-</span> <span class="dt">Nil</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb23"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>example <span class="ot">:</span> List′ <span class="ot">(</span>Bool ∷ String ∷ ℕ ∷ []<span class="ot">)</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>example <span class="ot">=</span> true ፦ <span class="st">&quot;true&quot;</span> ፦ <span class="dv">1</span> ፦ nil</span></code></pre></div>
</div>
</div>
<p>And look at that bizarre-looking list on the wrong side of “<code
class="sourceCode haskell"><span class="ot">::</span></code>”! Types
aren’t just describing values, they’re acting like values themselves.
What type does <code
class="sourceCode haskell">[<span class="dt">Bool</span>, <span class="dt">String</span>, <span class="dt">Integer</span>]</code>
even have, anyway? Why, <code
class="sourceCode haskell">[<span class="dt">Type</span>]</code> of
course!</p>
<p>So we see that types can be put in lists, and types have types: the
natural question then is:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Type</span><span class="ot"> ::</span> <span class="op">???</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb25"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Set</span> <span class="ot">:</span> ???</span></code></pre></div>
</div>
</div>
<p>And this is where Haskell and Agda diverge: in Haskell, we say <code
class="sourceCode haskell"><span class="dt">Type</span><span class="ot"> ::</span> <span class="dt">Type</span></code>
(as the old extension <code
class="sourceCode haskell"><span class="dt">TypeInType</span></code>
implied), and that’s that. From a certain point of view, we’ve opened
the door to Russell’s paradox (we’ve allowed a set to be a member of
itself). This isn’t an issue in Haskell, though, as the type-level
language was already inconsistent.</p>
<p>Agda goes another way, saying that <code
class="sourceCode agda"><span class="dt">Set</span></code> (Agda’s
equivalent for <code
class="sourceCode haskell"><span class="dt">Type</span></code>) has the
type <code class="sourceCode agda"><span class="dt">Set₁</span></code>,
and <code class="sourceCode agda"><span class="dt">Set₁</span></code>
has the type <code
class="sourceCode agda"><span class="dt">Set₂</span></code>, and so on<a
href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a>. These different sets are called
“universes” and their numbers “levels”. When we write <code
class="sourceCode agda">k ⊔ v ⊔ r</code>, we’re saying we want to take
the greatest universe level from those three possible levels: the level
of the key, the value, and the relation, respectively.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Type</span><span class="ot"> ::</span> <span class="dt">Type</span></span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb27"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Set</span> <span class="ot">:</span> <span class="dt">Set₁</span></span></code></pre></div>
</div>
</div>
<h1 id="rotations">Rotations</h1>
<p>AVL trees maintain their invariants through relatively simple
rotations. We’ll start with the right rotation, which fixes an imbalance
of two on the left. Because the size of the tree returned might change,
we’ll need to wrap it in a datatype:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span><span class="ot"> (++?) ::</span> (<span class="dt">N</span> <span class="ot">-&gt;</span> <span class="dt">Type</span>)</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> (<span class="dt">N</span> <span class="ot">-&gt;</span> <span class="dt">Type</span>)</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>           <span class="kw">where</span></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Stay</span><span class="ot"> ::</span> t n     <span class="ot">-&gt;</span> t <span class="op">++?</span> n</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Incr</span><span class="ot"> ::</span> t (<span class="dt">S</span> n) <span class="ot">-&gt;</span> t <span class="op">++?</span> n</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb29"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="ot">_</span>1?+⟨<span class="ot">_</span>⟩ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>𝓁<span class="ot">}</span> <span class="ot">(</span>T <span class="ot">:</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> 𝓁<span class="ot">)</span> <span class="ot">→</span> ℕ <span class="ot">→</span> <span class="dt">Set</span> 𝓁</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>T 1?+⟨ n ⟩ <span class="ot">=</span> ∃[ inc? ] T <span class="ot">(</span>if inc?</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>                            then suc n</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>                            else n<span class="ot">)</span></span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> 0+<span class="ot">_</span> tr <span class="ot">=</span> false , tr</span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> 1+<span class="ot">_</span> tr <span class="ot">=</span> true  , tr</span></code></pre></div>
</div>
</div>
<p>We could actually have the Agda definition be the same as Haskell’s,
it doesn’t make much difference. I’m mainly using it here to demonstrate
dependent pairs in Agda. The first member of the pair is just a boolean
(increased in height/not increased in height). The second member is a
tree whose height <em>depends</em> on the actual value of the boolean.
The <code class="sourceCode agda">∃</code> business is just a fancy
syntax; it also waggles its eyebrows at the way a (dependent) pair of
type <code>(x , y)</code> means “There exists an x such that y”.</p>
<p>Using this, we can write the type for right-rotation:</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">rotr ::</span> k</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> v</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">Tree</span> (<span class="dt">S</span> (<span class="dt">S</span> rh)) k v</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">Tree</span> rh k v</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">Tree</span> k v <span class="op">++?</span> <span class="dt">S</span> (<span class="dt">S</span> rh)</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb31"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>rotʳ <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>lb ub rh v<span class="ot">}</span> <span class="ot">{</span>V <span class="ot">:</span> Key <span class="ot">→</span> <span class="dt">Set</span> v<span class="ot">}</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>     <span class="ot">→</span> <span class="ot">(</span>k <span class="ot">:</span> Key<span class="ot">)</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>     <span class="ot">→</span> V k</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>     <span class="ot">→</span> Tree V lb [ k ] <span class="ot">(</span>suc <span class="ot">(</span>suc rh<span class="ot">))</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>     <span class="ot">→</span> Tree V [ k ] ub rh</span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>     <span class="ot">→</span> Tree V lb ub 1?+⟨ suc <span class="ot">(</span>suc rh<span class="ot">)</span> ⟩</span></code></pre></div>
</div>
</div>
<p>There are two possible cases, single rotation:</p>
<style>
.tree {
  margin: auto;
  width: 30%;
}
</style>
<div class="tree">
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a>   ┌a       ┌a</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a> ┌y┤       y┤</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a> │ └b <span class="op">---&gt;</span>  │ ┌b</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>x┤          └x┤</span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a> └c           └c</span></code></pre></div>
</div>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a>rotr x xv (<span class="dt">Node</span> y yv <span class="dt">L</span> a b) c <span class="ot">=</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Stay</span> (<span class="dt">Node</span> y yv <span class="dt">O</span> a (<span class="dt">Node</span> x xv <span class="dt">O</span> b c))</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>rotr x xv (<span class="dt">Node</span> y yv <span class="dt">O</span> a b) c <span class="ot">=</span></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Incr</span> (<span class="dt">Node</span> y yv <span class="dt">R</span> a (<span class="dt">Node</span> x xv <span class="dt">L</span> b c))</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb34"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>rotʳ x xv <span class="ot">(</span>node y yv ◿ a b<span class="ot">)</span> c <span class="ot">=</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>  0+ <span class="ot">(</span>node y yv ▽ a <span class="ot">(</span>node x xv ▽  b c<span class="ot">))</span></span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>rotʳ x xv <span class="ot">(</span>node y yv ▽ a b<span class="ot">)</span> c <span class="ot">=</span></span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a>  1+ <span class="ot">(</span>node y yv ◺ a <span class="ot">(</span>node x xv ◿  b c<span class="ot">))</span></span></code></pre></div>
</div>
</div>
<p>And double:</p>
<div class="tree">
<div class="sourceCode" id="cb35"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a>   ┌a           ┌a</span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a> ┌y┤          ┌y┤</span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a> │ │ ┌b       │ └b</span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a> │ └z┤  <span class="op">---&gt;</span> z┤</span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a> │   └c       │ ┌c</span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a>x┤            └x┤</span>
<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a> └d             └d</span></code></pre></div>
</div>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb36"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a>rotr x xv (<span class="dt">Node</span> y yv <span class="dt">R</span> a</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Node</span> z zv bl b c)) d <span class="ot">=</span></span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Stay</span> (<span class="dt">Node</span> z zv <span class="dt">O</span></span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a>         (<span class="dt">Node</span> y yv (balr bl) a b)</span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>         (<span class="dt">Node</span> x xv (ball bl) c d))</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb37"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a>rotʳ x xv <span class="ot">(</span>node y yv ◺  a</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>            <span class="ot">(</span>node z zv bl b c<span class="ot">))</span> d <span class="ot">=</span></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>  0+ <span class="ot">(</span>node z zv ▽</span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>       <span class="ot">(</span>node y yv <span class="ot">(</span>⃕ bl<span class="ot">)</span> a b<span class="ot">)</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>       <span class="ot">(</span>node x xv <span class="ot">(</span>⃔ bl<span class="ot">)</span> c d<span class="ot">))</span></span></code></pre></div>
</div>
</div>
<p>I won’t bore you with left-rotation: suffice to say, it’s the
opposite of right-rotation.</p>
<h1 id="insertion">Insertion</h1>
<p>Finally, the main event: insertion. Once the above functions have all
been defined, it’s not very difficult, as it happens: by and large, the
types guide you to the right answer. Of course, this is only after we
decided to use the pivotal pragmatism and balance approach.</p>
<div class="row">
<div class="column">
<div class="sourceCode" id="cb38"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a>insertWith</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> k</span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (v <span class="ot">-&gt;</span> v <span class="ot">-&gt;</span> v)</span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> k</span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> v</span>
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Tree</span> h k v</span>
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Tree</span> k v <span class="op">++?</span> h</span>
<span id="cb38-8"><a href="#cb38-8" aria-hidden="true" tabindex="-1"></a>insertWith _ v vc <span class="dt">Leaf</span> <span class="ot">=</span></span>
<span id="cb38-9"><a href="#cb38-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Incr</span> (<span class="dt">Node</span> v vc <span class="dt">O</span> <span class="dt">Leaf</span> <span class="dt">Leaf</span>)</span>
<span id="cb38-10"><a href="#cb38-10" aria-hidden="true" tabindex="-1"></a>insertWith f v vc (<span class="dt">Node</span> k kc bl tl tr) <span class="ot">=</span></span>
<span id="cb38-11"><a href="#cb38-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">case</span> <span class="fu">compare</span> v k <span class="kw">of</span></span>
<span id="cb38-12"><a href="#cb38-12" aria-hidden="true" tabindex="-1"></a>    <span class="dt">LT</span> <span class="ot">-&gt;</span></span>
<span id="cb38-13"><a href="#cb38-13" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> insertWith f v vc tl <span class="kw">of</span></span>
<span id="cb38-14"><a href="#cb38-14" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Stay</span> tl&#39; <span class="ot">-&gt;</span></span>
<span id="cb38-15"><a href="#cb38-15" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Stay</span> (<span class="dt">Node</span> k kc bl tl&#39; tr)</span>
<span id="cb38-16"><a href="#cb38-16" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Incr</span> tl&#39; <span class="ot">-&gt;</span> <span class="kw">case</span> bl <span class="kw">of</span></span>
<span id="cb38-17"><a href="#cb38-17" aria-hidden="true" tabindex="-1"></a>          <span class="dt">L</span> <span class="ot">-&gt;</span> rotr k kc tl&#39; tr</span>
<span id="cb38-18"><a href="#cb38-18" aria-hidden="true" tabindex="-1"></a>          <span class="dt">O</span> <span class="ot">-&gt;</span> <span class="dt">Incr</span> (<span class="dt">Node</span> k kc <span class="dt">L</span> tl&#39; tr)</span>
<span id="cb38-19"><a href="#cb38-19" aria-hidden="true" tabindex="-1"></a>          <span class="dt">R</span> <span class="ot">-&gt;</span> <span class="dt">Stay</span> (<span class="dt">Node</span> k kc <span class="dt">O</span> tl&#39; tr)</span>
<span id="cb38-20"><a href="#cb38-20" aria-hidden="true" tabindex="-1"></a>    <span class="dt">EQ</span> <span class="ot">-&gt;</span></span>
<span id="cb38-21"><a href="#cb38-21" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Stay</span> (<span class="dt">Node</span> v (f vc kc) bl tl tr)</span>
<span id="cb38-22"><a href="#cb38-22" aria-hidden="true" tabindex="-1"></a>    <span class="dt">GT</span> <span class="ot">-&gt;</span></span>
<span id="cb38-23"><a href="#cb38-23" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> insertWith f v vc tr <span class="kw">of</span></span>
<span id="cb38-24"><a href="#cb38-24" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Stay</span> tr&#39; <span class="ot">-&gt;</span></span>
<span id="cb38-25"><a href="#cb38-25" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Stay</span> (<span class="dt">Node</span> k kc bl tl tr&#39;)</span>
<span id="cb38-26"><a href="#cb38-26" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Incr</span> tr&#39; <span class="ot">-&gt;</span> <span class="kw">case</span> bl <span class="kw">of</span></span>
<span id="cb38-27"><a href="#cb38-27" aria-hidden="true" tabindex="-1"></a>          <span class="dt">L</span> <span class="ot">-&gt;</span> <span class="dt">Stay</span> (<span class="dt">Node</span> k kc <span class="dt">O</span> tl tr&#39;)</span>
<span id="cb38-28"><a href="#cb38-28" aria-hidden="true" tabindex="-1"></a>          <span class="dt">O</span> <span class="ot">-&gt;</span> <span class="dt">Incr</span> (<span class="dt">Node</span> k kc <span class="dt">R</span> tl tr&#39;)</span>
<span id="cb38-29"><a href="#cb38-29" aria-hidden="true" tabindex="-1"></a>          <span class="dt">R</span> <span class="ot">-&gt;</span> rotl k kc tl tr&#39;</span></code></pre></div>
</div>
<div class="column">
<div class="sourceCode" id="cb39"><pre
class="sourceCode agda"><code class="sourceCode agda"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a>insert <span class="ot">:</span> <span class="ot">∀</span> <span class="ot">{</span>l u h v<span class="ot">}</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>           <span class="ot">{</span>V <span class="ot">:</span> Key <span class="ot">→</span> <span class="dt">Set</span> v<span class="ot">}</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>           <span class="ot">(</span>k <span class="ot">:</span> Key<span class="ot">)</span></span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a>       <span class="ot">→</span> V k</span>
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a>       <span class="ot">→</span> <span class="ot">(</span>V k <span class="ot">→</span> V k <span class="ot">→</span> V k<span class="ot">)</span></span>
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a>       <span class="ot">→</span> Tree V l u h</span>
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a>       <span class="ot">→</span> l &lt; k &lt; u</span>
<span id="cb39-8"><a href="#cb39-8" aria-hidden="true" tabindex="-1"></a>       <span class="ot">→</span> Tree V l u 1?+⟨ h ⟩</span>
<span id="cb39-9"><a href="#cb39-9" aria-hidden="true" tabindex="-1"></a>insert v vc f <span class="ot">(</span>leaf l&lt;u<span class="ot">)</span> <span class="ot">(</span>l , u<span class="ot">)</span> <span class="ot">=</span></span>
<span id="cb39-10"><a href="#cb39-10" aria-hidden="true" tabindex="-1"></a>  1+ <span class="ot">(</span>node v vc ▽ <span class="ot">(</span>leaf l<span class="ot">)</span> <span class="ot">(</span>leaf u<span class="ot">))</span></span>
<span id="cb39-11"><a href="#cb39-11" aria-hidden="true" tabindex="-1"></a>insert v vc f <span class="ot">(</span>node k kc bl tl tr<span class="ot">)</span> prf</span>
<span id="cb39-12"><a href="#cb39-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">with</span> compare v k</span>
<span id="cb39-13"><a href="#cb39-13" aria-hidden="true" tabindex="-1"></a>insert v vc f <span class="ot">(</span>node k kc bl tl tr<span class="ot">)</span> <span class="ot">(</span>l , <span class="ot">_)</span></span>
<span id="cb39-14"><a href="#cb39-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">|</span> tri&lt; a <span class="ot">_</span> <span class="ot">_</span> <span class="kw">with</span> insert v vc f tl <span class="ot">(</span>l , a<span class="ot">)</span></span>
<span id="cb39-15"><a href="#cb39-15" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> 0+ tl′ <span class="ot">=</span> 0+ <span class="ot">(</span>node k kc bl tl′ tr<span class="ot">)</span></span>
<span id="cb39-16"><a href="#cb39-16" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> 1+ tl′ <span class="kw">with</span> bl</span>
<span id="cb39-17"><a href="#cb39-17" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> ◿ <span class="ot">=</span> rotʳ k kc tl′ tr</span>
<span id="cb39-18"><a href="#cb39-18" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> ▽ <span class="ot">=</span> 1+ <span class="ot">(</span>node k kc  ◿  tl′ tr<span class="ot">)</span></span>
<span id="cb39-19"><a href="#cb39-19" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> ◺ <span class="ot">=</span> 0+ <span class="ot">(</span>node k kc  ▽  tl′ tr<span class="ot">)</span></span>
<span id="cb39-20"><a href="#cb39-20" aria-hidden="true" tabindex="-1"></a>insert v vc f <span class="ot">(</span>node k kc bl tl tr<span class="ot">)</span> <span class="ot">_</span></span>
<span id="cb39-21"><a href="#cb39-21" aria-hidden="true" tabindex="-1"></a>    <span class="ot">|</span> tri≈ <span class="ot">_</span> refl <span class="ot">_</span> <span class="ot">=</span></span>
<span id="cb39-22"><a href="#cb39-22" aria-hidden="true" tabindex="-1"></a>        0+ <span class="ot">(</span>node k <span class="ot">(</span>f vc kc<span class="ot">)</span> bl tl tr<span class="ot">)</span></span>
<span id="cb39-23"><a href="#cb39-23" aria-hidden="true" tabindex="-1"></a>insert v vc f <span class="ot">(</span>node k kc bl tl tr<span class="ot">)</span> <span class="ot">(_</span> , u<span class="ot">)</span></span>
<span id="cb39-24"><a href="#cb39-24" aria-hidden="true" tabindex="-1"></a>    <span class="ot">|</span> tri&gt; <span class="ot">_</span> <span class="ot">_</span> c <span class="kw">with</span> insert v vc f tr <span class="ot">(</span>c , u<span class="ot">)</span></span>
<span id="cb39-25"><a href="#cb39-25" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> 0+ tr′ <span class="ot">=</span> 0+ <span class="ot">(</span>node k kc bl tl tr′<span class="ot">)</span></span>
<span id="cb39-26"><a href="#cb39-26" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> 1+ tr′ <span class="kw">with</span> bl</span>
<span id="cb39-27"><a href="#cb39-27" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> ◿ <span class="ot">=</span> 0+ <span class="ot">(</span>node k kc ▽ tl tr′<span class="ot">)</span></span>
<span id="cb39-28"><a href="#cb39-28" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> ▽ <span class="ot">=</span> 1+ <span class="ot">(</span>node k kc ◺ tl tr′<span class="ot">)</span></span>
<span id="cb39-29"><a href="#cb39-29" aria-hidden="true" tabindex="-1"></a><span class="ot">...</span> <span class="ot">|</span> ◺ <span class="ot">=</span> rotˡ k kc tl tr′</span></code></pre></div>
</div>
</div>
<h1 id="conclusion">Conclusion</h1>
<p>Overall, I’ve been enjoying programming in Agda. The things I liked
and didn’t like surprised me:</p>
<dl>
<dt>Editor Support</dt>
<dd>
<p>Is excellent. I use <a href="http://spacemacs.org">spacemacs</a>, and
the whole thing worked pretty seamlessly. Proof search and auto was
maybe not as powerful as Idris’, although that might be down to lack of
experience (note—as I write this, I see you can enable case-splitting in
proof search, so it looks like I was right about my lack of experience).
In many ways, it was much better than Haskell’s editor support:
personally, I have never managed to get case-splitting to work in my
Haskell setup, never mind some of the fancier features that you get in
Agda.</p>
<p>It’s worth noting that my experience with Idris is similar: maybe
it’s something about dependent types?</p>
<p>Of course, I missed lots of extra tools, like linters, code
formatters, etc., but the tight integration with the compiler was so
useful it more than made up for it.</p>
<p>Also, I’d implore anyone who’s had trouble with emacs before to give
<a href="http://spacemacs.org">spacemacs</a> a go. It works well
out-of-the-box, and has a system for keybinding discovery that
<em>actually works</em>.</p>
</dd>
<dt>Documentation</dt>
<dd>
<p>Pretty good, considering. There are some missing parts (<a
href="https://agda.readthedocs.io/en/v2.5.4.1/language/rewriting.html">rewriting</a>
and <a
href="https://agda.readthedocs.io/en/v2.5.4.1/language/telescopes.html">telescopes</a>
are both stubs on the documentation site), but there seemed to be more
fully worked-out examples available online for different concepts when I
needed to figure them out.</p>
</dd>
</dl>
<p>Now, the thing about a lot of these complaints/commendations
(<em>especially</em> with regards to tooling and personal setups) is
that people tend to be pretty bad about evaluating how difficult finicky
tasks like editor setups are. Once you’ve gotten the hang of some of
this stuff, you forget that you ever didn’t. Agda is the second
dependently-typed language I’ve really gone for a deepish dive on, and
I’ve been using spacemacs for a while, so YMMV.</p>
<p>One area of the language itself that I would have liked to see more
on was irrelevance. Looking back at the definition of the tree type, in
the Haskell version there’s no singleton storing the height (the balance
type stores all the information we need), which means that it definitely
doesn’t exist at runtime. As I understand it, that implies that the type
should be irrelevant in the equivalent Agda. However, when I actually
mark it as irrelevant, everything works fine, except that missing cases
warnings start showing up. I couldn’t figure out why: Haskell was able
to infer full case coverage without the index, after all. Equality proof
erasure, also: is it safe? Consistent?</p>
<p>All in all, I’d encourage more Haskellers to give Agda a try. It’s
fun, interesting, and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒰</mi><mi>𝓃</mi><mi>𝒾</mi><mi>𝒸</mi><mi>ℴ</mi><mi>𝒹</mi><mi>ℯ</mi></mrow><annotation encoding="application/x-tex">\mathcal{Unicode}</annotation></semantics></math>!</p>
<h1 id="further-reading">Further Reading</h1>
<p>No “deletion is left as an exercise to the reader” here, no sir!
Fuller implementations of both the Haskell and Agda versions of the code
here are available: first, a pdf of the Agda code with lovely colours is
<a href="/pdfs/AVL.pdf">here</a>. The accompanying repository is <a
href="https://github.com/oisdk/agda-avl">here</a>, and the equivalent
for the Haskell code is <a
href="https://github.com/oisdk/verified-avl">here</a>. Of course, if you
would rather read something by someone who knows what they’re talking
about, please see the references below.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-danielsson_agda_2018" class="csl-entry" role="listitem">
Danielsson, Nils Anders. 2018. <span>“The <span>Agda</span> standard
library.”</span>
</div>
<div id="ref-mcbride_how_2014" class="csl-entry" role="listitem">
McBride, Conor Thomas. 2014. <span>“How to <span>Keep Your
Neighbours</span> in <span>Order</span>.”</span> In <em>Proceedings of
the 19th <span>ACM SIGPLAN International Conference</span> on
<span>Functional Programming</span></em>, 297–309. <span>ICFP</span>
’14. New York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2628136.2628163">10.1145/2628136.2628163</a>.
</div>
<div id="ref-pfaff_performance_2004" class="csl-entry" role="listitem">
Pfaff, Ben. 2004. <span>“Performance <span>Analysis</span> of
<span>BSTs</span> in <span>System Software</span>.”</span> In
<em>Proceedings of the <span>Joint International Conference</span> on
<span>Measurement</span> and <span>Modeling</span> of <span>Computer
Systems</span></em>, 410–411. <span>SIGMETRICS</span>
’04/<span>Performance</span> ’04. New York, NY, USA: <span>ACM</span>.
doi:<a
href="https://doi.org/10.1145/1005686.1005742">10.1145/1005686.1005742</a>.
</div>
<div id="ref-weirich_depending_2014" class="csl-entry" role="listitem">
Weirich, Stephanie. 2014. <span>“Depending on
<span>Types</span>.”</span> In <em>Proceedings of the 19th <span>ACM
SIGPLAN International Conference</span> on <span>Functional
Programming</span></em>, 241–241. <span>ICFP</span> ’14. New York, NY,
USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2628136.2631168">10.1145/2628136.2631168</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>My phrasing is maybe a little confusing here. When <code
class="sourceCode haskell"><span class="dt">Set</span></code> “has the
type” <code class="sourceCode agda"><span class="dt">Set₁</span></code>
it means that <code
class="sourceCode haskell"><span class="dt">Set</span></code> is
<em>in</em> <code
class="sourceCode agda"><span class="dt">Set₁</span></code>, not the
other way around.<a href="#fnref1" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Mon, 30 Jul 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-07-30-verified-avl.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Probabilistic Functional Programming</title>
    <link>https://doisinkidney.com/posts/2018-07-17-probability-presentation.html</link>
    <description><![CDATA[<div class="info">
    Posted on July 17, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Probability&#39;." href="/tags/Probability.html" rel="tag">Probability</a>
    
</div>

<p><a href="/pdfs/prob-presentation.pdf">Here</a> are the slides for a
short talk I gave to a reading group I’m in at Harvard today. The
speaker notes are included in the pdf, code and the tex is available in
the <a
href="https://github.com/oisdk/prob-presentation">repository</a>.</p>
]]></description>
    <pubDate>Tue, 17 Jul 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-07-17-probability-presentation.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Probability 5 Ways</title>
    <link>https://doisinkidney.com/posts/2018-06-30-probability-5-ways.html</link>
    <description><![CDATA[<div class="info">
    Posted on June 30, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Probability&#39;." href="/tags/Probability.html" rel="tag">Probability</a>, <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Ever since the famous pearl by <span class="citation"
data-cites="erwig_functional_2006">Erwig and Kollmansberger (<a
href="#ref-erwig_functional_2006" role="doc-biblioref">2006</a>)</span>,
probabilistic programming with monads has been an interesting and
diverse area in functional programming, with many different
approaches.</p>
<p>I’m going to present five here, some of which I have not seen
before.</p>
<h1 id="the-classic">The Classic</h1>
<p>As presented in the paper, a simple and elegant formulation of
probability distributions looks like this:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Prob</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runProb ::</span> [(a, <span class="dt">Rational</span>)]</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div>
<p>It’s a list of possible events, each tagged with their probability of
happening. Here’s the probability distribution representing a die roll,
for instance:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">die ::</span> <span class="dt">Prob</span> <span class="dt">Integer</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>die <span class="ot">=</span> [ (x, <span class="dv">1</span><span class="op">/</span><span class="dv">6</span>) <span class="op">|</span> x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">6</span>] ]</span></code></pre></div>
<p>The semantics can afford to be a little fuzzy: it doesn’t hugely
matter if the probabilities don’t add up to 1 (you can still extract
meaningful answers when they don’t). However, I can’t see a way in which
either negative probabilities or an empty list would make sense. It
would be nice if those states were unrepresentable.</p>
<p>Its monadic structure multiplies conditional events:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f xs <span class="ot">=</span> <span class="dt">Prob</span> [ (f x, p) <span class="op">|</span> (x,p) <span class="ot">&lt;-</span> runProb xs ]</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Prob</span> [(x,<span class="dv">1</span>)]</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    fs <span class="op">&lt;*&gt;</span> xs</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> <span class="dt">Prob</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        [ (f x,fp<span class="op">*</span>xp)</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> (f,fp) <span class="ot">&lt;-</span> runProb fs</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>        , (x,xp) <span class="ot">&lt;-</span> runProb xs ]</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    xs <span class="op">&gt;&gt;=</span> f</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> <span class="dt">Prob</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>        [ (y,xp<span class="op">*</span>yp)</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> (x,xp) <span class="ot">&lt;-</span> runProb xs</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>        , (y,yp) <span class="ot">&lt;-</span> runProb (f x) ]</span></code></pre></div>
<p>In most of the examples, we’ll need a few extra functions in order
for the types to be useful. First is support:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">support ::</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>support <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">fst</span> <span class="op">.</span> runProb</span></code></pre></div>
<p>And second is expectation:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">expect ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Rational</span>) <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>expect p xs <span class="ot">=</span> <span class="fu">sum</span> [ p x <span class="op">*</span> xp <span class="op">|</span> (x,xp) <span class="ot">&lt;-</span> runProb xs ]</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="ot">probOf ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>probOf p <span class="ot">=</span> expect (bool <span class="dv">0</span> <span class="dv">1</span> <span class="op">.</span> p)</span></code></pre></div>
<p>It’s useful to be able to construct uniform distributions:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>uniform xs <span class="ot">=</span> <span class="dt">Prob</span> [ (x,n) <span class="op">|</span> x <span class="ot">&lt;-</span> xs ]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    n <span class="ot">=</span> <span class="dv">1</span> <span class="op">%</span> <span class="fu">toEnum</span> (<span class="fu">length</span> xs)</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>die <span class="ot">=</span> uniform [<span class="dv">1</span><span class="op">..</span><span class="dv">6</span>]</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> probOf (<span class="dv">7</span><span class="op">==</span>) <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> die</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> die</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> (x<span class="op">+</span>y)</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">%</span> <span class="dv">6</span></span></code></pre></div>
<h1 id="the-bells-and-whistles">The Bells and Whistles</h1>
<p>As elegant as the above approach is, it leaves something to be
desired when it comes to efficiency. In particular, you’ll see a
combinatorial explosion at every step. To demonstrate, let’s take the
example above, using three-sided dice instead so it doesn’t take up too
much space.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>die <span class="ot">=</span> uniform [<span class="dv">1</span><span class="op">..</span><span class="dv">3</span>]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>example <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> die</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> die</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> (x<span class="op">+</span>y)</span></code></pre></div>
<p>The probability table looks like this:</p>
<pre class="center"><code>2 1/9
3 2/9
4 1/3
5 2/9
6 1/9</code></pre>
<p>But the internal representation looks like this:</p>
<pre><code>2 1/9
3 1/9
4 1/9
3 1/9
4 1/9
5 1/9
4 1/9
5 1/9
6 1/9</code></pre>
<p>States are duplicated, because the implementation has no way of
knowing that two outcomes are the same. We could collapse equivalent
outcomes if we used a <code
class="sourceCode haskell"><span class="dt">Map</span></code>, but then
we can’t implement <code
class="sourceCode haskell"><span class="dt">Functor</span></code>, <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>,
or <code
class="sourceCode haskell"><span class="dt">Monad</span></code>. The
types:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    fmap ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> f <span class="kw">where</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="ot">    pure ::</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    (&lt;*&gt;) ::</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Monad</span> f <span class="kw">where</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="ot">    (&gt;&gt;=) ::</span> f a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> f b</span></code></pre></div>
<p>Don’t allow an <code
class="sourceCode haskell"><span class="dt">Ord</span></code>
constraint, which is what we’d need to remove duplicates. We can instead
make our own classes which <em>do</em> allow constraints:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE RebindableSyntax #-}</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeFamilies     #-}</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> (<span class="dt">Functor</span>(..),<span class="dt">Applicative</span>(..),<span class="dt">Monad</span>(..))</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Kind</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="kw">where</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">Domain</span> f<span class="ot"> a ::</span> <span class="dt">Constraint</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">Domain</span> f a <span class="ot">=</span> ()</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a><span class="ot">    fmap ::</span> <span class="dt">Domain</span> f b <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> f <span class="kw">where</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# MINIMAL pure, liftA2 #-}</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a><span class="ot">    pure   ::</span> <span class="dt">Domain</span> f a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a><span class="ot">    liftA2 ::</span> <span class="dt">Domain</span> f c <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c</span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a><span class="ot">    (&lt;*&gt;) ::</span> <span class="dt">Domain</span> f b <span class="ot">=&gt;</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a>    (<span class="op">&lt;*&gt;</span>) <span class="ot">=</span> liftA2 (<span class="op">$</span>)</span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Monad</span> f <span class="kw">where</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a><span class="ot">    (&gt;&gt;=) ::</span> <span class="dt">Domain</span> f b <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> f b</span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a><span class="fu">fail</span><span class="ot"> ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> a</span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a><span class="fu">fail</span> <span class="ot">=</span> <span class="fu">error</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a><span class="fu">return</span><span class="ot"> ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Domain</span> f a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true" tabindex="-1"></a><span class="fu">return</span> <span class="ot">=</span> <span class="fu">pure</span></span></code></pre></div>
<p>This setup gets over a couple common annoyances in Haskell, like
making <a
href="http://hackage.haskell.org/package/containers-0.6.0.1/docs/Data-Set.html"><code
class="sourceCode haskell"><span class="dt">Data.Set</span></code></a> a
Monad:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">Domain</span> <span class="dt">Set</span> a <span class="ot">=</span> <span class="dt">Ord</span> a</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> <span class="ot">=</span> Set.map</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> <span class="ot">=</span> Set.singleton</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>    liftA2 f xs ys <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>        x <span class="ot">&lt;-</span> xs</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>        y <span class="ot">&lt;-</span> ys</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>        <span class="fu">pure</span> (f x y)</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>    (<span class="op">&gt;&gt;=</span>) <span class="ot">=</span> <span class="fu">flip</span> <span class="fu">foldMap</span></span></code></pre></div>
<p>And, of course, the probability monad:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> a <span class="ot">=</span> <span class="dt">Prob</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runProb ::</span> <span class="dt">Map</span> a <span class="dt">Rational</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">Domain</span> <span class="dt">Prob</span> a <span class="ot">=</span> <span class="dt">Ord</span> a</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f <span class="ot">=</span> <span class="dt">Prob</span> <span class="op">.</span> Map.mapKeysWith (<span class="op">+</span>) f <span class="op">.</span> runProb</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Prob</span> (Map.singleton x <span class="dv">1</span>)</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>    liftA2 f xs ys <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>      x <span class="ot">&lt;-</span> xs</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>      y <span class="ot">&lt;-</span> ys</span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>      <span class="fu">pure</span> (f x y)</span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Prob</span> a) <span class="kw">where</span></span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Prob</span> Map.empty</span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>    <span class="fu">mappend</span> (<span class="dt">Prob</span> xs) (<span class="dt">Prob</span> ys) <span class="ot">=</span> <span class="dt">Prob</span> (Map.unionWith (<span class="op">+</span>) xs ys)</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Prob</span> xs <span class="op">&gt;&gt;=</span> f</span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> Map.foldMapWithKey ((<span class="dt">Prob</span> <span class="op">.</span>) <span class="op">.</span> <span class="fu">flip</span> (Map.map <span class="op">.</span> (<span class="op">*</span>)) <span class="op">.</span> runProb <span class="op">.</span> f) xs</span>
<span id="cb13-23"><a href="#cb13-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-24"><a href="#cb13-24" aria-hidden="true" tabindex="-1"></a>support <span class="ot">=</span> Map.keys <span class="op">.</span> runProb</span>
<span id="cb13-25"><a href="#cb13-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-26"><a href="#cb13-26" aria-hidden="true" tabindex="-1"></a>expect p <span class="ot">=</span> getSum <span class="op">.</span> Map.foldMapWithKey (\k v <span class="ot">-&gt;</span> <span class="dt">Sum</span> (p k <span class="op">*</span> v)) <span class="op">.</span> runProb</span>
<span id="cb13-27"><a href="#cb13-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-28"><a href="#cb13-28" aria-hidden="true" tabindex="-1"></a>probOf p <span class="ot">=</span> expect (bool <span class="dv">0</span> <span class="dv">1</span> <span class="op">.</span> p)</span>
<span id="cb13-29"><a href="#cb13-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-30"><a href="#cb13-30" aria-hidden="true" tabindex="-1"></a>uniform xs <span class="ot">=</span> <span class="dt">Prob</span> (Map.fromList [ (x,n) <span class="op">|</span> x <span class="ot">&lt;-</span> xs ])</span>
<span id="cb13-31"><a href="#cb13-31" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-32"><a href="#cb13-32" aria-hidden="true" tabindex="-1"></a>    n <span class="ot">=</span> <span class="dv">1</span> <span class="op">%</span> <span class="fu">toEnum</span> (<span class="fu">length</span> xs)</span>
<span id="cb13-33"><a href="#cb13-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-34"><a href="#cb13-34" aria-hidden="true" tabindex="-1"></a>ifThenElse <span class="dt">True</span> t _ <span class="ot">=</span> t</span>
<span id="cb13-35"><a href="#cb13-35" aria-hidden="true" tabindex="-1"></a>ifThenElse <span class="dt">False</span> _ f <span class="ot">=</span> f</span>
<span id="cb13-36"><a href="#cb13-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-37"><a href="#cb13-37" aria-hidden="true" tabindex="-1"></a>die <span class="ot">=</span> uniform [<span class="dv">1</span><span class="op">..</span><span class="dv">6</span>]</span>
<span id="cb13-38"><a href="#cb13-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-39"><a href="#cb13-39" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> probOf (<span class="dv">7</span><span class="op">==</span>) <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb13-40"><a href="#cb13-40" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> die</span>
<span id="cb13-41"><a href="#cb13-41" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> die</span>
<span id="cb13-42"><a href="#cb13-42" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> (x <span class="op">+</span> y)</span>
<span id="cb13-43"><a href="#cb13-43" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">%</span> <span class="dv">6</span></span></code></pre></div>
<h1 id="free">Free</h1>
<p>Coming up with the right implementation all at once is quite
difficult: luckily, there are more general techniques for designing DSLs
that break the problem into smaller parts, which also give us some
insight into the underlying composition of the probability monad.</p>
<p>The technique relies on an algebraic concept called “free objects”. A
free object for some class is a minimal implementation of that class.
The classic example is lists: they’re the free monoid. Monoid requires
that you have an additive operation, an empty element, and that the
additive operation be associative. Lists have all of these things: what
makes them <em>free</em>, though, is that they have nothing else. For
instance, the additive operation on lists (concatenation) isn’t
commutative: if it was, they wouldn’t be the free monoid any more,
because they satisfy an extra law that’s not in monoid.</p>
<p>For our case, we can use the free monad: this takes a functor and
gives it a monad instance, in a way we know will satisfy all the laws.
This encoding is used in several papers <span class="citation"
data-cites="scibior_practical_2015 larsen_memory_2011">(<a
href="#ref-scibior_practical_2015" role="doc-biblioref">Ścibior,
Ghahramani, and Gordon 2015</a>; <a href="#ref-larsen_memory_2011"
role="doc-biblioref">Larsen 2011</a>)</span>.</p>
<p>The idea is to first figure out what primitive operation you need.
We’ll use weighted choice:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">choose ::</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Prob</span> a</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>choose <span class="ot">=</span> <span class="op">...</span></span></code></pre></div>
<p>Then you encode it as a functor:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Choose</span> a</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Choose</span> <span class="dt">Rational</span> a a</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Functor</span>,<span class="dt">Foldable</span>)</span></code></pre></div>
<p>We’ll say the left-hand-choice has chance
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>p</mi><annotation encoding="application/x-tex">p</annotation></semantics></math>,
and the right-hand
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1</mn><mo>−</mo><mi>p</mi></mrow><annotation encoding="application/x-tex">1-p</annotation></semantics></math>.
Then, you just wrap it in the free monad:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Prob</span> <span class="ot">=</span> <span class="dt">Free</span> <span class="dt">Choose</span></span></code></pre></div>
<p>And you already have a monad instance. Support comes from the <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Foldable.html#v:toList"><code
class="sourceCode haskell"><span class="dt">Foldable</span></code></a>
instance:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Foldable</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="ot">support ::</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>support <span class="ot">=</span> toList</span></code></pre></div>
<p>Expectation is an “interpreter” for the DSL:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">expect ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Rational</span>) <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>expect p <span class="ot">=</span> iter f <span class="op">.</span> <span class="fu">fmap</span> p</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Choose</span> c l r) <span class="ot">=</span> l <span class="op">*</span> c <span class="op">+</span> r <span class="op">*</span> (<span class="dv">1</span><span class="op">-</span>c)</span></code></pre></div>
<p>For building up the tree, we can use Huffman’s algorithm:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fromList ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Rational</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Prob</span> a</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>fromList p <span class="ot">=</span> go <span class="op">.</span> <span class="fu">foldMap</span> (\x <span class="ot">-&gt;</span> singleton (p x) (<span class="dt">Pure</span> x))</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    go xs <span class="ot">=</span> <span class="kw">case</span> minView xs <span class="kw">of</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;empty list&quot;</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Just</span> ((xp,x),ys) <span class="ot">-&gt;</span> <span class="kw">case</span> minView ys <span class="kw">of</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Nothing</span> <span class="ot">-&gt;</span> x</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Just</span> ((yp,y),zs) <span class="ot">-&gt;</span></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>          go (insertHeap (xp<span class="op">+</span>yp) (<span class="dt">Free</span> (<span class="dt">Choose</span> (xp<span class="op">/</span>(xp<span class="op">+</span>yp)) x y)) zs)</span></code></pre></div>
<p>And finally, it gets the same notation as before:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>uniform <span class="ot">=</span> fromList (<span class="fu">const</span> <span class="dv">1</span>)</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>die <span class="ot">=</span> uniform [<span class="dv">1</span><span class="op">..</span><span class="dv">6</span>]</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>probOf p <span class="ot">=</span> expect (bool <span class="dv">0</span> <span class="dv">1</span> <span class="op">.</span> p)</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> probOf (<span class="dv">7</span><span class="op">==</span>) <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> die</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> die</span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> (x <span class="op">+</span> y)</span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">%</span> <span class="dv">6</span></span></code></pre></div>
<p>One of the advantages of the free approach is that it’s easy to
define multiple interpreters. We could, for instance, write an
interpreter that constructs a diagram:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> drawTree ((,) <span class="op">&lt;$&gt;</span> uniform <span class="st">&quot;abc&quot;</span> <span class="op">&lt;*&gt;</span> uniform <span class="st">&quot;de&quot;</span>)</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>           ┌(<span class="ch">&#39;c&#39;</span>,<span class="ch">&#39;d&#39;</span>)</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>     ┌<span class="dv">1</span> <span class="op">%</span> <span class="dv">2</span>┤</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>     │     └(<span class="ch">&#39;c&#39;</span>,<span class="ch">&#39;e&#39;</span>)</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">%</span> <span class="dv">3</span>┤</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>     │           ┌(<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;d&#39;</span>)</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>     │     ┌<span class="dv">1</span> <span class="op">%</span> <span class="dv">2</span>┤</span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>     │     │     └(<span class="ch">&#39;a&#39;</span>,<span class="ch">&#39;e&#39;</span>)</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>     └<span class="dv">1</span> <span class="op">%</span> <span class="dv">2</span>┤</span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>           │     ┌(<span class="ch">&#39;b&#39;</span>,<span class="ch">&#39;d&#39;</span>)</span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a>           └<span class="dv">1</span> <span class="op">%</span> <span class="dv">2</span>┤</span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a>                 └(<span class="ch">&#39;b&#39;</span>,<span class="ch">&#39;e&#39;</span>)</span></code></pre></div>
<h1 id="final">Final</h1>
<p>There’s a lot to be said about free objects in category theory, also.
Specifically, they’re related to initial and terminal (also called
final) objects. The encoding above is initial, the final encoding is
simply <code
class="sourceCode haskell"><span class="dt">Cont</span></code>:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Cont</span> r a <span class="ot">=</span> <span class="dt">Cont</span> {<span class="ot"> runCont ::</span> (a <span class="ot">-&gt;</span> r) <span class="ot">-&gt;</span> r }</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Prob</span> <span class="ot">=</span> <span class="dt">Cont</span> <span class="dt">Rational</span></span></code></pre></div>
<p>Here, also, we get the monad instance for free. In contrast to
previously, expect is free:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>expect <span class="ot">=</span> <span class="fu">flip</span> runCont</span></code></pre></div>
<p>Support, though, isn’t possible.</p>
<p>This version is also called the Giry monad: there’s a deep and
fascinating theory behind it, which I probably won’t be able to do
justice to here. Check out Jared Tobin’s post <span class="citation"
data-cites="tobin_implementing_2017">(<a
href="#ref-tobin_implementing_2017"
role="doc-biblioref">2017</a>)</span> for a good deep dive on it.</p>
<h1 id="cofree">Cofree</h1>
<p>The branching structure of the tree captures the semantics of the
probability monad well, but it doesn’t give us much insight into the
original implementation. The question is, how can we deconstruct
this:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> a</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Prob</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runProb ::</span> [(a, <span class="dt">Rational</span>)]</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div>
<p>Eric Kidd <span class="citation" data-cites="kidd_build_2007">(<a
href="#ref-kidd_build_2007" role="doc-biblioref">2007</a>)</span>
pointed out that the monad is the composition of the writer and list
monads:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Prob</span> <span class="ot">=</span> <span class="dt">WriterT</span> (<span class="dt">Product</span> <span class="dt">Rational</span>) []</span></code></pre></div>
<p>but that seems unsatisfying: in contrast to the tree-based version,
we don’t encode any branching structure, we’re able to have empty
distributions, and it has the combinatorial explosion problem.</p>
<p>Adding a weighting to nondeterminism is encapsulated more concretely
by the <code
class="sourceCode haskell"><span class="dt">ListT</span></code>
transformer. It looks like this:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ListT</span> m a</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">ListT</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runListT ::</span> m (<span class="dt">Maybe</span> (a, <span class="dt">ListT</span> m a))</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div>
<p>It’s a cons-list, with an effect before every layer<a href="#fn1"
class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a>.</p>
<p>While this can be used to give us the monad we need, I’ve found that
something more like this fits the abstraction better:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ListT</span> m a</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">ListT</span> a (m (<span class="dt">Maybe</span> (<span class="dt">ListT</span> m a)))</span></code></pre></div>
<p>It’s a nonempty list, with the first element exposed. Turns out this
is very similar to the cofree comonad:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Cofree</span> f a <span class="ot">=</span> a <span class="op">:&lt;</span> f (<span class="dt">Cofree</span> f a)</span></code></pre></div>
<p>Just like the initial free encoding, we can start with a primitive
operation:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Perhaps</span> a</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Impossible</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">WithChance</span> <span class="dt">Rational</span> a</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Functor</span>,<span class="dt">Foldable</span>)</span></code></pre></div>
<p>And we get all of our instances as well:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> a</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Prob</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runProb ::</span> <span class="dt">Cofree</span> <span class="dt">Perhaps</span> a</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>    } <span class="kw">deriving</span> (<span class="dt">Functor</span>,<span class="dt">Foldable</span>)</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Comonad</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>    extract (<span class="dt">Prob</span> xs) <span class="ot">=</span> extract xs</span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>    duplicate (<span class="dt">Prob</span> xs) <span class="ot">=</span> <span class="dt">Prob</span> (<span class="fu">fmap</span> <span class="dt">Prob</span> (duplicate xs))</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a><span class="ot">foldProb ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> b</span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a>foldProb f b <span class="ot">=</span> r <span class="op">.</span> runProb</span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a>    r (x <span class="op">:&lt;</span> <span class="dt">Impossible</span>) <span class="ot">=</span> b x</span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a>    r (x <span class="op">:&lt;</span> <span class="dt">WithChance</span> p xs) <span class="ot">=</span> f x p (r xs)</span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a><span class="ot">uniform ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Prob</span> a</span>
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a>uniform (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Prob</span> (coiterW f (<span class="dt">EnvT</span> (<span class="fu">length</span> xs) (x <span class="op">:|</span> xs)))</span>
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb30-19"><a href="#cb30-19" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">EnvT</span> <span class="dv">0</span> (_ <span class="op">:|</span> [])) <span class="ot">=</span> <span class="dt">Impossible</span></span>
<span id="cb30-20"><a href="#cb30-20" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">EnvT</span> n (_ <span class="op">:|</span> (y<span class="op">:</span>ys)))</span>
<span id="cb30-21"><a href="#cb30-21" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> <span class="dt">WithChance</span> (<span class="dv">1</span> <span class="op">%</span> <span class="fu">fromIntegral</span> n) (<span class="dt">EnvT</span> (n <span class="op">-</span> <span class="dv">1</span>) (y<span class="op">:|</span>ys))</span>
<span id="cb30-22"><a href="#cb30-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-23"><a href="#cb30-23" aria-hidden="true" tabindex="-1"></a><span class="ot">expect ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Rational</span>) <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb30-24"><a href="#cb30-24" aria-hidden="true" tabindex="-1"></a>expect p <span class="ot">=</span> foldProb f p</span>
<span id="cb30-25"><a href="#cb30-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb30-26"><a href="#cb30-26" aria-hidden="true" tabindex="-1"></a>    f x n xs <span class="ot">=</span> (p x <span class="op">*</span> n <span class="op">+</span> xs) <span class="op">/</span> (n <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb30-27"><a href="#cb30-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-28"><a href="#cb30-28" aria-hidden="true" tabindex="-1"></a><span class="ot">probOf ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb30-29"><a href="#cb30-29" aria-hidden="true" tabindex="-1"></a>probOf p <span class="ot">=</span> expect (\x <span class="ot">-&gt;</span> <span class="kw">if</span> p x <span class="kw">then</span> <span class="dv">1</span> <span class="kw">else</span> <span class="dv">0</span>)</span>
<span id="cb30-30"><a href="#cb30-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-31"><a href="#cb30-31" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb30-32"><a href="#cb30-32" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Prob</span> (x <span class="op">:&lt;</span> <span class="dt">Impossible</span>)</span>
<span id="cb30-33"><a href="#cb30-33" aria-hidden="true" tabindex="-1"></a>    (<span class="op">&lt;*&gt;</span>) <span class="ot">=</span> ap</span>
<span id="cb30-34"><a href="#cb30-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-35"><a href="#cb30-35" aria-hidden="true" tabindex="-1"></a><span class="ot">append ::</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Prob</span> a</span>
<span id="cb30-36"><a href="#cb30-36" aria-hidden="true" tabindex="-1"></a>append <span class="ot">=</span> foldProb f (\x y <span class="ot">-&gt;</span>  <span class="dt">Prob</span> <span class="op">.</span> (x <span class="op">:&lt;</span>) <span class="op">.</span> <span class="dt">WithChance</span> y <span class="op">.</span> runProb)</span>
<span id="cb30-37"><a href="#cb30-37" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb30-38"><a href="#cb30-38" aria-hidden="true" tabindex="-1"></a>    f e r a p <span class="ot">=</span> <span class="dt">Prob</span> <span class="op">.</span> (e <span class="op">:&lt;</span>) <span class="op">.</span> <span class="dt">WithChance</span> ip <span class="op">.</span> runProb <span class="op">.</span> a op</span>
<span id="cb30-39"><a href="#cb30-39" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb30-40"><a href="#cb30-40" aria-hidden="true" tabindex="-1"></a>        ip <span class="ot">=</span> p <span class="op">*</span> r <span class="op">/</span> (p <span class="op">+</span> r <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb30-41"><a href="#cb30-41" aria-hidden="true" tabindex="-1"></a>        op <span class="ot">=</span> p <span class="op">/</span> (r <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb30-42"><a href="#cb30-42" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-43"><a href="#cb30-43" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb30-44"><a href="#cb30-44" aria-hidden="true" tabindex="-1"></a>    xs <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> foldProb (append <span class="op">.</span> f) f xs</span></code></pre></div>
<p>We see here that we’re talking about gambling-style odds, rather than
probability. I wonder if the two representations are dual somehow?</p>
<p>The application of comonads to streams (<code
class="sourceCode haskell"><span class="dt">ListT</span></code>) has
been explored before <span class="citation"
data-cites="uustalu_essence_2005">(<a href="#ref-uustalu_essence_2005"
role="doc-biblioref">Uustalu and Vene 2005</a>)</span>; I wonder if
there are any insights to be gleaned from this particular probability
comonad.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-erwig_functional_2006" class="csl-entry" role="listitem">
Erwig, Martin, and Steve Kollmansberger. 2006. <span>“Functional pearls:
<span>Probabilistic</span> functional programming in
<span>Haskell</span>.”</span> <em>Journal of Functional Programming</em>
16 (1): 21–34. doi:<a
href="https://doi.org/10.1017/S0956796805005721">10.1017/S0956796805005721</a>.
</div>
<div id="ref-kidd_build_2007" class="csl-entry" role="listitem">
Kidd, Eric. 2007. <span>“Build your own probability monads.”</span>
</div>
<div id="ref-larsen_memory_2011" class="csl-entry" role="listitem">
Larsen, Ken Friis. 2011. <span>“Memory <span>Efficient
Implementation</span> of <span>Probability Monads</span>.”</span>
</div>
<div id="ref-scibior_practical_2015" class="csl-entry" role="listitem">
Ścibior, Adam, Zoubin Ghahramani, and Andrew D. Gordon. 2015.
<span>“Practical <span>Probabilistic Programming</span> with
<span>Monads</span>.”</span> In <em>Proceedings of the 2015 <span>ACM
SIGPLAN Symposium</span> on <span>Haskell</span></em>, 50:165–176.
Haskell ’15. New York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2804302.2804317">10.1145/2804302.2804317</a>.
</div>
<div id="ref-tobin_implementing_2017" class="csl-entry" role="listitem">
Tobin, Jared. 2017. <span>“Implementing the <span>Giry
Monad</span>.”</span> <em>jtobin.io</em>.
</div>
<div id="ref-uustalu_essence_2005" class="csl-entry" role="listitem">
Uustalu, Tarmo, and Varmo Vene. 2005. <span>“The <span>Essence</span> of
<span>Dataflow Programming</span>.”</span> In <em>Proceedings of the
<span>Third Asian Conference</span> on <span>Programming
Languages</span> and <span>Systems</span></em>, 2–18.
<span>APLAS</span>’05. Berlin, Heidelberg: <span>Springer-Verlag</span>.
doi:<a href="https://doi.org/10.1007/11575467_2">10.1007/11575467_2</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Note this is <em>not</em> the same as the <code
class="sourceCode haskell"><span class="dt">ListT</span></code> in <a
href="http://hackage.haskell.org/package/transformers-0.5.5.0/docs/Control-Monad-Trans-List.html">transformers</a>;
instead it’s a “<a
href="https://wiki.haskell.org/ListT_done_right">ListT done
right</a>”.<a href="#fnref1" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Sat, 30 Jun 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-06-30-probability-5-ways.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Scheduling Effects</title>
    <link>https://doisinkidney.com/posts/2018-06-23-scheduling-effects.html</link>
    <description><![CDATA[<div class="info">
    Posted on June 23, 2018
</div>
<div class="info">
    
        Part 4 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>After the <a
href="2018-06-03-breadth-first-traversals-in-too-much-detail.html">last
post</a>, Noah Easterly pointed me to their <a
href="https://hackage.haskell.org/package/tree-traversals">tree-traversals
library</a>, and in particular the <a
href="https://hackage.haskell.org/package/tree-traversals-0.1.0.0/docs/Control-Applicative-Phases.html#t:Phases"><code
class="sourceCode haskell"><span class="dt">Phases</span></code></a>
applicative transformer. It allows you to batch applicative effects to
be run together: for the breadth-first traversal, we can batch the
effects from each level together, giving us a lovely short solution to
the problem.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>breadthFirst c <span class="ot">=</span> runPhasesForwards <span class="op">.</span> go</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    go (x<span class="op">:&lt;</span>xs) <span class="ot">=</span> liftA2 (<span class="op">:&lt;</span>) (now (c x)) (delay (<span class="fu">traverse</span> go xs))</span></code></pre></div>
<p>In my efforts to speed this implementation up, I came across a wide
and interesting literature on scheduling effects, which I’ll go through
a little here.</p>
<h1 id="coroutines">Coroutines</h1>
<p>The first thing that jumps to mind, for me, when I think of
“scheduling” is coroutines. These are constructs that let you finely
control the order of execution of effects. They’re well explored in
Haskell by now, and most libraries will let you do something like the
following:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>oneThenTwo <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  liftIO <span class="op">$</span> <span class="fu">print</span> <span class="dv">1</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  delay <span class="op">$</span> liftIO <span class="op">$</span> <span class="fu">print</span> <span class="dv">2</span></span></code></pre></div>
<p>We first print <code>1</code>, then, after a delay, we print
<code>2</code>. The <code class="sourceCode haskell">delay</code>
doesn’t make a difference if we just run the whole thing:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> retract oneThenTwo</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span></code></pre></div>
<p>But you can see its effect when we use the <code
class="sourceCode haskell">interleave</code> combinator:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> retract <span class="op">$</span> interleave (<span class="fu">replicate</span> <span class="dv">3</span> oneThenTwo)</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span></code></pre></div>
<p>Hopefully you can see how useful this might be, and the similarity to
the <code
class="sourceCode haskell"><span class="dt">Phases</span></code>
construction.</p>
<p>The genealogy of most coroutine libraries in Haskell seems to trace
back to <span class="citation"
data-cites="blazevic_coroutine_2011">Blažević (<a
href="#ref-blazevic_coroutine_2011"
role="doc-biblioref">2011</a>)</span> or <span class="citation"
data-cites="kiselyov_iteratees_2012">Kiselyov (<a
href="#ref-kiselyov_iteratees_2012"
role="doc-biblioref">2012</a>)</span>: the implementation I have been
using in these past few examples (<a
href="http://hackage.haskell.org/package/free-5.0.2/docs/Control-Monad-Trans-Iter.html"><code>IterT</code></a>)
comes from a slightly different place. Let’s take a quick detour to
explore it a little.</p>
<h1 id="partiality">Partiality</h1>
<p>In functional programming, there are several constructions for
modeling error-like states: <code
class="sourceCode haskell"><span class="dt">Maybe</span></code> for your
nulls, <code
class="sourceCode haskell"><span class="dt">Either</span></code> for
your exceptions. What separates these approaches from the “unsafe”
variants (null pointers, unchecked exceptions) is that we can
<em>prove</em>, in the type system, that the error case is handled
correctly.</p>
<p>Conspicuously absent from the usual toolbox for modeling partiality
is a way to model <em>nontermination</em>. At first glance, it may seem
strange to attempt to do so in Haskell. After all, if I have a function
of type:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span></code></pre></div>
<p>I can prove that I won’t throw any errors (with <code
class="sourceCode haskell"><span class="dt">Either</span></code>, that
is), because the type <code
class="sourceCode haskell"><span class="dt">Int</span></code> doesn’t
contain <code
class="sourceCode haskell"><span class="dt">Left</span> _</code>. I’ve
also proved, miraculously, that I won’t make any null dereferences,
because <code
class="sourceCode haskell"><span class="dt">Int</span></code> also
doesn’t contain <code
class="sourceCode haskell"><span class="dt">Nothing</span></code>. I
<em>haven’t</em> proved, however, that I won’t loop infinitely, because
(in Haskell), <code
class="sourceCode haskell"><span class="dt">Int</span></code> absolutely
<em>does</em> contain
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>⊥</mi><annotation encoding="application/x-tex">\bot</annotation></semantics></math>.</p>
<p>So we’re somewhat scuppered. On the other hand, while we can’t
<em>prove</em> termination in Haskell, we can:</p>
<ol>
<li>Model it.</li>
<li>Prove it in something else.</li>
</ol>
<p>Which is exactly what Venanzio Capretta did in the fascinating (and
quite accessible) talk “Partiality is an effect” <span class="citation"
data-cites="capretta_partiality_2004">(<a
href="#ref-capretta_partiality_2004" role="doc-biblioref">Capretta,
Altenkirch, and Uustalu 2004</a>)</span><a href="#fn1"
class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a>.</p>
<p>The monad in question looks like this:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode idris"><code class="sourceCode idris"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Iter</span> a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">=</span> <span class="dt">Now</span> a</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">|</span> <span class="dt">Later</span> (<span class="dt">Inf</span> (<span class="dt">Iter</span> a))</span></code></pre></div>
<p>We’re writing in Idris for the time being, so that we can prove
termination and so on. The “recursive call” to <code
class="sourceCode haskell"><span class="dt">Iter</span></code> is
guarded by the <code
class="sourceCode haskell"><span class="dt">Inf</span></code> type: this
turns on a different kind of totality checking in the compiler. Usually,
Idris will prevent you from constructing infinite values. But that’s
exactly what we want to do here. Take the little-known function <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Prelude.html#v:until"><code
class="sourceCode haskell"><span class="fu">until</span></code></a>:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">until</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>It’s clearly not necessarily total, and the totality checker will
complain as such when we try and implement it directly:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode idris"><code class="sourceCode idris"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">until</span> <span class="ot">:</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>until p f x <span class="fu">=</span> <span class="kw">if</span> p x <span class="kw">then</span> x <span class="kw">else</span> until p f (f x)</span></code></pre></div>
<p>But we can use <code
class="sourceCode haskell"><span class="dt">Iter</span></code> to model
that possible totality:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode idris"><code class="sourceCode idris"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">until</span> <span class="ot">:</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Iter</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>until p f x <span class="fu">=</span> <span class="kw">if</span> p x <span class="kw">then</span> <span class="dt">Now</span> x <span class="kw">else</span> <span class="dt">Later</span> (until p f (f x))</span></code></pre></div>
<p>Of course, nothing’s for free: when we get the ability to construct
infinite values, we lose the ability to consume them.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode idris"><code class="sourceCode idris"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="fu">run</span> <span class="ot">:</span> <span class="dt">Iter</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>run (<span class="dt">Now</span> x) <span class="fu">=</span> x</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>run (<span class="dt">Later</span> x) <span class="fu">=</span> run x</span></code></pre></div>
<p>We get an error on the <code class="sourceCode haskell">run</code>
function. However, as you would expect, we can run <em>guarded</em>
iteration: iteration up until some finite point.</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode idris"><code class="sourceCode idris"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">runUntil</span> <span class="ot">:</span> <span class="dt">Nat</span> <span class="ot">-&gt;</span> <span class="dt">Iter</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>runUntil <span class="dt">Z</span> <span class="fu">_</span> <span class="fu">=</span> <span class="dt">Nothing</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>runUntil (<span class="dt">S</span> n) (<span class="dt">Now</span> x) <span class="fu">=</span> <span class="dt">Just</span> x</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>runUntil (<span class="dt">S</span> n) (<span class="dt">Later</span> x) <span class="fu">=</span> runUntil n x</span></code></pre></div>
<p>Making our way back to Haskell, we must first—as is the law—add a
type parameter, and upgrade our humble monad to a monad transformer:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">IterT</span> m a <span class="ot">=</span> <span class="dt">IterT</span> {<span class="ot"> runIterT ::</span> m (<span class="dt">Either</span> a (<span class="dt">IterT</span> m a)) }</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Iter</span> <span class="ot">=</span> <span class="dt">IterT</span> <span class="dt">Identity</span></span></code></pre></div>
<p>The semantic meaning of the extra <code
class="sourceCode haskell">m</code> here is interesting: each layer adds
not just a recursive step, or a single iteration, but a single effect.
Interpreting things in this way gets us back to the original goal:</p>
<h1 id="scheduling">Scheduling</h1>
<p>The <code
class="sourceCode haskell"><span class="dt">Later</span></code>
constructor above can be translated to a <code
class="sourceCode haskell">delay</code> function on the transformer:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>delay <span class="ot">=</span> <span class="dt">IterT</span> <span class="op">.</span> <span class="fu">pure</span> <span class="op">.</span> <span class="dt">Right</span></span></code></pre></div>
<p>And using this again, we can write the following incredibly short
definition for <code
class="sourceCode haskell">unfoldTreeM_BF</code>:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">unfoldTreeM_BF ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> m (a, [b])) <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> m (<span class="dt">Tree</span> a)</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>unfoldTreeM_BF f <span class="ot">=</span> retract <span class="op">.</span> go</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    go b <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>      (x,xs) <span class="ot">&lt;-</span> lift (f b)</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>      <span class="fu">fmap</span> (<span class="dt">Node</span> x) (interleave (<span class="fu">map</span> (delay <span class="op">.</span> go) xs))</span></code></pre></div>
<h1 id="applicative">Applicative</h1>
<p>It would be nice to bring this back to traversals, but alas, <code
class="sourceCode haskell"><span class="dt">IterT</span></code> is
pretty monad-centric. What’s more, if it’s analogous to <code
class="sourceCode haskell"><span class="dt">Phases</span></code> it
certainly doesn’t look like it:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Phases</span> f a <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lift</span><span class="ot"> ::</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:&lt;*&gt;) ::</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f b</span></code></pre></div>
<p>However, in the documentation for <a
href="http://hackage.haskell.org/package/free-5.0.2/docs/Control-Monad-Trans-Iter.html#t:IterT"><code
class="sourceCode haskell"><span class="dt">IterT</span></code></a>,
there’s the following little note:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="dt">IterT</span> <span class="op">~</span> <span class="dt">FreeT</span> <span class="dt">Identity</span></span></code></pre></div>
<p>Where <code
class="sourceCode haskell"><span class="dt">FreeT</span></code> is the
<a
href="http://hackage.haskell.org/package/free-5.0.2/docs/Control-Monad-Trans-Free.html">free
monad transformer</a>. This seems to strongly hint that we could get the
same thing for applicatives with <a
href="http://hackage.haskell.org/package/free-5.0.2/docs/Control-Applicative-Trans-Free.html"><code
class="sourceCode haskell"><span class="dt">ApT</span></code></a>. Let’s
try it:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Phases</span> f a <span class="ot">=</span> <span class="dt">Phases</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runPhases ::</span> <span class="dt">ApT</span> <span class="dt">Identity</span> f a</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    } <span class="kw">deriving</span> <span class="dt">Functor</span></span></code></pre></div>
<p>The <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
instance is a little hairy, but it <em>seems</em> correct:</p>
<details>
<summary>
Applicative Instance
</summary>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Applicative</span> (<span class="dt">Phases</span> f) <span class="kw">where</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Phases</span> <span class="op">.</span> <span class="fu">pure</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    liftA2 f&#39; (<span class="dt">Phases</span> (<span class="dt">ApT</span> xs&#39;)) (<span class="dt">Phases</span> (<span class="dt">ApT</span> ys&#39;)) <span class="ot">=</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Phases</span> (<span class="dt">ApT</span> (liftA2 (go f&#39;) xs&#39; ys&#39;))</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>        go</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="ot">            ::</span> ∀ a b c<span class="op">.</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>               (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c)</span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">ApF</span> <span class="dt">Identity</span> f a</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">ApF</span> <span class="dt">Identity</span> f b</span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">ApF</span> <span class="dt">Identity</span> f c</span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>        go f (<span class="dt">Pure</span> x) ys <span class="ot">=</span> <span class="fu">fmap</span> (f x) ys</span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>        go f xs (<span class="dt">Pure</span> y) <span class="ot">=</span> <span class="fu">fmap</span> (<span class="ot">`f`</span> y) xs</span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>        go f (<span class="dt">Ap</span> x (<span class="dt">ApT</span> xs)) (<span class="dt">Ap</span> y (<span class="dt">ApT</span> ys)) <span class="ot">=</span></span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Ap</span></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>                (liftA2 (,) x y)</span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a>                (<span class="dt">ApT</span> (liftA2 (go (\xx yy <span class="ot">-&gt;</span> <span class="fu">uncurry</span> f <span class="op">.</span> (xx <span class="op">***</span> yy))) xs ys))</span></code></pre></div>
</details>
<p>(on a side note: thank <em>goodness</em> for <code
class="sourceCode haskell">liftA2</code> finally getting into <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>)</p>
<p>And we get all the normal combinators:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">delay ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>delay <span class="ot">=</span> <span class="dt">Phases</span> <span class="op">.</span> <span class="dt">ApT</span> <span class="op">.</span> <span class="fu">pure</span> <span class="op">.</span> <span class="dt">Ap</span> (<span class="fu">pure</span> ()) <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">const</span> <span class="op">.</span> runPhases</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="ot">lift ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>lift <span class="ot">=</span> <span class="dt">Phases</span> <span class="op">.</span> liftApO</span></code></pre></div>
<p>The issue comes with running the thing at the end: <code
class="sourceCode haskell"><span class="dt">Monad</span></code> creeps
back in.</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">retract ::</span> <span class="dt">Monad</span> f <span class="ot">=&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>retract <span class="ot">=</span> <span class="fu">fmap</span> (runIdentity <span class="op">.</span> retractAp) <span class="op">.</span> joinApT <span class="op">.</span> runPhases</span></code></pre></div>
<p>Because the effects are all layered on top of each other, you need to
flatten them out at the end, which requires <code
class="sourceCode haskell">join</code>. Mind you, it does work: it’s
just not as general as it could be.</p>
<p>All’s not lost, though. Turns out, we never needed the transformer in
the first place: we could just define the different applicative instance
straight off.</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Phases</span> f a <span class="ot">=</span> <span class="dt">Phases</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runPhases ::</span> <span class="dt">Ap</span> f a</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    } <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Applicative</span> (<span class="dt">Phases</span> f) <span class="kw">where</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Phases</span> <span class="op">.</span> <span class="dt">Pure</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>    liftA2 f&#39; (<span class="dt">Phases</span> xs&#39;) (<span class="dt">Phases</span> ys&#39;) <span class="ot">=</span> <span class="dt">Phases</span> (go f&#39; xs&#39; ys&#39;)</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a><span class="ot">        go ::</span> ∀ a b c<span class="op">.</span></span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a>              (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c)</span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> <span class="dt">Ap</span> f a</span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> <span class="dt">Ap</span> f b</span>
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> <span class="dt">Ap</span> f c</span>
<span id="cb21-15"><a href="#cb21-15" aria-hidden="true" tabindex="-1"></a>        go f (<span class="dt">Pure</span> x) ys <span class="ot">=</span> <span class="fu">fmap</span> (f x) ys</span>
<span id="cb21-16"><a href="#cb21-16" aria-hidden="true" tabindex="-1"></a>        go f xs (<span class="dt">Pure</span> y) <span class="ot">=</span> <span class="fu">fmap</span> (<span class="ot">`f`</span> y) xs</span>
<span id="cb21-17"><a href="#cb21-17" aria-hidden="true" tabindex="-1"></a>        go f (<span class="dt">Ap</span> x xs) (<span class="dt">Ap</span> y ys) <span class="ot">=</span></span>
<span id="cb21-18"><a href="#cb21-18" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Ap</span></span>
<span id="cb21-19"><a href="#cb21-19" aria-hidden="true" tabindex="-1"></a>                (liftA2 (,) x y)</span>
<span id="cb21-20"><a href="#cb21-20" aria-hidden="true" tabindex="-1"></a>                (go (\xx yy <span class="ot">-&gt;</span> <span class="fu">uncurry</span> f <span class="op">.</span> (xx <span class="op">***</span> yy)) xs ys)</span>
<span id="cb21-21"><a href="#cb21-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-22"><a href="#cb21-22" aria-hidden="true" tabindex="-1"></a><span class="ot">delay ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb21-23"><a href="#cb21-23" aria-hidden="true" tabindex="-1"></a>delay <span class="ot">=</span> <span class="dt">Phases</span> <span class="op">.</span> <span class="dt">Ap</span> (<span class="fu">pure</span> ()) <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">const</span> <span class="op">.</span> runPhases</span>
<span id="cb21-24"><a href="#cb21-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-25"><a href="#cb21-25" aria-hidden="true" tabindex="-1"></a><span class="ot">retract ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Phases</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb21-26"><a href="#cb21-26" aria-hidden="true" tabindex="-1"></a>retract <span class="ot">=</span> retractAp <span class="op">.</span> runPhases</span>
<span id="cb21-27"><a href="#cb21-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-28"><a href="#cb21-28" aria-hidden="true" tabindex="-1"></a><span class="ot">lift ::</span> f a <span class="ot">-&gt;</span> <span class="dt">Phases</span> f a</span>
<span id="cb21-29"><a href="#cb21-29" aria-hidden="true" tabindex="-1"></a>lift <span class="ot">=</span> <span class="dt">Phases</span> <span class="op">.</span> liftAp</span></code></pre></div>
<h1 id="more-coroutines">More Coroutines</h1>
<p>In the wonderful article Coroutine Pipelines <span class="citation"
data-cites="blazevic_coroutine_2011">(<a
href="#ref-blazevic_coroutine_2011" role="doc-biblioref">Blažević
2011</a>)</span>, several different threads on coroutine-like
constructions are unified. What I’ve demonstrated above isn’t yet as
powerful as what you might see in a full coroutine library: ideally,
you’d want generators and sinks. As it turns out, when we look back at
the note from <code
class="sourceCode haskell"><span class="dt">IterT</span></code>:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="dt">IterT</span> <span class="op">~</span> <span class="dt">FreeT</span> <span class="dt">Identity</span></span></code></pre></div>
<p>We can get both of those other constructs by swapping out <code
class="sourceCode haskell"><span class="dt">Identity</span></code><a
href="#fn2" class="footnote-ref" id="fnref2"
role="doc-noteref"><sup>2</sup></a>:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Generator</span> a <span class="ot">=</span> <span class="dt">FreeT</span> ((,) a)</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Sink</span> a <span class="ot">=</span> <span class="dt">FreeT</span> ((<span class="ot">-&gt;</span>) a)</span></code></pre></div>
<p>(<code class="sourceCode haskell"><span class="dt">Sink</span></code>
is usually called an <code
class="sourceCode haskell"><span class="dt">Iteratee</span></code>)</p>
<p>This is the fundamental abstraction that underlies things like the
pipes library <span class="citation"
data-cites="gonzalez_pipes_2018">(<a href="#ref-gonzalez_pipes_2018"
role="doc-biblioref">Gonzalez 2018</a>)</span>.</p>
<h1 id="interleaving">Interleaving</h1>
<p>The only missing part from the first coroutine example by now is
<code class="sourceCode haskell">interleave</code>. In the free library,
it has the following signature:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="ot">interleave ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> [<span class="dt">IterT</span> m a] <span class="ot">-&gt;</span> <span class="dt">IterT</span> m [a]</span></code></pre></div>
<p>But we should be able to spot that, really, it’s a traversal. And, as
a traversal, it should rely on some underlying <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
instance. Let’s try and come up with one:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Parallel</span> m f a <span class="ot">=</span> <span class="dt">Parallel</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runParallel ::</span> <span class="dt">FreeT</span> m f a</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Functor</span> f, <span class="dt">Functor</span> m) <span class="ot">=&gt;</span></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Functor</span> (<span class="dt">Parallel</span> m f) <span class="kw">where</span></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f <span class="ot">=</span> <span class="dt">Parallel</span> <span class="op">.</span> <span class="dt">FreeT</span> <span class="op">.</span> <span class="fu">fmap</span> go <span class="op">.</span> runFreeT <span class="op">.</span> runParallel</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>        go <span class="ot">=</span> bimap f (<span class="dt">FreeT</span> <span class="op">.</span> <span class="fu">fmap</span> go <span class="op">.</span> runFreeT)</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Applicative</span> f, <span class="dt">Applicative</span> m) <span class="ot">=&gt;</span></span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Applicative</span> (<span class="dt">Parallel</span> m f) <span class="kw">where</span></span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Parallel</span> <span class="op">.</span> <span class="dt">FreeT</span> <span class="op">.</span> <span class="fu">pure</span> <span class="op">.</span> <span class="dt">Pure</span></span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Parallel</span> fs&#39; <span class="op">&lt;*&gt;</span> <span class="dt">Parallel</span> xs&#39; <span class="ot">=</span> <span class="dt">Parallel</span> (unw fs&#39; xs&#39;)</span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a>        unw (<span class="dt">FreeT</span> fs) (<span class="dt">FreeT</span> xs) <span class="ot">=</span> <span class="dt">FreeT</span> (liftA2 go fs xs)</span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a>        go (<span class="dt">Pure</span> f) <span class="ot">=</span> bimap f (runParallel <span class="op">.</span> <span class="fu">fmap</span> f <span class="op">.</span> <span class="dt">Parallel</span>)</span>
<span id="cb25-18"><a href="#cb25-18" aria-hidden="true" tabindex="-1"></a>        go (<span class="dt">Free</span> fs) <span class="ot">=</span> <span class="dt">Free</span> <span class="op">.</span> \<span class="kw">case</span></span>
<span id="cb25-19"><a href="#cb25-19" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Pure</span> x <span class="ot">-&gt;</span> <span class="fu">fmap</span> (runParallel <span class="op">.</span> <span class="fu">fmap</span> (<span class="op">$</span>x) <span class="op">.</span> <span class="dt">Parallel</span>) fs</span>
<span id="cb25-20"><a href="#cb25-20" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Free</span> xs <span class="ot">-&gt;</span> liftA2 unw fs xs</span></code></pre></div>
<p>Now, interleave is just <code
class="sourceCode haskell"><span class="fu">sequenceA</span></code>!</p>
<h1 id="applicatives-again">Applicatives, Again</h1>
<p>So we can see that there’s a “parallel” applicative for both the free
monad and the free applicative. To try and understand this type a little
better, we can leverage our intuition about a much simpler, more
familiar setting: lists. There’s an interesting similarity between lists
and the free monad: <code
class="sourceCode haskell"><span class="dt">FreeT</span> ((,) a)</code>)
looks a lot like “<a
href="https://wiki.haskell.org/ListT_done_right"><code
class="sourceCode haskell"><span class="dt">ListT</span></code> done
right</a>” (so much so, in fact, that most coroutine libraries provide
their own version of it). More concretely, list also has a famous
“parallel” applicative: <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Applicative.html#t:ZipList"><code
class="sourceCode haskell"><span class="dt">ZipList</span></code></a>!</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ZipList</span> a</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">ZipList</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> getZipList ::</span> [a]</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>    } <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">ZipList</span> <span class="kw">where</span></span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">ZipList</span> <span class="op">.</span> <span class="fu">repeat</span></span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>  liftA2 f (<span class="dt">ZipList</span> xs) (<span class="dt">ZipList</span> ys) <span class="ot">=</span> <span class="dt">ZipList</span> (<span class="fu">zipWith</span> f xs ys)</span></code></pre></div>
<p>We’ll use some of our knowledge about <code
class="sourceCode haskell"><span class="dt">ZipList</span></code> to
help us in the next section.</p>
<h1 id="timekeeping">Timekeeping</h1>
<p>We’ve seen that efforts to model both coroutines and partiality end
up in the same neighborhood: there’s yet another way to get there, which
seems (at first) almost the opposite of the second. It starts with a
blog post from Conor McBride <span class="citation"
data-cites="mcbride_time_2009">(<a href="#ref-mcbride_time_2009"
role="doc-biblioref">2009</a>)</span> called “Time flies like an
applicative functor”. Curiously, here too breadth-first labeling is the
focus. Remember first the lovely circular solution from <span
class="citation" data-cites="jones_linear-time_1993">Jones and Gibbons
(<a href="#ref-jones_linear-time_1993"
role="doc-biblioref">1993</a>)</span>:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> <span class="dt">Leaf</span> <span class="op">|</span> <span class="dt">Node</span> a (<span class="dt">Tree</span> a) (<span class="dt">Tree</span> a)</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a><span class="ot">relabel ::</span> <span class="dt">Tree</span> x <span class="ot">-&gt;</span> [[a]] <span class="ot">-&gt;</span> (<span class="dt">Tree</span> a, [[a]])</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>relabel <span class="dt">Leaf</span> xss <span class="ot">=</span> (<span class="dt">Leaf</span>,xss)</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>relabel (<span class="dt">Node</span> _ l r) ((x<span class="op">:</span>xs)<span class="op">:</span>xss0) <span class="ot">=</span></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> (l&#39;,xss1) <span class="ot">=</span> relabel l xss0</span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>      (r&#39;,xss2) <span class="ot">=</span> relabel r xss1</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span> (<span class="dt">Node</span> x l&#39; r&#39;,xs<span class="op">:</span>xss2)</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a><span class="ot">bflabel ::</span> <span class="dt">Tree</span> x <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a>bflabel tr xs <span class="ot">=</span> u</span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb27-13"><a href="#cb27-13" aria-hidden="true" tabindex="-1"></a>    (u,xss) <span class="ot">=</span> relabel tr (xs<span class="op">:</span>xss)</span></code></pre></div>
<p>As lovely as it is, spare a thought for the poor totality checker:
it’s hard to imagine how it would even <em>start</em> to show that
something so lazy and circular would terminate. <code
class="sourceCode haskell"><span class="dt">IterT</span></code> won’t
help us here, either: it can help us express programs that
<em>might</em> diverge, not weird-looking ones that definitely
won’t.</p>
<p>The solution presented is a type (<code
class="sourceCode haskell"><span class="dt">De</span></code>) which has
a limited set of combinators: a fixpoint (<code
class="sourceCode haskell"><span class="ot">fix ::</span> (<span class="dt">De</span> x <span class="ot">-&gt;</span> x) <span class="ot">-&gt;</span> x</code>),
and an applicative instance. As long as all problematic recursive calls
are instead expressed using those combinators, the termination checker
should be satisfied.</p>
<p><code class="sourceCode haskell"><span class="dt">De</span></code>
can be thought of as a “delay” wrapper. Values of type <code
class="sourceCode haskell"><span class="dt">De</span> a</code> are one
step in the future, <code
class="sourceCode haskell"><span class="dt">De</span> (<span class="dt">De</span> a)</code>
are two, and so on. This idea was later expanded upon in <span
class="citation" data-cites="atkey_how_2011">Atkey (<a
href="#ref-atkey_how_2011" role="doc-biblioref">2011</a>)</span> and
<span class="citation" data-cites="atkey_productive_2013">Atkey and
McBride (<a href="#ref-atkey_productive_2013"
role="doc-biblioref">2013</a>)</span> to <em>clock variables</em>.
Instead of types with a delay, types are tagged with how much more time
they have (something like “fuel” in the Idris sense, maybe). So a value
of type
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mi>a</mi><mi>𝖪</mi></msup><annotation encoding="application/x-tex">a^\mathsf{K}</annotation></semantics></math>
is tagged with time
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>𝖪</mi><annotation encoding="application/x-tex">\mathsf{K}</annotation></semantics></math>,
effectively meaning “I have
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>𝖪</mi><annotation encoding="application/x-tex">\mathsf{K}</annotation></semantics></math>
productive steps left before I diverge”. “Productive steps” will mean
something different for every data type: for lists, it could mean that
it can produce up until the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>𝖪</mi><annotation encoding="application/x-tex">\mathsf{K}</annotation></semantics></math>th
cons-cell. In the paper <span class="citation"
data-cites="atkey_productive_2013">(<a href="#ref-atkey_productive_2013"
role="doc-biblioref">Atkey and McBride 2013</a>)</span> this is fleshed
out a little more, with fixpoint combinators and so on. As a concrete
example, take the type of the cons operator on streams:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Cons</mtext><mo>:</mo><mtext mathvariant="normal">a</mtext><mo>→</mo><msup><mtext mathvariant="normal">Stream a</mtext><mi>𝖪</mi></msup><mo>→</mo><msup><mtext mathvariant="normal">Stream a</mtext><mrow><mi>𝖪</mi><mo>+</mo><mn>1</mn></mrow></msup></mrow><annotation encoding="application/x-tex">\begin{equation}
\text{Cons} : \text{a}
\rightarrow \text{Stream a}^\mathsf{K}
\rightarrow \text{Stream a}^{\mathsf{K}+1}
\end{equation}</annotation></semantics></math></p>
<p>It increments the clock on the type, saying that it has one more
productive step than it did before. This is kind of the opposite of a
“delay”: previously, the scheduling types have meant “this is available
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>𝖪</mi><annotation encoding="application/x-tex">\mathsf{K}</annotation></semantics></math>
number of steps in the future” rather than “this is available for
another
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>𝖪</mi><annotation encoding="application/x-tex">\mathsf{K}</annotation></semantics></math>
steps”. We can still describe delays in this system, though, using the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mo>⊳</mo><mi>𝖪</mi></msup><annotation encoding="application/x-tex">\rhd^\mathsf{K}</annotation></semantics></math>
notation:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Cons</mtext><mo>:</mo><mtext mathvariant="normal">a</mtext><mo>→</mo><msup><mo>⊳</mo><mi>𝖪</mi></msup><mtext mathvariant="normal">Stream a</mtext><mo>→</mo><mtext mathvariant="normal">Stream a</mtext></mrow><annotation encoding="application/x-tex">\begin{equation}
\text{Cons} : \text{a}
\rightarrow \rhd^\mathsf{K}\text{Stream a}
\rightarrow \text{Stream a}
\end{equation}</annotation></semantics></math></p>
<p>Let’s first try express some of this in the free monad:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">K</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">K</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Delay</span><span class="ot"> ::</span> <span class="dt">K</span> <span class="ot">-&gt;</span> (<span class="dt">Type</span> <span class="ot">-&gt;</span> <span class="dt">Type</span>) <span class="ot">-&gt;</span> (<span class="dt">Type</span> <span class="ot">-&gt;</span> <span class="dt">Type</span>) <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Now</span><span class="ot">   ::</span> a <span class="ot">-&gt;</span> <span class="dt">Delay</span> n f m a</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Later</span><span class="ot"> ::</span> f (<span class="dt">DelayT</span> n f m a) <span class="ot">-&gt;</span> <span class="dt">Delay</span> (<span class="dt">S</span> n) f m a</span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Functor</span> f, <span class="dt">Functor</span> m) <span class="ot">=&gt;</span> <span class="dt">Functor</span> (<span class="dt">Delay</span> n f m) <span class="kw">where</span></span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Now</span> x) <span class="ot">=</span> <span class="dt">Now</span> (f x)</span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Later</span> xs) <span class="ot">=</span> <span class="dt">Later</span> (<span class="fu">fmap</span> (<span class="fu">fmap</span> f) xs)</span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-11"><a href="#cb28-11" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">DelayT</span> n f m a <span class="ot">=</span> <span class="dt">DelayT</span> {<span class="ot"> runDelayT ::</span> m (<span class="dt">Delay</span> n f m a) }</span>
<span id="cb28-12"><a href="#cb28-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-13"><a href="#cb28-13" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Functor</span> f, <span class="dt">Functor</span> m) <span class="ot">=&gt;</span></span>
<span id="cb28-14"><a href="#cb28-14" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Functor</span> (<span class="dt">DelayT</span> n f m) <span class="kw">where</span></span>
<span id="cb28-15"><a href="#cb28-15" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f <span class="ot">=</span> <span class="dt">DelayT</span> <span class="op">.</span> <span class="fu">fmap</span> (<span class="fu">fmap</span> f) <span class="op">.</span> runDelayT</span></code></pre></div>
<p>We can straight away express one of the combinators from the paper,
<code class="sourceCode haskell">force</code>:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="ot">force ::</span> <span class="dt">Functor</span> m <span class="ot">=&gt;</span> (∀ k<span class="op">.</span> <span class="dt">DelayT</span> k f m a) <span class="ot">-&gt;</span> m a</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>force (<span class="dt">DelayT</span> xs) <span class="ot">=</span> <span class="fu">fmap</span> f xs</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> <span class="dt">Delay</span> <span class="dt">Z</span> f m a <span class="ot">-&gt;</span> a</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Now</span> x) <span class="ot">=</span> x</span></code></pre></div>
<p>Similar trick to <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Monad-ST.html#v:runST"><code
class="sourceCode haskell">runST</code></a> here: if the type is delayed
however long we want it to be, then it mustn’t really be delayed at
all.</p>
<p>Next, remember that we have types for streams (generators) from the
<code class="sourceCode haskell"><span class="dt">IterT</span></code>
monad:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Stream</span> n a <span class="ot">=</span> <span class="dt">DelayT</span> n ((,) a)</span></code></pre></div>
<p>And cons does indeed have the right type:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> <span class="dt">Applicative</span> m <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Stream</span> n a m b <span class="ot">-&gt;</span> <span class="dt">Stream</span> (<span class="dt">S</span> n) a m b</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>cons x xs <span class="ot">=</span> <span class="dt">DelayT</span> (<span class="fu">pure</span> (<span class="dt">Later</span> (x,xs)))</span></code></pre></div>
<p>We also get an applicative:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Applicative</span> f, <span class="dt">Applicative</span> m) <span class="ot">=&gt;</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Applicative</span> (<span class="dt">DelayT</span> n f m) <span class="kw">where</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">DelayT</span> <span class="op">.</span> <span class="fu">pure</span> <span class="op">.</span> <span class="dt">Now</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">DelayT</span> fs&#39; <span class="op">&lt;*&gt;</span> <span class="dt">DelayT</span> xs&#39; <span class="ot">=</span> <span class="dt">DelayT</span> (liftA2 go fs&#39; xs&#39;)</span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a><span class="ot">        go ::</span> ∀ k a b<span class="op">.</span> <span class="dt">Delay</span> k f m (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Delay</span> k f m a <span class="ot">-&gt;</span> <span class="dt">Delay</span> k f m b</span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>        go (<span class="dt">Now</span> f) <span class="ot">=</span> <span class="fu">fmap</span> f</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a>        go (<span class="dt">Later</span> fs) <span class="ot">=</span> <span class="dt">Later</span> <span class="op">.</span> \<span class="kw">case</span></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Now</span> x <span class="ot">-&gt;</span> <span class="fu">fmap</span> (<span class="fu">fmap</span> (<span class="op">$</span>x)) fs</span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Later</span> xs <span class="ot">-&gt;</span> liftA2 (<span class="op">&lt;*&gt;</span>) fs xs</span></code></pre></div>
<p>Now, I’m not sure how much this stuff actually corresponds to the
paper, but what caught my eye is the statement that <code
class="sourceCode haskell"><span class="dt">De</span></code> is a
classic “applicative-not-monad”: just like <code
class="sourceCode haskell"><span class="dt">ZipList</span></code>.
However, under the analogy that the free monad is listy, and the
parallel construction is ziplist-y, what we have in the <code
class="sourceCode haskell"><span class="dt">DelayT</span></code> is the
equivalent of a length-indexed list. These have an applicative instance
similar to ziplists: but they also have a monad. Can we apply the same
trick here?</p>
<h1 id="future-posts">Future Posts</h1>
<p>There’s a lot of fascinating stuff out there—about clock variables,
especially—that I hope to get a chance to learn about once I get a
chance. What I’m particularly interested to follow up on includes:</p>
<ol>
<li>Comonads and their relationship to these constructions. Streams are
naturally expressed as comonads, could they be used as a basis on which
to build a similar “delay” mechanism?</li>
<li>I’d love to explore more efficient implementations like the ones in
<span class="citation" data-cites="spivey_faster_2017">M. Spivey (<a
href="#ref-spivey_faster_2017"
role="doc-biblioref">2017</a>)</span>.</li>
<li>I’m interested to see the relationship between these types, power
series, and algebras for combinatorial search <span class="citation"
data-cites="spivey_algebras_2009">(<a href="#ref-spivey_algebras_2009"
role="doc-biblioref">J. M. Spivey 2009</a>)</span>.</li>
</ol>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-atkey_how_2011" class="csl-entry" role="listitem">
Atkey, Robert. 2011. <span>“How to be a <span>Productive
Programmer</span> - by putting things off until tomorrow.”</span>
Heriot-Watt University.
</div>
<div id="ref-atkey_productive_2013" class="csl-entry" role="listitem">
Atkey, Robert, and Conor McBride. 2013. <span>“Productive coprogramming
with guarded recursion.”</span> In, 197. <span>ACM Press</span>. doi:<a
href="https://doi.org/10.1145/2500365.2500597">10.1145/2500365.2500597</a>.
</div>
<div id="ref-blazevic_coroutine_2011" class="csl-entry" role="listitem">
Blažević, Mario. 2011. <span>“Coroutine <span>Pipelines</span>.”</span>
<em>The Monad.Reader</em> 19 (19) (August): 29–50.
</div>
<div id="ref-capretta_general_2005" class="csl-entry" role="listitem">
Capretta, Venanzio. 2005. <span>“General <span>Recursion</span> via
<span>Coinductive Types</span>.”</span> <em>Logical Methods in Computer
Science</em> 1 (2) (July). doi:<a
href="https://doi.org/10.2168/LMCS-1(2:1)2005">10.2168/LMCS-1(2:1)2005</a>.
<a
href="https://arxiv.org/abs/cs/0505037">https://arxiv.org/abs/cs/0505037</a>.
</div>
<div id="ref-capretta_partiality_2004" class="csl-entry"
role="listitem">
Capretta, Venanzio, Thorsten Altenkirch, and Tarmo Uustalu. 2004.
<span>“Partiality is an effect.”</span> In <em>Dependently <span>Typed
Programming</span></em>, 04381:20. Dagstuhl <span>Seminar
Proceedings</span>. Dagstuhl, Germany: <span>Internationales Begegnungs-
und Forschungszentrum für Informatik (IBFI), Schloss Dagstuhl,
Germany</span>.
</div>
<div id="ref-gonzalez_pipes_2018" class="csl-entry" role="listitem">
Gonzalez, Gabriel. 2018. <span>“Pipes: <span>Compositional</span>
pipelines.”</span>
</div>
<div id="ref-jones_linear-time_1993" class="csl-entry" role="listitem">
Jones, Geraint, and Jeremy Gibbons. 1993. <em>Linear-time
<span>Breadth</span>-first <span>Tree Algorithms</span>: <span>An
Exercise</span> in the <span>Arithmetic</span> of <span>Folds</span> and
<span>Zips</span></em>. <span>Dept of Computer Science, University of
Auckland</span>.
</div>
<div id="ref-kiselyov_iteratees_2012" class="csl-entry" role="listitem">
Kiselyov, Oleg. 2012. <span>“Iteratees.”</span> In <em>Proceedings of
the 11th <span>International Conference</span> on
<span>Functional</span> and <span>Logic Programming</span></em>,
166–181. Lecture <span>Notes</span> in <span>Computer Science</span>.
Berlin, Heidelberg: <span>Springer, Berlin, Heidelberg</span>. doi:<a
href="https://doi.org/10.1007/978-3-642-29822-6_15">10.1007/978-3-642-29822-6_15</a>.
</div>
<div id="ref-mcbride_time_2009" class="csl-entry" role="listitem">
McBride, Conor. 2009. <span>“Time flies like an applicative
functor.”</span> <em>Epilogue for Epigram</em>.
</div>
<div id="ref-spivey_algebras_2009" class="csl-entry" role="listitem">
Spivey, J. Michael. 2009. <span>“Algebras for combinatorial
search.”</span> <em>Journal of Functional Programming</em> 19 (3-4)
(July): 469–487. doi:<a
href="https://doi.org/10.1017/S0956796809007321">10.1017/S0956796809007321</a>.
</div>
<div id="ref-spivey_faster_2017" class="csl-entry" role="listitem">
Spivey, Michael. 2017. <span>“Faster coroutine pipelines.”</span>
<em>Proceedings of the ACM on Programming Languages</em> 1 (ICFP)
(August): 1–23. doi:<a
href="https://doi.org/10.1145/3110249">10.1145/3110249</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>There is a later, seemingly more formal version of the
talk available <span class="citation"
data-cites="capretta_general_2005">(<a href="#ref-capretta_general_2005"
role="doc-biblioref">Capretta 2005</a>)</span>, but the one from 2004
was a little easier for me to understand, and had a lot more Haskell
code.<a href="#fnref1" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Small note: <code>(,) a</code> and
<code>(-&gt;) a</code> are adjunct. I wonder if there is any implication
from this? Certainly, producers and consumers seem adjunct, but there’s
no instance I can find for it in adjunctions.<a href="#fnref2"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Sat, 23 Jun 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-06-23-scheduling-effects.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Rotations</title>
    <link>https://doisinkidney.com/posts/2018-06-03-rotations-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on June  3, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>This is just some cool-looking stuff I figured out when I was trying
to figure out zipper-like algorithms. When I do get around to doing a
deep dive on zippers (especially comonadic zippers) I’ll probably be
able to write a full post on some of the underlying theory (with maybe
some more efficient implementations).</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleContexts #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Rotations</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad.Tardis</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Applicative</span> ((&lt;**&gt;))</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- | &gt;&gt;&gt; rotations &quot;abcd&quot;</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- [&quot;abcd&quot;,&quot;bcda&quot;,&quot;cdab&quot;,&quot;dabc&quot;]</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="ot">rotations ::</span> [a] <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>rotations <span class="ot">=</span> <span class="fu">flip</span> evalTardis (<span class="fu">id</span>,<span class="fu">id</span>) <span class="op">.</span> <span class="fu">traverse</span> f</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    f x <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>      xs <span class="ot">&lt;-</span> <span class="fu">pure</span> [] <span class="op">&lt;**&gt;</span> getPast <span class="op">&lt;**&gt;</span> getFuture</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>      modifyBackwards ((<span class="op">:</span>) x <span class="op">.</span>)</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>      modifyForwards  (<span class="op">.</span> (<span class="op">:</span>) x)</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>      <span class="fu">pure</span> xs</span></code></pre></div>
]]></description>
    <pubDate>Sun, 03 Jun 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-06-03-rotations-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Breadth-First Traversals in Far Too Much Detail</title>
    <link>https://doisinkidney.com/posts/2018-06-03-breadth-first-traversals-in-too-much-detail.html</link>
    <description><![CDATA[<div class="info">
    Posted on June  3, 2018
</div>
<div class="info">
    
        Part 3 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>After looking at the algorithms I <a
href="2018-06-01-rose-trees-breadth-first-traversing.html">posted last
time</a>, I noticed some patterns emerging which I thought deserved a
slightly longer post. I’ll go through the problem <span class="citation"
data-cites="gibbons_breadth-first_2015">(<a
href="#ref-gibbons_breadth-first_2015" role="doc-biblioref">Gibbons
2015</a>)</span> in a little more detail, and present some more
algorithms to go along with it.</p>
<h1 id="the-problem">The Problem</h1>
<p>The original question was posed by <a
href="https://www.facebook.com/groups/programming.haskell/permalink/985981691412832/">Etian
Chatav</a>:</p>
<blockquote>
<p>What is the correct way to write breadth first traversal of a <code
class="sourceCode haskell">[<span class="dt">Tree</span>]</code>?</p>
</blockquote>
<p>The breadth-first traversal here is a traversal in the lensy sense,
i.e:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirst ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> [<span class="dt">Tree</span> a] <span class="ot">-&gt;</span> f [<span class="dt">Tree</span> b]</span></code></pre></div>
<p>The <code
class="sourceCode haskell"><span class="dt">Tree</span></code> type
we’re referring to here is a rose tree; we can take the one defined in
<a
href="http://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Tree.html#t:Tree"><code
class="sourceCode haskell"><span class="dt">Data.Tree</span></code></a>:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Node</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> rootLabel ::</span> a</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> subForest ::</span> [<span class="dt">Tree</span> a]</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div>
<p>Finally, instead of solving the (somewhat intermediate) problem of
traversing a forest, we’ll look directly at traversing the tree itself.
In other words, our solution should have the type:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirst ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> f (<span class="dt">Tree</span> b)</span></code></pre></div>
<h1 id="breadth-first-enumeration">Breadth-First Enumeration</h1>
<p>As in <span class="citation"
data-cites="gibbons_breadth-first_2015">Gibbons (<a
href="#ref-gibbons_breadth-first_2015"
role="doc-biblioref">2015</a>)</span>, let’s first look at just
converting the tree to a list in breadth-first order. In other words,
given the tree:</p>
<pre><code>   ┌3
 ┌2┤
 │ └4
1┤
 │ ┌6
 └5┤
   └7</code></pre>
<p>We want the list:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">5</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">7</span>]</span></code></pre></div>
<p>Last time I looked at this problem, the function I arrived at was as
follows:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirstEnumerate ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>breadthFirstEnumerate ts <span class="ot">=</span> f ts b []</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (xs <span class="op">:</span> bw)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b qs []</span></code></pre></div>
<p>It’s admittedly a little difficult to understand, but it’s really not
too complex: we’re popping items off the front of a queue, and pushing
the subforest onto the end. <code class="sourceCode haskell">fw</code>
is the recursive call here: that’s where we send the queue with the
element pushed on. Even though it may <em>look</em> like we’re pushing
onto the front (as we’re using a cons), this is really the <em>end</em>
of the queue, since it’s being consumed in reverse, with <code
class="sourceCode haskell"><span class="fu">foldl</span></code>.</p>
<p>We can compare it to the technique used in <span class="citation"
data-cites="allison_circular_2006">Allison (<a
href="#ref-allison_circular_2006" role="doc-biblioref">2006</a>)</span>
and <span class="citation" data-cites="smith_lloyd_2009">Smith (<a
href="#ref-smith_lloyd_2009" role="doc-biblioref">2009</a>)</span>,
where it’s called <em>corecursive queues</em>. Breadth-first enumeration
is accomplished as follows in <span class="citation"
data-cites="smith_lloyd_2009">Smith (<a href="#ref-smith_lloyd_2009"
role="doc-biblioref">2009</a>)</span>:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levelOrder ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>levelOrder tr <span class="ot">=</span> <span class="fu">map</span> rootLabel qs</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    qs <span class="ot">=</span> enqs [tr] <span class="dv">0</span> qs</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    enqs []     n xs <span class="ot">=</span> deq n xs</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    enqs (t<span class="op">:</span>ts) n xs <span class="ot">=</span> t <span class="op">:</span> enqs  ts (n<span class="op">+</span><span class="dv">1</span>) xs</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>    deq <span class="dv">0</span> _      <span class="ot">=</span> []</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    deq n (x<span class="op">:</span>xs) <span class="ot">=</span> enqs (subForest x) (n<span class="op">-</span><span class="dv">1</span>) xs</span></code></pre></div>
<p>We get to avoid tracking the length of the queue, however.</p>
<h1 id="level-order-enumeration">Level-Order Enumeration</h1>
<p>Before we go the full way to traversal, we can try add a little
structure to our breadth-first enumeration, by delimiting between levels
in the tree. We want our function to have the following type:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levels ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [[a]]</span></code></pre></div>
<p>Looking back at our example tree:</p>
<pre><code>   ┌3
 ┌2┤
 │ └4
1┤
 │ ┌6
 └5┤
   └7</code></pre>
<p>We now want the list:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">5</span>],[<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">6</span>,<span class="dv">7</span>]]</span></code></pre></div>
<p>This function is strictly more powerful than <code
class="sourceCode haskell">breadthFirstEnumerate</code>, as we can
define one in terms of the other:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>breadthFirstEnumerate <span class="ot">=</span> <span class="fu">concat</span> <span class="op">.</span> levels</span></code></pre></div>
<p>It’s also just a generally useful function, so there are several
example implementations available online.</p>
<h3 id="iterative-style">Iterative-Style</h3>
<p>The one provided in <a
href="http://hackage.haskell.org/package/containers-0.5.11.0/docs/src/Data.Tree.html#levels">Data.Tree</a>
is as follows:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>levels t <span class="ot">=</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">map</span> (<span class="fu">map</span> rootLabel) <span class="op">$</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>        <span class="fu">takeWhile</span> (<span class="fu">not</span> <span class="op">.</span> <span class="fu">null</span>) <span class="op">$</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>        <span class="fu">iterate</span> (<span class="fu">concatMap</span> subForest) [t]</span></code></pre></div>
<p>Pretty nice, but it looks to me like it’s doing a lot of redundant
work. We could write it as an unfold:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>levels t <span class="ot">=</span>  unfoldr (f <span class="op">.</span> <span class="fu">concat</span>) [[t]]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    f [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    f xs <span class="ot">=</span> <span class="dt">Just</span> (<span class="fu">unzip</span> [(y,ys) <span class="op">|</span> <span class="dt">Node</span> y ys <span class="ot">&lt;-</span> xs])</span></code></pre></div>
<p>The performance danger here lies in <code
class="sourceCode haskell"><span class="fu">unzip</span></code>: one
could potentially optimize that for a speedup.</p>
<h3 id="with-an-implicit-queue">With an (implicit) Queue</h3>
<p>Another definition, in the style of <code
class="sourceCode haskell">breadthFirstEnumerate</code> above, is as
follows:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>levels ts <span class="ot">=</span> f b ts [] []</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    f k (<span class="dt">Node</span> x xs) ls qs <span class="ot">=</span> k (x <span class="op">:</span> ls) (xs <span class="op">:</span> qs)</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    b _ [] <span class="ot">=</span> []</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    b k qs <span class="ot">=</span> k <span class="op">:</span> <span class="fu">foldl</span> (<span class="fu">foldl</span> f) b qs [] []</span></code></pre></div>
<p>Here, we maintain a stack building up the current level, as well as a
queue that we send to the next level. Because we’re consing onto the
front of the stack, the subforest needs to be traversed in reverse, to
build up the output list in the right order. This is why we’re using a
second <code
class="sourceCode haskell"><span class="fu">foldl</span></code> here,
whereas the original had <code
class="sourceCode haskell"><span class="fu">foldr</span></code> on the
inner loop.</p>
<h3 id="zippy-style">Zippy-Style</h3>
<p>Looking at the implicit queue version, I noticed that it’s just using
a church-encoded pair to reverse the direction of the fold. Instead of
doing both reversals, we can use a normal pair, and run it in one
direction:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>levels ts <span class="ot">=</span> b (f ts ([],[]))</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) (ls,qs) <span class="ot">=</span> (x<span class="op">:</span>ls,xs<span class="op">:</span>qs)</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    b (_,[]) <span class="ot">=</span> []</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>    b (k,qs) <span class="ot">=</span> k <span class="op">:</span> b (<span class="fu">foldr</span> (<span class="fu">flip</span> (<span class="fu">foldr</span> f)) ([],[]) qs)</span></code></pre></div>
<p>Secondly, we’re running a fold on the second component of the pair:
why not run the fold immediately, rather than building the intermediate
list. In fact, we’re running a fold over the <em>whole</em> thing, which
we can do straight away:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>levels ts <span class="ot">=</span> f ts []</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) (q<span class="op">:</span>qs) <span class="ot">=</span> (x<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) []     <span class="ot">=</span> [x]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>After looking at it for a while, I realized it’s similar to an
inlined version of the algorithm presented in <span class="citation"
data-cites="gibbons_breadth-first_2015">Gibbons (<a
href="#ref-gibbons_breadth-first_2015"
role="doc-biblioref">2015</a>)</span>:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>levels t <span class="ot">=</span> [rootLabel t] <span class="op">:</span> <span class="fu">foldr</span> (lzw (<span class="op">++</span>)) [] (<span class="fu">map</span> levels (subForest t))</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    lzw f (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> f x y <span class="op">:</span> lzw f xs ys</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    lzw _ xs [] <span class="ot">=</span> xs</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>    lzw _ [] ys <span class="ot">=</span> ys</span></code></pre></div>
<h1 id="cofree">Cofree</h1>
<p>Before going any further, all of the functions so far can be
redefined to work on the <a
href="http://hackage.haskell.org/package/free-5.0.2/docs/Control-Comonad-Cofree.html">cofree
comonad</a>:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Cofree</span> f a <span class="ot">=</span> a <span class="op">:&lt;</span> f (<span class="dt">Cofree</span> f a)</span></code></pre></div>
<p>When <code class="sourceCode haskell">f</code> is specialized to
<code class="sourceCode haskell">[]</code>, we get the original rose
tree. So far, though, all we actually require is <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>.</p>
<p>From now on, then, we’ll use <code
class="sourceCode haskell"><span class="dt">Cofree</span></code> instead
of <code
class="sourceCode haskell"><span class="dt">Tree</span></code>.</p>
<h1 id="traversing">Traversing</h1>
<p>Finally, we can begin on the traversal itself. We know how to execute
the effects in the right order, what’s missing is to build the tree back
up in the right order.</p>
<h3 id="filling">Filling</h3>
<p>First thing we’ll use is a trick with <code
class="sourceCode haskell"><span class="dt">Traversable</span></code>,
where we fill a container from a list. In other words:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>fill [(),(),(),()] [<span class="dv">1</span><span class="op">..</span>] <span class="ot">=</span> ([<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>],[<span class="dv">5</span><span class="op">..</span>])</span></code></pre></div>
<p>With the state monad (or applicative, in this case, I suppose), we
can define a “pop” action, which takes an element from the supply:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>pop <span class="ot">=</span> state (\(x<span class="op">:</span>xs) <span class="ot">-&gt;</span> (x,xs))</span></code></pre></div>
<p>And then we <code
class="sourceCode haskell"><span class="fu">traverse</span></code> that
action over our container:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>fill <span class="ot">=</span> <span class="fu">traverse</span> (<span class="fu">const</span> pop)</span></code></pre></div>
<p>When we use fill, it’ll have the following type:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirst ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Traversable</span> t)</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Cofree</span> t a <span class="ot">-&gt;</span> f (<span class="dt">Cofree</span> t b)</span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>breadthFirst <span class="ot">=</span> <span class="op">...</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">...</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    fill ::</span> t (<span class="dt">Cofree</span> t a) <span class="ot">-&gt;</span> <span class="dt">State</span> [<span class="dt">Cofree</span> t b] (t (<span class="dt">Cofree</span> t b))</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>    fill <span class="ot">=</span> <span class="fu">traverse</span> (<span class="fu">const</span> pop)</span></code></pre></div>
<p>Hopefully that makes sense: we’re going to get the subforest from
here:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Cofree</span> t a <span class="ot">=</span> a <span class="op">:&lt;</span> t (<span class="dt">Cofree</span> t a)</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>                       <span class="op">^^^^^^^^^^^^^^</span></span></code></pre></div>
<p>And we’re going to fill it with the result of the traversal, which
changes the contents from <code>a</code>s to <code>b</code>s.</p>
<h3 id="composing-applicatives">Composing Applicatives</h3>
<p>One of the nice things about working with applicatives is that they
compose, in a variety of different ways. In other words, if I have one
effect, <code class="sourceCode haskell">f</code>, and another <code
class="sourceCode haskell">g</code>, and I want to run them both on the
contents of some list, I can do it in one pass, either by layering the
effects, or putting them side-by-side.</p>
<p>In our case, we need to deal with two effects: the one generated by
the traversal, (the one the caller wants to use), and the internal state
we’re using to fill up the forests in our tree. We could use <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Data-Functor-Compose.html#t:Compose"><code
class="sourceCode haskell"><span class="dt">Compose</span></code></a>
explicitly, but we can avoid some calls to <code
class="sourceCode haskell"><span class="fu">pure</span></code> if we
write the combinators we’re going to use directly:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>map2</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Functor</span> f, <span class="dt">Functor</span> g)</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> g b <span class="ot">-&gt;</span> f (g c)</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>map2 f x xs <span class="ot">=</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> (\y <span class="ot">-&gt;</span> <span class="fu">fmap</span> (f y) xs) x</span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>app2</span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Applicative</span> g)</span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> g b <span class="ot">-&gt;</span> f (g c) <span class="ot">-&gt;</span> f (g d)</span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>app2 f x xs <span class="ot">=</span></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a>    liftA2 (\y <span class="ot">-&gt;</span> liftA2 (f y) xs) x</span></code></pre></div>
<p>The outer applicative (<code>f</code>) will be the user’s effect, the
inner will be <code>State</code>.</p>
<h1 id="take-1-zippy-style-traversing">Take 1: Zippy-Style
Traversing</h1>
<p>First we’ll try convert the zippy-style <code
class="sourceCode haskell">levels</code> to a traversal. First, convert
the function over to the cofree comonad:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>levels tr <span class="ot">=</span> f tr []</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs) <span class="ot">=</span> (x<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) []     <span class="ot">=</span> [x]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>Next, instead of building up a list of just the root labels, we’ll
pair them with the subforests:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a>breadthFirst tr <span class="ot">=</span> f tr []</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs) <span class="ot">=</span> ((x,xs)<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) []     <span class="ot">=</span> [(x,xs)]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>Next, we’ll fill the subforests:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a>breadthFirst tr <span class="ot">=</span> f tr []</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs) <span class="ot">=</span> ((x,fill xs)<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) []     <span class="ot">=</span> [(x,fill xs)]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>Then, we can run the applicative effect on the root label:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>breadthFirst c tr <span class="ot">=</span> f tr []</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs) <span class="ot">=</span> ((c x,fill xs)<span class="op">:</span>q) <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) []     <span class="ot">=</span> [(c x,fill xs)]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>Now, to combine the effects, we can use the combinators we defined
before:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>breadthFirst c tr <span class="ot">=</span> f tr []</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs) <span class="ot">=</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>        app2 (\y ys zs <span class="ot">-&gt;</span> (y<span class="op">:&lt;</span>ys) <span class="op">:</span> zs) (c x) (fill xs) q <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) [] <span class="ot">=</span></span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a>        map2 (\y ys <span class="ot">-&gt;</span> [y<span class="op">:&lt;</span>ys]) (c x) (fill xs) <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>This builds a list containing all of the level-wise traversals of the
tree. To collapse them into one, we can use a fold:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirst ::</span> (<span class="dt">Traversable</span> t, <span class="dt">Applicative</span> f)</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b)</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Cofree</span> t a</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> f (<span class="dt">Cofree</span> t b)</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>breadthFirst c tr <span class="ot">=</span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">head</span> <span class="op">&lt;$&gt;</span> <span class="fu">foldr</span> (liftA2 evalState) (<span class="fu">pure</span> []) (f tr [])</span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs) <span class="ot">=</span></span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>        app2 (\y ys zs <span class="ot">-&gt;</span> (y<span class="op">:&lt;</span>ys)<span class="op">:</span>zs) (c x) (fill xs) q <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) [] <span class="ot">=</span></span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a>        map2 (\y ys <span class="ot">-&gt;</span> [y<span class="op">:&lt;</span>ys]) (c x) (fill xs) <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<h1 id="take-2-queue-based-traversing">Take 2: Queue-Based
Traversing</h1>
<p>Converting the queue-based implementation is easy once we’ve done it
with the zippy one. The result is (to my eye) a little easier to read,
also:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>breadthFirst</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Traversable</span> t)</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Cofree</span> t a <span class="ot">-&gt;</span> f (<span class="dt">Cofree</span> t b)</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>breadthFirst c tr <span class="ot">=</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> <span class="fu">head</span> (f b tr e [])</span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>    f k (x<span class="op">:&lt;</span>xs) ls qs <span class="ot">=</span></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>      k (app2 (\y ys zs <span class="ot">-&gt;</span> (y<span class="op">:&lt;</span>ys)<span class="op">:</span>zs) (c x) (fill xs) ls) (xs<span class="op">:</span>qs)</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>    b _ [] <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a>    b l qs <span class="ot">=</span> liftA2 evalState l (<span class="fu">foldl</span> (<span class="fu">foldl</span> f) b qs e [])</span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> <span class="fu">pure</span> (<span class="fu">pure</span> [])</span></code></pre></div>
<p>There are a couple things to notice here: first, we’re not using
<code class="sourceCode haskell">map2</code> anywhere. That’s because in
the zippy version we were able to notice when the queue was exhausted,
so we could just output the singleton effect. Here, instead, we’re using
<code
class="sourceCode haskell"><span class="fu">pure</span> (<span class="fu">pure</span> [])</code>:
this is potentially a source of inefficiency, as <code
class="sourceCode haskell">liftA2 f (<span class="fu">pure</span> x) y</code>
is less efficient than <code
class="sourceCode haskell"><span class="fu">fmap</span> (f x) y</code>
for some applicatives.</p>
<p>On the other hand, we don’t build up a list of levels to be combined
with <code
class="sourceCode haskell"><span class="fu">foldr</span> (liftA2 evalState)</code>
at any point: we combine them at every level immediately. You may be
able to do the same in the zippy version, but I haven’t figured it out
yet.</p>
<h3 id="yoneda">Yoneda</h3>
<p>The final point to make here is to do with the very last thing we do
in the traversal: <code
class="sourceCode haskell"><span class="fu">fmap</span> <span class="fu">head</span></code>.
Strictly speaking, any <code
class="sourceCode haskell"><span class="fu">fmap</span></code>s in the
code should be unnecessary: we <em>should</em> be able to fuse them all
with any call to <code class="sourceCode haskell">liftA2</code>. This
transformation is often called the “Yoneda embedding”. We can use it
here like so:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a>breadthFirst</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> ∀ t a f b<span class="op">.</span> (<span class="dt">Traversable</span> t, <span class="dt">Applicative</span> f)</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Cofree</span> t a <span class="ot">-&gt;</span> f (<span class="dt">Cofree</span> t b)</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>breadthFirst c tr <span class="ot">=</span> f (b <span class="fu">head</span>) tr e []</span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>    f k (x<span class="op">:&lt;</span>xs) ls qs <span class="ot">=</span></span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>        k (app2 (\y ys zs <span class="ot">-&gt;</span> (y<span class="op">:&lt;</span>ys) <span class="op">:</span> zs) (c x) (fill xs) ls) (xs <span class="op">:</span> qs)</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a><span class="ot">    b ::</span> ∀ x<span class="op">.</span> ([<span class="dt">Cofree</span> t b] <span class="ot">-&gt;</span> x)</span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>      <span class="ot">-&gt;</span> f (<span class="dt">State</span> [<span class="dt">Cofree</span> t b] [<span class="dt">Cofree</span> t b])</span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>      <span class="ot">-&gt;</span> [t (<span class="dt">Cofree</span> t a)]</span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>      <span class="ot">-&gt;</span> f x</span>
<span id="cb32-13"><a href="#cb32-13" aria-hidden="true" tabindex="-1"></a>    b k _ [] <span class="ot">=</span> <span class="fu">pure</span> (k [])</span>
<span id="cb32-14"><a href="#cb32-14" aria-hidden="true" tabindex="-1"></a>    b k l qs <span class="ot">=</span></span>
<span id="cb32-15"><a href="#cb32-15" aria-hidden="true" tabindex="-1"></a>        liftA2 (\x <span class="ot">-&gt;</span> k <span class="op">.</span> evalState x) l (<span class="fu">foldl</span> (<span class="fu">foldl</span> f) (b <span class="fu">id</span>) qs e [])</span>
<span id="cb32-16"><a href="#cb32-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-17"><a href="#cb32-17" aria-hidden="true" tabindex="-1"></a>    e <span class="ot">=</span> <span class="fu">pure</span> (<span class="fu">pure</span> [])</span></code></pre></div>
<p>Notice that we need scoped type variables here, since the type of
<code class="sourceCode haskell">b</code> changes depending on when it’s
called.</p>
<h1 id="take-3-iterative-traversing">Take 3: Iterative Traversing</h1>
<p>Transforming the iterative version is slightly different from the
other two:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a>breadthFirst c tr <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">head</span> (go [tr])</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a>    go xs <span class="ot">=</span></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a>        liftA2</span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>            evalState</span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>            (getCompose (<span class="fu">traverse</span> f xs))</span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a>            (go (<span class="fu">foldr</span> (\(_<span class="op">:&lt;</span>ys) b <span class="ot">-&gt;</span> <span class="fu">foldr</span> (<span class="op">:</span>) b ys) [] xs))</span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) <span class="ot">=</span> <span class="dt">Compose</span> (map2 (<span class="op">:&lt;</span>) (c x) (fill xs))</span></code></pre></div>
<p>We’re using <code
class="sourceCode haskell"><span class="dt">Compose</span></code>
directly here, in contrast to the other two algorithms.</p>
<h1 id="comparison">Comparison</h1>
<p>Performance-wise, no one algorithm wins out in every case. For
enumeration, the zippy algorithm is the fastest in most cases—except
when the tree had a large branching factor; then, the iterative
algorithm wins out. For the traversals, the iterative algorithm is
usually better—except for monads with more expensive applicative
instances.</p>
<p>I’m still not convinced that the zippy traversal is as optimized as
it could be, however. If anyone has a better implementation, I’d love to
see it!</p>
<h1 id="fusion">Fusion</h1>
<p>Using the composability of applicatives, we can fuse several
operations over traversables into one pass. Unfortunately, however, this
can often introduce a memory overhead that makes the whole operation
slower overall. One such example is the iterative algorithm above:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>breadthFirst c tr <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">head</span> (go [tr])</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a>    go xs <span class="ot">=</span> liftA2 evalState zs (go (ys []))</span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Compose</span> (<span class="dt">Endo</span> ys,<span class="dt">Compose</span> zs) <span class="ot">=</span> <span class="fu">traverse</span> f xs</span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a>    f (x <span class="op">:&lt;</span> xs) <span class="ot">=</span></span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Compose</span></span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">Endo</span> (<span class="fu">flip</span> (<span class="fu">foldr</span> (<span class="op">:</span>)) xs)</span>
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a>            ,<span class="dt">Compose</span> (map2 (<span class="op">:&lt;</span>) (c x) (fill xs)))</span></code></pre></div>
<p>We only traverse the subforest of each node once now, fusing the fill
operation with building the list to send to the recursive call. This is
expensive (especially memory-wise), though, and traversing the
descendant is cheap; the result is that the one-pass version is slower
(in my tests).</p>
<h1 id="generalizing">Generalizing</h1>
<p>The cofree comonad allows us to generalize over the type of
“descendants”—from lists (in <code
class="sourceCode haskell"><span class="dt">Tree</span></code>) to
anything traversable. We could also generalize over the type of the
traversal itself: given a way to access the descendants of a node, we
should be able to traverse all nodes in a breadth-first order. This kind
of thing is usually accomplished by <a
href="http://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-Plated.html">Plated</a>:
it’s a class that gives you a traversal over the immediate descendants
of some recursive type. Adapting the iterative version is relatively
simple:</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirstOf ::</span> <span class="dt">Traversal&#39;</span> a a <span class="ot">-&gt;</span> <span class="dt">Traversal&#39;</span> a a</span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>breadthFirstOf trav c tr <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">head</span> (go [tr])</span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>    go xs <span class="ot">=</span></span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a>        liftA2</span>
<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a>            evalState</span>
<span id="cb35-8"><a href="#cb35-8" aria-hidden="true" tabindex="-1"></a>            (getCompose (<span class="fu">traverse</span> f xs))</span>
<span id="cb35-9"><a href="#cb35-9" aria-hidden="true" tabindex="-1"></a>            (go (<span class="fu">foldr</span> (\ys b <span class="ot">-&gt;</span> foldrOf trav (<span class="op">:</span>) b ys) [] xs))</span>
<span id="cb35-10"><a href="#cb35-10" aria-hidden="true" tabindex="-1"></a>    f xs <span class="ot">=</span> <span class="dt">Compose</span> (<span class="fu">fmap</span> fill (c xs))</span>
<span id="cb35-11"><a href="#cb35-11" aria-hidden="true" tabindex="-1"></a>    fill <span class="ot">=</span> trav (<span class="fu">const</span> (<span class="dt">State</span> (\(x<span class="op">:</span>xs) <span class="ot">-&gt;</span> (x, xs))))</span></code></pre></div>
<p>We can use this version to get back some of the old functions
above:</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirstEnumerate ::</span>  <span class="dt">Traversable</span> f <span class="ot">=&gt;</span> <span class="dt">Cofree</span> f a <span class="ot">-&gt;</span> [a]</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>breadthFirstEnumerate <span class="ot">=</span> toListOf (breadthFirstOf plate <span class="op">.</span> _extract)</span></code></pre></div>
<h1 id="unfolding">Unfolding</h1>
<p>Building a tree breadth-first, monadically, is still an unsolved
problem <span class="citation" data-cites="feuer_is_2015">(it looks
like: <a href="#ref-feuer_is_2015" role="doc-biblioref">Feuer
2015</a>)</span>.</p>
<p>Using some of these we can implement a monadic breadth-first unfold
for the cofree comonad:</p>
<div class="sourceCode" id="cb37"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="ot">unfoldM ::</span> (<span class="dt">Monad</span> m, <span class="dt">Traversable</span> t)</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> m (a, t b))</span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> b</span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> m (<span class="dt">Cofree</span> t a)</span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>unfoldM c tr <span class="ot">=</span> go <span class="fu">head</span> [tr]</span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a>    go k [] <span class="ot">=</span> <span class="fu">pure</span> (k [])</span>
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a>    go k xs <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a>        ys <span class="ot">&lt;-</span> <span class="fu">traverse</span> c xs</span>
<span id="cb37-10"><a href="#cb37-10" aria-hidden="true" tabindex="-1"></a>        go (k <span class="op">.</span> evalState (<span class="fu">traverse</span> f ys)) (toList (<span class="dt">Compose</span> (<span class="dt">Compose</span> ys)))</span>
<span id="cb37-11"><a href="#cb37-11" aria-hidden="true" tabindex="-1"></a>    f (x,xs) <span class="ot">=</span> <span class="fu">fmap</span> (x<span class="op">:&lt;</span>) (fill xs)</span></code></pre></div>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-allison_circular_2006" class="csl-entry" role="listitem">
Allison, Lloyd. 2006. <span>“Circular <span>Programs</span> and
<span>Self</span>-<span>Referential Structures</span>.”</span>
<em>Software: Practice and Experience</em> 19 (2) (October): 99–109.
doi:<a
href="https://doi.org/10.1002/spe.4380190202">10.1002/spe.4380190202</a>.
<a
href="http://users.monash.edu/~lloyd/tildeFP/1989SPE/">http://users.monash.edu/~lloyd/tildeFP/1989SPE/</a>.
</div>
<div id="ref-feuer_is_2015" class="csl-entry" role="listitem">
Feuer, David. 2015. <span>“Is a lazy, breadth-first monadic rose tree
unfold possible?”</span> Question. <em>Stack Overflow</em>. <a
href="https://stackoverflow.com/q/27748526">https://stackoverflow.com/q/27748526</a>.
</div>
<div id="ref-gibbons_breadth-first_2015" class="csl-entry"
role="listitem">
Gibbons, Jeremy. 2015. <span>“Breadth-<span>First
Traversal</span>.”</span> <em>Patterns in Functional Programming</em>.
<a
href="https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/">https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/</a>.
</div>
<div id="ref-smith_lloyd_2009" class="csl-entry" role="listitem">
Smith, Leon P. 2009. <span>“Lloyd <span>Allison</span>’s
<span>Corecursive Queues</span>: <span>Why Continuations
Matter</span>.”</span> <em>The Monad.Reader</em> 14 (14) (July): 28. <a
href="https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf">https://meldingmonads.files.wordpress.com/2009/06/corecqueues.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Sun, 03 Jun 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-06-03-breadth-first-traversals-in-too-much-detail.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Breadth-First Rose Trees: Traversals and the Cofree Comonad</title>
    <link>https://doisinkidney.com/posts/2018-06-01-rose-trees-breadth-first-traversing.html</link>
    <description><![CDATA[<div class="info">
    Posted on June  1, 2018
</div>
<div class="info">
    
        Part 2 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>I was looking again at the issue of writing breadth-first traversals
for rose trees, and in particular the problem explored in <span
class="citation" data-cites="gibbons_breadth-first_2015">Gibbons (<a
href="#ref-gibbons_breadth-first_2015"
role="doc-biblioref">2015</a>)</span>. The breadth-first traversal here
is a traversal in the lensy sense.</p>
<p>First, let’s look back at getting the levels out of the tree. Here’s
the old function I arrived at last time:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levels ::</span> <span class="dt">Forest</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>levels ts <span class="ot">=</span> <span class="fu">foldl</span> f b ts [] []</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    f k (<span class="dt">Node</span> x xs) ls qs <span class="ot">=</span> k (x <span class="op">:</span> ls) (xs <span class="op">:</span> qs)</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    b _ [] <span class="ot">=</span> []</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    b k qs <span class="ot">=</span> k <span class="op">:</span> <span class="fu">foldl</span> (<span class="fu">foldl</span> f) b qs [] []</span></code></pre></div>
<p>After wrangling the definition a little, I got to the following (much
cleaner) definition:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levels ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>levels tr <span class="ot">=</span> f tr [] <span class="kw">where</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  f (<span class="dt">Node</span> x xs) (y<span class="op">:</span>ys) <span class="ot">=</span> (x<span class="op">:</span>y) <span class="op">:</span> <span class="fu">foldr</span> f ys xs</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  f (<span class="dt">Node</span> x xs) []     <span class="ot">=</span> [x]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<h1 id="cofree">Cofree</h1>
<p>Before going any further, all of the functions so far can be
redefined to work on the <a
href="http://hackage.haskell.org/package/free-5.0.2/docs/Control-Comonad-Cofree.html">cofree
comonad</a>:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Cofree</span> f a <span class="ot">=</span> a <span class="op">:&lt;</span> f (<span class="dt">Cofree</span> f a)</span></code></pre></div>
<p>When <code class="sourceCode haskell">f</code> is specialized to
<code class="sourceCode haskell">[]</code>, we get the original rose
tree. But what we actually require is much less specific: <code
class="sourceCode haskell">levels</code>, for instance, only needs <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levelsCofree ::</span> <span class="dt">Foldable</span> f <span class="ot">=&gt;</span> <span class="dt">Cofree</span> f a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>levelsCofree tr <span class="ot">=</span> f tr []</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> (x<span class="op">:</span>y) <span class="op">:</span> <span class="fu">foldr</span> f ys xs</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) []     <span class="ot">=</span> [x]   <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span></code></pre></div>
<p>Using this, we can write the efficient breadth-first traversal:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>breadthFirst</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Traversable</span> t)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Cofree</span> t a <span class="ot">-&gt;</span> f (<span class="dt">Cofree</span> t b)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>breadthFirst c (t<span class="op">:&lt;</span>ts) <span class="ot">=</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    liftA2 evalState (map2 (<span class="op">:&lt;</span>) (c t) (fill ts)) chld</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    chld <span class="ot">=</span> <span class="fu">foldr</span> (liftA2 evalState) (<span class="fu">pure</span> []) (<span class="fu">foldr</span> f [] ts)</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    fill <span class="ot">=</span> <span class="fu">traverse</span> (<span class="fu">const</span> (state (\(x<span class="op">:</span>xs) <span class="ot">-&gt;</span> (x,xs))))</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs)</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> app2 (\y ys zs <span class="ot">-&gt;</span> (y<span class="op">:&lt;</span>ys) <span class="op">:</span> zs) (c x) (fill xs) q</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>        <span class="op">:</span> <span class="fu">foldr</span> f qs xs</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) []</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=</span> map2 (\y ys <span class="ot">-&gt;</span> [y<span class="op">:&lt;</span>ys]) (c x) (fill xs)</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>        <span class="op">:</span> <span class="fu">foldr</span> f [] xs</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>    map2 k x xs <span class="ot">=</span> <span class="fu">fmap</span>   (\y <span class="ot">-&gt;</span> <span class="fu">fmap</span>   (k y) xs) x</span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a>    app2 k x xs <span class="ot">=</span> liftA2 (\y <span class="ot">-&gt;</span> liftA2 (k y) xs) x</span></code></pre></div>
<p>At every level, the subforest’s shape it taken (<code
class="sourceCode haskell">fill</code>), and it’s traversed recursively.
We can fuse these two steps into one:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>breadthFirst</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Traversable</span> t, <span class="dt">Applicative</span> f)</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">Cofree</span> t a  <span class="ot">-&gt;</span> f (<span class="dt">Cofree</span> t b)</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>breadthFirst c (t<span class="op">:&lt;</span>ts) <span class="ot">=</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    liftA2</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>        evalState</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>        (map2 (<span class="op">:&lt;</span>) (c t) fill)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>        (<span class="fu">foldr</span> (liftA2 evalState) (<span class="fu">pure</span> []) (chld []))</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Compose</span> (<span class="dt">Endo</span> chld,fill) <span class="ot">=</span> go ts</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>    go <span class="ot">=</span> <span class="fu">traverse</span> (\x <span class="ot">-&gt;</span> <span class="dt">Compose</span> (<span class="dt">Endo</span> (f x), state (\(y<span class="op">:</span>ys) <span class="ot">-&gt;</span> (y,ys))))</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) (q<span class="op">:</span>qs) <span class="ot">=</span> app2 (\y ys zs <span class="ot">-&gt;</span> (y<span class="op">:&lt;</span>ys) <span class="op">:</span> zs) (c x) r q <span class="op">:</span> rs qs</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> <span class="dt">Compose</span> (<span class="dt">Endo</span> rs,r) <span class="ot">=</span> go xs</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>    f (x<span class="op">:&lt;</span>xs) [] <span class="ot">=</span> map2 (\y ys <span class="ot">-&gt;</span> [y<span class="op">:&lt;</span>ys]) (c x) r <span class="op">:</span> rs []</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span> <span class="dt">Compose</span> (<span class="dt">Endo</span> rs,r) <span class="ot">=</span> go xs</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>    map2 k x xs <span class="ot">=</span> <span class="fu">fmap</span>   (\y <span class="ot">-&gt;</span> <span class="fu">fmap</span>   (k y) xs) x</span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>    app2 k x xs <span class="ot">=</span> liftA2 (\y <span class="ot">-&gt;</span> liftA2 (k y) xs) x</span></code></pre></div>
<p>The overhead from this approach scraps any benefit, though.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-gibbons_breadth-first_2015" class="csl-entry"
role="listitem">
Gibbons, Jeremy. 2015. <span>“Breadth-<span>First
Traversal</span>.”</span> <em>Patterns in Functional Programming</em>.
<a
href="https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/">https://patternsinfp.wordpress.com/2015/03/05/breadth-first-traversal/</a>.
</div>
</div>
]]></description>
    <pubDate>Fri, 01 Jun 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-06-01-rose-trees-breadth-first-traversing.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Swapping</title>
    <link>https://doisinkidney.com/posts/2018-05-30-swapping-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on May 30, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE RecursiveDo #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Swap</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map.Strict</span> <span class="kw">as</span> <span class="dt">Map</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Map.Strict</span>   (<span class="dt">Map</span>)</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.IntMap</span>          (<span class="dt">IntMap</span>)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.IntMap.Strict</span> <span class="kw">as</span> <span class="dt">IntMap</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.IntMap.Lazy</span>   <span class="kw">as</span> <span class="dt">LazyIntMap</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Lens</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Arrow</span>           ((&amp;&amp;&amp;))</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Monad</span>           ((&gt;=&gt;))</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Monad.Fix</span>       (mfix)</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Monad.State</span>     (<span class="dt">StateT</span>(..),execState,state)</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Maybe</span>  (fromMaybe)</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Monoid</span> (<span class="dt">First</span>(..))</span></code></pre></div>
<p>Say you want to swap two items in a mapping structure—<a
href="http://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Map-Strict.html">Data.Map.Strict</a>,
<a
href="https://hackage.haskell.org/package/unordered-containers-0.2.9.0/docs/Data-HashMap-Strict.html">Data.HashMap</a>,
etc. The normal way uses far too many operations:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- |</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; swapAt4 1 2 (Map.fromList (zip [1..5] [&#39;a&#39;..]))</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- fromList [(1,&#39;b&#39;),(2,&#39;a&#39;),(3,&#39;c&#39;),(4,&#39;d&#39;),(5,&#39;e&#39;)]</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="ot">swapAt4 ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Map</span> a b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>swapAt4 i j xs <span class="ot">=</span> <span class="kw">case</span> Map.lookup i xs <span class="kw">of</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nothing</span> <span class="ot">-&gt;</span> xs</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Just</span> x <span class="ot">-&gt;</span> <span class="kw">case</span> Map.lookup j xs <span class="kw">of</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nothing</span> <span class="ot">-&gt;</span> xs</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Just</span> y <span class="ot">-&gt;</span> Map.insert i y (Map.insert j x xs)</span></code></pre></div>
<p>Two lookups, and two insertions. We can cut it down to three
operations with <a
href="http://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Map-Strict.html#v:insertLookupWithKey"><code>insertLookupWithKey</code></a>:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- |</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; swapAt3 1 2 (Map.fromList (zip [1..5] [&#39;a&#39;..]))</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- fromList [(1,&#39;b&#39;),(2,&#39;a&#39;),(3,&#39;c&#39;),(4,&#39;d&#39;),(5,&#39;e&#39;)]</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">swapAt3 ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Map</span> a b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>swapAt3 i j xs <span class="ot">=</span> <span class="kw">case</span> Map.lookup i xs <span class="kw">of</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nothing</span> <span class="ot">-&gt;</span> xs</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Just</span> x <span class="ot">-&gt;</span> <span class="kw">case</span> Map.insertLookupWithKey (<span class="fu">const</span> <span class="fu">const</span>) j x xs <span class="kw">of</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Nothing</span>,_) <span class="ot">-&gt;</span> xs</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Just</span> y,ys) <span class="ot">-&gt;</span> Map.insert i y ys</span></code></pre></div>
<p>Then, using laziness, we can write the above program <a
href="https://doi.org/10.1007/BF00264249">circularly</a>, reducing the
number of lookups to 2:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">swapAt2 ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Map</span> a b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>swapAt2 i j xs <span class="ot">=</span> zs</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>     (ival,ys) <span class="ot">=</span> Map.updateLookupWithKey (replace jval) i xs</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>     (jval,zs) <span class="ot">=</span> Map.updateLookupWithKey (replace ival) j ys</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>     replace x <span class="ot">=</span> <span class="fu">const</span> (<span class="dt">Just</span> <span class="op">.</span> (<span class="ot">`fromMaybe`</span> x))</span></code></pre></div>
<p>Unfortunately, Data.Map isn’t lazy enough for this: the above won’t
terminate. Interestingly, Data.IntMap <em>is</em> lazy enough:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">swapAt2Int ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">IntMap</span> a <span class="ot">-&gt;</span> <span class="dt">IntMap</span> a</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>swapAt2Int i j xs <span class="ot">=</span> zs</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    (ival,ys) <span class="ot">=</span> LazyIntMap.updateLookupWithKey (replace jval) i xs</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    (jval,zs) <span class="ot">=</span>     IntMap.updateLookupWithKey (replace ival) j ys</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    replace x <span class="ot">=</span> <span class="fu">const</span> (<span class="dt">Just</span> <span class="op">.</span> (<span class="ot">`fromMaybe`</span> x))</span></code></pre></div>
<p>Notice how we have to use the lazy version of <code
class="sourceCode haskell">updateLookupWithKey</code>. Again, though,
this version has a problem: it won’t terminate when one of the keys is
missing.</p>
<p>Thankfully, both of our problems can be solved by abstracting a
little and using <a
href="http://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-At.html#t:Ixed">Ixed</a>
from lens:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- |</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; swapIx 1 2 &quot;abc&quot;</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- &quot;acb&quot;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="ot">swapIx ::</span> <span class="dt">Ixed</span> a <span class="ot">=&gt;</span> <span class="dt">Index</span> a <span class="ot">-&gt;</span> <span class="dt">Index</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>swapIx i j xs <span class="ot">=</span> zs</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">First</span> ival, ys) <span class="ot">=</span> ix i (replace jval) xs</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">First</span> jval, zs) <span class="ot">=</span> ix j (replace ival) ys</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>    replace x <span class="ot">=</span> <span class="dt">First</span> <span class="op">.</span> <span class="dt">Just</span> <span class="op">&amp;&amp;&amp;</span> (<span class="ot">`fromMaybe`</span> x)</span></code></pre></div>
<p>Because <code class="sourceCode haskell">ix</code> is a traversal, it
won’t do anything when there’s a missing key, which is what we want.
Also, it adds extra laziness, as the caller of a traversal gets certain
extra controls over the strictness of the traversal.</p>
<p>You may notice the stateful pattern above. However, translating it
over as-is presents a problem: the circular bindings won’t work in
vanilla do notation. For that, we need <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Monad-Fix.html"><code
class="sourceCode haskell"><span class="dt">MonadFix</span></code></a>
and <a
href="https://ocharles.org.uk/blog/posts/2014-12-09-recursive-do.html">Recursive
Do</a>:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">swapSt ::</span> <span class="dt">Ixed</span> a <span class="ot">=&gt;</span> <span class="dt">Index</span> a <span class="ot">-&gt;</span> <span class="dt">Index</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>swapSt i j <span class="ot">=</span> execState <span class="op">$</span> mdo</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    ival <span class="ot">&lt;-</span> replace i jval</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    jval <span class="ot">&lt;-</span> replace j ival</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> ()</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    replace i (<span class="dt">First</span> x) <span class="ot">=</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>        state (ix i (<span class="dt">First</span> <span class="op">.</span> <span class="dt">Just</span> <span class="op">&amp;&amp;&amp;</span> (<span class="ot">`fromMaybe`</span> x)))</span></code></pre></div>
<p>Finally, we can use <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Monad-Fix.html#v:mfix"><code
class="sourceCode haskell">mfix</code></a> directly, and we’ll get the
following clean-looking solution:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">swap ::</span> <span class="dt">Ixed</span> a <span class="ot">=&gt;</span> <span class="dt">Index</span> a <span class="ot">-&gt;</span> <span class="dt">Index</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>swap i j <span class="ot">=</span> execState (mfix (replace i <span class="op">&gt;=&gt;</span> replace j))</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    replace i (<span class="dt">First</span> x) <span class="ot">=</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>        state (ix i (<span class="dt">First</span> <span class="op">.</span> <span class="dt">Just</span> <span class="op">&amp;&amp;&amp;</span> (<span class="ot">`fromMaybe`</span> x)))</span></code></pre></div>
<p>This works for most containers, even strict ones like
Data.Map.Strict. It also works for Data.Vector. It does <em>not</em>
work for Data.Vector.Unboxed, though.</p>
]]></description>
    <pubDate>Wed, 30 May 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-05-30-swapping-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Sorting Small Things in Haskell</title>
    <link>https://doisinkidney.com/posts/2018-05-06-sorting-small.html</link>
    <description><![CDATA[<div class="info">
    Posted on May  6, 2018
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Sorting.html">1-part series on Sorting</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Algorithms&#39;." href="/tags/Algorithms.html" rel="tag">Algorithms</a>
    
</div>

<p>I was working on some performance-intensive stuff recently, and I ran
into the issue of sorting very small amounts of values (think 3, 4,
5).</p>
<p>The standard way to do this is with <a
href="https://en.wikipedia.org/wiki/Sorting_network">sorting
networks</a>. The way I’ll be using doesn’t actually perform any
parallelism (unfortunately), but it is a clean way to write the networks
in Haskell without too much repetition.</p>
<p><a href="http://pages.ripco.net/~jgamble/nw.html">This</a> website
will generate an optimal sorting network for your given size, and the
output (for 3) looks like this:</p>
<pre><code>[[1,2]]
[[0,2]]
[[0,1]]</code></pre>
<p>Each pair of indices represents a “compare-and-swap” operation: so
the first line means “compare the value at 1 to the value at 2: if it’s
bigger, swap them”. For 5, the network looks like this:</p>
<pre><code>[[0,1],[2,3]]
[[0,2],[1,3]]
[[1,2],[0,4]]
[[1,4]]
[[2,4]]
[[3,4]]</code></pre>
<p>Pairs on the same line can be performed in parallel.</p>
<p>For our case, I’m going to be looking at sorting tuples, but the
technique can easily be generalized to vectors, etc.</p>
<p>The first trick is to figure out how to do “swapping”: we don’t want
mutation, so what we can do instead is swap the <em>reference</em> to
some value, by shadowing its name. In other words:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">swap2 ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> (a, a)</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>swap2 lte x y <span class="op">|</span> lte x y <span class="ot">=</span> (x, y)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (y, x)</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="ot">sort3 ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (a,a,a) <span class="ot">-&gt;</span> (a,a,a)</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>sort3 lte (_0,_1,_2)</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="kw">case</span> swap2 lte _1 _2 <span class="kw">of</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>      (_1, _2) <span class="ot">-&gt;</span> <span class="kw">case</span> swap2 lte _0 _2 <span class="kw">of</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>        (_0, _2) <span class="ot">-&gt;</span> <span class="kw">case</span> swap2 lte _0 _1 <span class="kw">of</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>          (_0, _1) <span class="ot">-&gt;</span> (_0, _1, _2)</span></code></pre></div>
<p>The indentation is hard to read, though, and wrapping-and-unwrapping
tuples makes me nervous about the performance (although it may be
inlined). The next step is to <em>church-encode</em> the pairs
returned:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">swap2 ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>swap2 lte x y k</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> lte x y <span class="ot">=</span> k x y</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> k y x</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="ot">sort3 ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (a,a,a) <span class="ot">-&gt;</span> (a,a,a)</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>sort3 lte (_0,_1,_2)</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> swap2 lte _1 _2 <span class="op">$</span> \ _1 _2 <span class="ot">-&gt;</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>      swap2 lte _0 _2 <span class="op">$</span> \ _0 _2 <span class="ot">-&gt;</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>      swap2 lte _0 _1 <span class="op">$</span> \ _0 _1 <span class="ot">-&gt;</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>      (_0,_1,_2)</span></code></pre></div>
<p>Then, to get this to compile down to efficient code, we can make
judicious use of <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/GHC-Exts.html#v:inline"><code
class="sourceCode haskell">inline</code></a> from GHC.Exts:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">GHC.Exts</span> (inline)</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ot">swap2 ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>swap2 lte x y k</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> inline lte x y <span class="ot">=</span> inline k x y</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> inline k y x</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE swap2 #-}</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ot">sort3 ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (a, a, a) <span class="ot">-&gt;</span> (a, a, a)</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>sort3 lte (_0,_1,_2)</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> swap2 lte _1 _2 <span class="op">$</span> \ _1 _2 <span class="ot">-&gt;</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>      swap2 lte _0 _2 <span class="op">$</span> \ _0 _2 <span class="ot">-&gt;</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>      swap2 lte _0 _1 <span class="op">$</span> \ _0 _1 <span class="ot">-&gt;</span></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>      (_0,_1,_2)</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE sort3 #-}</span></span></code></pre></div>
<p>And to see if this really does make efficient code, let’s look at the
core (cleaned up):</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>sort3</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> \ (<span class="ot">lte ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>)</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>      (<span class="ot">ds ::</span> (a, a, a)) <span class="ot">-&gt;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> ds <span class="kw">of</span> wild_X8 (_0, _1, _2) <span class="ot">-&gt;</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> lte _1 _2 <span class="kw">of</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">False</span> <span class="ot">-&gt;</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>          <span class="kw">case</span> lte _0 _1 <span class="kw">of</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>            <span class="dt">False</span> <span class="ot">-&gt;</span> (_2, _1, _0)</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>            <span class="dt">True</span> <span class="ot">-&gt;</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>              <span class="kw">case</span> lte _0 _2 <span class="kw">of</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>                <span class="dt">False</span> <span class="ot">-&gt;</span> (_2, _0, _1)</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>                <span class="dt">True</span> <span class="ot">-&gt;</span> (_0, _2, _1)</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>        <span class="dt">True</span> <span class="ot">-&gt;</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>          <span class="kw">case</span> lte _0 _2 <span class="kw">of</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>            <span class="dt">False</span> <span class="ot">-&gt;</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>              <span class="kw">case</span> lte _2 _1 <span class="kw">of</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>                <span class="dt">False</span> <span class="ot">-&gt;</span> (_1, _2, _0)</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>                <span class="dt">True</span> <span class="ot">-&gt;</span> (_2, _1, _0)</span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a>            <span class="dt">True</span> <span class="ot">-&gt;</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>              <span class="kw">case</span> lte _0 _1 <span class="kw">of</span></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a>                <span class="dt">False</span> <span class="ot">-&gt;</span> (_1, _0, _2)</span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a>                <span class="dt">True</span> <span class="ot">-&gt;</span> wild_X8</span></code></pre></div>
<p>Fantastic! When we specialize to <code
class="sourceCode haskell"><span class="dt">Int</span></code>, we get
all of the proper unpacking:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">sort3Int ::</span> (<span class="dt">Int</span>, <span class="dt">Int</span>, <span class="dt">Int</span>) <span class="ot">-&gt;</span> (<span class="dt">Int</span>, <span class="dt">Int</span>, <span class="dt">Int</span>)</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>sort3Int <span class="ot">=</span> inline sort3 (<span class="op">&lt;=</span>)</span></code></pre></div>
<p>Core (with just the variable names cleaned up this time):</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>sort3Int</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> \ (<span class="ot">w ::</span> (<span class="dt">Int</span>, <span class="dt">Int</span>, <span class="dt">Int</span>)) <span class="ot">-&gt;</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> w <span class="kw">of</span> w_X { (_0, _1, _2) <span class="ot">-&gt;</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> _0 <span class="kw">of</span> w_0 { <span class="dt">GHC.Types.I</span><span class="op">#</span> _0U <span class="ot">-&gt;</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> _1 <span class="kw">of</span> w_1 { <span class="dt">GHC.Types.I</span><span class="op">#</span> _1U <span class="ot">-&gt;</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> _2 <span class="kw">of</span> w_2 { <span class="dt">GHC.Types.I</span><span class="op">#</span> _2U <span class="ot">-&gt;</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> <span class="op">GHC.Prim.&lt;=#</span> _1U _2U <span class="kw">of</span> {</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>        __DEFAULT <span class="ot">-&gt;</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>          <span class="kw">case</span> <span class="op">GHC.Prim.&lt;=#</span> _0U _1U <span class="kw">of</span> {</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>            __DEFAULT <span class="ot">-&gt;</span> (w_2, w_1, w_0);</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>            <span class="dv">1</span><span class="op">#</span> <span class="ot">-&gt;</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>              <span class="kw">case</span> <span class="op">GHC.Prim.&lt;=#</span> _0U _2U <span class="kw">of</span> {</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>                __DEFAULT <span class="ot">-&gt;</span> (w_2, w_0, w_1);</span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>                <span class="dv">1</span><span class="op">#</span> <span class="ot">-&gt;</span> (w_0, w_2, w_1)</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>              }</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>          };</span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>        <span class="dv">1</span><span class="op">#</span> <span class="ot">-&gt;</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>          <span class="kw">case</span> <span class="op">GHC.Prim.&lt;=#</span> _0U _2U <span class="kw">of</span> {</span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>            __DEFAULT <span class="ot">-&gt;</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>              <span class="kw">case</span> <span class="op">GHC.Prim.&lt;=#</span> _2U _1U <span class="kw">of</span> {</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>                __DEFAULT <span class="ot">-&gt;</span> (w_1, w_2, w_0);</span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>                <span class="dv">1</span><span class="op">#</span> <span class="ot">-&gt;</span> (w_2, w_1, w_0)</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>              };</span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>            <span class="dv">1</span><span class="op">#</span> <span class="ot">-&gt;</span></span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>              <span class="kw">case</span> <span class="op">GHC.Prim.&lt;=#</span> _0U _1U <span class="kw">of</span> {</span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a>                __DEFAULT <span class="ot">-&gt;</span> (w_1, w_0, w_2);</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a>                <span class="dv">1</span><span class="op">#</span> <span class="ot">-&gt;</span> w_X</span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a>              }</span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a>          }</span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a>      }</span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a>      }</span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a>      }</span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true" tabindex="-1"></a>      }</span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a>      }</span></code></pre></div>
<p>Now, for the real test: sorting 5-tuples, using the network
above.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">sort5 ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> (a,a,a,a,a) <span class="ot">-&gt;</span> (a,a,a,a,a)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>sort5 lte (_0,_1,_2,_3,_4)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> swap2 lte _0 _1 <span class="op">$</span> \ _0 _1 <span class="ot">-&gt;</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>      swap2 lte _2 _3 <span class="op">$</span> \ _2 _3 <span class="ot">-&gt;</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>      swap2 lte _0 _2 <span class="op">$</span> \ _0 _2 <span class="ot">-&gt;</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>      swap2 lte _1 _3 <span class="op">$</span> \ _1 _3 <span class="ot">-&gt;</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>      swap2 lte _1 _2 <span class="op">$</span> \ _1 _2 <span class="ot">-&gt;</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>      swap2 lte _0 _4 <span class="op">$</span> \ _0 _4 <span class="ot">-&gt;</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>      swap2 lte _1 _4 <span class="op">$</span> \ _1 _4 <span class="ot">-&gt;</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>      swap2 lte _2 _4 <span class="op">$</span> \ _2 _4 <span class="ot">-&gt;</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>      swap2 lte _3 _4 <span class="op">$</span> \ _3 _4 <span class="ot">-&gt;</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>      (_0,_1,_2,_3,_4)</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE sort5 #-}</span></span></code></pre></div>
<p>The core output from this is over 1000 lines long: you can see it
(with the variable names cleaned up) <a
href="https://gist.github.com/oisdk/ec25d76d918135c4c28777e1b84ead5f">here</a>.</p>
<p>In my benchmarks, these functions are indeed quicker than their
counterparts in vector, but I’m not confident in my knowledge of Haskell
performance to make much of a strong statement about them.</p>
]]></description>
    <pubDate>Sun, 06 May 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-05-06-sorting-small.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Type-Level Induction in Haskell</title>
    <link>https://doisinkidney.com/posts/2018-05-05-induction.html</link>
    <description><![CDATA[<div class="info">
    Posted on May  5, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Dependent Types&#39;." href="/tags/Dependent%20Types.html" rel="tag">Dependent Types</a>
    
</div>

<p>The code from this post is available as a <a
href="https://gist.github.com/oisdk/23c430b807c788dd43dc4d986c5fdfdd">gist</a>.</p>
<p>One of the most basic tools for use in type-level programming is the
Peano definition of the natural numbers:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> ℕ</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Z</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">S</span> ℕ</span></code></pre></div>
<p>Using the new <code
class="sourceCode haskell"><span class="dt">TypeFamilyDependencies</span></code>
extension, these numbers can be used to describe the “size” of some
type. I’m going to use the proportion symbol here:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> (t ∷ k) ∝ (n ∷ ℕ) <span class="ot">=</span> (a ∷ <span class="dt">Type</span>) <span class="op">|</span> a → t n k</span></code></pre></div>
<p>Using this type family we can describe induction on the natural
numbers:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Finite</span> n <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    induction ∷ t ∝ <span class="dt">Z</span> → (∀ k<span class="op">.</span> t ∝ k → t ∝ <span class="dt">S</span> k) → t ∝ n</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Finite</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    induction z _ <span class="ot">=</span> z</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# inline induction #-}</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Finite</span> n ⇒ <span class="dt">Finite</span> (<span class="dt">S</span> n) <span class="kw">where</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    induction z s <span class="ot">=</span> s (induction z s)</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# inline induction #-}</span></span></code></pre></div>
<p>The <code class="sourceCode haskell">induction</code> function reads
as the standard mathematical definition of induction: given a proof
(value) of the zero case, and a proof that any proof is true for its
successor, we can give you a proof of the case for any finite
number.</p>
<p>An added bonus here is that the size of something can usually be
resolved at compile-time, so any inductive function on it should also be
resolved at compile time.</p>
<p>We can use it to provide the standard instances for basic
length-indexed lists:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> n a <span class="kw">where</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Nil</span>  ∷ <span class="dt">List</span> <span class="dt">Z</span> a</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>        (<span class="op">:-</span>) ∷ a → <span class="dt">List</span> n a → <span class="dt">List</span> (<span class="dt">S</span> n) a</span></code></pre></div>
<p>Some instances for those lists are easy:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">List</span> n) <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> _ <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (x <span class="op">:-</span> xs) <span class="ot">=</span> f x <span class="op">:-</span> <span class="fu">fmap</span> f xs</span></code></pre></div>
<p>However, for <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>,
we need some way to recurse on the size of the list. This is where
induction comes in.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> &#39;(<span class="dt">List</span>,a) ∝ n <span class="ot">=</span> <span class="dt">List</span> n a</span></code></pre></div>
<p>This lets us write <code
class="sourceCode haskell"><span class="fu">pure</span></code> in a
pleasingly simple way:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Finite</span> n ⇒</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Applicative</span> (<span class="dt">List</span> n) <span class="kw">where</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> induction <span class="dt">Nil</span> (x <span class="op">:-</span>)</span></code></pre></div>
<p>But can we also write <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>
using induction? Yes! Because we’ve factored out the induction itself,
we just need to describe the notion of a “sized” function:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> a ↦ b</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> ((x ∷ a) ↦ (y ∷ b)) ∝ n <span class="ot">=</span> (x ∝ n) → (y ∝ n)</span></code></pre></div>
<p>Then we can write <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code> as
so:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Finite</span> n ⇒</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Applicative</span> (<span class="dt">List</span> n) <span class="kw">where</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> induction <span class="dt">Nil</span> (x <span class="op">:-</span>)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    (<span class="op">&lt;*&gt;</span>) <span class="ot">=</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>        induction</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>            (\<span class="dt">Nil</span> <span class="dt">Nil</span> → <span class="dt">Nil</span>)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>            (\k (f <span class="op">:-</span> fs) (x <span class="op">:-</span> xs) → f x <span class="op">:-</span> k fs xs)</span></code></pre></div>
<p>What about the <code
class="sourceCode haskell"><span class="dt">Monad</span></code>
instance? For that, we need a little bit of plumbing: the type signature
of <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code>
is:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>(<span class="op">&gt;&gt;=</span>) ∷ m a → (a → m b) → m b</span></code></pre></div>
<p>One of the parameters (the second <code>a</code>) doesn’t have a
size: we’ll need to work around that, with <code
class="sourceCode haskell"><span class="dt">Const</span></code>:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">instance</span> (<span class="dt">Const</span> a ∷ ℕ → <span class="dt">Type</span>) ∝ n <span class="ot">=</span> <span class="dt">Const</span> a n</span></code></pre></div>
<p>Using this, we can write our <code
class="sourceCode haskell"><span class="dt">Monad</span></code>
instance:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>head&#39; ∷ <span class="dt">List</span> (<span class="dt">S</span> n) a → a</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>head&#39; (x <span class="op">:-</span> _) <span class="ot">=</span> x</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>tail&#39; ∷ <span class="dt">List</span> (<span class="dt">S</span> n) a → <span class="dt">List</span> n a</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>tail&#39; (_ <span class="op">:-</span> xs) <span class="ot">=</span> xs</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Finite</span> n ⇒</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Monad</span> (<span class="dt">List</span> n) <span class="kw">where</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>    xs <span class="op">&gt;&gt;=</span> (f ∷ a → <span class="dt">List</span> n b) <span class="ot">=</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>        induction</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>            (\<span class="dt">Nil</span> _ → <span class="dt">Nil</span>)</span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>            (\k (y <span class="op">:-</span> ys) fn → head&#39; (fn (<span class="dt">Const</span> y)) <span class="op">:-</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>                               k ys (tail&#39; <span class="op">.</span> fn <span class="op">.</span> <span class="dt">Const</span> <span class="op">.</span> getConst))</span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a>            xs</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>            (f <span class="op">.</span> getConst ∷ <span class="dt">Const</span> a n → <span class="dt">List</span> n b)</span></code></pre></div>
<h2 id="type-family-dependencies">Type Family Dependencies</h2>
<p>Getting the above to work actually took a surprising amount of work:
the crux is that the <code class="sourceCode haskell">∝</code> type
family needs to be injective, so the “successor” proof can typecheck.
Unfortunately, this means that every type can only have one notion of
“size”. What I’d prefer is to be able to pass in a function indicating
exactly <em>how</em> to get the size out of a type, that could change
depending on the situation. So we could recurse on the first argument of
a function, for instance, or just its second, or just the result. This
would need either type-level lambdas (which would be cool), or <a
href="https://ghc.haskell.org/trac/ghc/ticket/10832">generalized type
family dependencies</a>.</p>
]]></description>
    <pubDate>Sat, 05 May 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-05-05-induction.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>5 Cool Things You Can Do With Pattern Synonyms</title>
    <link>https://doisinkidney.com/posts/2018-04-12-pattern-synonyms.html</link>
    <description><![CDATA[<div class="info">
    Posted on April 12, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Pattern Synonyms&#39;." href="/tags/Pattern%20Synonyms.html" rel="tag">Pattern Synonyms</a>
    
</div>

<p><a
href="https://ghc.haskell.org/trac/ghc/wiki/PatternSynonyms">Pattern
Synonyms</a> is an excellent extension for Haskell. There are some <a
href="https://ocharles.org.uk/blog/posts/2014-12-03-pattern-synonyms.html">very</a>
<a
href="https://www.schoolofhaskell.com/user/icelandj/Pattern%20synonyms">cool</a>
examples of their use out there, and I thought I’d add to the list.</p>
<h1 id="make-things-look-like-lists">Make Things Look Like Lists</h1>
<p>Lists are <em>the</em> fundamental data structure for functional
programmers. Unfortunately, once more specialized structures are
required, you often have to switch over to an uncomfortable, annoying
API which isn’t as pleasant or fun to use as cons and nil. With pattern
synonyms, though, that’s not so! For instance, here’s how you would do
it with a run-length-encoded list:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">ConsN</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Int</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>            a</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>            (<span class="dt">List</span> a)</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">ConsN</span> i y ys)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">==</span> y <span class="ot">=</span> <span class="dt">ConsN</span> (i<span class="op">+</span><span class="dv">1</span>) y ys</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>cons x xs <span class="ot">=</span> <span class="dt">ConsN</span> <span class="dv">1</span> x xs</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="ot">uncons ::</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (a, <span class="dt">List</span> a)</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>uncons <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>uncons (<span class="dt">ConsN</span> <span class="dv">1</span> x xs) <span class="ot">=</span> <span class="dt">Just</span> (x, xs)</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>uncons (<span class="dt">ConsN</span> n x xs) <span class="ot">=</span> <span class="dt">Just</span> (x, <span class="dt">ConsN</span> (n<span class="op">-</span><span class="dv">1</span>) x xs)</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span><span class="ot"> (:-) ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> x <span class="op">:-</span> xs <span class="ot">&lt;-</span> (uncons <span class="ot">-&gt;</span> <span class="dt">Just</span> (x, xs))</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    x <span class="op">:-</span> xs <span class="ot">=</span> cons x xs</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# COMPLETE Nil, (:-) #-}</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> b <span class="ot">-&gt;</span> <span class="dt">List</span> (a,b)</span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> (x <span class="op">:-</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> (x,y) <span class="op">:-</span> <span class="fu">zip</span> xs ys</span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> _ _ <span class="ot">=</span> <span class="dt">Nil</span></span></code></pre></div>
<p>A little more useful would be to do the same with a heap:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Leaf</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Node</span> a (<span class="dt">Tree</span> a) (<span class="dt">Tree</span> a)</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="ot">smerge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>smerge <span class="dt">Leaf</span> ys <span class="ot">=</span> ys</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>smerge xs <span class="dt">Leaf</span> <span class="ot">=</span> xs</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>smerge h1<span class="op">@</span>(<span class="dt">Node</span> x lx rx) h2<span class="op">@</span>(<span class="dt">Node</span> y ly ry)</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> <span class="dt">Node</span> x (smerge h2 rx) lx</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Node</span> y (smerge h1 ry) ly</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>cons x <span class="ot">=</span> smerge (<span class="dt">Node</span> x <span class="dt">Leaf</span> <span class="dt">Leaf</span>)</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="ot">uncons ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (a, <span class="dt">Tree</span> a)</span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>uncons <span class="dt">Leaf</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>uncons (<span class="dt">Node</span> x l r) <span class="ot">=</span> <span class="dt">Just</span> (x, smerge l r)</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span><span class="ot"> (:-) ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> x <span class="op">:-</span> xs <span class="ot">&lt;-</span> (uncons <span class="ot">-&gt;</span> <span class="dt">Just</span> (x, xs))</span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>    x <span class="op">:-</span> xs <span class="ot">=</span> cons x xs</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# COMPLETE Leaf, (:-) #-}</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a><span class="fu">sort</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a><span class="fu">sort</span> <span class="ot">=</span> go <span class="op">.</span> <span class="fu">foldr</span> (<span class="op">:-</span>) <span class="dt">Leaf</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>    go <span class="dt">Leaf</span> <span class="ot">=</span> []</span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>    go (x <span class="op">:-</span> xs) <span class="ot">=</span> x <span class="op">:</span> go xs</span></code></pre></div>
<p>In fact, this pattern can be generalized, so <em>any</em>
container-like-thing with a cons-like-thing can be modified as you would
with lists. You can see the generalization in <a
href="https://hackage.haskell.org/package/lens-4.16.1/docs/Control-Lens-Cons.html#v::-60-">lens</a>.</p>
<h1 id="retroactively-make-lyah-examples-work">Retroactively Make <a
href="http://learnyouahaskell.com">LYAH</a> Examples Work</h1>
<p>One of the most confusing things I remember about learning Haskell
early-on was that the vast majority of the Monads examples didn’t work,
because they were written pre-transformers. In other words, the state
monad was defined like so:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">State</span> s a <span class="ot">=</span> <span class="dt">State</span> {<span class="ot"> runState ::</span> s <span class="ot">-&gt;</span> (a, s) }</span></code></pre></div>
<p>But in transformers nowadays (which is where you get <code
class="sourceCode haskell"><span class="dt">State</span></code> from if
you import it in the normal way), the definition is:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">StateT</span> s m a <span class="ot">=</span> <span class="dt">StateT</span> {<span class="ot"> runStateT ::</span> s <span class="ot">-&gt;</span> m (a, s) }</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">State</span> s <span class="ot">=</span> <span class="dt">StateT</span> s <span class="dt">Identity</span></span></code></pre></div>
<p>This results in some <em>very</em> confusing error messages when you
try run example code.</p>
<p>However, we can pretend that the change never happened, with a simple
pattern synonym:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">StateT</span> s m a <span class="ot">=</span> <span class="dt">StateT</span> {<span class="ot"> runStateT ::</span> s <span class="ot">-&gt;</span> m (a, s) }</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">State</span> s <span class="ot">=</span> <span class="dt">StateT</span> s <span class="dt">Identity</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="ot">runState ::</span> <span class="dt">State</span> s a <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> (a, s)</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>runState xs <span class="ot">=</span> runIdentity <span class="op">.</span> runStateT xs</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">State</span><span class="ot"> ::</span> (s <span class="ot">-&gt;</span> (a, s)) <span class="ot">-&gt;</span> <span class="dt">State</span> s a</span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">State</span> x <span class="ot">&lt;-</span> (runState <span class="ot">-&gt;</span> x)</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">State</span> x <span class="ot">=</span> <span class="dt">StateT</span> (<span class="dt">Identity</span> <span class="op">.</span> x)</span></code></pre></div>
<h1
id="getting-type-level-numbers-with-an-efficient-runtime-representation">Getting
Type-Level Numbers With an Efficient Runtime Representation</h1>
<p>If you want to write type-level proofs on numbers, you’ll probably
end up using Peano numerals and singletons:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Nat</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Nat</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Natty</span> n <span class="kw">where</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Zy</span><span class="ot"> ::</span> <span class="dt">Natty</span> <span class="dt">Z</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Sy</span><span class="ot"> ::</span> <span class="dt">Natty</span> n <span class="ot">-&gt;</span> <span class="dt">Natty</span> (<span class="dt">S</span> n)</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> (<span class="op">+</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>) (<span class="ot">m ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Nat</span> <span class="kw">where</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Z</span> <span class="op">+</span> m <span class="ot">=</span> m</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">S</span> n <span class="op">+</span> m <span class="ot">=</span> <span class="dt">S</span> (n <span class="op">+</span> m)</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="ot">plusZeroIsZero ::</span> <span class="dt">Natty</span> n <span class="ot">-&gt;</span> n <span class="op">+</span> <span class="dt">Z</span> <span class="op">:~:</span> n</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>plusZeroIsZero <span class="dt">Zy</span> <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>plusZeroIsZero (<span class="dt">Sy</span> n) <span class="ot">=</span> <span class="kw">case</span> plusZeroIsZero n <span class="kw">of</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Refl</span> <span class="ot">-&gt;</span> <span class="dt">Refl</span></span></code></pre></div>
<p>Pretty cool, right? We can even erase the proof (if we really trust
it) using rewrite rules:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# RULES</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ot">&quot;plusZeroIsZero&quot; forall n. plusZeroIsZero n = unsafeCoerce Refl</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ot">#-}</span></span></code></pre></div>
<p>This isn’t <em>ideal</em>, but it’s getting there.</p>
<p>However, if we ever want to use these things at runtime (perhaps as a
type-level indication of some data structure’s size), we’re going to
rely on the value-level Peano addition, which is bad news.</p>
<p>Not so with pattern synonyms!</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="kw">family</span> <span class="dt">The</span><span class="ot"> k ::</span> k <span class="ot">-&gt;</span> <span class="dt">Type</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Sing</span> (<span class="ot">a ::</span> k) <span class="kw">where</span><span class="ot"> sing ::</span> <span class="dt">The</span> k (<span class="ot">a ::</span> k)</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Nat</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Nat</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="kw">instance</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">=</span> <span class="dt">NatSing</span> <span class="dt">Natural</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Sing</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">NatSing</span> <span class="dv">0</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Sing</span> n <span class="ot">=&gt;</span> <span class="dt">Sing</span> (<span class="dt">S</span> n) <span class="kw">where</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>        (<span class="ot">coerce ::</span> (<span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span>) <span class="ot">-&gt;</span> (<span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> (<span class="dt">S</span> n)))</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>            <span class="fu">succ</span> sing</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Natty</span> n <span class="kw">where</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>        <span class="dt">ZZy</span><span class="ot"> ::</span> <span class="dt">Natty</span> <span class="dt">Z</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>        <span class="dt">SSy</span><span class="ot"> ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">Natty</span> (<span class="dt">S</span> n)</span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a><span class="ot">getNatty ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">Natty</span> n</span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>getNatty (<span class="dt">NatSing</span><span class="ot"> n ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n) <span class="ot">=</span> <span class="kw">case</span> n <span class="kw">of</span></span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>  <span class="dv">0</span> <span class="ot">-&gt;</span> gcastWith (unsafeCoerce <span class="dt">Refl</span><span class="ot"> ::</span> n <span class="op">:~:</span> <span class="dt">Z</span>) <span class="dt">ZZy</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>  _ <span class="ot">-&gt;</span> gcastWith (unsafeCoerce <span class="dt">Refl</span><span class="ot"> ::</span> n <span class="op">:~:</span> <span class="dt">S</span> m) (<span class="dt">SSy</span> (<span class="dt">NatSing</span> (<span class="fu">pred</span> n)))</span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">Zy</span><span class="ot"> ::</span> () <span class="ot">=&gt;</span> (n <span class="op">~</span> <span class="dt">Z</span>) <span class="ot">=&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> n</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">Zy</span> <span class="ot">&lt;-</span> (getNatty <span class="ot">-&gt;</span> <span class="dt">ZZy</span>) <span class="kw">where</span> <span class="dt">Zy</span> <span class="ot">=</span> <span class="dt">NatSing</span> <span class="dv">0</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">Sy</span><span class="ot"> ::</span> () <span class="ot">=&gt;</span> (n <span class="op">~</span> <span class="dt">S</span> m) <span class="ot">=&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> m <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> n</span>
<span id="cb8-30"><a href="#cb8-30" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">Sy</span> x <span class="ot">&lt;-</span> (getNatty <span class="ot">-&gt;</span> <span class="dt">SSy</span> x) <span class="kw">where</span> <span class="dt">Sy</span> (<span class="dt">NatSing</span> x) <span class="ot">=</span> <span class="dt">NatSing</span> (<span class="fu">succ</span> x)</span>
<span id="cb8-31"><a href="#cb8-31" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# COMPLETE Zy, Sy #-}</span></span>
<span id="cb8-32"><a href="#cb8-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-33"><a href="#cb8-33" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> (<span class="op">+</span>) (<span class="ot">n ::</span> <span class="dt">Nat</span>) (<span class="ot">m ::</span> <span class="dt">Nat</span>)<span class="ot"> ::</span> <span class="dt">Nat</span> <span class="kw">where</span></span>
<span id="cb8-34"><a href="#cb8-34" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Z</span> <span class="op">+</span> m <span class="ot">=</span> m</span>
<span id="cb8-35"><a href="#cb8-35" aria-hidden="true" tabindex="-1"></a>        <span class="dt">S</span> n <span class="op">+</span> m <span class="ot">=</span> <span class="dt">S</span> (n <span class="op">+</span> m)</span>
<span id="cb8-36"><a href="#cb8-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-37"><a href="#cb8-37" aria-hidden="true" tabindex="-1"></a><span class="co">-- | Efficient addition, with type-level proof.</span></span>
<span id="cb8-38"><a href="#cb8-38" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> m <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> (n <span class="op">+</span> m)</span>
<span id="cb8-39"><a href="#cb8-39" aria-hidden="true" tabindex="-1"></a>add <span class="ot">=</span> (<span class="ot">coerce ::</span> (<span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span>)</span>
<span id="cb8-40"><a href="#cb8-40" aria-hidden="true" tabindex="-1"></a>              <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> m <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> (n <span class="op">+</span> m)) (<span class="op">+</span>)</span>
<span id="cb8-41"><a href="#cb8-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-42"><a href="#cb8-42" aria-hidden="true" tabindex="-1"></a><span class="co">-- | Proof on efficient representation.</span></span>
<span id="cb8-43"><a href="#cb8-43" aria-hidden="true" tabindex="-1"></a><span class="ot">addZeroRight ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> n <span class="op">+</span> <span class="dt">Z</span> <span class="op">:~:</span> n</span>
<span id="cb8-44"><a href="#cb8-44" aria-hidden="true" tabindex="-1"></a>addZeroRight <span class="dt">Zy</span> <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb8-45"><a href="#cb8-45" aria-hidden="true" tabindex="-1"></a>addZeroRight (<span class="dt">Sy</span> n) <span class="ot">=</span> gcastWith (addZeroRight n) <span class="dt">Refl</span></span></code></pre></div>
<p>(unfortunately, incomplete pattern warnings don’t work here)</p>
<h1 id="hide-your-implementations">Hide Your Implementations</h1>
<p>So you’ve got a tree type:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Tip</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Bin</span> a (<span class="dt">Tree</span> a) (<span class="dt">Tree</span> a)</span></code></pre></div>
<p>And you’ve spent some time writing a (reasonably difficult) function
on the tree:</p>
<details>
<summary>
Complicated function on the tree
</summary>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">showTree ::</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>showTree <span class="dt">Tip</span> <span class="ot">=</span> <span class="st">&quot;&quot;</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>showTree (<span class="dt">Bin</span> x&#39; ls&#39; rs&#39;) <span class="ot">=</span> go <span class="dt">True</span> <span class="fu">id</span> xlen&#39; ls&#39;</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>                          <span class="op">$</span> <span class="fu">showString</span> xshw&#39;</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>                          <span class="op">$</span> endc ls&#39; rs&#39;</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>                          <span class="op">$</span> <span class="fu">showChar</span> <span class="ch">&#39;\n&#39;</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>                          <span class="op">$</span> go <span class="dt">False</span> <span class="fu">id</span> xlen&#39; rs&#39; <span class="st">&quot;&quot;</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    xshw&#39; <span class="ot">=</span> <span class="fu">show</span> x&#39;</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>    xlen&#39; <span class="ot">=</span> <span class="fu">length</span> xshw&#39;</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>    go _ _ _ <span class="dt">Tip</span> <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>    go up k i (<span class="dt">Bin</span> x ls rs) <span class="ot">=</span> branch <span class="dt">True</span> ls</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span> k</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span> pad i</span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span> <span class="fu">showChar</span> (bool <span class="ch">&#39;└&#39;</span> <span class="ch">&#39;┌&#39;</span> up)</span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span> <span class="fu">showString</span> xshw</span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span> endc ls rs</span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span> <span class="fu">showChar</span> <span class="ch">&#39;\n&#39;</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>                            <span class="op">.</span> branch <span class="dt">False</span> rs</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a>        xshw <span class="ot">=</span> <span class="fu">show</span> x</span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a>        xlen <span class="ot">=</span> <span class="fu">length</span> xshw</span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>        branch d</span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> d <span class="op">==</span> up <span class="ot">=</span> go d (k <span class="op">.</span> pad i) (xlen <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> go d (k <span class="op">.</span> pad i <span class="op">.</span> <span class="fu">showChar</span> <span class="ch">&#39;│&#39;</span>) xlen</span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a>    endc <span class="dt">Tip</span>    <span class="dt">Tip</span>    <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a>    endc <span class="dt">Bin</span> {} <span class="dt">Tip</span>    <span class="ot">=</span> <span class="fu">showChar</span> <span class="ch">&#39;┘&#39;</span></span>
<span id="cb10-30"><a href="#cb10-30" aria-hidden="true" tabindex="-1"></a>    endc <span class="dt">Tip</span>    <span class="dt">Bin</span> {} <span class="ot">=</span> <span class="fu">showChar</span> <span class="ch">&#39;┐&#39;</span></span>
<span id="cb10-31"><a href="#cb10-31" aria-hidden="true" tabindex="-1"></a>    endc <span class="dt">Bin</span> {} <span class="dt">Bin</span> {} <span class="ot">=</span> <span class="fu">showChar</span> <span class="ch">&#39;┤&#39;</span></span>
<span id="cb10-32"><a href="#cb10-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-33"><a href="#cb10-33" aria-hidden="true" tabindex="-1"></a>    pad <span class="ot">=</span> (<span class="op">++</span>) <span class="op">.</span> <span class="fu">flip</span> <span class="fu">replicate</span> <span class="ch">&#39; &#39;</span></span></code></pre></div>
</details>
<p>But, for some reason or another, you need to add a field to your
<code class="sourceCode haskell"><span class="dt">Bin</span></code>
constructor, to store the size of the subtree (for instance). Does this
function have to change? No! Simply change the tree definition as
so:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Tip</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Bin&#39;</span> <span class="dt">Int</span> a (<span class="dt">Tree</span> a) (<span class="dt">Tree</span> a)</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">Bin</span> x ls rs <span class="ot">&lt;-</span> <span class="dt">Bin&#39;</span> n x ls rs</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# COMPLETE Tip, Bin #-}</span></span></code></pre></div>
<p>And all the old code works!</p>
<p>This gets to the core of pattern synonyms: it’s another tool which we
can use to separate implementation from API.</p>
<h1 id="better-smart-constructors">Better Smart Constructors</h1>
<p>Say you’ve got a data type that has certain constraints on what
values it can hold. You’re not writing a paper for ICFP, so expressing
those constraints as a beautiful type isn’t required: you just want to
only export the constructor and accessors, and write some tests to make
sure that those functions always obey the constraints.</p>
<p>But once you do this you’ve lost something: pattern-matching. Let’s
get it back with pattern synonyms!</p>
<p>As our simple example, our constraint is going to be “A list where
the values are always ordered”:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">List</span> a <span class="ot">=</span> <span class="dt">List</span> {<span class="ot"> getList ::</span> [a] }</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>cons x (<span class="dt">List</span> xs) <span class="ot">=</span> <span class="dt">List</span> (insert x xs)</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span><span class="ot"> (:-) ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> a</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> x <span class="op">:-</span> xs <span class="ot">&lt;-</span> (<span class="dt">List</span> (x<span class="op">:</span>xs))</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>    x <span class="op">:-</span> xs <span class="ot">=</span> cons x xs</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">List</span> []</span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# COMPLETE Nil, (:-) #-}</span></span></code></pre></div>
]]></description>
    <pubDate>Thu, 12 Apr 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-04-12-pattern-synonyms.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Strict Applicative Transformer</title>
    <link>https://doisinkidney.com/posts/2018-03-21-strictify-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 21, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Adapted from <a
href="https://www.reddit.com/r/haskell/comments/86021n/strictifying_traversals/">this
post</a> on reddit. It’s possible to take a lazy traversal and make it
strict.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE BangPatterns #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Seq</span> (fmap&#39;,traverse&#39;) <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Coerce</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Applicative</span> (liftA2)</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Seq</span> a <span class="ot">=</span> <span class="dt">Seq</span> {<span class="ot"> unSeq ::</span> a }</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Seq</span> <span class="kw">where</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f x <span class="ot">=</span> <span class="kw">let</span> <span class="op">!</span>vx <span class="ot">=</span> unSeq x <span class="kw">in</span> <span class="dt">Seq</span> (f vx)</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE fmap #-}</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&lt;$</span> xs <span class="ot">=</span> <span class="kw">let</span> <span class="op">!</span>_ <span class="ot">=</span> unSeq xs <span class="kw">in</span> <span class="dt">Seq</span> x</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE (&lt;$) #-}</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Seq</span> <span class="kw">where</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Seq</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE pure #-}</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>  fs <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> <span class="kw">let</span> <span class="op">!</span>vx <span class="ot">=</span> unSeq xs <span class="kw">in</span> <span class="dt">Seq</span> (unSeq fs vx)</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE (&lt;*&gt;) #-}</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">*&gt;</span> ys <span class="ot">=</span> <span class="kw">let</span> <span class="op">!</span>_ <span class="ot">=</span> unSeq xs <span class="kw">in</span> ys</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE (*&gt;) #-}</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">&lt;*</span> ys <span class="ot">=</span> <span class="kw">let</span> <span class="op">!</span>_ <span class="ot">=</span> unSeq ys <span class="kw">in</span> xs</span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE (&lt;*) #-}</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="ot">fmap&#39; ::</span> <span class="dt">Traversable</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>fmap&#39; <span class="ot">=</span> (<span class="ot">coerce ::</span> ((a <span class="ot">-&gt;</span> <span class="dt">Seq</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Seq</span> (f b)) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b) <span class="fu">traverse</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE fmap&#39; #-}</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">SeqT</span> f a <span class="ot">=</span> <span class="dt">SeqT</span> {<span class="ot"> unSeqT ::</span> f a }</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Functor</span> (<span class="dt">SeqT</span> f) <span class="kw">where</span></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f <span class="ot">=</span> <span class="dt">SeqT</span> <span class="op">#.</span> <span class="fu">fmap</span> (\ <span class="op">!</span>vx <span class="ot">-&gt;</span> f vx) <span class="op">.#</span> unSeqT</span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE fmap #-}</span></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a><span class="ot">(#.) ::</span> <span class="dt">Coercible</span> b c <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> c</span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>(<span class="op">#.</span>) _ <span class="ot">=</span> coerce</span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE (#.) #-}</span></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a><span class="ot">(.#) ::</span> <span class="dt">Coercible</span> a b <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> c</span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>(<span class="op">.#</span>) f _ <span class="ot">=</span> coerce f</span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE (.#) #-}</span></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">SeqT</span> f) <span class="kw">where</span></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">SeqT</span> <span class="op">#.</span> <span class="fu">pure</span></span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE pure #-}</span></span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;*&gt;</span>) <span class="ot">=</span> (<span class="ot">coerce ::</span> (f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> (<span class="dt">SeqT</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">SeqT</span> f a <span class="ot">-&gt;</span> <span class="dt">SeqT</span> f b)) (liftA2 (\fs <span class="op">!</span>vx <span class="ot">-&gt;</span> fs vx))</span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE (&lt;*&gt;) #-}</span></span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a>  liftA2 f <span class="ot">=</span> (<span class="ot">coerce ::</span> (f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c) <span class="ot">-&gt;</span> (<span class="dt">SeqT</span> f a <span class="ot">-&gt;</span> <span class="dt">SeqT</span> f b <span class="ot">-&gt;</span> <span class="dt">SeqT</span> f c)) (liftA2 (\ <span class="op">!</span>x <span class="op">!</span>y <span class="ot">-&gt;</span> f x y))</span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE liftA2 #-}</span></span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a><span class="ot">traverse&#39; ::</span> (<span class="dt">Traversable</span> t, <span class="dt">Applicative</span> f) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> f (t b)</span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a>traverse&#39; <span class="ot">=</span> (<span class="ot">coerce ::</span> ((a <span class="ot">-&gt;</span> <span class="dt">SeqT</span> f b) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> <span class="dt">SeqT</span> f (t b)) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> f (t b)) <span class="fu">traverse</span></span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE traverse&#39; #-}</span></span></code></pre></div>
<p>You need traversable in order to get the strictness: there’s a
similar way to get a stricter fmap <a
href="http://hackage.haskell.org/package/base-4.11.1.0/docs/Control-Monad.html#v:-60--36--33--62-">with
monad instead</a>:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;$!&gt;) ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m b</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE (&lt;$!&gt;) #-}</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>f <span class="op">&lt;$!&gt;</span> m <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> m</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> z <span class="ot">=</span> f x</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  z <span class="ot">`seq`</span> <span class="fu">return</span> z</span></code></pre></div>
]]></description>
    <pubDate>Wed, 21 Mar 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-03-21-strictify-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Countdown</title>
    <link>https://doisinkidney.com/posts/2018-03-20-countdown.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 20, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Algorithms&#39;." href="/tags/Algorithms.html" rel="tag">Algorithms</a>
    
</div>

<p>There’s a popular UK TV show called <a
href="https://en.wikipedia.org/wiki/Countdown_(game_show)">Countdown</a>
with a round where contestants have to get as close to some target
number as possible by constructing an arithmetic expression from six
random numbers.</p>
<p>You don’t have to use all of the numbers, and you’re allowed use four
operations: addition, subtraction, multiplication, and division.
Additionally, each stage of the calculation must result in a positive
integer.</p>
<p>Here’s an example. Try get to the target 586:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>100</mn><mo>,</mo><mn>25</mn><mo>,</mo><mn>1</mn><mo>,</mo><mn>5</mn><mo>,</mo><mn>3</mn><mo>,</mo><mn>10</mn></mrow><annotation encoding="application/x-tex">100,25,1,5,3,10</annotation></semantics></math></p>
<p>On the show, contestants get 30 seconds to think of an answer.</p>
<details>
<summary>
Solution
</summary>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>25</mn><mo>*</mo><mn>3</mn><mo>+</mo><mn>10</mn><mo>+</mo><mn>100</mn><mo>*</mo><mn>5</mn><mo>+</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">25 * 3 + 10 + 100 * 5 + 1</annotation></semantics></math>
</details>
<p>Solving it in Haskell was first explored in depth in <span
class="citation" data-cites="hutton_countdown_2002">Hutton (<a
href="#ref-hutton_countdown_2002" role="doc-biblioref">2002</a>)</span>.
There, a basic “generate-and-test” implementation was provided and
proven correct.</p>
<p>As an optimization problem, there are several factors which will
influence the choice of algorithm:</p>
<ol type="1">
<li>There’s no obvious heuristic for constructing subexpressions in
order to get to a final result. In other words, if we have
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>25</mn><mo>*</mo><mn>3</mn><mo>+</mo><mn>10</mn></mrow><annotation encoding="application/x-tex">25 * 3 + 10</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>25</mn><mo>*</mo><mn>3</mn><mo>*</mo><mn>10</mn></mrow><annotation encoding="application/x-tex">25 * 3 * 10</annotation></semantics></math>,
there’s no easy way to tell which is “closer” to
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mn>586</mn><annotation encoding="application/x-tex">586</annotation></semantics></math>.
The latter is closer numerically, but the former is what we ended up
using in the solution.</li>
<li>Because certain subexpressions aren’t allowed, we’ll be able to
prune the search space as we go.</li>
<li>Ideally, we’d only want to calculate each possible subexpression
once, making it a pretty standard dynamic programming problem.</li>
</ol>
<p>I’ll be focusing on the third point in this post, but we can add the
second point in at the end. First, however, let’s write a naive
implementation.</p>
<h2 id="generating-all-expressions">Generating all Expressions</h2>
<p>I can’t think of a simpler way to solve the problem than
generate-and-test, so we’ll work from there. Testing is easy (<code
class="sourceCode haskell">(target <span class="op">==</span>) <span class="op">.</span> eval</code>),
so we’ll focus on generation. The core function we’ll use for this is
usually called “unmerges”:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>unmerges [x,y] <span class="ot">=</span> [([x],[y])]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>unmerges (x<span class="op">:</span>xs) <span class="ot">=</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    ([x],xs) <span class="op">:</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">concat</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>        [ [(x<span class="op">:</span>ys,zs),(ys,x<span class="op">:</span>zs)]</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> (ys,zs) <span class="ot">&lt;-</span> unmerges xs ]</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>unmerges _ <span class="ot">=</span> []</span></code></pre></div>
<p>It generates all possible 2-partitions of a list, ignoring order:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> unmerges <span class="st">&quot;abc&quot;</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>[(<span class="st">&quot;a&quot;</span>,<span class="st">&quot;bc&quot;</span>),(<span class="st">&quot;ab&quot;</span>,<span class="st">&quot;c&quot;</span>),(<span class="st">&quot;b&quot;</span>,<span class="st">&quot;ac&quot;</span>)]</span></code></pre></div>
<p>I haven’t looked much into how to optimize this function or make it
nicer, as we’ll be swapping it out later.</p>
<p>Next, we need to make the recursive calls:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">allExprs ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>allExprs _ [x] <span class="ot">=</span> [x]</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>allExprs c xs <span class="ot">=</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    [ e</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> (ys,zs) <span class="ot">&lt;-</span> unmerges xs</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    , y <span class="ot">&lt;-</span> allExprs c ys</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    , z <span class="ot">&lt;-</span> allExprs c zs</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    , e <span class="ot">&lt;-</span> c y z ]</span></code></pre></div>
<p>Finally, using the <a
href="https://hackage.haskell.org/package/simple-reflect">simple-reflect</a>
library, we can take a look at the output:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> allExprs (\x y <span class="ot">-&gt;</span> [x<span class="op">+</span>y,x<span class="op">*</span>y]) [<span class="dv">1</span>,<span class="dv">2</span>]<span class="ot"> ::</span> [<span class="dt">Expr</span>]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span> <span class="op">+</span> <span class="dv">2</span>,<span class="dv">1</span> <span class="op">*</span> <span class="dv">2</span>]</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> allExprs (\x y <span class="ot">-&gt;</span> [x<span class="op">+</span>y]) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]<span class="ot"> ::</span> [<span class="dt">Expr</span>]</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span> <span class="op">+</span> (<span class="dv">2</span> <span class="op">+</span> <span class="dv">3</span>),<span class="dv">1</span> <span class="op">+</span> <span class="dv">2</span> <span class="op">+</span> <span class="dv">3</span>,<span class="dv">2</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> <span class="dv">3</span>)]</span></code></pre></div>
<p>Even at this early stage, we can actually already write a rudimentary
solution:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">countdown ::</span> [<span class="dt">Integer</span>] <span class="ot">-&gt;</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> [<span class="dt">Expr</span>]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>countdown xs targ <span class="ot">=</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">filter</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>        ((<span class="op">==</span>) targ <span class="op">.</span> <span class="fu">toInteger</span>)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>        (allExprs</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>             (\x y <span class="ot">-&gt;</span> [x,y,x<span class="op">+</span>y,x<span class="op">*</span>y])</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>             (<span class="fu">map</span> <span class="fu">fromInteger</span> xs))</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">mapM_</span> <span class="fu">print</span> (countdown [<span class="dv">100</span>,<span class="dv">25</span>,<span class="dv">1</span>,<span class="dv">5</span>,<span class="dv">3</span>,<span class="dv">10</span>] <span class="dv">586</span>)</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> (<span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> <span class="dv">10</span>))</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> (<span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">10</span>))</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> <span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> (<span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a><span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> (<span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> <span class="dv">10</span>))</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a><span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> <span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a><span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> (<span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> <span class="dv">10</span>))</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span>) <span class="op">+</span> <span class="dv">10</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> <span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> <span class="dv">10</span></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true" tabindex="-1"></a><span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> <span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span>) <span class="op">+</span> <span class="dv">10</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true" tabindex="-1"></a><span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> <span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true" tabindex="-1"></a><span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">10</span>))</span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true" tabindex="-1"></a><span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> <span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true" tabindex="-1"></a><span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> (<span class="dv">1</span> <span class="op">+</span> <span class="dv">10</span>))</span></code></pre></div>
<p>As you can see from the output, there’s a lot of repetition. We’ll
need to do some memoization to speed it up.</p>
<h2 id="pure-memoization">Pure Memoization</h2>
<p>The normal way most programmers think about “memoization” is
something like this:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>memo_dict <span class="op">=</span> {<span class="dv">0</span>:<span class="dv">0</span>,<span class="dv">1</span>:<span class="dv">1</span>}</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> fib(n):</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> n <span class="kw">in</span> memo_dict:</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> memo_dict[n]</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>        res <span class="op">=</span> fib(n<span class="op">-</span><span class="dv">1</span>) <span class="op">+</span> fib(n<span class="op">-</span><span class="dv">2</span>)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>        memo_dict[n] <span class="op">=</span> res</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> res</span></code></pre></div>
<p>In other words, it’s a fundamentally stateful process. We need to
mutate some mapping when we haven’t seen the argument before.</p>
<p>Using laziness, though, we can emulate the same behavior purely.
Instead of mutating the mapping on function calls, we fill the whole
thing at the beginning, and then index into it. As long as the mapping
is lazy, it’ll only evaluate the function calls when they’re needed. We
could use lists as our mapping to the natural numbers:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>fibs <span class="ot">=</span> <span class="dv">0</span> <span class="op">:</span> <span class="dv">1</span> <span class="op">:</span> <span class="fu">map</span> fib [<span class="dv">2</span><span class="op">..</span>]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>fib n <span class="ot">=</span> fibs <span class="op">!!</span> (n<span class="op">-</span><span class="dv">1</span>) <span class="op">+</span> fibs <span class="op">!!</span> (n<span class="op">-</span><span class="dv">2</span>)</span></code></pre></div>
<p>The benefit here is that we avoid the extra work of redundant calls.
However, we pay for the speedup in three ways:</p>
<ol class="example" type="1">
<li>Space: we need to take up memory space storing the cached
solutions.</li>
<li>Indexing: while we no longer have to pay for the expensive recursive
calls, we <em>do</em> now have to pay for indexing into the data
structure. In this example, we’re paying linear time to index into the
list.</li>
<li>Generality: the memoization is tied directly to the argument type to
the function. We need to be able to use the argument to our memoized
function as an index into some data structure. While a lot of argument
types admit some type of indexing (whether they’re <code
class="sourceCode haskell"><span class="dt">Hashable</span></code>,
<code class="sourceCode haskell"><span class="dt">Ord</span></code>,
etc.), some don’t, and we can’t memoize those using this technique.</li>
</ol>
<p>We’re going to look at a technique that allow us to somewhat mitigate
2 and 3 above, using something called a <em>nexus</em>.</p>
<h2 id="nexuses">Nexuses</h2>
<p>The standard technique of memoization is focused on the arguments to
the function, creating a concrete representation of them in memory to
map to the results. Using nexuses, as described in <span
class="citation" data-cites="bird_functional_2003">Bird and Hinze (<a
href="#ref-bird_functional_2003" role="doc-biblioref">2003</a>)</span>,
we’ll instead focus on the function itself, creating a concrete
representation of its call graph in memory. Here’s the call graph of
Fibonacci:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>                                            ┌fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>                                   ┌fib(<span class="dv">2</span>)<span class="ot">=</span><span class="dv">1</span>┤</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>                                   │        └fib(<span class="dv">0</span>)<span class="ot">=</span><span class="dv">0</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>                          ┌fib(<span class="dv">3</span>)<span class="ot">=</span><span class="dv">2</span>┤</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>                          │        └fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>                 ┌fib(<span class="dv">4</span>)<span class="ot">=</span><span class="dv">3</span>┤</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>                 │        │        ┌fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>                 │        └fib(<span class="dv">2</span>)<span class="ot">=</span><span class="dv">1</span>┤</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>                 │                 └fib(<span class="dv">0</span>)<span class="ot">=</span><span class="dv">0</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>        ┌fib(<span class="dv">5</span>)<span class="ot">=</span><span class="dv">5</span>┤</span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>        │        │                 ┌fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>        │        │        ┌fib(<span class="dv">2</span>)<span class="ot">=</span><span class="dv">1</span>┤</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>        │        │        │        └fib(<span class="dv">0</span>)<span class="ot">=</span><span class="dv">0</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>        │        └fib(<span class="dv">3</span>)<span class="ot">=</span><span class="dv">2</span>┤</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>        │                 └fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>fib(<span class="dv">6</span>)<span class="ot">=</span><span class="dv">8</span>┤</span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>        │                          ┌fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>        │                 ┌fib(<span class="dv">2</span>)<span class="ot">=</span><span class="dv">1</span>┤</span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a>        │                 │        └fib(<span class="dv">0</span>)<span class="ot">=</span><span class="dv">0</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true" tabindex="-1"></a>        │        ┌fib(<span class="dv">3</span>)<span class="ot">=</span><span class="dv">2</span>┤</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true" tabindex="-1"></a>        │        │        └fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true" tabindex="-1"></a>        └fib(<span class="dv">4</span>)<span class="ot">=</span><span class="dv">3</span>┤</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true" tabindex="-1"></a>                 │        ┌fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true" tabindex="-1"></a>                 └fib(<span class="dv">2</span>)<span class="ot">=</span><span class="dv">1</span>┤</span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true" tabindex="-1"></a>                          └fib(<span class="dv">0</span>)<span class="ot">=</span><span class="dv">0</span></span></code></pre></div>
<p>Turning <em>that</em> into a concrete datatype wouldn’t do us much
good: it still has the massively redundant computations in it. However,
we can recognize that entire subtrees are duplicates of each other: in
those cases, instead of creating both subtrees, we could just create one
and have each parent point to it<a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"><sup>1</sup></a>:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>        ┌fib(<span class="dv">5</span>)<span class="ot">=</span><span class="dv">5</span>┬────────┬fib(<span class="dv">3</span>)<span class="ot">=</span><span class="dv">2</span>┬────────┬fib(<span class="dv">1</span>)<span class="ot">=</span><span class="dv">1</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>fib(<span class="dv">6</span>)<span class="ot">=</span><span class="dv">8</span>┤        │        │        │        │</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>        └────────┴fib(<span class="dv">4</span>)<span class="ot">=</span><span class="dv">3</span>┴────────┴fib(<span class="dv">2</span>)<span class="ot">=</span><span class="dv">1</span>┴fib(<span class="dv">0</span>)<span class="ot">=</span><span class="dv">0</span></span></code></pre></div>
<p>This is a nexus. In Haskell, it’s not observably different from the
other form, except that it takes up significantly less space. It’s also
much quicker to construct.</p>
<p>If we use it to memoize <code class="sourceCode haskell">fib</code>,
we’ll no longer be indexing on the argument: we’ll instead follow the
relevant branch in the tree to the subcomputation, which is just chasing
a pointer. It also means the argument doesn’t have to be constrained to
any specific type. Here’s how you’d do it:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Leaf</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Node</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> val   ::</span> <span class="dt">Integer</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> left  ::</span> <span class="dt">Tree</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> right ::</span> <span class="dt">Tree</span>}</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a><span class="ot">fib ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>fib <span class="ot">=</span> val <span class="op">.</span> go</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>    go <span class="dv">0</span> <span class="ot">=</span> <span class="dt">Node</span> <span class="dv">0</span> <span class="dt">Leaf</span> <span class="dt">Leaf</span></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>    go <span class="dv">1</span> <span class="ot">=</span> <span class="dt">Node</span> <span class="dv">1</span> (<span class="dt">Node</span> <span class="dv">0</span> <span class="dt">Leaf</span> <span class="dt">Leaf</span>) <span class="dt">Leaf</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>    go n <span class="ot">=</span> node t (left t) <span class="kw">where</span> t <span class="ot">=</span> go (n<span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a>    node l r <span class="ot">=</span> <span class="dt">Node</span> (val l <span class="op">+</span> val r) l r</span></code></pre></div>
<p>So this approach sounds amazing, right? No constraints on the
argument type, no need to pay for indexing: why doesn’t everyone use it
everywhere? The main reason is that figuring out a nexus for the
call-graph is <em>hard</em>. In fact, finding an optimal one is NP-hard
in general <span class="citation" data-cites="steffen_table_2006">(<a
href="#ref-steffen_table_2006" role="doc-biblioref">Steffen and
Giegerich 2006</a>)</span>.</p>
<p>The second problem is that it’s difficult to abstract out. The
standard technique of memoization relies on building a mapping from keys
to values: about as bread-and-butter as it gets in programming. Even
more, we already know how to say “values of this type can be used
efficiently as keys in some mapping”: for Data.Map it’s <code
class="sourceCode haskell"><span class="dt">Ord</span></code>, for
Data.HashMap it’s <code
class="sourceCode haskell"><span class="dt">Hashable</span></code>. All
of this together means we can build a nice library for memoization which
exports the two following functions:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">memoHash ::</span> <span class="dt">Hashable</span> a <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b)</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="ot">memoOrd ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b)</span></code></pre></div>
<p>Building a nexus, however, is not bread-and-butter. On top of that,
it’s difficult to say something like “recursive functions of this
structure can be constructed using a nexus”. What’s the typeclass for
that? In comparison to the signatures above, the constraint will need to
be on the <em>arrows</em>, not the <code
class="sourceCode haskell">a</code>. Even talking about the structure of
recursive functions is regarded as somewhat of an advanced subject: that
said, the <a
href="https://hackage.haskell.org/package/recursion-schemes">recursion-schemes</a>
package allows us to do so, and even has facilities for constructing
something <em>like</em> nexuses with histomorphisms <span
class="citation" data-cites="tobin_time_2016">(<a
href="#ref-tobin_time_2016" role="doc-biblioref">Tobin 2016</a>)</span>.
I’m still looking to see if there’s a library out there that
<em>does</em> manage to abstract nexuses in an ergonomic way, so I’d
love to hear if there was one (or if there’s some more generalized form
which accomplishes the same).</p>
<h2 id="memoizing-countdown">Memoizing Countdown</h2>
<p>That’s enough preamble. The nexus we want to construct for countdown
is <em>not</em> going to memoize as much as possible: in particular,
we’re only going to memoize the shape of the trees, not the operators
used. This will massively reduce the memory overhead, and still give a
decent speedup <span class="citation"
data-cites="bird_countdown:_2005">(<a href="#ref-bird_countdown:_2005"
role="doc-biblioref">Bird and Mu 2005, 11</a> “building a skeleton tree
first”)</span>.</p>
<p>With that in mind, the ideal nexus looks something like this:</p>
<p><img src="/images/boolean-lattice.svg" /></p>
<p>We can represent the tree in Haskell as a rose tree:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Node</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> root   ::</span> a</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> forest ::</span> <span class="dt">Forest</span> a</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Forest</span> a <span class="ot">=</span> [<span class="dt">Tree</span> a]</span></code></pre></div>
<p>Constructing the nexus itself isn’t actually the most interesting
part of this solution: <em>consuming</em> it is. We need to be able to
go from the structure above into a list that’s the equivalent of <code
class="sourceCode haskell">unmerges</code>. Doing a breadth-first
traversal of the diagram above (without the top element) will give
us:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mi>c</mi><mo>,</mo><mi>a</mi><mi>b</mi><mi>d</mi><mo>,</mo><mi>a</mi><mi>c</mi><mi>d</mi><mo>,</mo><mi>b</mi><mi>c</mi><mi>d</mi><mo>,</mo><mi>a</mi><mi>b</mi><mo>,</mo><mi>a</mi><mi>c</mi><mo>,</mo><mi>b</mi><mi>c</mi><mo>,</mo><mi>a</mi><mi>d</mi><mo>,</mo><mi>b</mi><mi>d</mi><mo>,</mo><mi>c</mi><mi>d</mi><mo>,</mo><mi>a</mi><mo>,</mo><mi>b</mi><mo>,</mo><mi>c</mi><mo>,</mo><mi>d</mi></mrow><annotation encoding="application/x-tex">abc, abd, acd, bcd, ab, ac, bc, ad, bd, cd, a, b, c, d</annotation></semantics></math></p>
<p>If you split that list in half, and zip it with its reverse, you’ll
get the output of <code class="sourceCode haskell">unmerges</code>.</p>
<p>However, the breadth-first traversal of the diagram isn’t the same
thing as the breadth-first traversal of the rose tree. The latter will
traverse
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mi>c</mi><mo>,</mo><mi>a</mi><mi>b</mi><mi>d</mi><mo>,</mo><mi>a</mi><mi>c</mi><mi>d</mi><mo>,</mo><mi>b</mi><mi>c</mi><mi>d</mi></mrow><annotation encoding="application/x-tex">abc, abd, acd, bcd</annotation></semantics></math>,
and then the children of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">abc</annotation></semantics></math>
(<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mo>,</mo><mi>a</mi><mi>c</mi><mo>,</mo><mi>b</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">ab,ac,bc</annotation></semantics></math>),
and then the children of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mi>d</mi></mrow><annotation encoding="application/x-tex">abd</annotation></semantics></math>
(<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mo>,</mo><mi>a</mi><mi>d</mi><mo>,</mo><mi>b</mi><mi>d</mi></mrow><annotation encoding="application/x-tex">ab,ad,bd</annotation></semantics></math>):
and here’s our problem. We traverse
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi></mrow><annotation encoding="application/x-tex">ab</annotation></semantics></math>
twice, because we can’t know that
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mi>c</mi></mrow><annotation encoding="application/x-tex">abc</annotation></semantics></math>
and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>b</mi><mi>d</mi></mrow><annotation encoding="application/x-tex">abd</annotation></semantics></math>
are pointing to the same value. What we have to do is first prune the
tree, removing duplicates, and then perform a breadth-first traversal on
that.</p>
<h3 id="pruning">Pruning</h3>
<p>Luckily, the duplicates follow a pattern, allowing us to remove them
without having to do any equality checking. In each row, the first node
has no duplicates in its children, the second’s first child is a
duplicate, the third’s first and second children are duplicates, and so
on. You should be able to see this in the diagram above. Adapting a
little from the paper, we get an algorithm like this:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">para ::</span> (a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>para f b <span class="ot">=</span> go</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    go [] <span class="ot">=</span> b</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    go (x<span class="op">:</span>xs) <span class="ot">=</span> f x xs (go xs)</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="ot">prune ::</span> <span class="dt">Forest</span> a <span class="ot">-&gt;</span> <span class="dt">Forest</span> a</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>prune ts <span class="ot">=</span> pruneAt ts <span class="dv">0</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    pruneAt <span class="ot">=</span> para f (<span class="fu">const</span> [])</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x []) t _ _ <span class="ot">=</span> <span class="dt">Node</span> x [] <span class="op">:</span> t</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x us) _ a k <span class="ot">=</span></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Node</span> x (pruneAt (<span class="fu">drop</span> k us) k) <span class="op">:</span> a (k <span class="op">+</span> <span class="dv">1</span>)</span></code></pre></div>
<h3 id="breadth-first-traversal">Breadth-First Traversal</h3>
<p>I went through this in a <a
href="/posts/2018-03-17-rose-trees-breadth-first.html">previous
post</a>, so this is the end solution:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirst ::</span> <span class="dt">Forest</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>breadthFirst ts <span class="ot">=</span> <span class="fu">foldr</span> f b ts []</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (xs<span class="op">:</span>bw)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>    b q <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b q []</span></code></pre></div>
<p>With the appropriate incantations, this is actually the fastest
implementation I’ve found.</p>
<h3 id="fusing">Fusing</h3>
<p>We can actually inline both of the above functions, fusing them
together:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">spanNexus ::</span> <span class="dt">Forest</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>spanNexus ts <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="fu">const</span> b) ts <span class="dv">0</span> []</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x us) fw k bw <span class="ot">=</span> x <span class="op">:</span> fw (k<span class="op">+</span><span class="dv">1</span>) ((<span class="fu">drop</span> k us, k) <span class="op">:</span> bw)</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>    b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">uncurry</span> <span class="op">.</span> <span class="fu">foldr</span> f <span class="op">.</span> <span class="fu">const</span>) b qs []</span></code></pre></div>
<h3 id="halving-convolving-and-folding">Halving, Convolving, and
Folding</h3>
<p>So, now we can go from the tree to our list of splits. Next step is
to convert that list into the output of unmerges, by zipping the reverse
of the first half with the second. We can use an algorithm described in
<span class="citation" data-cites="danvy_there_2005">Danvy and Goldberg
(<a href="#ref-danvy_there_2005" role="doc-biblioref">2005</a>)</span>
to do the zipping and reversing:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>fold xs n <span class="ot">=</span> go xs n (<span class="fu">const</span> [])</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>    go xs <span class="dv">0</span>     k <span class="ot">=</span> k xs</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    go (x<span class="op">:</span>xs) n k <span class="ot">=</span> go xs (n<span class="op">-</span><span class="dv">2</span>) (\(y<span class="op">:</span>ys) <span class="ot">-&gt;</span> (x,y) <span class="op">:</span> k ys)</span></code></pre></div>
<p>And we can inline the function which collapses those results into
one:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>fold xs n <span class="ot">=</span> go xs n (<span class="fu">const</span> [])</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    go <span class="dv">0</span> xss k <span class="ot">=</span> k xss</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    go n (xs<span class="op">:</span>xss) k <span class="ot">=</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>        go (n<span class="op">-</span><span class="dv">2</span>) xss (\(ys<span class="op">:</span>yss) <span class="ot">-&gt;</span> [ z</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>                                      <span class="op">|</span> x <span class="ot">&lt;-</span> xs</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>                                      , y <span class="ot">&lt;-</span> ys</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>                                      , z <span class="ot">&lt;-</span> cmb x y</span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>                                      ] <span class="op">++</span> k yss)</span></code></pre></div>
<p>And that’s all we need!</p>
<details>
<summary>
Full Code
</summary>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Tree</span> <span class="kw">as</span> <span class="dt">Rose</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Leaf</span> <span class="dt">Int</span> a</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Node</span> [<span class="dt">Tree</span> a]</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Show</span>,<span class="dt">Eq</span>,<span class="dt">Functor</span>)</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a><span class="ot">enumerateTrees ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>enumerateTrees _ [] <span class="ot">=</span> []</span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>enumerateTrees cmb xs <span class="ot">=</span> (extract <span class="op">.</span> steps <span class="op">.</span> initial) xs</span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a>    step <span class="ot">=</span> <span class="fu">map</span> nodes <span class="op">.</span> <span class="fu">group</span></span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a>    steps [x] <span class="ot">=</span> x</span>
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a>    steps xs <span class="ot">=</span> steps (step xs)</span>
<span id="cb20-16"><a href="#cb20-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-17"><a href="#cb20-17" aria-hidden="true" tabindex="-1"></a>    initial <span class="ot">=</span> <span class="fu">map</span> (<span class="dt">Leaf</span> <span class="dv">1</span> <span class="op">.</span> <span class="fu">flip</span> <span class="dt">Rose.Node</span> [] <span class="op">.</span> <span class="fu">pure</span>)</span>
<span id="cb20-18"><a href="#cb20-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-19"><a href="#cb20-19" aria-hidden="true" tabindex="-1"></a>    extract (<span class="dt">Leaf</span> _ x) <span class="ot">=</span> Rose.rootLabel x</span>
<span id="cb20-20"><a href="#cb20-20" aria-hidden="true" tabindex="-1"></a>    extract (<span class="dt">Node</span> [x]) <span class="ot">=</span> extract x</span>
<span id="cb20-21"><a href="#cb20-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-22"><a href="#cb20-22" aria-hidden="true" tabindex="-1"></a>    <span class="fu">group</span> [_] <span class="ot">=</span> []</span>
<span id="cb20-23"><a href="#cb20-23" aria-hidden="true" tabindex="-1"></a>    <span class="fu">group</span> (<span class="dt">Leaf</span> _ x<span class="op">:</span>vs) <span class="ot">=</span> <span class="dt">Node</span> [<span class="dt">Leaf</span> <span class="dv">2</span> [x, y] <span class="op">|</span> <span class="dt">Leaf</span> _ y <span class="ot">&lt;-</span> vs] <span class="op">:</span> <span class="fu">group</span> vs</span>
<span id="cb20-24"><a href="#cb20-24" aria-hidden="true" tabindex="-1"></a>    <span class="fu">group</span> (<span class="dt">Node</span>   u<span class="op">:</span>vs) <span class="ot">=</span> <span class="dt">Node</span> (<span class="fu">zipWith</span> comb (<span class="fu">group</span> u) vs) <span class="op">:</span> <span class="fu">group</span> vs</span>
<span id="cb20-25"><a href="#cb20-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-26"><a href="#cb20-26" aria-hidden="true" tabindex="-1"></a>    comb (<span class="dt">Leaf</span> n xs) (<span class="dt">Leaf</span> _ x) <span class="ot">=</span> <span class="dt">Leaf</span> (n <span class="op">+</span> <span class="dv">1</span>) (xs <span class="op">++</span> [x])</span>
<span id="cb20-27"><a href="#cb20-27" aria-hidden="true" tabindex="-1"></a>    comb (<span class="dt">Node</span> us) (<span class="dt">Node</span> vs) <span class="ot">=</span> <span class="dt">Node</span> (<span class="fu">zipWith</span> comb us vs)</span>
<span id="cb20-28"><a href="#cb20-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-29"><a href="#cb20-29" aria-hidden="true" tabindex="-1"></a>    forest ts <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="fu">const</span> b) ts <span class="dv">0</span> []</span>
<span id="cb20-30"><a href="#cb20-30" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb20-31"><a href="#cb20-31" aria-hidden="true" tabindex="-1"></a>        f (<span class="dt">Rose.Node</span> x []) fw <span class="op">!</span>k bw <span class="ot">=</span> x <span class="op">:</span> fw (k <span class="op">+</span> <span class="dv">1</span>) bw</span>
<span id="cb20-32"><a href="#cb20-32" aria-hidden="true" tabindex="-1"></a>        f (<span class="dt">Rose.Node</span> x us) fw <span class="op">!</span>k bw <span class="ot">=</span> x <span class="op">:</span> fw (k <span class="op">+</span> <span class="dv">1</span>) ((<span class="fu">drop</span> k us, k) <span class="op">:</span> bw)</span>
<span id="cb20-33"><a href="#cb20-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-34"><a href="#cb20-34" aria-hidden="true" tabindex="-1"></a>        b [] <span class="ot">=</span> []</span>
<span id="cb20-35"><a href="#cb20-35" aria-hidden="true" tabindex="-1"></a>        b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">uncurry</span> <span class="op">.</span> <span class="fu">foldr</span> f <span class="op">.</span> <span class="fu">const</span>) b qs []</span>
<span id="cb20-36"><a href="#cb20-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-37"><a href="#cb20-37" aria-hidden="true" tabindex="-1"></a>    nodes (<span class="dt">Leaf</span> n x) <span class="ot">=</span> <span class="dt">Leaf</span> <span class="dv">1</span> (node n x)</span>
<span id="cb20-38"><a href="#cb20-38" aria-hidden="true" tabindex="-1"></a>    nodes (<span class="dt">Node</span> xs) <span class="ot">=</span> <span class="dt">Node</span> (<span class="fu">map</span> nodes xs)</span>
<span id="cb20-39"><a href="#cb20-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-40"><a href="#cb20-40" aria-hidden="true" tabindex="-1"></a>    node n ts <span class="ot">=</span> <span class="dt">Rose.Node</span> (walk (<span class="dv">2</span> <span class="op">^</span> n <span class="op">-</span> <span class="dv">2</span>) (forest ts) (<span class="fu">const</span> [])) ts</span>
<span id="cb20-41"><a href="#cb20-41" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb20-42"><a href="#cb20-42" aria-hidden="true" tabindex="-1"></a>        walk <span class="dv">0</span> xss k <span class="ot">=</span> k xss</span>
<span id="cb20-43"><a href="#cb20-43" aria-hidden="true" tabindex="-1"></a>        walk n (xs<span class="op">:</span>xss) k <span class="ot">=</span></span>
<span id="cb20-44"><a href="#cb20-44" aria-hidden="true" tabindex="-1"></a>            walk (n<span class="op">-</span><span class="dv">2</span>) xss (\(ys<span class="op">:</span>yss) <span class="ot">-&gt;</span> [ z</span>
<span id="cb20-45"><a href="#cb20-45" aria-hidden="true" tabindex="-1"></a>                                         <span class="op">|</span> x <span class="ot">&lt;-</span> xs</span>
<span id="cb20-46"><a href="#cb20-46" aria-hidden="true" tabindex="-1"></a>                                         , y <span class="ot">&lt;-</span> ys</span>
<span id="cb20-47"><a href="#cb20-47" aria-hidden="true" tabindex="-1"></a>                                         , z <span class="ot">&lt;-</span> cmb x y</span>
<span id="cb20-48"><a href="#cb20-48" aria-hidden="true" tabindex="-1"></a>                                         ] <span class="op">++</span> k yss)</span></code></pre></div>
</details>
<h2 id="using-it-for-countdown">Using it for Countdown</h2>
<p>The first thing to do for the Countdown solution is to figure out a
representation for expressions. The one from simple-reflect is perfect
for displaying the result, but we should memoize its calculation.</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Memoed</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Memoed</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> expr   ::</span> <span class="dt">Expr</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> result ::</span> <span class="dt">Int</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>  }</span></code></pre></div>
<p>Then, some helpers for building:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Op</span> <span class="ot">=</span> <span class="dt">Add</span> <span class="op">|</span> <span class="dt">Dif</span> <span class="op">|</span> <span class="dt">Mul</span> <span class="op">|</span> <span class="dt">Div</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>binOp f g x y <span class="ot">=</span> <span class="dt">Memoed</span> ((f <span class="ot">`on`</span> expr) x y) ((g <span class="ot">`on`</span> result) x y)</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a><span class="ot">apply ::</span> <span class="dt">Op</span> <span class="ot">-&gt;</span> <span class="dt">Memoed</span> <span class="ot">-&gt;</span> <span class="dt">Memoed</span> <span class="ot">-&gt;</span> <span class="dt">Memoed</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>apply <span class="dt">Add</span> x y <span class="ot">=</span> binOp (<span class="op">+</span>) (<span class="op">+</span>) x y</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>apply <span class="dt">Dif</span> x y</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> result y <span class="op">&lt;</span> result x <span class="ot">=</span> binOp (<span class="op">-</span>) (<span class="op">-</span>) x y</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> binOp (<span class="op">-</span>) (<span class="op">-</span>) y x</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>apply <span class="dt">Mul</span> x y <span class="ot">=</span> binOp (<span class="op">*</span>) (<span class="op">*</span>) x y</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>apply <span class="dt">Div</span> x y <span class="ot">=</span> binOp <span class="fu">div</span> <span class="fu">div</span> x y</span></code></pre></div>
<p>Finally, the full algorithm:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ot">enumerateExprs ::</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [<span class="dt">Memoed</span>]</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>enumerateExprs <span class="ot">=</span> enumerateTrees cmb <span class="op">.</span> <span class="fu">map</span> (\x <span class="ot">-&gt;</span> <span class="dt">Memoed</span> (<span class="fu">fromIntegral</span> x) x)</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>    cmb x y <span class="ot">=</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>        nubs <span class="op">$</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>        x <span class="op">:</span></span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>        y <span class="op">:</span></span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>        [ apply op x y</span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> op <span class="ot">&lt;-</span> [<span class="dt">Add</span>, <span class="dt">Dif</span>, <span class="dt">Mul</span>, <span class="dt">Div</span>]</span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>        , legal op (result x) (result y) ]</span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>    legal <span class="dt">Add</span> _ _ <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a>    legal <span class="dt">Dif</span> x y <span class="ot">=</span> x <span class="op">/=</span> y</span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a>    legal <span class="dt">Mul</span> _ _ <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a>    legal <span class="dt">Div</span> x y <span class="ot">=</span> x <span class="ot">`mod`</span> y <span class="op">==</span> <span class="dv">0</span></span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a>    nubs xs <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="fu">const</span> []) xs IntSet.empty</span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a>        f e a s</span>
<span id="cb23-18"><a href="#cb23-18" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> IntSet.member (result e) s <span class="ot">=</span> a s</span>
<span id="cb23-19"><a href="#cb23-19" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> e <span class="op">:</span> a (IntSet.insert (result e) s)</span>
<span id="cb23-20"><a href="#cb23-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-21"><a href="#cb23-21" aria-hidden="true" tabindex="-1"></a><span class="ot">countdown ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [<span class="dt">Int</span>] <span class="ot">-&gt;</span> [<span class="dt">Expr</span>]</span>
<span id="cb23-22"><a href="#cb23-22" aria-hidden="true" tabindex="-1"></a>countdown targ <span class="ot">=</span> <span class="fu">map</span> expr <span class="op">.</span> <span class="fu">filter</span> ((<span class="op">==</span>) targ <span class="op">.</span> result) <span class="op">.</span> enumerateExprs</span>
<span id="cb23-23"><a href="#cb23-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-24"><a href="#cb23-24" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (<span class="fu">mapM_</span> <span class="fu">print</span> <span class="op">.</span> reduction <span class="op">.</span> <span class="fu">head</span>) (countdown <span class="dv">586</span> [<span class="dv">100</span>,<span class="dv">25</span>,<span class="dv">1</span>,<span class="dv">5</span>,<span class="dv">3</span>,<span class="dv">10</span>])</span>
<span id="cb23-25"><a href="#cb23-25" aria-hidden="true" tabindex="-1"></a><span class="dv">25</span> <span class="op">*</span> <span class="dv">3</span> <span class="op">+</span> <span class="dv">1</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb23-26"><a href="#cb23-26" aria-hidden="true" tabindex="-1"></a><span class="dv">75</span> <span class="op">+</span> <span class="dv">1</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb23-27"><a href="#cb23-27" aria-hidden="true" tabindex="-1"></a><span class="dv">76</span> <span class="op">+</span> (<span class="dv">100</span> <span class="op">*</span> <span class="dv">5</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb23-28"><a href="#cb23-28" aria-hidden="true" tabindex="-1"></a><span class="dv">76</span> <span class="op">+</span> (<span class="dv">500</span> <span class="op">+</span> <span class="dv">10</span>)</span>
<span id="cb23-29"><a href="#cb23-29" aria-hidden="true" tabindex="-1"></a><span class="dv">76</span> <span class="op">+</span> <span class="dv">510</span></span>
<span id="cb23-30"><a href="#cb23-30" aria-hidden="true" tabindex="-1"></a><span class="dv">586</span></span></code></pre></div>
<p>There are some optimizations going on here, taken mainly from <span
class="citation" data-cites="bird_countdown:_2005">Bird and Mu (<a
href="#ref-bird_countdown:_2005"
role="doc-biblioref">2005</a>)</span>:</p>
<ol type="1">
<li>We filter out illegal operations, as described originally.</li>
<li>We filter out any expressions that have the same value.</li>
</ol>
<h2 id="testing-the-implementation">Testing the Implementation</h2>
<p>So we’ve followed the paper, written the code: time to test. The
specification of the function is relatively simple: calculate all
applications of the commutative operator to some input, <em>without</em>
recalculating subtrees.</p>
<p>We’ll need a free structure for the “commutative operator”:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Leaf</span> a</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Tree</span> a <span class="op">:^:</span> <span class="dt">Tree</span> a</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Foldable</span>,<span class="dt">Eq</span>,<span class="dt">Ord</span>,<span class="dt">Show</span>)</span></code></pre></div>
<p>Here’s the problem: it’s not commutative! We can remedy it by only
exporting a constructor that creates the tree in a commutative way, and
we can make it a pattern synonym so it looks normal:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveFoldable  #-}</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE PatternSynonyms #-}</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Commutative</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">Tree</span>(<span class="dt">Leaf</span>)</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>  ,<span class="kw">pattern</span> (<span class="op">:*:</span>))</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Leaf</span> a</span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Tree</span> a <span class="op">:^:</span> <span class="dt">Tree</span> a</span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Eq</span>,<span class="dt">Ord</span>,<span class="dt">Show</span>,<span class="dt">Foldable</span>)</span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span><span class="ot"> (:*:) ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Tree</span> a</span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> xs <span class="op">:*:</span> ys <span class="ot">&lt;-</span> xs <span class="op">:^:</span> ys <span class="kw">where</span></span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">:*:</span> ys</span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> xs <span class="op">&lt;=</span> ys <span class="ot">=</span> xs <span class="op">:^:</span> ys</span>
<span id="cb25-18"><a href="#cb25-18" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> ys <span class="op">:^:</span> xs</span>
<span id="cb25-19"><a href="#cb25-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-20"><a href="#cb25-20" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# COMPLETE Leaf, (:*:) #-}</span></span></code></pre></div>
<p>Now we need to check if all applications are actually tested. First,
to generate all trees:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="ot">allTrees ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Set</span> (<span class="dt">Tree</span> a)</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>allTrees [x] <span class="ot">=</span> Set.singleton (<span class="dt">Leaf</span> x)</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>allTrees xs <span class="ot">=</span> Set.unions (<span class="fu">map</span> (<span class="fu">uncurry</span> f) (unmerges xs))</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>    f ls rs <span class="ot">=</span> Set.fromList ((liftA2 (<span class="op">:*:</span>) <span class="ot">`on`</span> (Set.toList <span class="op">.</span> allTrees)) ls rs)</span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a><span class="ot">allSubTrees ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Set</span> (<span class="dt">Tree</span> a)</span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>allSubTrees [x] <span class="ot">=</span> Set.singleton (<span class="dt">Leaf</span> x)</span>
<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a>allSubTrees xs <span class="ot">=</span></span>
<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a>    Set.unions (<span class="fu">map</span> (<span class="fu">uncurry</span> f <span class="op">.</span> (allSubTrees <span class="op">***</span> allSubTrees)) (unmerges xs))</span>
<span id="cb26-11"><a href="#cb26-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb26-12"><a href="#cb26-12" aria-hidden="true" tabindex="-1"></a>    f ls rs <span class="ot">=</span></span>
<span id="cb26-13"><a href="#cb26-13" aria-hidden="true" tabindex="-1"></a>        Set.unions</span>
<span id="cb26-14"><a href="#cb26-14" aria-hidden="true" tabindex="-1"></a>            [ls, rs, Set.fromList ((liftA2 (<span class="op">:*:</span>) <span class="ot">`on`</span> Set.toList) ls rs)]</span></code></pre></div>
<p>Then, to test:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_exhaustiveSearch ::</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>prop_exhaustiveSearch n <span class="ot">=</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>         <span class="kw">let</span> src <span class="ot">=</span> [<span class="dv">0</span> <span class="op">..</span> <span class="fu">fromIntegral</span> n]</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>             expect <span class="ot">=</span> allSubTrees src</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>             actual <span class="ot">=</span></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a>                 Set.fromList</span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>                     (enumerateTrees</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>                          (\xs ys <span class="ot">-&gt;</span></span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a>                                [xs, ys, xs <span class="op">:*:</span> ys])</span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a>                          (<span class="fu">map</span> <span class="dt">Leaf</span> src))</span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a>         <span class="kw">in</span> expect <span class="op">==</span> actual</span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-13"><a href="#cb27-13" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_exhaustiveSearchFull ::</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb27-14"><a href="#cb27-14" aria-hidden="true" tabindex="-1"></a>prop_exhaustiveSearchFull n <span class="ot">=</span></span>
<span id="cb27-15"><a href="#cb27-15" aria-hidden="true" tabindex="-1"></a>         <span class="kw">let</span> src <span class="ot">=</span> [<span class="dv">0</span> <span class="op">..</span> <span class="fu">fromIntegral</span> n]</span>
<span id="cb27-16"><a href="#cb27-16" aria-hidden="true" tabindex="-1"></a>             expect <span class="ot">=</span> Map.fromSet (<span class="fu">const</span> <span class="dv">1</span>) (allTrees src)</span>
<span id="cb27-17"><a href="#cb27-17" aria-hidden="true" tabindex="-1"></a>             actual <span class="ot">=</span></span>
<span id="cb27-18"><a href="#cb27-18" aria-hidden="true" tabindex="-1"></a>                 freqs</span>
<span id="cb27-19"><a href="#cb27-19" aria-hidden="true" tabindex="-1"></a>                     (enumerateTrees</span>
<span id="cb27-20"><a href="#cb27-20" aria-hidden="true" tabindex="-1"></a>                          (\xs ys <span class="ot">-&gt;</span> [xs <span class="op">:*:</span> ys])</span>
<span id="cb27-21"><a href="#cb27-21" aria-hidden="true" tabindex="-1"></a>                          (<span class="fu">map</span> <span class="dt">Leaf</span> src))</span>
<span id="cb27-22"><a href="#cb27-22" aria-hidden="true" tabindex="-1"></a>         <span class="kw">in</span> expect <span class="op">==</span> actual</span></code></pre></div>
<p>Testing for repeated calls is more tricky. Remember, the memoization
is supposed to be unobservable: in order to see it, we’re going to have
to use some unsafe operations.</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>traceSubsequences</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> ((<span class="dt">Tree</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Tree</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [<span class="dt">Tree</span> <span class="dt">Int</span>]) <span class="ot">-&gt;</span> [<span class="dt">Tree</span> <span class="dt">Int</span>] <span class="ot">-&gt;</span> [<span class="dt">Tree</span> <span class="dt">Int</span>])</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> [<span class="dt">Int</span>]</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> (<span class="dt">Map</span> (<span class="dt">Tree</span> <span class="dt">Int</span>) <span class="dt">Int</span>, [<span class="dt">Tree</span> <span class="dt">Int</span>])</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>traceSubsequences enm ints <span class="ot">=</span></span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>    runST <span class="op">$</span></span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">do</span> ref <span class="ot">&lt;-</span> newSTRef Map.empty</span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a>       <span class="kw">let</span> res <span class="ot">=</span> enm (combine ref) (<span class="fu">map</span> (conv ref) ints)</span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>       traverse_ (<span class="fu">foldr</span> <span class="fu">seq</span> (<span class="fu">pure</span> ())) res</span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a>       intm <span class="ot">&lt;-</span> readSTRef ref</span>
<span id="cb28-11"><a href="#cb28-11" aria-hidden="true" tabindex="-1"></a>       <span class="fu">pure</span> (intm, res)</span>
<span id="cb28-12"><a href="#cb28-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb28-13"><a href="#cb28-13" aria-hidden="true" tabindex="-1"></a>    combine ref xs ys <span class="ot">=</span> unsafeRunST ([xs <span class="op">:*:</span> ys] <span class="op">&lt;$</span> modifySTRef&#39; ref (incr (xs <span class="op">:*:</span> ys)))</span>
<span id="cb28-14"><a href="#cb28-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# NOINLINE combine #-}</span></span>
<span id="cb28-15"><a href="#cb28-15" aria-hidden="true" tabindex="-1"></a>    conv ref x <span class="ot">=</span> unsafeRunST (<span class="dt">Leaf</span> x <span class="op">&lt;$</span> modifySTRef&#39; ref (incr (<span class="dt">Leaf</span> x)))</span>
<span id="cb28-16"><a href="#cb28-16" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# NOINLINE conv #-}</span></span>
<span id="cb28-17"><a href="#cb28-17" aria-hidden="true" tabindex="-1"></a>    unsafeRunST cmp <span class="ot">=</span> unsafePerformIO (unsafeSTToIO cmp)</span>
<span id="cb28-18"><a href="#cb28-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-19"><a href="#cb28-19" aria-hidden="true" tabindex="-1"></a><span class="ot">prop_noRepeatedCalls ::</span> <span class="dt">Property</span></span>
<span id="cb28-20"><a href="#cb28-20" aria-hidden="true" tabindex="-1"></a>prop_noRepeatedCalls <span class="ot">=</span></span>
<span id="cb28-21"><a href="#cb28-21" aria-hidden="true" tabindex="-1"></a>    property <span class="op">$</span> sized <span class="op">$</span></span>
<span id="cb28-22"><a href="#cb28-22" aria-hidden="true" tabindex="-1"></a>    \n <span class="ot">-&gt;</span></span>
<span id="cb28-23"><a href="#cb28-23" aria-hidden="true" tabindex="-1"></a>         <span class="fu">pure</span> <span class="op">$</span></span>
<span id="cb28-24"><a href="#cb28-24" aria-hidden="true" tabindex="-1"></a>         <span class="kw">let</span> src <span class="ot">=</span> [<span class="dv">0</span> <span class="op">..</span> n]</span>
<span id="cb28-25"><a href="#cb28-25" aria-hidden="true" tabindex="-1"></a>             (tint,tres) <span class="ot">=</span> <span class="fu">fmap</span> freqs (traceSubsequences enumerateTrees src)</span>
<span id="cb28-26"><a href="#cb28-26" aria-hidden="true" tabindex="-1"></a>             (fint,fres) <span class="ot">=</span> <span class="fu">fmap</span> freqs (traceSubsequences dummyEnumerate src)</span>
<span id="cb28-27"><a href="#cb28-27" aria-hidden="true" tabindex="-1"></a>         <span class="kw">in</span> counterexample</span>
<span id="cb28-28"><a href="#cb28-28" aria-hidden="true" tabindex="-1"></a>                (mapCompare (freqs (allSubTrees src)) tint)</span>
<span id="cb28-29"><a href="#cb28-29" aria-hidden="true" tabindex="-1"></a>                (<span class="fu">all</span> (<span class="dv">1</span> <span class="op">==</span>) tint) <span class="op">.&amp;&amp;.</span></span>
<span id="cb28-30"><a href="#cb28-30" aria-hidden="true" tabindex="-1"></a>            counterexample (mapCompare tres fres) (tres <span class="op">==</span> fres) <span class="op">.&amp;&amp;.</span></span>
<span id="cb28-31"><a href="#cb28-31" aria-hidden="true" tabindex="-1"></a>            (n <span class="op">&gt;</span> <span class="dv">2</span> <span class="op">==&gt;</span> tint <span class="op">/=</span> fint)</span></code></pre></div>
<p>Here, <code class="sourceCode haskell">dummyEnumerate</code> is some
method which performs the same task, but <em>doesn’t</em> construct a
nexus, so we can ensure that our tests really do catch faulty
implementations.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-bird_functional_2003" class="csl-entry" role="listitem">
Bird, Richard, and Ralf Hinze. 2003. <span>“Functional
<span>Pearl</span> <span>Trouble</span> <span>Shared</span> is
<span>Trouble</span> <span>Halved</span>.”</span> In <em>Proceedings of
the 2003 <span>ACM</span> <span>SIGPLAN</span> <span>Workshop</span> on
<span>Haskell</span></em>, 1–6. Haskell ’03. New York, NY, USA: ACM.
doi:<a
href="https://doi.org/10.1145/871895.871896">10.1145/871895.871896</a>.
<a
href="http://doi.acm.org/10.1145/871895.871896">http://doi.acm.org/10.1145/871895.871896</a>.
</div>
<div id="ref-bird_countdown:_2005" class="csl-entry" role="listitem">
Bird, Richard, and Shin-Cheng Mu. 2005. <span>“Countdown: <span>A</span>
case study in origami programming.”</span> <em>Journal of Functional
Programming</em> 15 (05) (August): 679. doi:<a
href="https://doi.org/10.1017/S0956796805005642">10.1017/S0956796805005642</a>.
<a
href="http://www.journals.cambridge.org/abstract_S0956796805005642">http://www.journals.cambridge.org/abstract_S0956796805005642</a>.
</div>
<div id="ref-danvy_there_2005" class="csl-entry" role="listitem">
Danvy, Olivier, and Mayer Goldberg. 2005. <span>“There and
<span>Back</span> <span>Again</span>.”</span> <em>BRICS Report
Series</em> 12 (3). doi:<a
href="https://doi.org/10.7146/brics.v12i3.21869">10.7146/brics.v12i3.21869</a>.
<a
href="https://tidsskrift.dk/brics/article/view/21869">https://tidsskrift.dk/brics/article/view/21869</a>.
</div>
<div id="ref-hutton_countdown_2002" class="csl-entry" role="listitem">
Hutton, Graham. 2002. <span>“The <span>Countdown</span>
<span>Problem</span>.”</span> <em>J. Funct. Program.</em> 12 (6)
(November): 609–616. doi:<a
href="https://doi.org/10.1017/S0956796801004300">10.1017/S0956796801004300</a>.
<a
href="http://www.cs.nott.ac.uk/~pszgmh/countdown.pdf">http://www.cs.nott.ac.uk/~pszgmh/countdown.pdf</a>.
</div>
<div id="ref-steffen_table_2006" class="csl-entry" role="listitem">
Steffen, Peter, and Robert Giegerich. 2006. <span>“Table
<span>Design</span> in <span>Dynamic</span>
<span>Programming</span>.”</span> <em>Information and Computation</em>
204 (9) (September): 1325–1345. doi:<a
href="https://doi.org/10.1016/j.ic.2006.02.006">10.1016/j.ic.2006.02.006</a>.
<a
href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.85.601&amp;rep=rep1&amp;type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.85.601&amp;rep=rep1&amp;type=pdf</a>.
</div>
<div id="ref-tobin_time_2016" class="csl-entry" role="listitem">
Tobin, Jared. 2016. <span>“Time <span>Traveling</span>
<span>Recursion</span> <span>Schemes</span>.”</span> <em>jtobin.io</em>.
<a
href="https://jtobin.io/time-traveling-recursion">https://jtobin.io/time-traveling-recursion</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>If you think that structure looks more like a funny
linked list than a tree, that’s because it is. Instead of talking about
“left” and “right” branches, we could talk about the first and second
elements in a list: in fact, this is exactly what’s happening in the
famous <code
class="sourceCode haskell"><span class="fu">zipWith</span></code>
Fibonacci implementation (in reverse).</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>fibs <span class="ot">=</span> <span class="dv">0</span> <span class="op">:</span> <span class="dv">1</span> <span class="op">:</span> <span class="fu">zipWith</span> (<span class="op">+</span>) fibs (<span class="fu">tail</span> fibs)</span></code></pre></div>
<p>Or, in my favourite version:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>fib n <span class="ot">=</span> fix ((<span class="op">:</span>) <span class="dv">0</span> <span class="op">.</span> <span class="fu">scanl</span> (<span class="op">+</span>) <span class="dv">1</span>) <span class="op">!!</span> n</span></code></pre></div>
<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></li>
</ol>
</section>
]]></description>
    <pubDate>Tue, 20 Mar 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-03-20-countdown.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Convolutions</title>
    <link>https://doisinkidney.com/posts/2018-03-19-convolutions-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 19, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Convolutions of a list give a different traversal order than what you
would traditionally expect. Adapted from <a
href="https://byorgey.wordpress.com/2008/04/22/list-convolutions/">here</a>.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- | &gt;&gt;&gt; mapM_ print ([1..5] &lt;.&gt; [1..5])</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(1,1)]</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(1,2),(2,1)]</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(1,3),(2,2),(3,1)]</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(1,4),(2,3),(3,2),(4,1)]</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(1,5),(2,4),(3,3),(4,2),(5,1)]</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(2,5),(3,4),(4,3),(5,2)]</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(3,5),(4,4),(5,3)]</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(4,5),(5,4)]</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(5,5)]</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;.&gt;) ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [[(a,b)]]</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>xs <span class="op">&lt;.&gt;</span> ys <span class="ot">=</span> <span class="fu">foldr</span> f [] xs <span class="kw">where</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  f x <span class="ot">=</span> <span class="fu">foldr</span> g <span class="fu">id</span> ys <span class="op">.</span> ([] <span class="op">:</span>) <span class="kw">where</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    g y k <span class="op">~</span>(z <span class="op">:~</span> zs) <span class="ot">=</span> ((x,y) <span class="op">:</span> z) <span class="op">:</span> k zs</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="ot">unconsMon ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> [m] <span class="ot">-&gt;</span> (m, [m])</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>unconsMon (x<span class="op">:</span>xs) <span class="ot">=</span> (x, xs)</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>unconsMon []     <span class="ot">=</span> (<span class="fu">mempty</span>, [])</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span><span class="ot"> (:~) ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> m <span class="ot">-&gt;</span> [m] <span class="ot">-&gt;</span> [m]</span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> (<span class="op">:~</span>) x xs <span class="ot">&lt;-</span> (unconsMon <span class="ot">-&gt;</span> (x, xs))</span></code></pre></div>
]]></description>
    <pubDate>Mon, 19 Mar 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-03-19-convolutions-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Rose Trees, Breadth-First</title>
    <link>https://doisinkidney.com/posts/2018-03-17-rose-trees-breadth-first.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 17, 2018
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Breadth-First%20Traversals.html">10-part series on Breadth-First Traversals</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>In contrast to the more common binary trees, in a rose tree every
node can have any number of children.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Node</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> root   ::</span> a</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> forest ::</span> <span class="dt">Forest</span> a</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Forest</span> a <span class="ot">=</span> [<span class="dt">Tree</span> a]</span></code></pre></div>
<p>One of the important manipulations of this data structure, which
forms the basis for several other algorithms, is a breadth-first
traversal. I’d like to go through a couple of techniques for
implementing it, and how more generally you can often get away with
using much simpler data structures if you really pinpoint the API you
need from them.</p>
<p>As a general technique, <span class="citation"
data-cites="okasaki_breadth-first_2000">Okasaki (<a
href="#ref-okasaki_breadth-first_2000"
role="doc-biblioref">2000</a>)</span> advises that a queue be used:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirst ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>breadthFirst tr <span class="ot">=</span> go (singleton tr)</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    go q <span class="ot">=</span> <span class="kw">case</span> pop q <span class="kw">of</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Nothing</span> <span class="ot">-&gt;</span> []</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Just</span> (<span class="dt">Node</span> x xs,qs) <span class="ot">-&gt;</span> x <span class="op">:</span> go (qs <span class="ot">`append`</span> xs)</span></code></pre></div>
<p>There are three functions left undefined there: <code
class="sourceCode haskell">singleton</code>, <code
class="sourceCode haskell">pop</code>, and <code
class="sourceCode haskell">append</code>. They represent the API of our
as-of-yet unimplemented queue, and their complexity will dictate the
complexity of the overall algorithm. As a (bad) first choice, we could
use simple lists, with the functions defined thus:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>singleton x <span class="ot">=</span> [x]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>pop (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Just</span> (x,xs)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>pop [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>append <span class="ot">=</span> (<span class="op">++</span>)</span></code></pre></div>
<p>Those repeated appends are bad news. The queue needs to be able to
support popping from one side and appending from the other, which is
something lists absolutely <em>cannot</em> do well.</p>
<p>We could swap in a more general queue implementation, possibly using
Data.Sequence, or a pair of lists. But these are more complex and
general than we need, so let’s try and pare down the requirements a
little more.</p>
<p>First, we don’t need a pop: the go function can be expressed as a
fold instead. Second, we don’t need <em>every</em> append to be
immediately stuck into the queue, we can batch them, first appending to
a structure that’s efficient for appends, and then converting that to a
structure which is efficient for folds. In code:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">breadthFirst ::</span> <span class="dt">Forest</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>breadthFirst ts <span class="ot">=</span> <span class="fu">foldr</span> f b ts []</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Node</span> x xs) fw bw <span class="ot">=</span> x <span class="op">:</span> fw (xs <span class="op">:</span> bw)</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    b [] <span class="ot">=</span> []</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    b qs <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> f) b qs []</span></code></pre></div>
<p>We’re consing instead of appending, but the consumption is being done
in the correct direction anyway, because of the <code
class="sourceCode haskell"><span class="fu">foldl</span></code>.</p>
<h2 id="levels">Levels</h2>
<p>So next step: to get the <code
class="sourceCode haskell">levels</code> function from Data.Tree.
Instead of doing a breadth-first traversal, it returns the nodes at each
<em>level</em> of the tree. Conceptually, every time we did the reverse
above (called <code
class="sourceCode haskell"><span class="fu">foldl</span></code>), we
will do a cons as well:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">levels ::</span> <span class="dt">Forest</span> a <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>levels ts <span class="ot">=</span> <span class="fu">foldl</span> f b ts [] []</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    f k (<span class="dt">Node</span> x xs) ls qs <span class="ot">=</span> k (x <span class="op">:</span> ls) (xs <span class="op">:</span> qs)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    b _ [] <span class="ot">=</span> []</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    b k qs <span class="ot">=</span> k <span class="op">:</span> <span class="fu">foldl</span> (<span class="fu">foldl</span> f) b qs [] []</span></code></pre></div>
<h2 id="unfolding">Unfolding</h2>
<p>The original reason I started work on these problems was <a
href="https://github.com/haskell/containers/issues/124">this</a> issue
in containers. It concerns the <a
href="https://hackage.haskell.org/package/containers-0.5.11.0/docs/Data-Tree.html#v:unfoldTreeM_BF"><code>unfoldTreeM_BF</code></a>
function. An early go at rewriting it, inspired by levels above, looks
like this:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode numberSource haskell numberLines"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1"></a><span class="ot">unfoldForestM_BF ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> m (a, [b])) <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> m (<span class="dt">Forest</span> a)</span>
<span id="cb6-2"><a href="#cb6-2"></a>unfoldForestM_BF f ts <span class="ot">=</span> b [ts] (<span class="fu">const</span> <span class="fu">id</span>)</span>
<span id="cb6-3"><a href="#cb6-3"></a>  <span class="kw">where</span></span>
<span id="cb6-4"><a href="#cb6-4"></a>    b [] k <span class="ot">=</span> <span class="fu">pure</span> (k [] [])</span>
<span id="cb6-5"><a href="#cb6-5"></a>    b qs k <span class="ot">=</span> <span class="fu">foldl</span> (<span class="fu">foldr</span> t) b qs [] (\x <span class="ot">-&gt;</span> k [] <span class="op">.</span> <span class="fu">foldr</span> (<span class="fu">uncurry</span> run) <span class="fu">id</span> x)</span>
<span id="cb6-6"><a href="#cb6-6"></a></span>
<span id="cb6-7"><a href="#cb6-7"></a>    t a fw bw k <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb6-8"><a href="#cb6-8"></a>        (x,cs) <span class="ot">&lt;-</span> f a</span>
<span id="cb6-9"><a href="#cb6-9"></a>        <span class="kw">let</span> <span class="op">!</span>n <span class="ot">=</span> <span class="fu">length</span> cs</span>
<span id="cb6-10"><a href="#cb6-10"></a>        fw (cs <span class="op">:</span> bw) (k <span class="op">.</span> (<span class="op">:</span>) (x, n))</span>
<span id="cb6-11"><a href="#cb6-11"></a></span>
<span id="cb6-12"><a href="#cb6-12"></a>    run x n xs ys <span class="ot">=</span></span>
<span id="cb6-13"><a href="#cb6-13"></a>      <span class="kw">case</span> <span class="fu">splitAt</span> n ys <span class="kw">of</span></span>
<span id="cb6-14"><a href="#cb6-14"></a>          (cs,zs) <span class="ot">-&gt;</span> <span class="dt">Node</span> x cs <span class="op">:</span> xs zs</span></code></pre></div>
<p>It basically performs the same thing as the levels function, but
builds the tree back up in the end using the <code
class="sourceCode haskell">run</code> function. In order to do that, we
store the length of each subforest on line 9, so that each node knows
how much to take from each level.</p>
<p>A possible optimization is to stop taking the length. Anything in
list processing that takes a length screams “wrong” to me (although it’s
not always true!) so I often try to find a way to avoid it. The first
option would be to keep the <code class="sourceCode haskell">cs</code>
on line 8 around, and use <em>it</em> as an indicator for the length.
That keeps it around longer than strictly necessary, though. The other
option is to add a third level: for <code
class="sourceCode haskell">breadthFirst</code> above, we had one level;
for <code class="sourceCode haskell">levels</code>, we added another, to
indicate the structure of the nodes and their subtrees; here, we can add
a third, to maintain that structure when building back up:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">unfoldForestM_BF ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> m (a, [b])) <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> m (<span class="dt">Forest</span> a)</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>unfoldForestM_BF f ts <span class="ot">=</span> b [ts] (\ls <span class="ot">-&gt;</span> <span class="fu">concat</span> <span class="op">.</span> ls)</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    b [] k <span class="ot">=</span> <span class="fu">pure</span> (k <span class="fu">id</span> [])</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    b qs k <span class="ot">=</span> <span class="fu">foldl</span> g b qs [] (\ls <span class="ot">-&gt;</span> k <span class="fu">id</span> <span class="op">.</span> ls)</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>    g a xs qs k <span class="ot">=</span> <span class="fu">foldr</span> t (\ls ys <span class="ot">-&gt;</span> a ys (k <span class="op">.</span> run ls)) xs [] qs</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>    t a fw xs bw <span class="ot">=</span> f a <span class="op">&gt;&gt;=</span> \(x,cs) <span class="ot">-&gt;</span> fw (x<span class="op">:</span>xs) (cs<span class="op">:</span>bw)</span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>    run x xs <span class="ot">=</span> <span class="fu">uncurry</span> (<span class="op">:</span>) <span class="op">.</span> <span class="fu">foldl</span> go ((,) [] <span class="op">.</span> xs) x</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>        go ys y (z<span class="op">:</span>zs) <span class="ot">=</span> (<span class="dt">Node</span> y z <span class="op">:</span> ys&#39;, zs&#39;)</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>          <span class="kw">where</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>            (ys&#39;,zs&#39;) <span class="ot">=</span> ys zs</span></code></pre></div>
<p>This unfortunately <em>slows down</em> the code.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-okasaki_breadth-first_2000" class="csl-entry"
role="listitem">
Okasaki, Chris. 2000. <span>“Breadth-first <span>Numbering</span>:
<span>Lessons</span> from a <span>Small Exercise</span> in
<span>Algorithm Design</span>.”</span> In <em>Proceedings of the
<span>Fifth ACM SIGPLAN International Conference</span> on
<span>Functional Programming</span></em>, 131–136. <span>ICFP</span>
’00. New York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/351240.351253">10.1145/351240.351253</a>.
<a
href="https://www.cs.tufts.edu/~nr/cs257/archive/chris-okasaki/breadth-first.pdf">https://www.cs.tufts.edu/~nr/cs257/archive/chris-okasaki/breadth-first.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Sat, 17 Mar 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-03-17-rose-trees-breadth-first.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Choose a random item from a list in one pass</title>
    <link>https://doisinkidney.com/posts/2018-03-15-one-pass-choose-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 15, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Adapted from <a
href="https://blog.plover.com/prog/weighted-reservoir-sampling.html">here</a>.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">System.Random</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">choose ::</span> (<span class="dt">Foldable</span> f, <span class="dt">RandomGen</span> g) <span class="ot">=&gt;</span>  f a <span class="ot">-&gt;</span> g <span class="ot">-&gt;</span> (a, g)</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>choose xs g <span class="ot">=</span> h (<span class="fu">foldl</span> f (<span class="dv">0</span><span class="ot"> ::</span> <span class="dt">Integer</span>, <span class="fu">error</span> <span class="st">&quot;choose: empty list&quot;</span>, g) xs)</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    h (_,x,g) <span class="ot">=</span> (x,g)</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    f (c,y,g) x <span class="ot">=</span> <span class="kw">case</span> randomR (<span class="dv">0</span>,c) g <span class="kw">of</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        (<span class="dv">0</span>,g&#39;) <span class="ot">-&gt;</span> (c<span class="op">+</span><span class="dv">1</span>,x,g&#39;)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>        (_,g&#39;) <span class="ot">-&gt;</span> (c<span class="op">+</span><span class="dv">1</span>,y,g&#39;)</span></code></pre></div>
]]></description>
    <pubDate>Thu, 15 Mar 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-03-15-one-pass-choose-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Single-Pass Huffman Coding</title>
    <link>https://doisinkidney.com/posts/2018-02-17-single-pass-huffman.html</link>
    <description><![CDATA[<div class="info">
    Posted on February 17, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Folds&#39;." href="/tags/Folds.html" rel="tag">Folds</a>
    
</div>

<p>While working on something else, I figured out a nice Haskell
implementation of Huffman coding, and I thought I’d share it here. I’ll
go through a few techniques for transforming a multi-pass algorithm into
a single-pass one first, and then I’ll show how to use them for Huffman.
If you just want to skip to the code, it’s provided at the end <a
href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a>.</p>
<p>The algorithm isn’t single-pass in the sense of <a
href="https://www2.cs.duke.edu/csed/curious/compression/adaptivehuff.html">Adaptive
Huffman Coding</a>: it still uses the normal Huffman algorithm, but the
input is transformed in the same traversal that builds the tree to
transform it.</p>
<h2 id="circular-programming">Circular Programming</h2>
<p>There are several techniques for turning multi-pass algorithms into
single-pass ones in functional languages. Perhaps the most famous is
circular programming: using <em>laziness</em> to eliminate a pass. <span
class="citation" data-cites="bird_using_1984">R. S. Bird (<a
href="#ref-bird_using_1984" role="doc-biblioref">1984</a>)</span> used
this to great effect in solving the repmin problem:</p>
<blockquote>
<p>Given a tree of integers, replace every integer with the minimum
integer in the tree, in one pass.</p>
</blockquote>
<p>For an imperative programmer, the problem is relatively easy: first,
write the code to find the minimum value in the tree in the standard
way, using a loop and a “smallest so far” accumulator. Then, inside the
loop, after updating the accumulator, set the value of the leaf to be a
<em>reference</em> to the accumulator.</p>
<p>At first, that solution may seem necessarily impure: we’re using
global, mutable state to update many things at once. However, as the
paper shows, we can claw back purity using laziness:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> <span class="dt">Leaf</span> a <span class="op">|</span> <span class="dt">Tree</span> a <span class="op">:*:</span> <span class="dt">Tree</span> a</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ot">repMin ::</span> <span class="dt">Tree</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Tree</span> <span class="dt">Integer</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>repMin xs <span class="ot">=</span> ys <span class="kw">where</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  (m, ys) <span class="ot">=</span> go xs</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  go (<span class="dt">Leaf</span> x) <span class="ot">=</span> (x, <span class="dt">Leaf</span> m)</span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  go (xs <span class="op">:*:</span> ys) <span class="ot">=</span> (<span class="fu">min</span> x y, xs&#39; <span class="op">:*:</span> ys&#39;)</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>      (x,xs&#39;) <span class="ot">=</span> go xs</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>      (y,ys&#39;) <span class="ot">=</span> go ys</span></code></pre></div>
<h2 id="there-and-back-again">There and Back Again</h2>
<p>Let’s say we don’t have laziness at our disposal: are we hosed? No <a
href="#fn2" class="footnote-ref" id="fnref2"
role="doc-noteref"><sup>2</sup></a>! <span class="citation"
data-cites="danvy_there_2005">Danvy and Goldberg (<a
href="#ref-danvy_there_2005" role="doc-biblioref">2005</a>)</span>
explore this very issue, by posing the question:</p>
<blockquote>
<p>Given two lists, xs and ys, can you zip xs with the reverse of ys in
one pass?</p>
</blockquote>
<p>The technique used to solve the problem is named “There and Back
Again”; it should be clear why from one of the solutions:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>convolve xs ys <span class="ot">=</span> walk xs <span class="fu">const</span> <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  walk [] k <span class="ot">=</span> k [] ys</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  walk (x<span class="op">:</span>xs) k <span class="ot">=</span> walk xs (\r (y<span class="op">:</span>ys) <span class="ot">-&gt;</span> k ((x,y) <span class="op">:</span> r) ys)</span></code></pre></div>
<p>The traversal of one list builds up the function to consume the
other. We could write repmin in the same way:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>repMin <span class="ot">=</span> <span class="fu">uncurry</span> (<span class="op">$</span>) <span class="op">.</span> go <span class="kw">where</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  go (<span class="dt">Leaf</span> x) <span class="ot">=</span> (<span class="dt">Leaf</span>, x)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  go (xs <span class="op">:*:</span> ys) <span class="ot">=</span> (\m <span class="ot">-&gt;</span> xs&#39; m <span class="op">:*:</span> ys&#39; m, <span class="fu">min</span> xm ym) <span class="kw">where</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    (xs&#39;,xm) <span class="ot">=</span> go xs</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    (ys&#39;,ym) <span class="ot">=</span> go ys</span></code></pre></div>
<h2 id="cayley-representations">Cayley Representations</h2>
<p>If you’re doing a lot of appending to some list-like structure, you
probably don’t want to use actual lists: you’ll end up traversing the
left-hand-side of the append many more times than necessary. A type you
can drop in to use instead is difference lists <span class="citation"
data-cites="hughes_novel_1986">(<a href="#ref-hughes_novel_1986"
role="doc-biblioref">Hughes 1986</a>)</span>:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">DList</span> a <span class="ot">=</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ot">rep ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">DList</span> a</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>rep <span class="ot">=</span> (<span class="op">++</span>)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="fu">abs</span><span class="ot"> ::</span> <span class="dt">DList</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="fu">abs</span> xs <span class="ot">=</span> xs []</span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="ot">append ::</span> <span class="dt">DList</span> a <span class="ot">-&gt;</span> <span class="dt">DList</span> a <span class="ot">-&gt;</span> <span class="dt">DList</span> a</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>append <span class="ot">=</span> (<span class="op">.</span>)</span></code></pre></div>
<p><code class="sourceCode haskell">append</code> is
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
in this representation. In fact, for any monoid with a slow <code
class="sourceCode haskell"><span class="fu">mappend</span></code>, you
can use the same trick: it’s called the Cayley representation, and
available as <code
class="sourceCode haskell"><span class="dt">Endo</span></code> in <a
href="https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-Monoid.html#t:Endo">Data.Monoid</a>.</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">rep ::</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Endo</span> a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>rep x <span class="ot">=</span> <span class="dt">Endo</span> (<span class="fu">mappend</span> x)</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="fu">abs</span><span class="ot"> ::</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span> <span class="dt">Endo</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="fu">abs</span> (<span class="dt">Endo</span> f) <span class="ot">=</span> f <span class="fu">mempty</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">Endo</span> a) <span class="kw">where</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Endo</span> <span class="fu">id</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> (<span class="dt">Endo</span> f) (<span class="dt">Endo</span> g) <span class="ot">=</span> <span class="dt">Enfo</span> (f <span class="op">.</span> g)</span></code></pre></div>
<p>You can actually do the same transformation for “monoids” in the
categorical sense: applying it to monads, for instance, will give you
codensity <span class="citation" data-cites="rivas_notions_2014">(<a
href="#ref-rivas_notions_2014" role="doc-biblioref">Rivas and Jaskelioff
2014</a>)</span>.</p>
<h2 id="traversable">Traversable</h2>
<p>Looking back—just for a second—to the repmin example, we should be
able to spot a pattern we can generalize. There’s really nothing
tree-specific about it, so why can’t we apply it to lists? Or other
structures, for that matter? It turns out we can: the <code
class="sourceCode haskell">mapAccumL</code> function is tailor-made to
this need:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">repMin ::</span> <span class="dt">Traversable</span> t <span class="ot">=&gt;</span> t <span class="dt">Integer</span> <span class="ot">-&gt;</span> t <span class="dt">Integer</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>repMin xs <span class="ot">=</span> ys <span class="kw">where</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  (<span class="op">~</span>(<span class="dt">Just</span> m), ys) <span class="ot">=</span> mapAccumL f <span class="dt">Nothing</span> xs</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  f <span class="dt">Nothing</span> x <span class="ot">=</span> (<span class="dt">Just</span> x, m)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  f (<span class="dt">Just</span> y) x <span class="ot">=</span> (<span class="dt">Just</span> (<span class="fu">min</span> x y), m)</span></code></pre></div>
<p>The tilde before the <code
class="sourceCode haskell"><span class="dt">Just</span></code> ensures
this won’t fail on empty input.</p>
<h1 id="huffman-coding">Huffman Coding</h1>
<p>Finally, it’s time for the main event. Huffman coding is a
<em>very</em> multi-pass algorithm, usually. The steps look like
this:</p>
<ol type="1">
<li>Build a frequency table for each character in the input.</li>
<li>Build a priority queue from that frequency table.</li>
<li>Iteratively pop elements and combine them (into Huffman trees) from
the queue until there’s only one left.</li>
<li>That Huffman tree can be used to construct the mapping from items
back to their Huffman codes.</li>
<li>Traverse the input again, using the constructed mapping to replace
elements with their codes.</li>
</ol>
<p>We can’t <em>skip</em> any of these steps: we can try to perform them
all at once, though.</p>
<p>Let’s write the multi-pass version first. We’ll need the frequency
table:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">frequencies ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Map</span> a <span class="dt">Int</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>frequencies <span class="ot">=</span> Map.fromListWith (<span class="op">+</span>) <span class="op">.</span> <span class="fu">map</span> (<span class="fu">flip</span> (,) <span class="dv">1</span>)</span></code></pre></div>
<p>And a heap, ordered on the frequencies of its elements (I’m using a
skew heap here):</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heap</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Node</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Int</span> a (<span class="dt">Heap</span> a) (<span class="dt">Heap</span> a)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">Heap</span> a) <span class="kw">where</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> <span class="dt">Nil</span> ys <span class="ot">=</span> ys</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> xs <span class="dt">Nil</span> <span class="ot">=</span> xs</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> h1<span class="op">@</span>(<span class="dt">Node</span> i x lx rx) h2<span class="op">@</span>(<span class="dt">Node</span> j y ly ry)</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> i <span class="op">&lt;=</span> j    <span class="ot">=</span> <span class="dt">Node</span> i x (<span class="fu">mappend</span> h2 rx) lx</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Node</span> j y (<span class="fu">mappend</span> h1 ry) ly</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Nil</span></span></code></pre></div>
<p>Next, we need to build the tree<a href="#fn3" class="footnote-ref"
id="fnref3" role="doc-noteref"><sup>3</sup></a>. We can use the tree
type from above.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">buildTree ::</span> <span class="dt">Map</span> a <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Tree</span> a)</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>buildTree <span class="ot">=</span> prune <span class="op">.</span> toHeap <span class="kw">where</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  toHeap <span class="ot">=</span> Map.foldMapWithKey (\k v <span class="ot">-&gt;</span> <span class="dt">Node</span> v (<span class="dt">Leaf</span> k) <span class="dt">Nil</span> <span class="dt">Nil</span>)</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  prune <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  prune (<span class="dt">Node</span> i x l r) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">mappend</span> l r <span class="kw">of</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> x</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Node</span> j y l&#39; r&#39; <span class="ot">-&gt;</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>      prune (<span class="fu">mappend</span> (<span class="dt">Node</span> (i<span class="op">+</span>j) (x <span class="op">:*:</span> y) <span class="dt">Nil</span> <span class="dt">Nil</span>) (<span class="fu">mappend</span> l&#39; r&#39;))</span></code></pre></div>
<p>Then, a way to convert between the tree and a map:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toMapping ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Map</span> a [<span class="dt">Bool</span>]</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>toMapping (<span class="dt">Leaf</span> x) <span class="ot">=</span> Map.singleton x []</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>toMapping (xs <span class="op">:*:</span> ys) <span class="ot">=</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    Map.union (<span class="fu">fmap</span> (<span class="dt">True</span><span class="op">:</span>) (toMapping xs)) (<span class="fu">fmap</span> (<span class="dt">False</span><span class="op">:</span>) (toMapping ys))</span></code></pre></div>
<p>And finally, putting the whole thing together:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">huffman ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> (<span class="dt">Maybe</span> (<span class="dt">Tree</span> a), [[<span class="dt">Bool</span>]])</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>huffman xs <span class="ot">=</span> (tree, <span class="fu">map</span> (mapb <span class="op">Map.!</span>) xs) <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  freq <span class="ot">=</span> frequencies xs</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  tree <span class="ot">=</span> buildTree freq</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  mapb <span class="ot">=</span> <span class="fu">maybe</span> Map.empty toMapping tree</span></code></pre></div>
<h2 id="removing-the-passes">Removing the passes</h2>
<p>The first thing to fix is the <code
class="sourceCode haskell">toMapping</code> function: at every level, it
calls <code class="sourceCode haskell">union</code>, a complex and
expensive operation. However, <code
class="sourceCode haskell">union</code> and <code
class="sourceCode haskell">empty</code> form a monoid, so we can use the
Cayley representation to reduce the calls to a minimum. Next, we want to
get rid of the <code
class="sourceCode haskell"><span class="fu">fmap</span></code>s: we can
do that by assembling a function to perform the <code
class="sourceCode haskell"><span class="fu">fmap</span></code> as we go,
as in <code class="sourceCode haskell">convolve</code><a href="#fn4"
class="footnote-ref" id="fnref4"
role="doc-noteref"><sup>4</sup></a>.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">toMapping ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Map</span> a [<span class="dt">Bool</span>]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>toMapping tree <span class="ot">=</span> go tree <span class="fu">id</span> Map.empty <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  go (<span class="dt">Leaf</span> x) k <span class="ot">=</span> Map.insert x (k [])</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  go (xs <span class="op">:*:</span> ys) k <span class="ot">=</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    go xs (k <span class="op">.</span> (<span class="op">:</span>) <span class="dt">True</span>) <span class="op">.</span> go ys (k <span class="op">.</span> (<span class="op">:</span>) <span class="dt">False</span>)</span></code></pre></div>
<p>Secondly, we can integrate the <code
class="sourceCode haskell">toMapping</code> function with the <code
class="sourceCode haskell">buildTree</code> function, removing another
pass:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">buildTree ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Map</span> a <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Tree</span> a, <span class="dt">Map</span> a [<span class="dt">Bool</span>])</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>buildTree <span class="ot">=</span> prune <span class="op">.</span> toHeap <span class="kw">where</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  toHeap <span class="ot">=</span> Map.foldMapWithKey (\k v <span class="ot">-&gt;</span> <span class="dt">Node</span> v (<span class="dt">Leaf</span> k, leaf k) <span class="dt">Nil</span> <span class="dt">Nil</span>)</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  prune <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  prune (<span class="dt">Node</span> i x l r) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">mappend</span> l r <span class="kw">of</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="fu">fmap</span> (\k <span class="ot">-&gt;</span> k <span class="fu">id</span> Map.empty) x)</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Node</span> j y l&#39; r&#39; <span class="ot">-&gt;</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>      prune (<span class="fu">mappend</span> (<span class="dt">Node</span> (i<span class="op">+</span>j) (cmb x y) <span class="dt">Nil</span> <span class="dt">Nil</span>) (<span class="fu">mappend</span> l&#39; r&#39;))</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>  leaf x k <span class="ot">=</span> Map.insert x (k [])</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  node xs ys k <span class="ot">=</span> xs (k <span class="op">.</span> (<span class="op">:</span>) <span class="dt">True</span>) <span class="op">.</span> ys (k <span class="op">.</span> (<span class="op">:</span>) <span class="dt">False</span>)</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>  cmb (xt,xm) (yt,ym) <span class="ot">=</span> (xt <span class="op">:*:</span> yt, node xm ym)</span></code></pre></div>
<p>Finally, to remove the second pass over the list, we can copy repmin,
using <code class="sourceCode haskell">mapAccumL</code> to both
construct the mapping and apply it to the structure in one go.</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">huffman ::</span> (<span class="dt">Ord</span> a, <span class="dt">Traversable</span> t) <span class="ot">=&gt;</span> t a <span class="ot">-&gt;</span> (<span class="dt">Maybe</span> (<span class="dt">Tree</span> a), t [<span class="dt">Bool</span>])</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>huffman xs <span class="ot">=</span> (<span class="fu">fmap</span> <span class="fu">fst</span> tree, ys) <span class="kw">where</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  (freq,ys) <span class="ot">=</span> mapAccumL f Map.empty xs</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  f fm x <span class="ot">=</span> (Map.insertWith (<span class="op">+</span>) x <span class="dv">1</span> fm, mapb <span class="op">Map.!</span> x)</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>  tree <span class="ot">=</span> buildTree freq</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>  mapb <span class="ot">=</span> <span class="fu">maybe</span> Map.empty <span class="fu">snd</span> tree</span></code></pre></div>
<p>And that’s it!</p>
<h1 id="generalization">Generalization</h1>
<p>The similarity between the repmin function and the solution above is
suggestive: is there a way to <em>encode</em> this idea of making a
multi-pass algorithm single-pass? Of course! We can use an
applicative:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Circular</span> a b c <span class="ot">=</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Circular</span> <span class="op">!</span>a</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>             (b <span class="ot">-&gt;</span> c)</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">Circular</span> a b) <span class="kw">where</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (<span class="dt">Circular</span> tally run) <span class="ot">=</span> <span class="dt">Circular</span> tally (f <span class="op">.</span> run)</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Applicative</span> (<span class="dt">Circular</span> a b) <span class="kw">where</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Circular</span> <span class="fu">mempty</span> (<span class="fu">const</span> x)</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Circular</span> fl fr <span class="op">&lt;*&gt;</span> <span class="dt">Circular</span> xl xr <span class="ot">=</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Circular</span></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a>            (<span class="fu">mappend</span> fl xl)</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a>            (\r <span class="ot">-&gt;</span> fr r (xr r))</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>liftHuffman</span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> a</span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Circular</span> (<span class="dt">Map</span> a <span class="dt">Int</span>) (<span class="dt">Map</span> a [<span class="dt">Bool</span>]) [<span class="dt">Bool</span>]</span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a>liftHuffman x <span class="ot">=</span> <span class="dt">Circular</span> (Map.singleton x <span class="dv">1</span>) (<span class="op">Map.!</span> x)</span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a>runHuffman</span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> a</span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Circular</span> (<span class="dt">Map</span> a <span class="dt">Int</span>) (<span class="dt">Map</span> a [<span class="dt">Bool</span>]) r <span class="ot">-&gt;</span> (<span class="dt">Maybe</span> (<span class="dt">Tree</span> a), r)</span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a>runHuffman (<span class="dt">Circular</span> smry run) <span class="ot">=</span></span>
<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a>    <span class="fu">maybe</span> (<span class="dt">Nothing</span>, run Map.empty) (<span class="dt">Just</span> <span class="op">***</span> run) (buildTree smry)</span>
<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-27"><a href="#cb16-27" aria-hidden="true" tabindex="-1"></a>huffman</span>
<span id="cb16-28"><a href="#cb16-28" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Ord</span> a, <span class="dt">Traversable</span> t)</span>
<span id="cb16-29"><a href="#cb16-29" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> t a <span class="ot">-&gt;</span> (<span class="dt">Maybe</span> (<span class="dt">Tree</span> a), t [<span class="dt">Bool</span>])</span>
<span id="cb16-30"><a href="#cb16-30" aria-hidden="true" tabindex="-1"></a>huffman <span class="ot">=</span> runHuffman <span class="op">.</span> <span class="fu">traverse</span> liftHuffman</span></code></pre></div>
<p>Thanks to it being an applicative, you can do all the fun lensy
things with it:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">showBin ::</span> [<span class="dt">Bool</span>] <span class="ot">-&gt;</span> <span class="dt">String</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>showBin <span class="ot">=</span> <span class="fu">map</span> (bool <span class="ch">&#39;0&#39;</span> <span class="ch">&#39;1&#39;</span>)</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="kw">let</span> liftBin <span class="ot">=</span> <span class="fu">fmap</span> showBin <span class="op">.</span> liftHuffman</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (<span class="fu">snd</span> <span class="op">.</span> runHuffman <span class="op">.</span> (each<span class="op">.</span><span class="fu">traverse</span>) liftBin) (<span class="st">&quot;abb&quot;</span>, <span class="st">&quot;cad&quot;</span>, <span class="st">&quot;c&quot;</span>)</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>([<span class="st">&quot;01&quot;</span>,<span class="st">&quot;11&quot;</span>,<span class="st">&quot;11&quot;</span>],[<span class="st">&quot;00&quot;</span>,<span class="st">&quot;01&quot;</span>,<span class="st">&quot;10&quot;</span>],[<span class="st">&quot;00&quot;</span>])</span></code></pre></div>
<p>Bringing us back to the start, it can also let us solve repmin!</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftRepMin ::</span> a <span class="ot">-&gt;</span> <span class="dt">Circular</span> (<span class="dt">Option</span> (<span class="dt">Min</span> a)) a a</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>liftRepMin x <span class="ot">=</span> <span class="dt">Circular</span> (<span class="fu">pure</span> (<span class="fu">pure</span> x)) <span class="fu">id</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="ot">runRepMin ::</span> <span class="dt">Circular</span> (<span class="dt">Option</span> (<span class="dt">Min</span> a)) a b <span class="ot">-&gt;</span> b</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>runRepMin (<span class="dt">Circular</span> m r) <span class="ot">=</span> r (<span class="kw">case</span> m <span class="kw">of</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Option</span> (<span class="dt">Just</span> (<span class="dt">Min</span> x)) <span class="ot">-&gt;</span> x)</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a><span class="ot">repMin ::</span> (<span class="dt">Ord</span> a, <span class="dt">Traversable</span> t) <span class="ot">=&gt;</span> t a <span class="ot">-&gt;</span> t a</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>repMin <span class="ot">=</span> runRepMin <span class="op">.</span> <span class="fu">traverse</span> liftRepMin</span></code></pre></div>
<h1 id="related">Related</h1>
<p>So the <code
class="sourceCode haskell"><span class="dt">Circular</span></code> type
is actually just the product of reader and writer, and is closely
related to the <a
href="https://github.com/treeowl/sort-traversable">sort</a> type.</p>
<p>It’s also related to the <a
href="https://www.reddit.com/r/haskell/comments/7qwzn4/an_update_about_the_store_monad_and_state_comonad/"><code
class="sourceCode haskell"><span class="dt">Prescient</span></code></a>
type, which I noticed after I’d written the above.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-bird_using_1984" class="csl-entry" role="listitem">
Bird, R. S. 1984. <span>“Using <span>Circular</span>
<span>Programs</span> to <span>Eliminate</span> <span>Multiple</span>
<span>Traversals</span> of <span>Data</span>.”</span> <em>Acta Inf.</em>
21 (3) (October): 239–250. doi:<a
href="https://doi.org/10.1007/BF00264249">10.1007/BF00264249</a>. <a
href="http://dx.doi.org/10.1007/BF00264249">http://dx.doi.org/10.1007/BF00264249</a>.
</div>
<div id="ref-bird_more_1997" class="csl-entry" role="listitem">
Bird, Richard, Geraint Jones, and Oege De Moor. 1997. <span>“More haste‚
less speed: Lazy versus eager evaluation.”</span> <em>Journal of
Functional Programming</em> 7 (5) (September): 541–547. doi:<a
href="https://doi.org/10.1017/S0956796897002827">10.1017/S0956796897002827</a>.
<a
href="https://ora.ox.ac.uk/objects/uuid:761a4646-60a2-4622-a1e0-ddea11507d57/datastreams/ATTACHMENT01">https://ora.ox.ac.uk/objects/uuid:761a4646-60a2-4622-a1e0-ddea11507d57/datastreams/ATTACHMENT01</a>.
</div>
<div id="ref-danvy_there_2005" class="csl-entry" role="listitem">
Danvy, Olivier, and Mayer Goldberg. 2005. <span>“There and
<span>Back</span> <span>Again</span>.”</span> <a
href="http://brics.dk/RS/05/3/BRICS-RS-05-3.pdf">http://brics.dk/RS/05/3/BRICS-RS-05-3.pdf</a>.
</div>
<div id="ref-hughes_novel_1986" class="csl-entry" role="listitem">
Hughes, R. John Muir. 1986. <span>“A <span>Novel</span>
<span>Representation</span> of <span>Lists</span> and <span>Its</span>
<span>Application</span> to the <span>Function</span>
"<span>Reverse</span>".”</span> <em>Information Processing Letters</em>
22 (3) (March): 141–144. doi:<a
href="https://doi.org/10.1016/0020-0190(86)90059-1">10.1016/0020-0190(86)90059-1</a>.
<a
href="http://www.sciencedirect.com/science/article/pii/0020019086900591">http://www.sciencedirect.com/science/article/pii/0020019086900591</a>.
</div>
<div id="ref-pippenger_pure_1997" class="csl-entry" role="listitem">
Pippenger, Nicholas. 1997. <span>“Pure <span>Versus</span>
<span>Impure</span> <span>Lisp</span>.”</span> <em>ACM Trans. Program.
Lang. Syst.</em> 19 (2) (March): 223–238. doi:<a
href="https://doi.org/10.1145/244795.244798">10.1145/244795.244798</a>.
<a
href="http://doi.acm.org/10.1145/244795.244798">http://doi.acm.org/10.1145/244795.244798</a>.
</div>
<div id="ref-rivas_notions_2014" class="csl-entry" role="listitem">
Rivas, Exequiel, and Mauro Jaskelioff. 2014. <span>“Notions of
<span>Computation</span> as <span>Monoids</span>.”</span>
<em>arXiv:1406.4823 [cs, math]</em> (May). <a
href="http://arxiv.org/abs/1406.4823">http://arxiv.org/abs/1406.4823</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Huffman coding single-pass implementation:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Map.Strict</span>  (<span class="dt">Map</span>)</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map.Strict</span>  <span class="kw">as</span> <span class="dt">Map</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Traversable</span> (mapAccumL)</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heap</span> a</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Node</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Int</span> a (<span class="dt">Heap</span> a) (<span class="dt">Heap</span> a)</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">Heap</span> a) <span class="kw">where</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> <span class="dt">Nil</span> ys <span class="ot">=</span> ys</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> xs <span class="dt">Nil</span> <span class="ot">=</span> xs</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> h1<span class="op">@</span>(<span class="dt">Node</span> i x lx rx) h2<span class="op">@</span>(<span class="dt">Node</span> j y ly ry)</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> i <span class="op">&lt;=</span> j    <span class="ot">=</span> <span class="dt">Node</span> i x (<span class="fu">mappend</span> h2 rx) lx</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Node</span> j y (<span class="fu">mappend</span> h1 ry) ly</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a <span class="ot">=</span> <span class="dt">Leaf</span> a <span class="op">|</span> <span class="dt">Tree</span> a <span class="op">:*:</span> <span class="dt">Tree</span> a</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="ot">buildTree ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Map</span> a <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Tree</span> a, <span class="dt">Map</span> a [<span class="dt">Bool</span>])</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>buildTree <span class="ot">=</span> prune <span class="op">.</span> toHeap <span class="kw">where</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>  toHeap <span class="ot">=</span> Map.foldMapWithKey (\k v <span class="ot">-&gt;</span> <span class="dt">Node</span> v (<span class="dt">Leaf</span> k, leaf k) <span class="dt">Nil</span> <span class="dt">Nil</span>)</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>  prune <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  prune (<span class="dt">Node</span> i x l r) <span class="ot">=</span> <span class="kw">case</span> <span class="fu">mappend</span> l r <span class="kw">of</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span> <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="fu">fmap</span> (\k <span class="ot">-&gt;</span> k <span class="fu">id</span> Map.empty) x)</span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Node</span> j y l&#39; r&#39; <span class="ot">-&gt;</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>      prune (<span class="fu">mappend</span> (<span class="dt">Node</span> (i<span class="op">+</span>j) (cmb x y) <span class="dt">Nil</span> <span class="dt">Nil</span>) (<span class="fu">mappend</span> l&#39; r&#39;))</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>  leaf x k <span class="ot">=</span> Map.insert x (k [])</span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>  node xs ys k <span class="ot">=</span> xs (k <span class="op">.</span> (<span class="op">:</span>) <span class="dt">True</span>) <span class="op">.</span> ys (k <span class="op">.</span> (<span class="op">:</span>) <span class="dt">False</span>)</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>  cmb (xt,xm) (yt,ym) <span class="ot">=</span> (xt <span class="op">:*:</span> yt, node xm ym)</span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a><span class="ot">huffman ::</span> (<span class="dt">Ord</span> a, <span class="dt">Traversable</span> t) <span class="ot">=&gt;</span> t a <span class="ot">-&gt;</span> (<span class="dt">Maybe</span> (<span class="dt">Tree</span> a), t [<span class="dt">Bool</span>])</span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>huffman xs <span class="ot">=</span> (<span class="fu">fmap</span> <span class="fu">fst</span> tree, ys) <span class="kw">where</span></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>  (freq,ys) <span class="ot">=</span> mapAccumL f Map.empty xs</span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>  f fm x <span class="ot">=</span> (Map.insertWith (<span class="op">+</span>) x <span class="dv">1</span> fm, mapb <span class="op">Map.!</span> x)</span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a>  tree <span class="ot">=</span> buildTree freq</span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a>  mapb <span class="ot">=</span> <span class="fu">maybe</span> Map.empty <span class="fu">snd</span> tree</span></code></pre></div>
<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></li>
<li id="fn2"><p>Well, that’s a little bit of a lie. In terms of
asymptotics, <span class="citation"
data-cites="pippenger_pure_1997">Pippenger (<a
href="#ref-pippenger_pure_1997" role="doc-biblioref">1997</a>)</span>
stated a problem that could be solved in linear time in impure Lisp, but
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi mathvariant="normal">Ω</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\Omega(n \log n)</annotation></semantics></math>
in pure Lisp. <span class="citation" data-cites="bird_more_1997">R.
Bird, Jones, and Moor (<a href="#ref-bird_more_1997"
role="doc-biblioref">1997</a>)</span> then produced an algorithm that
could solve the problem in linear time, by using laziness. So, in some
cases, laziness will give you asymptotics you can’t get without it (if
you want to stay pure).<a href="#fnref2" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn3"><p>There’s actually a nicer version of the <code
class="sourceCode haskell">buildTree</code> function which uses <code
class="sourceCode haskell"><span class="dt">StateT</span> (<span class="dt">Heap</span> a) <span class="dt">Maybe</span></code>,
but it’s equivalent to this one under the hood, and I thought might be a
little distracting.<a href="#fnref3" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn4"><p>Something to notice about this function is that it’s
going top-down and bottom-up at the same time. Combining the maps (with
<code class="sourceCode haskell">(<span class="op">.</span>)</code>) is
done bottom-up, but building the codes is top-down. This means the codes
are built in reverse order! That’s why the accumulating parameter (<code
class="sourceCode haskell">k</code>) is a difference list, rather than a
normal list. As it happens, if normal lists were used, the function
would be slightly more efficient through sharing, but the codes would
all be reversed.<a href="#fnref4" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Sat, 17 Feb 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-02-17-single-pass-huffman.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Monadic List Functions</title>
    <link>https://doisinkidney.com/posts/2018-02-11-monadic-list.functions.html</link>
    <description><![CDATA[<div class="info">
    Posted on February 11, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Applicative&#39;." href="/tags/Applicative.html" rel="tag">Applicative</a>
    
</div>

<p>Here’s an old Haskell chestnut:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> filterM (\_ <span class="ot">-&gt;</span> [<span class="dt">False</span>, <span class="dt">True</span>]) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>[[],[<span class="dv">3</span>],[<span class="dv">2</span>],[<span class="dv">2</span>,<span class="dv">3</span>],[<span class="dv">1</span>],[<span class="dv">1</span>,<span class="dv">3</span>],[<span class="dv">1</span>,<span class="dv">2</span>],[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]]</span></code></pre></div>
<p><code
class="sourceCode haskell">filterM (\_ <span class="ot">-&gt;</span> [<span class="dt">False</span>,<span class="dt">True</span>])</code>
gives the power set of some input list. It’s one of the especially
magical demonstrations of monads. From a high-level perspective, it
makes sense: for each element in the list, we want it to be present in
one output, and not present in another. It’s hard to see how it actually
<em>works</em>, though. The (old<a href="#fn1" class="footnote-ref"
id="fnref1" role="doc-noteref"><sup>1</sup></a>) <a
href="https://hackage.haskell.org/package/base-4.7.0.0/docs/src/Control-Monad.html#filterM">source</a>
for <code class="sourceCode haskell">filterM</code> doesn’t help hugely,
either:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">filterM          ::</span> (<span class="dt">Monad</span> m) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m [a]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>filterM _ []     <span class="ot">=</span>  <span class="fu">return</span> []</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>filterM p (x<span class="op">:</span>xs) <span class="ot">=</span>  <span class="kw">do</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>   flg <span class="ot">&lt;-</span> p x</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>   ys  <span class="ot">&lt;-</span> filterM p xs</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>   <span class="fu">return</span> (<span class="kw">if</span> flg <span class="kw">then</span> x<span class="op">:</span>ys <span class="kw">else</span> ys)</span></code></pre></div>
<p>Again, elegant and beautiful (aside from the three-space indent), but
opaque. Despite not really getting how it works, I was encouraged by its
simplicity to try my hand at some of the other functions from
Data.List.</p>
<h2 id="grouping">Grouping</h2>
<p>Let’s start with the subject of my <a
href="2018-01-07-groupBy.html">last post</a>. Here’s the
implementation:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupBy ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>groupBy p xs <span class="ot">=</span> build (\c n <span class="ot">-&gt;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> f x a q</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> q x <span class="ot">=</span> (x <span class="op">:</span> ys, zs)</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> ([], c (x <span class="op">:</span> ys) zs)</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span> (ys,zs) <span class="ot">=</span> a (p x)</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span> <span class="fu">snd</span> (<span class="fu">foldr</span> f (<span class="fu">const</span> ([], n)) xs (<span class="fu">const</span> <span class="dt">False</span>)))</span></code></pre></div>
<p>It translates over pretty readily:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupByM ::</span> <span class="dt">Applicative</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> m <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m [[a]]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>groupByM p xs <span class="ot">=</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> <span class="fu">snd</span> (<span class="fu">foldr</span> f (<span class="fu">const</span> (<span class="fu">pure</span> ([], []))) xs (<span class="fu">const</span> (<span class="fu">pure</span> (<span class="dt">False</span>))))</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    f x a q <span class="ot">=</span> liftA2 st (q x) (a (p x)) <span class="kw">where</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>      st b (ys,zs)</span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> b <span class="ot">=</span> (x <span class="op">:</span> ys, zs)</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> ([], (x<span class="op">:</span>ys)<span class="op">:</span>zs)</span></code></pre></div>
<p>Let’s try it with a similar example to <code
class="sourceCode haskell">filterM</code>:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupByM (\_ _ <span class="ot">-&gt;</span> [<span class="dt">False</span>, <span class="dt">True</span>]) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>[[[<span class="dv">1</span>],[<span class="dv">2</span>],[<span class="dv">3</span>]],[[<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">3</span>]],[[<span class="dv">1</span>,<span class="dv">2</span>],[<span class="dv">3</span>]],[[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]]]</span></code></pre></div>
<p>It gives the partitions of the list!</p>
<h2 id="sorting">Sorting</h2>
<p>So these monadic generalisations have been discovered before, several
times over. There’s even a <a
href="https://hackage.haskell.org/package/monadlist-0.0.2">package</a>
with monadic versions of the functions in Data.List. Exploring this idea
with a little more formality is the paper “All Sorts of Permutations”
<span class="citation" data-cites="christiansen_all_2016">(<a
href="#ref-christiansen_all_2016" role="doc-biblioref">Christiansen,
Danilenko, and Dylus 2016</a>)</span>, and accompanying presentation <a
href="https://www.youtube.com/watch?v=vV3jqTxJ9Wc">on YouTube</a>. They
show that the monadic version of sort produces permutations of the input
list, and examine the output from different sorting algorithms. Here’s a
couple of their implementations, altered slightly:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insertM ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> m <span class="dt">Bool</span>) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m [a]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>insertM _ x [] <span class="ot">=</span> <span class="fu">pure</span> [x]</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>insertM p x yys<span class="op">@</span>(y<span class="op">:</span>ys) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  lte <span class="ot">&lt;-</span> p x y</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">if</span> lte</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">then</span> <span class="fu">pure</span> (x<span class="op">:</span>yys)</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">else</span> <span class="fu">fmap</span> (y<span class="op">:</span>) (insertM p x ys)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="ot">insertSortM ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> m <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m [a]</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>insertSortM p <span class="ot">=</span> foldrM (insertM p) []</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a><span class="ot">partitionM ::</span> <span class="dt">Applicative</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m ([a],[a])</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>partitionM p <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="fu">pure</span> ([],[])) <span class="kw">where</span></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a>  f x <span class="ot">=</span> liftA2 ifStmt (p x) <span class="kw">where</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a>    ifStmt flg (tr,fl)</span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> flg <span class="ot">=</span> (x<span class="op">:</span>tr,fl)</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> (tr,x<span class="op">:</span>fl)</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a><span class="ot">quickSortM ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> m <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m [a]</span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true" tabindex="-1"></a>quickSortM p [] <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true" tabindex="-1"></a>quickSortM p (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a>  (gt,le) <span class="ot">&lt;-</span> partitionM (p x) xs</span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true" tabindex="-1"></a>  ls <span class="ot">&lt;-</span> quickSortM p le</span>
<span id="cb6-24"><a href="#cb6-24" aria-hidden="true" tabindex="-1"></a>  gs <span class="ot">&lt;-</span> quickSortM p gt</span>
<span id="cb6-25"><a href="#cb6-25" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> (ls <span class="op">++</span> [x] <span class="op">++</span> gs)</span>
<span id="cb6-26"><a href="#cb6-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-27"><a href="#cb6-27" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> insertSortM (\_ _ <span class="ot">-&gt;</span> [<span class="dt">False</span>,<span class="dt">True</span>]) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb6-28"><a href="#cb6-28" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>],[<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">2</span>],[<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">2</span>],[<span class="dv">2</span>,<span class="dv">1</span>,<span class="dv">3</span>],[<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">1</span>],[<span class="dv">3</span>,<span class="dv">2</span>,<span class="dv">1</span>]]</span>
<span id="cb6-29"><a href="#cb6-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-30"><a href="#cb6-30" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> quickSortM (\_ _ <span class="ot">-&gt;</span> [<span class="dt">False</span>,<span class="dt">True</span>]) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb6-31"><a href="#cb6-31" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">3</span>,<span class="dv">2</span>,<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">1</span>,<span class="dv">3</span>],[<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">2</span>],[<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">2</span>],[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]]</span></code></pre></div>
<p>As it should be easy to see, they’re very concise and elegant, and
strongly resemble the pure versions of the algorithms.</p>
<h2 id="state">State</h2>
<p>So the examples above are very interesting and cool, but they don’t
necessarily have a place in real Haskell code. If you wanted to find the
permutations, partitions, or power set of a list you’d probably use a
more standard implementation. That’s not to say that these monadic
functions have no uses, though: especially when coupled with <code
class="sourceCode haskell"><span class="dt">State</span></code> they
yield readable and fast implementations for certain tricky functions.
<code class="sourceCode haskell">ordNub</code>, for instance:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">ordNub ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>ordNub <span class="ot">=</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">flip</span> evalState Set.empty <span class="op">.</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  filterM</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    (\x <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>       flg <span class="ot">&lt;-</span> gets (Set.notMember x)</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>       when flg (modify (Set.insert x))</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>       <span class="fu">pure</span> flg)</span></code></pre></div>
<p>Alternatively, using a monadic version of <code
class="sourceCode haskell">maximumOn</code>:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">maximumOnM ::</span> (<span class="dt">Applicative</span> m, <span class="dt">Ord</span> b) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m (<span class="dt">Maybe</span> a)</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>maximumOnM p <span class="ot">=</span> (<span class="fu">fmap</span> <span class="op">.</span> <span class="fu">fmap</span>) <span class="fu">snd</span> <span class="op">.</span> <span class="fu">foldl</span> f (<span class="fu">pure</span> <span class="dt">Nothing</span>)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    f a e <span class="ot">=</span> liftA2 g a (p e)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>        g <span class="dt">Nothing</span> q <span class="ot">=</span> <span class="dt">Just</span> (q, e)</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        g b<span class="op">@</span>(<span class="dt">Just</span> (o, y)) q</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> o <span class="op">&lt;</span> q <span class="ot">=</span> <span class="dt">Just</span> (q, e)</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> b</span></code></pre></div>
<p>You can write a one-pass <code
class="sourceCode haskell">mostFrequent</code>:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mostFrequent ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>mostFrequent <span class="ot">=</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">flip</span> evalState Map.empty <span class="op">.</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  maximumOnM</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>    (\x <span class="ot">-&gt;</span> <span class="fu">maybe</span> <span class="dv">1</span> <span class="fu">succ</span> <span class="op">&lt;$&gt;</span> state (Map.insertLookupWithKey (<span class="fu">const</span> (<span class="op">+</span>)) x <span class="dv">1</span>))</span></code></pre></div>
<h2 id="decision-trees">Decision Trees</h2>
<p>One of the nicest things about the paper was the diagrams of decision
trees provided for each sorting algorithm. I couldn’t find a library to
do that for me, so I had a go at producing my own. First, we’ll need a
data type to represent the tree itself:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">DecTree</span> t a</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Pure</span> a</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Choice</span> t (<span class="dt">DecTree</span> t a) (<span class="dt">DecTree</span> t a)</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> <span class="dt">Functor</span></span></code></pre></div>
<p>We’ll say the left branch is “true” and the right “false”.
Applicative and monad instances are relatively mechanical<a href="#fn2"
class="footnote-ref" id="fnref2"
role="doc-noteref"><sup>2</sup></a>:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> (<span class="dt">DecTree</span> t) <span class="kw">where</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Pure</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span> f <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> <span class="fu">fmap</span> f xs</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Choice</span> c ls rs <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> <span class="dt">Choice</span> c (ls <span class="op">&lt;*&gt;</span> xs) (rs <span class="op">&lt;*&gt;</span> xs)</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> (<span class="dt">DecTree</span> t) <span class="kw">where</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span> x <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> f x</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Choice</span> c ls rs <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="dt">Choice</span> c (ls <span class="op">&gt;&gt;=</span> f) (rs <span class="op">&gt;&gt;=</span> f)</span></code></pre></div>
<p>We can now create a comparator function that constructs one of these
trees, and remembers the values it was given:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">traceCompare ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">DecTree</span> (a,a) <span class="dt">Bool</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>traceCompare x y <span class="ot">=</span> <span class="dt">Choice</span> (x,y) (<span class="dt">Pure</span> <span class="dt">True</span>) (<span class="dt">Pure</span> <span class="dt">False</span>)</span></code></pre></div>
<p>Finally, to draw the tree, I’ll use a function from my <a
href="https://github.com/oisdk/binary-tree">binary tree</a> library:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">printDecTree ::</span> (<span class="dt">Show</span> a, <span class="dt">Show</span> b) <span class="ot">=&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">DecTree</span> (a,a) b <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>printDecTree rel t <span class="ot">=</span> <span class="fu">putStr</span> (drawTreeWith <span class="fu">id</span> (go t) <span class="st">&quot;&quot;</span>) <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  go (<span class="dt">Pure</span> xs) <span class="ot">=</span> <span class="dt">Node</span> (<span class="fu">show</span> xs) <span class="dt">Leaf</span> <span class="dt">Leaf</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  go (<span class="dt">Choice</span> (x,y) tr fl) <span class="ot">=</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Node</span> (<span class="fu">show</span> x <span class="op">++</span> rel <span class="op">++</span> <span class="fu">show</span> y) (go tr) (go fl)</span></code></pre></div>
<p>And we get these really nice diagrams out:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (printDecTree <span class="st">&quot;&lt;=&quot;</span> <span class="op">.</span> insertSortM traceCompare) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>         ┌[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    ┌<span class="dv">1</span><span class="op">&lt;=</span><span class="dv">2</span>┤</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>    │    │    ┌[<span class="dv">2</span>,<span class="dv">1</span>,<span class="dv">3</span>]</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    │    └<span class="dv">1</span><span class="op">&lt;=</span><span class="dv">3</span>┤</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    │         └[<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">1</span>]</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span><span class="op">&lt;=</span><span class="dv">3</span>┤</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>    │    ┌[<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">2</span>]</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>    └<span class="dv">1</span><span class="op">&lt;=</span><span class="dv">3</span>┤</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>         │    ┌[<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">2</span>]</span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>         └<span class="dv">1</span><span class="op">&lt;=</span><span class="dv">2</span>┤</span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>              └[<span class="dv">3</span>,<span class="dv">2</span>,<span class="dv">1</span>]</span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (printDecTree <span class="st">&quot;&lt;=&quot;</span> <span class="op">.</span> quickSortM traceCompare) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a>              ┌[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a>         ┌<span class="dv">2</span><span class="op">&lt;=</span><span class="dv">3</span>┤</span>
<span id="cb14-19"><a href="#cb14-19" aria-hidden="true" tabindex="-1"></a>         │    └[<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">2</span>]</span>
<span id="cb14-20"><a href="#cb14-20" aria-hidden="true" tabindex="-1"></a>    ┌<span class="dv">1</span><span class="op">&lt;=</span><span class="dv">3</span>┤</span>
<span id="cb14-21"><a href="#cb14-21" aria-hidden="true" tabindex="-1"></a>    │    └[<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">2</span>]</span>
<span id="cb14-22"><a href="#cb14-22" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span><span class="op">&lt;=</span><span class="dv">2</span>┤</span>
<span id="cb14-23"><a href="#cb14-23" aria-hidden="true" tabindex="-1"></a>    │    ┌[<span class="dv">2</span>,<span class="dv">1</span>,<span class="dv">3</span>]</span>
<span id="cb14-24"><a href="#cb14-24" aria-hidden="true" tabindex="-1"></a>    └<span class="dv">1</span><span class="op">&lt;=</span><span class="dv">3</span>┤</span>
<span id="cb14-25"><a href="#cb14-25" aria-hidden="true" tabindex="-1"></a>         │    ┌[<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">1</span>]</span>
<span id="cb14-26"><a href="#cb14-26" aria-hidden="true" tabindex="-1"></a>         └<span class="dv">2</span><span class="op">&lt;=</span><span class="dv">3</span>┤</span>
<span id="cb14-27"><a href="#cb14-27" aria-hidden="true" tabindex="-1"></a>              └[<span class="dv">3</span>,<span class="dv">2</span>,<span class="dv">1</span>]</span></code></pre></div>
<p>We can also try it out with the other monadic list functions:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (printDecTree <span class="st">&quot;=&quot;</span> <span class="op">.</span> groupByM traceCompare) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>       ┌[[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]]</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>   ┌<span class="dv">2</span><span class="ot">=</span><span class="dv">3</span>┤</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>   │   └[[<span class="dv">1</span>,<span class="dv">2</span>],[<span class="dv">3</span>]]</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span><span class="ot">=</span><span class="dv">2</span>┤</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>   │   ┌[[<span class="dv">1</span>],[<span class="dv">2</span>,<span class="dv">3</span>]]</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>   └<span class="dv">2</span><span class="ot">=</span><span class="dv">3</span>┤</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>       └[[<span class="dv">1</span>],[<span class="dv">2</span>],[<span class="dv">3</span>]]</span></code></pre></div>
<h2 id="applicative">Applicative</h2>
<p>You might notice that none of these “monadic” functions actually
require a monad constraint: they’re all applicative. There’s a
straightforward implementation that relies only on applicative for most
of these functions, with a notable exception: sort. Getting
<em>that</em> to work with just applicative is the subject of a future
post.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-christiansen_all_2016" class="csl-entry" role="listitem">
Christiansen, Jan, Nikita Danilenko, and Sandra Dylus. 2016. <span>“All
<span>Sorts</span> of <span>Permutations</span> (<span>Functional</span>
<span>Pearl</span>).”</span> In <em>Proceedings of the 21st
<span>ACM</span> <span>SIGPLAN</span> <span>International</span>
<span>Conference</span> on <span>Functional</span>
<span>Programming</span></em>, 168–179. <span>ICFP</span> 2016. New
York, NY, USA: ACM. doi:<a
href="https://doi.org/10.1145/2951913.2951949">10.1145/2951913.2951949</a>.
<a
href="http://informatik.uni-kiel.de/~sad/icfp2016-preprint.pdf">http://informatik.uni-kiel.de/~sad/icfp2016-preprint.pdf</a>.
</div>
</div>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>The definition has since been <a
href="https://hackage.haskell.org/package/base-4.10.1.0/docs/src/Control.Monad.html#filterM">updated</a>
to more modern Haskell: it now uses a fold, and only requires <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>.<a
href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>Part of the reason the instances are so mechanical is
that this type strongly resembles the <a
href="https://hackage.haskell.org/package/free-5/docs/Control-Monad-Free.html#t:Free">free
monad</a>:</p>
<p><code
class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Free</span> f a <span class="ot">=</span> <span class="dt">Pure</span> a <span class="op">|</span> <span class="dt">Free</span> (f (<span class="dt">Free</span> f a))</code></p>
<p>In fact, the example given in the <code
class="sourceCode haskell"><span class="dt">MonadFree</span></code>
class is the following:</p>
<p><code
class="sourceCode haskell"><span class="kw">data</span> <span class="dt">Pair</span> a <span class="ot">=</span> <span class="dt">Pair</span> a a</code></p>
<p><code
class="sourceCode haskell"><span class="kw">type</span> <span class="dt">Tree</span> <span class="ot">=</span> <span class="dt">Free</span> <span class="dt">Pair</span></code></p>
<p>The only difference with the above type and the decision tree is that
the decision tree carries a tag with it.</p>
<p>So what’s so interesting about this relationship? Well, <code
class="sourceCode haskell"><span class="dt">Pair</span></code> is
actually a <a
href="https://hackage.haskell.org/package/adjunctions-4.4/docs/Data-Functor-Rep.html">representable
functor</a>. Any representable functor <code
class="sourceCode haskell">f a</code> can be converted to (and from) a
function <code
class="sourceCode haskell">key <span class="ot">-&gt;</span> a</code>,
where <code class="sourceCode haskell">key</code> is the specific key
for <code class="sourceCode haskell">f</code>. The key for <code
class="sourceCode haskell"><span class="dt">Pair</span></code> is <code
class="sourceCode haskell"><span class="dt">Bool</span></code>: the
result of the function we passed in to the sorting functions!</p>
<p>In general, you can make a “decision tree” for any function of type
<code
class="sourceCode haskell">a <span class="ot">-&gt;</span> b</code> like
so:</p>
<p><code
class="sourceCode haskell"><span class="kw">type</span> <span class="dt">DecTree</span> a b r <span class="ot">=</span> <span class="dt">Rep</span> f <span class="op">~</span> b <span class="ot">=&gt;</span> <span class="dt">Free</span> (<span class="dt">Compose</span> ((,) a) f) r</code></p>
<p>But more on that in a later post.<a href="#fnref2"
class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Sun, 11 Feb 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-02-11-monadic-list.functions.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>groupBy</title>
    <link>https://doisinkidney.com/posts/2018-01-07-groupBy.html</link>
    <description><![CDATA[<div class="info">
    Posted on January  7, 2018
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Folds&#39;." href="/tags/Folds.html" rel="tag">Folds</a>
    
</div>

<p>Here’s a useful function from <a
href="https://hackage.haskell.org/package/base-4.10.1.0/docs/Data-List.html#v:groupBy">Data.List</a>:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupBy ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>groupBy (<span class="op">==</span>) <span class="st">&quot;aabcdda&quot;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="co">-- [&quot;aa&quot;,&quot;b&quot;,&quot;c&quot;,&quot;dd&quot;,&quot;a&quot;]</span></span></code></pre></div>
<p>However, as has been pointed out before<a href="#fn1"
class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>,
<code class="sourceCode haskell">groupBy</code> expects an equivalence
relation, and can exhibit surprising behavior when it doesn’t get one.
Let’s say, for instance, that we wanted to group numbers that were close
together:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupClose ::</span> [<span class="dt">Integer</span>] <span class="ot">-&gt;</span> [[<span class="dt">Integer</span>]]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>groupClose <span class="ot">=</span> groupBy (\x y <span class="ot">-&gt;</span> <span class="fu">abs</span> (x <span class="op">-</span> y) <span class="op">&lt;</span> <span class="dv">3</span>)</span></code></pre></div>
<p>What would you expect on the list <code>[1, 2, 3, 4, 5]</code>? All
in the same group? Well, what you actually get is:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>],[<span class="dv">4</span>,<span class="dv">5</span>]]</span></code></pre></div>
<p>This is because the implementation of <code
class="sourceCode haskell">groupBy</code> only compares to the first
element in each group:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>groupBy _  []           <span class="ot">=</span>  []</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>groupBy eq (x<span class="op">:</span>xs)       <span class="ot">=</span>  (x<span class="op">:</span>ys) <span class="op">:</span> groupBy eq zs</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>                           <span class="kw">where</span> (ys,zs) <span class="ot">=</span> <span class="fu">span</span> (eq x) xs</span></code></pre></div>
<p>Brandon Simmons gave a <a
href="http://brandon.si/code/an-alternative-definition-for-datalistgroupby/">definition</a>
of <code class="sourceCode haskell">groupBy</code> that is perhaps more
useful, but it used explicit recursion, rather than a fold.</p>
<p>A definition with <code
class="sourceCode haskell"><span class="fu">foldr</span></code> turned
out to be trickier than I expected. I found some of the laziness
properties especially difficult:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">head</span> (groupBy (<span class="op">==</span>) (<span class="dv">1</span><span class="op">:</span><span class="dv">2</span><span class="op">:</span><span class="fu">undefined</span>))</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span>]</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (<span class="fu">head</span> <span class="op">.</span> <span class="fu">head</span>) (groupBy (<span class="op">==</span>) (<span class="dv">1</span><span class="op">:</span><span class="fu">undefined</span>))</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (<span class="fu">head</span> <span class="op">.</span> <span class="fu">head</span> <span class="op">.</span> <span class="fu">tail</span>) (groupBy (<span class="op">==</span>) (<span class="dv">1</span><span class="op">:</span><span class="dv">2</span><span class="op">:</span><span class="fu">undefined</span>))</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span></code></pre></div>
<p>Here’s the definition I came up with, after some deliberation:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupBy ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>groupBy p xs <span class="ot">=</span> build (\c n <span class="ot">-&gt;</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> f x a q</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> q x <span class="ot">=</span> (x <span class="op">:</span> ys, zs)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> ([], c (x <span class="op">:</span> ys) zs)</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span> (ys,zs) <span class="ot">=</span> a (p x)</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span> <span class="fu">snd</span> (<span class="fu">foldr</span> f (<span class="fu">const</span> ([], n)) xs (<span class="fu">const</span> <span class="dt">False</span>)))</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE groupBy #-}</span></span></code></pre></div>
<p>Seemingly benign changes to the function will break one or more of
the above tests. In particular, the laziness of a “where” binding needs
to be taken into account. Here’s an early attempt which failed:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">groupBy ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>groupBy p xs <span class="ot">=</span> build (\c n <span class="ot">-&gt;</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> f x a q d</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> q x <span class="ot">=</span> a (p x) (d <span class="op">.</span> (<span class="op">:</span>) x)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> d [] (a (p x) (c <span class="op">.</span> (<span class="op">:</span>) x))</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span> <span class="fu">foldr</span> f (\_ d <span class="ot">-&gt;</span> d [] n) xs (<span class="fu">const</span> <span class="dt">False</span>) (\ _ y <span class="ot">-&gt;</span> y))</span></code></pre></div>
<p>Once done, though, it works as expected:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupBy (<span class="op">==</span>) <span class="st">&quot;aaabcccdda&quot;</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>[<span class="st">&quot;aaa&quot;</span>,<span class="st">&quot;b&quot;</span>,<span class="st">&quot;ccc&quot;</span>,<span class="st">&quot;dd&quot;</span>,<span class="st">&quot;a&quot;</span>]</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupBy (<span class="op">==</span>) []</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>[]</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> groupBy (<span class="op">&lt;=</span>) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">0</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">2</span>]</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">2</span>,<span class="dv">3</span>],[<span class="dv">1</span>,<span class="dv">2</span>],[<span class="dv">0</span>,<span class="dv">4</span>,<span class="dv">5</span>],[<span class="dv">2</span>]]</span></code></pre></div>
<p>It’s the fastest version I could find that obeyed the above laziness
properties.</p>
<p>The <a href="https://ghc.haskell.org/trac/ghc/ticket/13593">GHC page
on the issue</a> unfortunately seems to indicate the implementation
won’t be changed. Ah, well. Regardless, I have a <a
href="https://github.com/oisdk/groupBy">repository</a> with the
implementation above (with extra fusion machinery added) and comparisons
to other implementations.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>There are several threads on the libraries mailing list
on this topic:</p>
<dl>
<dt>2006</dt>
<dd>
<a
href="http://www.haskell.org/pipermail/haskell-cafe/2006-October/019148.html">mapAccumL
- find max in-sequence subsequence</a>
</dd>
<dt>2007</dt>
<dd>
<a
href="https://mail.haskell.org/pipermail/libraries/2007-August/008028.html">Data.List.groupBy
with non-transitive equality predicate</a> (this is the longest
discussion on the topic)
</dd>
<dt>2008</dt>
<dd>
<a
href="https://mail.haskell.org/pipermail/libraries/2008-September/010629.html">Generalize
groupBy in a useful way?</a>
</dd>
<dt>2009</dt>
<dd>
<a
href="https://mail.haskell.org/pipermail/libraries/2009-June/011866.html">nubBy
seems broken in recent GHCs</a>
</dd>
</dl>
<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></li>
</ol>
</section>
]]></description>
    <pubDate>Sun, 07 Jan 2018 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2018-01-07-groupBy.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Unfoldl</title>
    <link>https://doisinkidney.com/posts/2017-12-14-unfoldl-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on December 14, 2017
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE LambdaCase #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Unfoldl</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">GHC.Base</span> (build)</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Tuple</span> (swap)</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="ot">unfoldl ::</span> (b <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (a, b)) <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> [a]</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>unfoldl f b <span class="ot">=</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    build</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>        (\c n <span class="ot">-&gt;</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>              <span class="kw">let</span> r a <span class="ot">=</span> <span class="fu">maybe</span> a (<span class="fu">uncurry</span> (r <span class="op">.</span> (<span class="ot">`c`</span> a))) <span class="op">.</span> f</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>              <span class="kw">in</span> r n b)</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- | &gt;&gt;&gt; toDigs 10 123</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- [1,2,3]</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="ot">toDigs ::</span> (<span class="dt">Integral</span> a, <span class="dt">Num</span> a) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>toDigs base <span class="ot">=</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>  unfoldl (\<span class="kw">case</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a>    <span class="dv">0</span> <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    n <span class="ot">-&gt;</span> <span class="dt">Just</span> (swap (n <span class="ot">`quotRem`</span> base)))</span></code></pre></div>
]]></description>
    <pubDate>Thu, 14 Dec 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-12-14-unfoldl-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Balancing Folds</title>
    <link>https://doisinkidney.com/posts/2017-10-30-balancing-folds.html</link>
    <description><![CDATA[<div class="info">
    Posted on October 30, 2017
</div>
<div class="info">
    
        Part 1 of a <a href="/series/Balanced%20Folds.html">3-part series on Balanced Folds</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Folds&#39;." href="/tags/Folds.html" rel="tag">Folds</a>
    
</div>

<p>There are three main ways to fold things in Haskell: from the right,
from the left, and from either side. Let’s look at the left vs right
variants first. <code
class="sourceCode haskell"><span class="fu">foldr</span></code> works
from the right:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldr</span> (<span class="op">+</span>) <span class="dv">0</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">+</span> (<span class="dv">2</span> <span class="op">+</span> (<span class="dv">3</span> <span class="op">+</span> <span class="dv">0</span>))</span></code></pre></div>
<p>And <code
class="sourceCode haskell"><span class="fu">foldl</span></code> from the
left:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldl</span> (<span class="op">+</span>) <span class="dv">0</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>((<span class="dv">0</span> <span class="op">+</span> <span class="dv">1</span>) <span class="op">+</span> <span class="dv">2</span>) <span class="op">+</span> <span class="dv">3</span></span></code></pre></div>
<p>As you’ll notice, the result of the two operations above is the same
(6; although one may take much longer than the other). In fact,
<em>whenever</em> the result of <code
class="sourceCode haskell"><span class="fu">foldr</span></code> and
<code class="sourceCode haskell"><span class="fu">foldl</span></code> is
the same for a pair of arguments (in this case <code
class="sourceCode haskell"><span class="op">+</span></code> and <code
class="sourceCode haskell"><span class="dv">0</span></code>), we say
that that pair forms a <a
href="https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Monoid.html#t:Monoid"><code
class="sourceCode haskell"><span class="dt">Monoid</span></code></a> for
some type (well, there’s some extra stuff to do with <code
class="sourceCode haskell"><span class="dv">0</span></code>, but I only
care about associativity at the moment). In this case, the <a
href="https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Monoid.html#t:Sum"><code
class="sourceCode haskell"><span class="dt">Sum</span></code></a> monoid
is formed:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Sum</span> a <span class="ot">=</span> <span class="dt">Sum</span> {<span class="ot"> getSum ::</span> a }</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Sum</span> a) <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Sum</span> <span class="dv">0</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> (<span class="dt">Sum</span> x) (<span class="dt">Sum</span> y) <span class="ot">=</span> <span class="dt">Sum</span> (x <span class="op">+</span> y)</span></code></pre></div>
<p>When you know that you have a monoid, you can use the <a
href="https://hackage.haskell.org/package/base-4.10.0.0/docs/Data-Foldable.html#v:foldMap"><code
class="sourceCode haskell"><span class="fu">foldMap</span></code></a>
function: this is the third kind of fold. It says that you don’t care
which of <code
class="sourceCode haskell"><span class="fu">foldl</span></code> or <code
class="sourceCode haskell"><span class="fu">foldr</span></code> is used,
so the implementer of <code
class="sourceCode haskell"><span class="fu">foldMap</span></code> can
put the parentheses wherever they want:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">foldMap</span> <span class="dt">Sum</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>(<span class="dv">1</span> <span class="op">+</span> <span class="dv">2</span>) <span class="op">+</span> (<span class="dv">3</span> <span class="op">+</span> <span class="dv">0</span>)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span> <span class="op">+</span> ((<span class="dv">1</span> <span class="op">+</span> <span class="dv">2</span>) <span class="op">+</span> <span class="dv">3</span>)</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>((<span class="dv">0</span> <span class="op">+</span> <span class="dv">1</span>) <span class="op">+</span> <span class="dv">2</span>) <span class="op">+</span> <span class="dv">3</span></span></code></pre></div>
<p>And we can’t tell the difference from the result. This is a pretty
bare-bones introduction to folds and monoids: you won’t need to know
more than that for the rest of this post, but the topic area is
fascinating and deep, so don’t let me give you the impression that I’ve
done anything more than scratched the surface.</p>
<h1 id="other-ways-to-fold">Other Ways to Fold</h1>
<p>Quite often, we <em>do</em> care about where the parentheses go.
Take, for instance, a binary tree type, with values at the leaves:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Empty</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Leaf</span> a</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Tree</span> a <span class="op">:*:</span> <span class="dt">Tree</span> a</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Show</span> (<span class="dt">Tree</span> a) <span class="kw">where</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">show</span> <span class="dt">Empty</span> <span class="ot">=</span> <span class="st">&quot;()&quot;</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">show</span> (<span class="dt">Leaf</span> x) <span class="ot">=</span> <span class="fu">show</span> x</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">show</span> (l <span class="op">:*:</span> r) <span class="ot">=</span> <span class="st">&quot;(&quot;</span> <span class="op">++</span> <span class="fu">show</span> l <span class="op">++</span> <span class="st">&quot;*&quot;</span> <span class="op">++</span> <span class="fu">show</span> r <span class="op">++</span> <span class="st">&quot;)&quot;</span></span></code></pre></div>
<p>We can’t (well, shouldn’t) use <code
class="sourceCode haskell"><span class="fu">foldMap</span></code> here,
because we would be able to tell the difference between different
arrangements of parentheses:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> <span class="fu">foldMap</span> something [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>((<span class="dv">1</span><span class="op">*</span><span class="dv">2</span>)<span class="op">*</span>(<span class="dv">3</span><span class="op">*</span>())) │ (()<span class="op">*</span>((<span class="dv">1</span><span class="op">*</span><span class="dv">2</span>)<span class="op">*</span><span class="dv">3</span>)) │ (((()<span class="op">*</span><span class="dv">1</span>)<span class="op">*</span><span class="dv">2</span>)<span class="op">*</span><span class="dv">3</span>)</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>───────────────┼────────────────┼───────────────</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>       ┌<span class="dv">1</span>      │      ┌()       │       ┌()</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>      ┌┤       │      ┤         │      ┌┤</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>      │└<span class="dv">2</span>      │      │ ┌<span class="dv">1</span>      │      │└<span class="dv">1</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>      ┤        │      │┌┤       │     ┌┤</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>      │┌<span class="dv">3</span>      │      ││└<span class="dv">2</span>      │     │└<span class="dv">2</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>      └┤       │      └┤        │     ┤</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>       └()     │       └<span class="dv">3</span>       │     └<span class="dv">3</span></span></code></pre></div>
<p>So we use one of the folds which lets us choose the arrangements of
parentheses:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (<span class="fu">foldr</span> (<span class="op">:*:</span>) <span class="dt">Empty</span> <span class="op">.</span> <span class="fu">map</span> <span class="dt">Leaf</span>) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>(<span class="dv">1</span><span class="op">*</span>(<span class="dv">2</span><span class="op">*</span>(<span class="dv">3</span><span class="op">*</span>(<span class="dv">4</span><span class="op">*</span>(<span class="dv">5</span><span class="op">*</span>(<span class="dv">6</span><span class="op">*</span>()))))))</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>     ┌<span class="dv">1</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    ┌┤</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    │└<span class="dv">2</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>   ┌┤</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>   │└<span class="dv">3</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  ┌┤</span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>  │└<span class="dv">4</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a> ┌┤</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a> │└<span class="dv">5</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>┌┤</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>│└<span class="dv">6</span></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>┤</span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a>└()</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (<span class="fu">foldl</span> (<span class="op">:*:</span>) <span class="dt">Empty</span> <span class="op">.</span> <span class="fu">map</span> <span class="dt">Leaf</span>) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>]</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true" tabindex="-1"></a>((((((()<span class="op">*</span><span class="dv">1</span>)<span class="op">*</span><span class="dv">2</span>)<span class="op">*</span><span class="dv">3</span>)<span class="op">*</span><span class="dv">4</span>)<span class="op">*</span><span class="dv">5</span>)<span class="op">*</span><span class="dv">6</span>)</span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true" tabindex="-1"></a>┌()</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true" tabindex="-1"></a>┤</span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true" tabindex="-1"></a>│┌<span class="dv">1</span></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true" tabindex="-1"></a>└┤</span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true" tabindex="-1"></a> │┌<span class="dv">2</span></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true" tabindex="-1"></a> └┤</span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true" tabindex="-1"></a>  │┌<span class="dv">3</span></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true" tabindex="-1"></a>  └┤</span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true" tabindex="-1"></a>   │┌<span class="dv">4</span></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true" tabindex="-1"></a>   └┤</span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true" tabindex="-1"></a>    │┌<span class="dv">5</span></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true" tabindex="-1"></a>    └┤</span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true" tabindex="-1"></a>     └<span class="dv">6</span></span></code></pre></div>
<p>The issue is that neither of the trees generated are necessarily what
we want: often, we want something more <em>balanced</em>.</p>
<h2 id="treefold">TreeFold</h2>
<p>To try and find a more balanced fold, let’s (for now) assume we’re
always going to get non-empty input. This will let us simplify the <code
class="sourceCode haskell"><span class="dt">Tree</span></code> type a
little, to:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> a</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Leaf</span> a</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Tree</span> a <span class="op">:*:</span> <span class="dt">Tree</span> a</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> <span class="dt">Foldable</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Show</span> (<span class="dt">Tree</span> a) <span class="kw">where</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">show</span> (<span class="dt">Leaf</span> x) <span class="ot">=</span> <span class="fu">show</span> x</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">show</span> (l <span class="op">:*:</span> r) <span class="ot">=</span> <span class="st">&quot;(&quot;</span> <span class="op">++</span> <span class="fu">show</span> l <span class="op">++</span> <span class="st">&quot;*&quot;</span> <span class="op">++</span> <span class="fu">show</span> r <span class="op">++</span> <span class="st">&quot;)&quot;</span></span></code></pre></div>
<p>Then, we can use Jon Fairbairn’s fold described in <a
href="http://www.mail-archive.com/haskell@haskell.org/msg01788.html">this</a>
email, adapted a bit for our non-empty input:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.List.NonEmpty</span> (<span class="dt">NonEmpty</span>(..))</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>treeFold f <span class="ot">=</span> go</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    go (x <span class="op">:|</span> []) <span class="ot">=</span> x</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    go (a <span class="op">:|</span> b<span class="op">:</span>l) <span class="ot">=</span> go (f a b <span class="op">:|</span> pairMap l)</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>    pairMap (x<span class="op">:</span>y<span class="op">:</span>rest) <span class="ot">=</span> f x y <span class="op">:</span> pairMap rest</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>    pairMap xs <span class="ot">=</span> xs</span></code></pre></div>
<p>There are two parts to this function: <code
class="sourceCode haskell">pairMap</code> and the <code
class="sourceCode haskell">go</code> helper. <code
class="sourceCode haskell">pairMap</code> combines adjacent elements in
the list using the combining function. As a top-level function it might
look like this:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>pairMap f (x<span class="op">:</span>y<span class="op">:</span>rest) <span class="ot">=</span> f x y <span class="op">:</span> pairMap f rest</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>pairMap f xs <span class="ot">=</span> xs</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>pairMap (<span class="op">++</span>) [<span class="st">&quot;a&quot;</span>,<span class="st">&quot;b&quot;</span>,<span class="st">&quot;c&quot;</span>,<span class="st">&quot;d&quot;</span>,<span class="st">&quot;e&quot;</span>]</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- [&quot;ab&quot;,&quot;cd&quot;,&quot;e&quot;]</span></span></code></pre></div>
<p>As you can see, it leaves any leftovers untouched at the end of the
list.</p>
<p>The <code class="sourceCode haskell">go</code> helper applies <code
class="sourceCode haskell">pairMap</code> repeatedly to the list until
it has only one element. This gives us much more balanced results that
<code class="sourceCode haskell"><span class="fu">foldl</span></code> or
<code class="sourceCode haskell"><span class="fu">foldr</span></code>
(turn on <code
class="sourceCode haskell"><span class="op">-</span><span class="dt">XOverloadedLists</span></code>
to write non-empty lists using this syntax):</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (treeFold (<span class="op">:*:</span>) <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Leaf</span>) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>]</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>(((<span class="dv">1</span><span class="op">*</span><span class="dv">2</span>)<span class="op">*</span>(<span class="dv">3</span><span class="op">*</span><span class="dv">4</span>))<span class="op">*</span>(<span class="dv">5</span><span class="op">*</span><span class="dv">6</span>))</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  ┌<span class="dv">1</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a> ┌┤</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a> │└<span class="dv">2</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>┌┤</span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>││┌<span class="dv">3</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>│└┤</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>│ └<span class="dv">4</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>┤</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>│┌<span class="dv">5</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>└┤</span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a> └<span class="dv">6</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (treeFold (<span class="op">:*:</span>) <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Leaf</span>) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>,<span class="dv">7</span>,<span class="dv">8</span>]</span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a>(((<span class="dv">1</span><span class="op">*</span><span class="dv">2</span>)<span class="op">*</span>(<span class="dv">3</span><span class="op">*</span><span class="dv">4</span>))<span class="op">*</span>((<span class="dv">5</span><span class="op">*</span><span class="dv">6</span>)<span class="op">*</span>(<span class="dv">7</span><span class="op">*</span><span class="dv">8</span>)))</span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a>  ┌<span class="dv">1</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a> ┌┤</span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a> │└<span class="dv">2</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a>┌┤</span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a>││┌<span class="dv">3</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a>│└┤</span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a>│ └<span class="dv">4</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a>┤</span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a>│ ┌<span class="dv">5</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a>│┌┤</span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a>││└<span class="dv">6</span></span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true" tabindex="-1"></a>└┤</span>
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true" tabindex="-1"></a> │┌<span class="dv">7</span></span>
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true" tabindex="-1"></a> └┤</span>
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true" tabindex="-1"></a>  └<span class="dv">8</span></span></code></pre></div>
<p>However, there are still cases where one branch will be much larger
than its sibling. The fold fills a balanced binary tree from the left,
but any leftover elements are put at the top level. In other words:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (treeFold (<span class="op">:*:</span>) <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Leaf</span>) [<span class="dv">1</span><span class="op">..</span><span class="dv">9</span>]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>((((<span class="dv">1</span><span class="op">*</span><span class="dv">2</span>)<span class="op">*</span>(<span class="dv">3</span><span class="op">*</span><span class="dv">4</span>))<span class="op">*</span>((<span class="dv">5</span><span class="op">*</span><span class="dv">6</span>)<span class="op">*</span>(<span class="dv">7</span><span class="op">*</span><span class="dv">8</span>)))<span class="op">*</span><span class="dv">9</span>)</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>   ┌<span class="dv">1</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  ┌┤</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  │└<span class="dv">2</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a> ┌┤</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a> ││┌<span class="dv">3</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a> │└┤</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a> │ └<span class="dv">4</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>┌┤</span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>││ ┌<span class="dv">5</span></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a>││┌┤</span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a>│││└<span class="dv">6</span></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a>│└┤</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a>│ │┌<span class="dv">7</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a>│ └┤</span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a>│  └<span class="dv">8</span></span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a>┤</span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a>└<span class="dv">9</span></span></code></pre></div>
<p>That <code
class="sourceCode haskell"><span class="dv">9</span></code> hanging out
on its own there is a problem.</p>
<h2 id="typewriters-and-slaloms">Typewriters and Slaloms</h2>
<p>One observation we can make is that <code
class="sourceCode haskell">pairMap</code> always starts from the same
side on each iteration, like a typewriter moving from one line to the
next. This has the consequence of building up the leftovers on one side,
leaving them until the top level.</p>
<p>We can improve the situation slightly by going back and forth,
slalom-style, so we consume leftovers on each iteration:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>treeFold f <span class="ot">=</span> goTo <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  goTo (y <span class="op">:|</span> []) <span class="ot">=</span> y</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  goTo (a <span class="op">:|</span> b <span class="op">:</span> rest) <span class="ot">=</span> goFro (pairMap f (f a b) rest)</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  goFro (y <span class="op">:|</span> []) <span class="ot">=</span> y</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>  goFro (a <span class="op">:|</span> b <span class="op">:</span> rest) <span class="ot">=</span> goTo (pairMap (<span class="fu">flip</span> f) (f b a) rest)</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>  pairMap f <span class="ot">=</span> go [] <span class="kw">where</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>    go ys y (a<span class="op">:</span>b<span class="op">:</span>rest) <span class="ot">=</span> go (y<span class="op">:</span>ys) (f a b) rest</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>    go ys y [z] <span class="ot">=</span> z <span class="op">:|</span> y <span class="op">:</span> ys</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>    go ys y [] <span class="ot">=</span> y <span class="op">:|</span> ys</span></code></pre></div>
<p>Notice that we have to flip the combining function to make sure the
ordering is the same on output. For the earlier example, this solves the
issue:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (treeFold (<span class="op">:*:</span>) <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Leaf</span>) [<span class="dv">1</span><span class="op">..</span><span class="dv">9</span>]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>(((<span class="dv">1</span><span class="op">*</span><span class="dv">2</span>)<span class="op">*</span>((<span class="dv">3</span><span class="op">*</span><span class="dv">4</span>)<span class="op">*</span>(<span class="dv">5</span><span class="op">*</span><span class="dv">6</span>)))<span class="op">*</span>((<span class="dv">7</span><span class="op">*</span><span class="dv">8</span>)<span class="op">*</span><span class="dv">9</span>))</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  ┌<span class="dv">1</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a> ┌┤</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a> │└<span class="dv">2</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>┌┤</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>││ ┌<span class="dv">3</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>││┌┤</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>│││└<span class="dv">4</span></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>│└┤</span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>│ │┌<span class="dv">5</span></span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>│ └┤</span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>│  └<span class="dv">6</span></span>
<span id="cb14-14"><a href="#cb14-14" aria-hidden="true" tabindex="-1"></a>┤</span>
<span id="cb14-15"><a href="#cb14-15" aria-hidden="true" tabindex="-1"></a>│ ┌<span class="dv">7</span></span>
<span id="cb14-16"><a href="#cb14-16" aria-hidden="true" tabindex="-1"></a>│┌┤</span>
<span id="cb14-17"><a href="#cb14-17" aria-hidden="true" tabindex="-1"></a>││└<span class="dv">8</span></span>
<span id="cb14-18"><a href="#cb14-18" aria-hidden="true" tabindex="-1"></a>└┤</span>
<span id="cb14-19"><a href="#cb14-19" aria-hidden="true" tabindex="-1"></a> └<span class="dv">9</span></span></code></pre></div>
<p>It does <em>not</em> build up the tree as balanced as it possibly
could, though:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;&gt;&gt;</span> (treeFold (<span class="op">:*:</span>) <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Leaf</span>) [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>,<span class="dv">6</span>]</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>((<span class="dv">1</span><span class="op">*</span><span class="dv">2</span>)<span class="op">*</span>((<span class="dv">3</span><span class="op">*</span><span class="dv">4</span>)<span class="op">*</span>(<span class="dv">5</span><span class="op">*</span><span class="dv">6</span>)))</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a> ┌<span class="dv">1</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>┌┤</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>│└<span class="dv">2</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>┤</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>│ ┌<span class="dv">3</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>│┌┤</span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>││└<span class="dv">4</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>└┤</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a> │┌<span class="dv">5</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a> └┤</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>  └<span class="dv">6</span></span></code></pre></div>
<p>There’s four elements in the right branch, and two in the left in the
above example. Three in each would be optimal.</p>
<p>Wait—optimal in what sense, exactly? What do we mean when we say one
tree is more balanced than another? Let’s say the “balance factor” is
the largest difference in size of two sibling trees:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">balFac ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>balFac <span class="ot">=</span> <span class="fu">fst</span> <span class="op">.</span> go <span class="kw">where</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  go ::</span> <span class="dt">Tree</span> a <span class="ot">-&gt;</span> (<span class="dt">Integer</span>, <span class="dt">Integer</span>)</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  go (<span class="dt">Leaf</span> _) <span class="ot">=</span> (<span class="dv">0</span>, <span class="dv">1</span>)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>  go (l <span class="op">:*:</span> r) <span class="ot">=</span> (lb <span class="ot">`max`</span> rb <span class="ot">`max`</span> <span class="fu">abs</span> (rs <span class="op">-</span> ls), rs <span class="op">+</span> ls) <span class="kw">where</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    (lb,ls) <span class="ot">=</span> go l</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>    (rb,rs) <span class="ot">=</span> go r</span></code></pre></div>
<p>And one tree is more balanced than another if it has a smaller
balance factor.</p>
<p>There’s effectively no limit on the balance factor for the typewriter
method: when the input is one larger than a power of two, it’ll stick
the one extra in one branch and the rest in another (as with <code
class="sourceCode haskell">[<span class="dv">1</span><span class="op">..</span><span class="dv">9</span>]</code>
in the example above).</p>
<p>For the slalom method, it looks like there’s something more
interesting going on, limit-wise. I haven’t been able to verify this
formally (yet), but from what I can tell, a tree of height
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
will have at most a balance factor of the
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>th
<a href="https://oeis.org/A001045">Jacobsthal number</a>. That’s
(apparently) also the number of ways to tie a tie using
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>+</mo><mn>2</mn></mrow><annotation encoding="application/x-tex">n + 2</annotation></semantics></math>
turns.</p>
<p>That was just gathered from some quick experiments and <a
href="https://oeis.org/">oeis.org</a>, but it seems to make sense
intuitively. Jacobsthal numbers are defined like this:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>j <span class="dv">0</span> <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>j <span class="dv">1</span> <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>j n <span class="ot">=</span> j (n<span class="op">-</span><span class="dv">1</span>) <span class="op">+</span> <span class="dv">2</span> <span class="op">*</span> j (n<span class="op">-</span><span class="dv">2</span>)</span></code></pre></div>
<p>So, at the top level, there’s the imbalance caused by the second-last
<code class="sourceCode haskell">pairFold</code>, plus the imbalance
caused by the third-to-last. However, the third-to-last imbalance is
twice what it was at that level, because it is now working with an
already-paired-up list. Why isn’t the second last imbalance also
doubled? Because it’s counteracted by the fact that we turned around:
the imbalance is in an element that’s a leftover element. At least
that’s what my intuition is at this point.</p>
<p>The minimum balance factor is, of course, one. Unfortunately, to
achieve that, I lost some of the properties of the previous folds:</p>
<h2 id="lengths">Lengths</h2>
<p>Up until now, I have been avoiding taking the length of the incoming
list. It would lose a lot of laziness, cause an extra traversal, and
generally seems like an ugly solution. Nonetheless, it gives the most
balanced results I could find so far:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>treeFold f (x<span class="op">:|</span>xs) <span class="ot">=</span> go (<span class="fu">length</span> (x<span class="op">:</span>xs)) (x<span class="op">:</span>xs) <span class="kw">where</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  go <span class="dv">1</span> [y] <span class="ot">=</span> y</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>  go n ys <span class="ot">=</span> f (go m a) (go (n<span class="op">-</span>m) b) <span class="kw">where</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>    (a,b) <span class="ot">=</span> <span class="fu">splitAt</span> m ys</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>    m <span class="ot">=</span> n <span class="ot">`div`</span> <span class="dv">2</span></span></code></pre></div>
<p><code
class="sourceCode haskell"><span class="fu">splitAt</span></code> is an
inefficient operation, but if we let the left-hand call return its
unused input from the list, we can avoid it:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>treeFold f (x<span class="op">:|</span>xs) <span class="ot">=</span> <span class="fu">fst</span> (go (<span class="fu">length</span> (x<span class="op">:</span>xs)) (x<span class="op">:</span>xs)) <span class="kw">where</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  go <span class="dv">1</span> (y<span class="op">:</span>ys) <span class="ot">=</span> (y,ys)</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>  go n ys <span class="ot">=</span> (f l r, rs) <span class="kw">where</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>    (l,ls) <span class="ot">=</span> go m ys</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>    (r,rs) <span class="ot">=</span> go (n<span class="op">-</span>m) ls</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>    m <span class="ot">=</span> n <span class="ot">`div`</span> <span class="dv">2</span></span></code></pre></div>
<p>Finally, you may have spotted the state monad in this last version.
We can make the similarity explicit:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFold ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>treeFold f (x<span class="op">:|</span>xs) <span class="ot">=</span> evalState (go (<span class="fu">length</span> (x<span class="op">:</span>xs))) (x<span class="op">:</span>xs) <span class="kw">where</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  go <span class="dv">1</span> <span class="ot">=</span> state (\(y<span class="op">:</span>ys) <span class="ot">-&gt;</span> (y,ys))</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>  go n <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">let</span> m <span class="ot">=</span> n <span class="ot">`div`</span> <span class="dv">2</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    l <span class="ot">&lt;-</span> go m</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>    r <span class="ot">&lt;-</span> go (n<span class="op">-</span>m)</span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">return</span> (f l r)</span></code></pre></div>
<p>And there you have it: three different ways to fold in a more
balanced way. Perhaps surprisingly, the first is the fastest in my
tests. I’d love to hear if there’s a more balanced version (which is
lazy, ideally) that is just as efficient as the first
implementation.</p>
<h1 id="stable-summation">Stable Summation</h1>
<p>I have found two other uses for these folds other than simply
constructing more balanced binary trees. The first is summation of
floating-point numbers. If you sum floating-point numbers in the usual
way with <code class="sourceCode haskell">foldl&#39;</code> (or, indeed,
with an accumulator in an imperative language), you will see an error
growth of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(n)</annotation></semantics></math>,
where
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
is the number of floats you’re summing.</p>
<p>A well-known solution to this problem is the <a
href="https://en.wikipedia.org/wiki/Kahan_summation_algorithm">Kahan
summation algorithm</a>. It carries with it a running compensation for
accumulating errors, giving it
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(1)</annotation></semantics></math>
error growth. There are two downsides to the algorithm: it takes four
times the number of numerical operations to perform, and isn’t
parallel.</p>
<p>For that reason, it’s often not used in practice: instead, floats are
summed <em>pairwise</em>, in a manner often referred to as <a
href="https://en.wikipedia.org/wiki/Pairwise_summation">cascade
summation</a>. This is what’s used in <a
href="https://github.com/numpy/numpy/pull/3685">NumPy</a>. The error
growth isn’t quite as
good—<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝒪</mi><mo stretchy="false" form="prefix">(</mo><mrow><mi>log</mi><mo>&#8289;</mo></mrow><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\mathcal{O}(\log{n})</annotation></semantics></math>—but
it takes the exact same number of operations as normal summation. On top
of that:</p>
<h1 id="parallelization">Parallelization</h1>
<p>Dividing a fold into roughly-equal chunks is exactly the kind of
problem encountered when trying to parallelize certain algorithms.
Adapting the folds above so that their work is performed in parallel is
surprisingly easy:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">splitPar ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> a</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>splitPar f <span class="ot">=</span> go</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>    go l r <span class="dv">0</span> <span class="ot">=</span> f (l <span class="dv">0</span>) (r <span class="dv">0</span>)</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>    go l r n <span class="ot">=</span> lt <span class="ot">`par`</span> (rt <span class="ot">`pseq`</span> f lt rt)</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>        lt <span class="ot">=</span> l (n<span class="op">-</span>m)</span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>        rt <span class="ot">=</span> r m</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>        m <span class="ot">=</span> n <span class="ot">`div`</span> <span class="dv">2</span></span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFoldParallel ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a>treeFoldParallel f xs <span class="ot">=</span></span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a>    treeFold <span class="fu">const</span> (splitPar f) xs numCapabilities</span></code></pre></div>
<p>The above will split the fold into <code
class="sourceCode haskell">numCapabilities</code> chunks, and perform
each one in parallel. <code
class="sourceCode haskell">numCapabilities</code> is a constant defined
in <a
href="https://hackage.haskell.org/package/base-4.10.0.0/docs/GHC-Conc.html">GHC.Conc</a>:
it’s the number of threads which can be run simultaneously at any one
time. Alternatively, you could the function include a parameter for how
many chunks to split the computation into. You could also have the fold
adapt as it went, choosing whether or not to spark based on how many
sparks exist at any given time:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">parseq ::</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>parseq a b <span class="ot">=</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    runST</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>        (bool (par a b) (<span class="fu">seq</span> a b) <span class="op">&lt;$&gt;</span></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>         unsafeIOToST (liftA2 (<span class="op">&gt;</span>) numSparks getNumCapabilities))</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a><span class="ot">treeFoldAdaptive ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> a</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>treeFoldAdaptive f <span class="ot">=</span></span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>    Lazy.treeFold</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>        (\l r <span class="ot">-&gt;</span></span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>              r <span class="ot">`parseq`</span> (l <span class="ot">`parseq`</span> f l r))</span></code></pre></div>
<p>Adapted from <a
href="https://www.reddit.com/r/haskell/comments/73umrw/another_parallelism_primitive_parseq/dnurduu/?utm_content=permalink&amp;utm_medium=front&amp;utm_source=reddit&amp;utm_name=haskell">this</a>
comment by Edward Kmett. This is actually the fastest version of all the
folds.</p>
<p>All of this is provided in a <a
href="https://hackage.haskell.org/package/treefold">library</a> I’ve put
up on Hackage.</p>
]]></description>
    <pubDate>Mon, 30 Oct 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-10-30-balancing-folds.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Convolutions and Semirings</title>
    <link>https://doisinkidney.com/posts/2017-10-13-convolutions-and-semirings.html</link>
    <description><![CDATA[<div class="info">
    Posted on October 13, 2017
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Semirings&#39;." href="/tags/Semirings.html" rel="tag">Semirings</a>
    
</div>

<p>I have been working a little more on my <a
href="https://hackage.haskell.org/package/semiring-num">semirings
library</a> recently, and I have come across some interesting functions
in the process. First, a quick recap on the <code
class="sourceCode haskell"><span class="dt">Semiring</span></code> class
and some related functions:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Semiring</span> a <span class="kw">where</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  one ::</span> a</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  zero ::</span> a</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">infixl</span> <span class="dv">6</span> <span class="op">&lt;+&gt;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;+&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">infixl</span> <span class="dv">7</span> <span class="op">&lt;.&gt;</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;.&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Semiring</span> a) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> a</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>add <span class="ot">=</span> foldl&#39; (<span class="op">&lt;+&gt;</span>) zero</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="ot">mul ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Semiring</span> a) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> a</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>mul <span class="ot">=</span> foldl&#39; (<span class="op">&lt;.&gt;</span>) one</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">Integer</span> <span class="kw">where</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> (<span class="op">+</span>)</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> (<span class="op">*</span>)</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">Bool</span> <span class="kw">where</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> (<span class="op">||</span>)</span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> (<span class="op">&amp;&amp;</span>)</span></code></pre></div>
<p>You can think of it as a replacement for <code
class="sourceCode haskell"><span class="dt">Num</span></code>, but it
turns out to be much more generally useful than that.</p>
<h1 id="matrix-multiplication">Matrix Multiplication</h1>
<p>The first interesting function is to do with matrix multiplication.
Here’s the code for multiplying two matrices represented as nested
lists:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mulMatrix ::</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span> [[a]] <span class="ot">-&gt;</span> [[a]] <span class="ot">-&gt;</span> [[a]]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>mulMatrix xs ys <span class="ot">=</span> <span class="fu">map</span> (\row <span class="ot">-&gt;</span> <span class="fu">map</span> (add <span class="op">.</span> <span class="fu">zipWith</span> (<span class="op">&lt;.&gt;</span>) row) cs) xs</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    cs <span class="ot">=</span> transpose ys</span></code></pre></div>
<p>One of the issues with this code (other than its woeful performance)
is that it seems needlessly list-specific. <code
class="sourceCode haskell"><span class="fu">zipWith</span></code> seems
like the kind of thing that exists on a bunch of different structures.
Indeed, the <a
href="https://hackage.haskell.org/package/base-4.10.0.0/docs/Control-Applicative.html#t:ZipList"><code
class="sourceCode haskell"><span class="dt">ZipList</span></code>
wrapper</a> uses <code
class="sourceCode haskell"><span class="fu">zipWith</span></code> as its
<code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>
implementation. Let’s try that for now:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mulMatrix ::</span> (<span class="dt">Semiring</span> a, <span class="dt">Applicative</span> f) <span class="ot">=&gt;</span> f (f a) <span class="ot">-&gt;</span> f (f a) <span class="ot">-&gt;</span> f (f a)</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>mulMatrix xs ys <span class="ot">=</span> <span class="fu">fmap</span> (\row <span class="ot">-&gt;</span> <span class="fu">fmap</span> (add <span class="op">.</span> liftA2 (<span class="op">&lt;.&gt;</span>) row) cs) xs</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    cs <span class="ot">=</span> transpose ys</span></code></pre></div>
<p>Of course, now <code class="sourceCode haskell">add</code> needs to
work on our <code class="sourceCode haskell">f</code>, so it should be
<code
class="sourceCode haskell"><span class="dt">Foldable</span></code></p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>mulMatrix</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  ::</span> (<span class="dt">Semiring</span> a, <span class="dt">Applicative</span> f, <span class="dt">Foldable</span> f)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=&gt;</span> f (f a) <span class="ot">-&gt;</span> f (f a) <span class="ot">-&gt;</span> f (f a)</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>mulMatrix <span class="ot">=</span> <span class="op">...</span></span></code></pre></div>
<p><code class="sourceCode haskell">transpose</code> is the missing
piece now. A little bit of <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
magic can help us out again, though: <code
class="sourceCode haskell"><span class="fu">sequenceA</span></code> is
<code class="sourceCode haskell">transpose</code> on <code
class="sourceCode haskell"><span class="dt">ZipList</span></code>s <span
class="citation" data-cites="mcbride_applicative_2008">(<a
href="#ref-mcbride_applicative_2008" role="doc-biblioref">McBride and
Paterson 2008</a>)</span>.</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>mulMatrix</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  ::</span> (<span class="dt">Semiring</span> a, <span class="dt">Applicative</span> f, <span class="dt">Traversable</span> f)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=&gt;</span> f (f a) <span class="ot">-&gt;</span> f (f a) <span class="ot">-&gt;</span> f (f a)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>mulMatrix xs ys <span class="ot">=</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> (\row <span class="ot">-&gt;</span> <span class="fu">fmap</span> (add <span class="op">.</span> liftA2 (<span class="op">&lt;.&gt;</span>) row) cs) xs</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    cs <span class="ot">=</span> <span class="fu">sequenceA</span> ys</span></code></pre></div>
<p>One further generalization: The two <code
class="sourceCode haskell">f</code>s don’t actually need to be the
same:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>mulMatrix</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Applicative</span> n</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>       ,<span class="dt">Traversable</span> m</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>       ,<span class="dt">Applicative</span> m</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>       ,<span class="dt">Applicative</span> p</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>       ,<span class="dt">Semiring</span> a)</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> n (m a) <span class="ot">-&gt;</span> m (p a) <span class="ot">-&gt;</span> n (p a)</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>mulMatrix xs ys <span class="ot">=</span> <span class="fu">fmap</span> (\row <span class="ot">-&gt;</span> <span class="fu">fmap</span> (add <span class="op">.</span> liftA2 (<span class="op">&lt;.&gt;</span>) row) cs) xs</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>    cs <span class="ot">=</span> <span class="fu">sequenceA</span> ys</span></code></pre></div>
<p>Happily, the way that the wrappers (<code
class="sourceCode haskell">n</code>, <code
class="sourceCode haskell">m</code>, and <code
class="sourceCode haskell">p</code>) match up coincides precisely with
how matrix dimensions match up in matrix multiplication. Quoting from
the <a
href="https://en.wikipedia.org/wiki/Matrix_multiplication">Wikipedia
definition</a>:</p>
<blockquote>
<p>if
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>A</mi><annotation encoding="application/x-tex">A</annotation></semantics></math>
is an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>×</mo><mi>m</mi></mrow><annotation encoding="application/x-tex">n \times m</annotation></semantics></math>
matrix and
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>B</mi><annotation encoding="application/x-tex">B</annotation></semantics></math>
is an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>m</mi><mo>×</mo><mi>p</mi></mrow><annotation encoding="application/x-tex">m \times p</annotation></semantics></math>
matrix, their matrix product
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>A</mi><mi>B</mi></mrow><annotation encoding="application/x-tex">AB</annotation></semantics></math>
is an
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>n</mi><mo>×</mo><mi>p</mi></mrow><annotation encoding="application/x-tex">n \times p</annotation></semantics></math>
matrix</p>
</blockquote>
<p>This function is present in the <a
href="https://hackage.haskell.org/package/linear-1.20.7/docs/Linear-Matrix.html#v:-33--42--33-">linear
package</a> with some different constraints. In fairness, <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
probably isn’t the best thing to use here since it doesn’t work for so
many instances (<a
href="https://hackage.haskell.org/package/base-4.10.0.0/docs/Control-Monad-Zip.html"><code
class="sourceCode haskell"><span class="dt">MonadZip</span></code></a>
or something similar may be more suitable), but it’s very handy to have,
and works out-of the box for types like:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Three</span> a</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Three</span> a a a</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> (<span class="dt">Functor</span>, <span class="dt">Foldable</span>, <span class="dt">Traversable</span>, <span class="dt">Eq</span>, <span class="dt">Ord</span>, <span class="dt">Show</span>)</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Three</span> <span class="kw">where</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Three</span> x x x</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Three</span> fx fy fz <span class="op">&lt;*&gt;</span> <span class="dt">Three</span> xx xy xz <span class="ot">=</span> <span class="dt">Three</span> (fx xx) (fy xy) (fz xz)</span></code></pre></div>
<p>Which makes it (to my mind) useful enough to keep. Also, it hugely
simplified the code for <a
href="https://github.com/oisdk/Square/blob/master/src/Data/Square.hs#L183">matrix
multiplication in square matrices</a> I had, from <span class="citation"
data-cites="okasaki_fast_1999">Okasaki (<a href="#ref-okasaki_fast_1999"
role="doc-biblioref">1999</a>)</span>.</p>
<h1 id="convolutions">Convolutions</h1>
<p>If you’re putting a general class in a library that you want people
to use, and there exist sensible instances for common Haskell types, you
should probably provide those instances in the library to avoid orphans.
The meaning of “sensible” here is vague: generally speaking, if there is
only one obvious or clear instance, then it’s sensible. For a list
instance for the semiring class, for instance, I could figure out
several law-abiding definitions for <code
class="sourceCode haskell"><span class="op">&lt;+&gt;</span></code>,
<code class="sourceCode haskell">one</code> and <code
class="sourceCode haskell">zero</code>, but only one for <code
class="sourceCode haskell"><span class="op">&lt;.&gt;</span></code>:
polynomial multiplication. You know, where you multiply two polynomials
like so:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><msup><mi>x</mi><mn>3</mn></msup><mo>+</mo><mn>2</mn><mi>x</mi><mo>+</mo><mn>3</mn><mo stretchy="false" form="postfix">)</mo><mo stretchy="false" form="prefix">(</mo><mn>5</mn><mi>x</mi><mo>+</mo><mn>3</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>4</mn><mo stretchy="false" form="postfix">)</mo><mo>=</mo><mn>9</mn><msup><mi>x</mi><mn>5</mn></msup><mo>+</mo><mn>15</mn><msup><mi>x</mi><mn>4</mn></msup><mo>+</mo><mn>18</mn><msup><mi>x</mi><mn>3</mn></msup><mo>+</mo><mn>28</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>38</mn><mi>x</mi><mo>+</mo><mn>24</mn></mrow><annotation encoding="application/x-tex">(x^3 + 2x + 3)(5x + 3x^2 + 4) = 9x^5 + 15x^4 + 18x^3 + 28x^2 + 38x + 24</annotation></semantics></math></p>
<p>A more general definition looks something like this:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><msub><mi>a</mi><mn>0</mn></msub><msup><mi>x</mi><mn>0</mn></msup><mo>+</mo><msub><mi>a</mi><mn>1</mn></msub><msup><mi>x</mi><mn>1</mn></msup><mo>+</mo><msub><mi>a</mi><mn>2</mn></msub><msup><mi>x</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo><mo stretchy="false" form="prefix">(</mo><msub><mi>b</mi><mn>0</mn></msub><msup><mi>x</mi><mn>0</mn></msup><mo>+</mo><msub><mi>b</mi><mn>1</mn></msub><msup><mi>x</mi><mn>1</mn></msup><mo>+</mo><msub><mi>b</mi><mn>2</mn></msub><msup><mi>x</mi><mn>2</mn></msup><mo stretchy="false" form="postfix">)</mo><mo>=</mo></mrow><annotation encoding="application/x-tex">(a_0x^0 + a_1x^1 + a_2x^2)(b_0x^0 + b_1x^1 + b_2x^2) =</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>a</mi><mn>0</mn></msub><msub><mi>b</mi><mn>0</mn></msub><msup><mi>x</mi><mn>0</mn></msup><mo>+</mo><mo stretchy="false" form="prefix">(</mo><msub><mi>a</mi><mn>0</mn></msub><msub><mi>b</mi><mn>1</mn></msub><mo>+</mo><msub><mi>a</mi><mn>1</mn></msub><msub><mi>b</mi><mn>0</mn></msub><mo stretchy="false" form="postfix">)</mo><msup><mi>x</mi><mn>1</mn></msup><mo>+</mo><mo stretchy="false" form="prefix">(</mo><msub><mi>a</mi><mn>0</mn></msub><msub><mi>b</mi><mn>2</mn></msub><mo>+</mo><msub><mi>a</mi><mn>1</mn></msub><msub><mi>b</mi><mn>1</mn></msub><mo>+</mo><msub><mi>a</mi><mn>2</mn></msub><msub><mi>b</mi><mn>0</mn></msub><mo stretchy="false" form="postfix">)</mo><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mo stretchy="false" form="prefix">(</mo><msub><mi>a</mi><mn>1</mn></msub><msub><mi>b</mi><mn>2</mn></msub><mo>+</mo><msub><mi>a</mi><mn>2</mn></msub><msub><mi>b</mi><mn>1</mn></msub><mo stretchy="false" form="postfix">)</mo><msup><mi>x</mi><mn>3</mn></msup><mo>+</mo><msub><mi>a</mi><mn>2</mn></msub><msub><mi>b</mi><mn>2</mn></msub><msup><mi>x</mi><mn>4</mn></msup></mrow><annotation encoding="application/x-tex">a_0b_0x^0 + (a_0b_1 + a_1b_0)x^1 + (a_0b_2 + a_1b_1 + a_2b_0)x^2 + (a_1b_2 + a_2b_1)x^3 + a_2b_2x^4</annotation></semantics></math></p>
<p>Or, fully generalized:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>c</mi><mi>k</mi></msub><mo>=</mo><msub><mi>a</mi><mn>0</mn></msub><msub><mi>b</mi><mi>k</mi></msub><mo>+</mo><msub><mi>a</mi><mn>1</mn></msub><msub><mi>b</mi><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></msub><mo>+</mo><mi>…</mi><mo>+</mo><msub><mi>a</mi><mrow><mi>k</mi><mo>−</mo><mn>1</mn></mrow></msub><msub><mi>b</mi><mn>1</mn></msub><mo>+</mo><msub><mi>a</mi><mi>k</mi></msub><msub><mi>b</mi><mn>0</mn></msub></mrow><annotation encoding="application/x-tex">c_k = a_0b_k + a_1b_{k-1} + \ldots + a_{k-1}b_1 + a_kb_0</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>f</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo stretchy="false" form="postfix">)</mo><mo>×</mo><mi>g</mi><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo stretchy="false" form="postfix">)</mo><mo>=</mo><munderover><mo>∑</mo><mrow><mi>i</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>n</mi><mo>+</mo><mi>m</mi></mrow></munderover><msub><mi>c</mi><mi>i</mi></msub><msup><mi>x</mi><mi>i</mi></msup></mrow><annotation encoding="application/x-tex">f(x) \times g(x) = \sum_{i=0}^{n+m}c_ix^i</annotation></semantics></math></p>
<p>So it turns out that you can represent polynomials pretty elegantly
as lists. Take an example from above:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msup><mi>x</mi><mn>3</mn></msup><mo>+</mo><mn>2</mn><mi>x</mi><mo>+</mo><mn>3</mn></mrow><annotation encoding="application/x-tex">x^3 + 2x + 3</annotation></semantics></math></p>
<p>And rearrange it in order of the powers of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>x</mi><annotation encoding="application/x-tex">x</annotation></semantics></math>:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn><msup><mi>x</mi><mn>0</mn></msup><mo>+</mo><mn>2</mn><msup><mi>x</mi><mn>1</mn></msup><mo>+</mo><msup><mi>x</mi><mn>3</mn></msup></mrow><annotation encoding="application/x-tex">3x^0 + 2x^1 + x^3</annotation></semantics></math></p>
<p>And fill in missing coefficients:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>3</mn><msup><mi>x</mi><mn>0</mn></msup><mo>+</mo><mn>2</mn><msup><mi>x</mi><mn>1</mn></msup><mo>+</mo><mn>0</mn><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><mn>1</mn><msup><mi>x</mi><mn>3</mn></msup></mrow><annotation encoding="application/x-tex">3x^0 + 2x^1 + 0x^2 + 1x^3</annotation></semantics></math></p>
<p>And then the list representation of that polynomial is the list of
those coefficients:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>[<span class="dv">3</span>, <span class="dv">2</span>, <span class="dv">0</span>, <span class="dv">1</span>]</span></code></pre></div>
<p>For me, the definitions of multiplication above were pretty hard to
understand. In Haskell, however, the definition is quite beautiful:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span> <span class="dt">Semiring</span> [a] <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> [one]</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> []</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  [] <span class="op">&lt;+&gt;</span> ys <span class="ot">=</span> ys</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">&lt;+&gt;</span> [] <span class="ot">=</span> xs</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  (x<span class="op">:</span>xs) <span class="op">&lt;+&gt;</span> (y<span class="op">:</span>ys) <span class="ot">=</span> x <span class="op">&lt;+&gt;</span> y <span class="op">:</span> (xs <span class="op">&lt;+&gt;</span> ys)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  _ <span class="op">&lt;.&gt;</span> [] <span class="ot">=</span> []</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  [] <span class="op">&lt;.&gt;</span> _ <span class="ot">=</span> []</span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>  (x<span class="op">:</span>xs) <span class="op">&lt;.&gt;</span> (y<span class="op">:</span>ys) <span class="ot">=</span> (x<span class="op">&lt;.&gt;</span>y) <span class="op">:</span> <span class="fu">map</span> (x<span class="op">&lt;.&gt;</span>) ys <span class="op">&lt;+&gt;</span> xs <span class="op">&lt;.&gt;</span> (y<span class="op">:</span>ys)</span></code></pre></div>
<p>This definition for <code
class="sourceCode haskell"><span class="op">&lt;.&gt;</span></code> can
be found on page 4 of <span class="citation"
data-cites="mcilroy_power_1999">McIlroy (<a
href="#ref-mcilroy_power_1999" role="doc-biblioref">1999</a>)</span>.
Although there was a version of the paper with a slightly different
definition:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>_ <span class="op">&lt;.&gt;</span> [] <span class="ot">=</span> []</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>[] <span class="op">&lt;.&gt;</span> _ <span class="ot">=</span> []</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>(x<span class="op">:</span>xs) <span class="op">&lt;.&gt;</span> (y<span class="op">:</span>ys)</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> (x<span class="op">&lt;.&gt;</span>y) <span class="op">:</span> (<span class="fu">map</span> (x<span class="op">&lt;.&gt;</span>) ys <span class="op">&lt;+&gt;</span> <span class="fu">map</span> (<span class="op">&lt;.&gt;</span>y) xs <span class="op">&lt;+&gt;</span> (zero <span class="op">:</span> (xs <span class="op">&lt;.&gt;</span> ys)))</span></code></pre></div>
<p>Similar to one which appeared in <span class="citation"
data-cites="dolan_fun_2013">Dolan (<a href="#ref-dolan_fun_2013"
role="doc-biblioref">2013</a>)</span>.</p>
<p>As it happens, I prefer the first definition. It’s shorter, and I
figured out how to write it as a fold:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>_ <span class="op">&lt;.&gt;</span> [] <span class="ot">=</span> []</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>xs <span class="op">&lt;.&gt;</span> ys <span class="ot">=</span> <span class="fu">foldr</span> f [] xs <span class="kw">where</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  f x zs <span class="ot">=</span> <span class="fu">map</span> (x <span class="op">&lt;.&gt;</span>) ys <span class="op">&lt;+&gt;</span> (zero <span class="op">:</span> zs)</span></code></pre></div>
<p>And if you inline the <code
class="sourceCode haskell"><span class="op">&lt;+&gt;</span></code>, you
get a reasonable speedup:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>xs <span class="op">&lt;.&gt;</span> ys <span class="ot">=</span> <span class="fu">foldr</span> f [] xs</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    f x zs <span class="ot">=</span> <span class="fu">foldr</span> (g x) <span class="fu">id</span> ys (zero <span class="op">:</span> zs)</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    g x y a (z<span class="op">:</span>zs) <span class="ot">=</span> x <span class="op">&lt;.&gt;</span> y <span class="op">&lt;+&gt;</span> z <span class="op">:</span> a zs</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    g x y a [] <span class="ot">=</span> x <span class="op">&lt;.&gt;</span> y <span class="op">:</span> a []</span></code></pre></div>
<p>The definition of <code
class="sourceCode haskell"><span class="op">&lt;+&gt;</span></code> can
also use a fold on either side for fusion purposes:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> <span class="fu">foldr</span> f <span class="fu">id</span> <span class="kw">where</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  f x xs (y<span class="op">:</span>ys) <span class="ot">=</span> x <span class="op">&lt;+&gt;</span> y <span class="op">:</span> xs ys</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  f x xs [] <span class="ot">=</span> x <span class="op">:</span> xs []</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> <span class="fu">flip</span> (<span class="fu">foldr</span> f <span class="fu">id</span>) <span class="kw">where</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  f y ys (x<span class="op">:</span>xs) <span class="ot">=</span> x <span class="op">&lt;+&gt;</span> y <span class="op">:</span> ys xs</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>  f y ys [] <span class="ot">=</span> y <span class="op">:</span> ys []</span></code></pre></div>
<p>There are rules in the library to choose one of the above definitions
if fusion is available.</p>
<p>This definition is much more widely useful than it may seem at first.
Say, for instance, you wanted to search through pairs of things from two
infinite lists. You can’t use the normal way to pair things for lists,
the Cartesian product, because it will diverge:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>[(x,y) <span class="op">|</span> x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>], y <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>]]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9),(1,10)...</span></span></code></pre></div>
<p>You’ll never get beyond 1 in the first list. Zipping isn’t an option
either, because you won’t really explore the search space, only
corresponding pairs. <a
href="https://byorgey.wordpress.com/2008/04/22/list-convolutions/">Brent
Yorgey showed</a> that if you want a list like this:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>[(y,x<span class="op">-</span>y) <span class="op">|</span> x <span class="ot">&lt;-</span> [<span class="dv">0</span><span class="op">..</span>], y <span class="ot">&lt;-</span> [<span class="dv">0</span><span class="op">..</span>x] ]</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- [(0,0),(0,1),(1,0),(0,2),(1,1),(2,0),(0,3),(1,2),(2,1),(3,0)...</span></span></code></pre></div>
<p>Then what you’re looking for is a convolution (the same thing as
polynomial multiplication). <code
class="sourceCode haskell"><span class="op">&lt;.&gt;</span></code>
above can be adapted readily:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">convolve ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [[(a,b)]]</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>convolve xs ys <span class="ot">=</span> <span class="fu">foldr</span> f [] xs</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    f x zs <span class="ot">=</span> <span class="fu">foldr</span> (g x) <span class="fu">id</span> ys ([] <span class="op">:</span> zs)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>    g x y a (z<span class="op">:</span>zs) <span class="ot">=</span> ((x, y) <span class="op">:</span> z) <span class="op">:</span> a zs</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>    g x y a [] <span class="ot">=</span> [(x, y)] <span class="op">:</span> a []</span></code></pre></div>
<p>Flatten out this result to get your ordering. This convolution is a
little different from the one in the blog post. By inlining <code
class="sourceCode haskell"><span class="op">&lt;+&gt;</span></code> we
can avoid the expensive <code
class="sourceCode haskell"><span class="op">++</span></code> function,
without using difference lists.</p>
<h1 id="long-multiplication">Long Multiplication</h1>
<p>Here’s another cool use of lists as polynomials: they can be used as
a <a href="https://en.Wikipedia.org/wiki/Positional_notation">positional
numeral system</a>. Most common numeral systems are positional,
including Arabic (the system you most likely use, where twenty-four is
written as 24) and binary. Non-positional systems are things like Roman
numerals. Looking at the Arabic system for now, we see that the way of
writing down numbers:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mn>1989</mn><annotation encoding="application/x-tex">1989</annotation></semantics></math></p>
<p>Can be thought of as the sum of each digit multiplied by ten to the
power of its position:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1989</mn><mo>=</mo><mn>1</mn><mo>×</mo><msup><mn>10</mn><mn>3</mn></msup><mo>+</mo><mn>9</mn><mo>×</mo><msup><mn>10</mn><mn>2</mn></msup><mo>+</mo><mn>8</mn><mo>×</mo><msup><mn>10</mn><mn>1</mn></msup><mo>+</mo><mn>9</mn><mo>×</mo><msup><mn>10</mn><mn>0</mn></msup></mrow><annotation encoding="application/x-tex">1989 = 1 \times 10^3 \plus 9 \times 10^2 \plus 8 \times 10^1 \plus 9 \times 10^0</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1989</mn><mo>=</mo><mn>1</mn><mo>×</mo><mn>1000</mn><mo>+</mo><mn>9</mn><mo>×</mo><mn>100</mn><mo>+</mo><mn>8</mn><mo>×</mo><mn>10</mn><mo>+</mo><mn>9</mn><mo>×</mo><mn>1</mn></mrow><annotation encoding="application/x-tex">1989 = 1 \times 1000 \plus 9 \times 100 \plus 8 \times 10 \plus 9 \times 1</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1989</mn><mo>=</mo><mn>1000</mn><mo>+</mo><mn>900</mn><mo>+</mo><mn>80</mn><mo>+</mo><mn>9</mn></mrow><annotation encoding="application/x-tex">1989 = 1000 \plus 900 \plus 80 \plus 9</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>1989</mn><mo>=</mo><mn>1989</mn></mrow><annotation encoding="application/x-tex">1989 = 1989</annotation></semantics></math></p>
<p>Where the positions are numbered from the right. In other words, it’s
our polynomial list from above in reverse. As well as that, the
convolution is long multiplication.</p>
<p>Now, taking this straight off we can try some examples:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- 12 + 15 = 27</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span>, <span class="dv">1</span>] <span class="op">&lt;+&gt;</span> [<span class="dv">5</span>, <span class="dv">1</span>] <span class="op">==</span> [<span class="dv">7</span>, <span class="dv">2</span>]</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="co">-- 23 * 2 = 46</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>[<span class="dv">3</span>, <span class="dv">2</span>] <span class="op">&lt;.&gt;</span> [<span class="dv">2</span>] <span class="op">==</span> [<span class="dv">6</span>, <span class="dv">4</span>]</span></code></pre></div>
<p>The issue, of course, is that we’re not handling carrying
properly:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>[<span class="dv">6</span>] <span class="op">&lt;+&gt;</span> [<span class="dv">6</span>] <span class="op">==</span> [<span class="dv">12</span>]</span></code></pre></div>
<p>No matter: we can perform all the carries after the addition, and
everything works out fine:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>carry</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Integral</span> a</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>carry base xs <span class="ot">=</span> <span class="fu">foldr</span> f (toBase base) xs <span class="dv">0</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>    f e a cin <span class="ot">=</span> r <span class="op">:</span> a q <span class="kw">where</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>      (q,r) <span class="ot">=</span> <span class="fu">quotRem</span> (cin <span class="op">+</span> e) base</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a><span class="ot">toBase ::</span> <span class="dt">Integral</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>toBase base <span class="ot">=</span> unfoldr f <span class="kw">where</span></span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a>  f <span class="dv">0</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a>  f n <span class="ot">=</span> <span class="dt">Just</span> (swap (<span class="fu">quotRem</span> n base))</span></code></pre></div>
<p>Wrap the whole thing in a newtype and we can have a <code
class="sourceCode haskell"><span class="dt">Num</span></code>
instance:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Positional</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Positional</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> withBase ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> [<span class="dt">Integer</span>]</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Positional</span> <span class="kw">where</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Positional</span> x <span class="op">+</span> <span class="dt">Positional</span> y <span class="ot">=</span> <span class="dt">Positional</span> (carry <span class="op">&lt;*&gt;</span> x <span class="op">&lt;+&gt;</span> y)</span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Positional</span> x <span class="op">*</span> <span class="dt">Positional</span> y <span class="ot">=</span> <span class="dt">Positional</span> (carry <span class="op">&lt;*&gt;</span> x <span class="op">&lt;.&gt;</span> y)</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fromInteger</span> m <span class="ot">=</span> <span class="dt">Positional</span> (\base <span class="ot">-&gt;</span> toBase base m)</span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">abs</span> <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">signum</span> <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a>  <span class="fu">negate</span> <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a><span class="ot">toDigits ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Positional</span> <span class="ot">-&gt;</span> [<span class="dt">Integer</span>]</span>
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a>toDigits base p <span class="ot">=</span> <span class="fu">reverse</span> (withBase p base)</span></code></pre></div>
<p>This also lets us choose our base after the fact:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>sumHundred <span class="ot">=</span> (<span class="fu">sum</span> <span class="op">.</span> <span class="fu">map</span> <span class="fu">fromInteger</span>) [<span class="dv">1</span><span class="op">..</span><span class="dv">100</span>]</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>toDigits <span class="dv">10</span> sumHundred</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- [5,0,5,0]</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>toDigits <span class="dv">2</span> sumHundred</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- [1,0,0,1,1,1,0,1,1,1,0,1,0]</span></span></code></pre></div>
<h1 id="vectors">Vectors</h1>
<p>All the hand-optimizing, inlining, and fusion magic in the world
won’t make a list-based implementation of convolution faster than a
proper one on vectors, unfortunately. In particular, for larger vectors,
a fast Fourier transform can be used. Also, usually code like this will
be parallelized, rather than sequential. That said, it can be helpful to
implement the slower version on vectors, in the usual indexed way, for
comparison’s sake:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Semiring</span> (<span class="dt">Vector</span> a) <span class="kw">where</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    one <span class="ot">=</span> Vector.singleton one</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>    zero <span class="ot">=</span> Vector.empty</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>    xs <span class="op">&lt;+&gt;</span> ys <span class="ot">=</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>        <span class="kw">case</span> <span class="fu">compare</span> (Vector.length xs) (Vector.length ys) <span class="kw">of</span></span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>            <span class="dt">EQ</span> <span class="ot">-&gt;</span> Vector.zipWith (<span class="op">&lt;+&gt;</span>) xs ys</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>            <span class="dt">LT</span> <span class="ot">-&gt;</span> Vector.unsafeAccumulate (<span class="op">&lt;+&gt;</span>) ys (Vector.indexed xs)</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>            <span class="dt">GT</span> <span class="ot">-&gt;</span> Vector.unsafeAccumulate (<span class="op">&lt;+&gt;</span>) xs (Vector.indexed ys)</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>    signal <span class="op">&lt;.&gt;</span> kernel</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> Vector.null signal <span class="ot">=</span> Vector.empty</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> Vector.null kernel <span class="ot">=</span> Vector.empty</span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> Vector.generate (slen <span class="op">+</span> klen <span class="op">-</span> <span class="dv">1</span>) f</span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a>        f n <span class="ot">=</span></span>
<span id="cb22-16"><a href="#cb22-16" aria-hidden="true" tabindex="-1"></a>            foldl&#39;</span>
<span id="cb22-17"><a href="#cb22-17" aria-hidden="true" tabindex="-1"></a>                (\a k <span class="ot">-&gt;</span></span>
<span id="cb22-18"><a href="#cb22-18" aria-hidden="true" tabindex="-1"></a>                      a <span class="op">&lt;+&gt;</span></span>
<span id="cb22-19"><a href="#cb22-19" aria-hidden="true" tabindex="-1"></a>                      Vector.unsafeIndex signal k <span class="op">&lt;.&gt;</span></span>
<span id="cb22-20"><a href="#cb22-20" aria-hidden="true" tabindex="-1"></a>                      Vector.unsafeIndex kernel (n <span class="op">-</span> k))</span>
<span id="cb22-21"><a href="#cb22-21" aria-hidden="true" tabindex="-1"></a>                zero</span>
<span id="cb22-22"><a href="#cb22-22" aria-hidden="true" tabindex="-1"></a>                [kmin <span class="op">..</span> kmax]</span>
<span id="cb22-23"><a href="#cb22-23" aria-hidden="true" tabindex="-1"></a>          <span class="kw">where</span></span>
<span id="cb22-24"><a href="#cb22-24" aria-hidden="true" tabindex="-1"></a>            <span class="op">!</span>kmin <span class="ot">=</span> <span class="fu">max</span> <span class="dv">0</span> (n <span class="op">-</span> (klen <span class="op">-</span> <span class="dv">1</span>))</span>
<span id="cb22-25"><a href="#cb22-25" aria-hidden="true" tabindex="-1"></a>            <span class="op">!</span>kmax <span class="ot">=</span> <span class="fu">min</span> n (slen <span class="op">-</span> <span class="dv">1</span>)</span>
<span id="cb22-26"><a href="#cb22-26" aria-hidden="true" tabindex="-1"></a>        <span class="op">!</span>slen <span class="ot">=</span> Vector.length signal</span>
<span id="cb22-27"><a href="#cb22-27" aria-hidden="true" tabindex="-1"></a>        <span class="op">!</span>klen <span class="ot">=</span> Vector.length kernel</span></code></pre></div>
<h1 id="search">Search</h1>
<p>As has been observed before <span class="citation"
data-cites="rivas_monoids_2015">(<a href="#ref-rivas_monoids_2015"
role="doc-biblioref">Rivas, Jaskelioff, and Schrijvers 2015</a>)</span>
there’s a pretty suggestive similarity between semirings and the <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>/<code
class="sourceCode haskell"><span class="dt">Alternative</span></code>
classes in Haskell:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Semiring</span> a <span class="kw">where</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  one ::</span> a</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  zero ::</span> a</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;+&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;.&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Applicative</span> f <span class="kw">where</span></span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a><span class="ot">  pure ::</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;*&gt;) ::</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Alternative</span> f <span class="kw">where</span></span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a><span class="ot">  empty ::</span> f a</span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;|&gt;) ::</span> f a <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f a</span></code></pre></div>
<p>So can our implementation of convolution be used to implement the
methods for these classes? Partially:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Search</span> f a <span class="ot">=</span> <span class="dt">Search</span> {<span class="ot"> runSearch ::</span> [f a] }</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Functor</span> (<span class="dt">Search</span> f) <span class="kw">where</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Search</span> xs) <span class="ot">=</span> <span class="dt">Search</span> ((<span class="fu">fmap</span><span class="op">.</span><span class="fu">fmap</span>) f xs)</span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Search</span> f) <span class="kw">where</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Search</span> [<span class="fu">pure</span> x]</span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>  _ <span class="op">&lt;*&gt;</span> <span class="dt">Search</span> [] <span class="ot">=</span> <span class="dt">Search</span> []</span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Search</span> xs <span class="op">&lt;*&gt;</span> <span class="dt">Search</span> ys <span class="ot">=</span> <span class="dt">Search</span> (<span class="fu">foldr</span> f [] xs) <span class="kw">where</span></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>    f x zs <span class="ot">=</span> <span class="fu">foldr</span> (g x) <span class="fu">id</span> ys (empty <span class="op">:</span> zs)</span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a>    g x y a (z<span class="op">:</span>zs) <span class="ot">=</span> (x <span class="op">&lt;*&gt;</span> y <span class="op">&lt;|&gt;</span> z) <span class="op">:</span> a zs</span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a>    g x y a [] <span class="ot">=</span> (x <span class="op">&lt;*&gt;</span> y) <span class="op">:</span> a []</span>
<span id="cb24-13"><a href="#cb24-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-14"><a href="#cb24-14" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> <span class="dt">Alternative</span> (<span class="dt">Search</span> f) <span class="kw">where</span></span>
<span id="cb24-15"><a href="#cb24-15" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Search</span> xs <span class="op">&lt;|&gt;</span> <span class="dt">Search</span> ys <span class="ot">=</span> <span class="dt">Search</span> (go xs ys) <span class="kw">where</span></span>
<span id="cb24-16"><a href="#cb24-16" aria-hidden="true" tabindex="-1"></a>    go [] ys <span class="ot">=</span> ys</span>
<span id="cb24-17"><a href="#cb24-17" aria-hidden="true" tabindex="-1"></a>    go xs [] <span class="ot">=</span> xs</span>
<span id="cb24-18"><a href="#cb24-18" aria-hidden="true" tabindex="-1"></a>    go (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> (x <span class="op">&lt;|&gt;</span> y) <span class="op">:</span> go xs ys</span>
<span id="cb24-19"><a href="#cb24-19" aria-hidden="true" tabindex="-1"></a>  empty <span class="ot">=</span> <span class="dt">Search</span> []</span></code></pre></div>
<p>At first, this seems perfect: the types all match up, and the
definitions seem sensible. The issue is with the laws: <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
and <code
class="sourceCode haskell"><span class="dt">Alternative</span></code>
are missing <em>four</em> that semirings require. In particular:
commutativity of plus, annihilation by zero, and distributivity left and
right:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>xs <span class="op">&lt;|&gt;</span> ys <span class="ot">=</span> ys <span class="op">&lt;|&gt;</span> xs</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>empty <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> fs <span class="op">&lt;*&gt;</span> empty <span class="ot">=</span> empty</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>fs <span class="op">&lt;*&gt;</span> (xs <span class="op">&lt;|&gt;</span> ys) <span class="ot">=</span> fs <span class="op">&lt;*&gt;</span> xs <span class="op">&lt;|&gt;</span> fs <span class="op">&lt;*&gt;</span> ys</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>(fs <span class="op">&lt;|&gt;</span> gs) <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> fs <span class="op">&lt;*&gt;</span> xs <span class="op">&lt;|&gt;</span> gs <span class="op">&lt;*&gt;</span> ys</span></code></pre></div>
<p>The vast majority of the instances of <code
class="sourceCode haskell"><span class="dt">Alternative</span></code>
today fail one or more of these laws. Taking lists as an example, <code
class="sourceCode haskell"><span class="op">++</span></code> obviously
isn’t commutative, and <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code> only
distributes when it’s on the right.</p>
<p>What’s the problem, though? Polynomial multiplication follows
<em>more</em> laws than those required by <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>:
why should that worry us? Unfortunately, in order for multiplication to
follow those laws, it actually relies on the underlying semiring being
law-abiding. And it <em>fails</em> the applicative laws when it
isn’t.</p>
<p>There are two angles from which we could come at this problem: either
we relax the semiring laws and try and make our implementation of
convolution rely on them as little as possible, or we find <code
class="sourceCode haskell"><span class="dt">Alternative</span></code>
instances which follow the semiring laws. Or we could meet in the
middle, relaxing the laws as much as possible until we find some <code
class="sourceCode haskell"><span class="dt">Alternative</span></code>s
that meet our standards.</p>
<p>This has actually been accomplished in several papers: the previously
mentioned <span class="citation" data-cites="rivas_monoids_2015">Rivas,
Jaskelioff, and Schrijvers (<a href="#ref-rivas_monoids_2015"
role="doc-biblioref">2015</a>)</span> discusses near-semirings, defined
as semiring-like structures with associativity, identity, and these two
laws:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mn>0</mn><mo>×</mo><mi>x</mi><mo>=</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">0 \times x = 0</annotation></semantics></math>
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>+</mo><mi>y</mi><mo stretchy="false" form="postfix">)</mo><mo>×</mo><mi>z</mi><mo>=</mo><mo stretchy="false" form="prefix">(</mo><mi>x</mi><mo>×</mo><mi>z</mi><mo stretchy="false" form="postfix">)</mo><mo>+</mo><mo stretchy="false" form="prefix">(</mo><mi>y</mi><mo>×</mo><mi>z</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">(x \plus y) \times z = (x \times z) \plus (y \times z)</annotation></semantics></math></p>
<p>In contrast to normal semirings, zero only annihilates when it’s on
the left, and multiplication only distributes over addition when it’s on
the right. Addition is not required to be commutative.</p>
<p>The lovely paper <span class="citation"
data-cites="spivey_algebras_2009">Spivey (<a
href="#ref-spivey_algebras_2009" role="doc-biblioref">2009</a>)</span>
has a similar concept: a “bunch”.</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Bunch</span> m <span class="kw">where</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  return ::</span> a <span class="ot">-&gt;</span> m a</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&gt;&gt;=) ::</span> m a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m b</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  zero ::</span> m a</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;|&gt;) ::</span> m a <span class="ot">-&gt;</span> m a <span class="ot">-&gt;</span> m a</span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a><span class="ot">  wrap ::</span> m a <span class="ot">-&gt;</span> m a</span></code></pre></div>
<p>The laws are all the same (with <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>
implemented in terms of <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code>),
and the extra <code class="sourceCode haskell">wrap</code> operation can
be expressed like so:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">wrap ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> <span class="dt">Search</span> f a <span class="ot">-&gt;</span> <span class="dt">Search</span> f a</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>wrap (<span class="dt">Search</span> xs) <span class="ot">=</span> <span class="dt">Search</span> (empty <span class="op">:</span> xs)</span></code></pre></div>
<p>A definition of <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code> for
our polynomials is also provided:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>[] <span class="op">&gt;&gt;=</span> _ <span class="ot">=</span> []</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>(x<span class="op">:</span>xs) <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">&lt;|&gt;</span>) empty (<span class="fu">fmap</span> f x) <span class="op">&lt;|&gt;</span> wrap (xs <span class="op">&gt;&gt;=</span> f)</span></code></pre></div>
<p>This will require the underlying <code
class="sourceCode haskell">f</code> to be <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>. We
can inline a little, and express the whole thing as a fold:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Foldable</span> f, <span class="dt">Alternative</span> f) <span class="ot">=&gt;</span> <span class="dt">Monad</span> (<span class="dt">Search</span> f) <span class="kw">where</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Search</span> xs <span class="op">&gt;&gt;=</span> k <span class="ot">=</span> <span class="fu">foldr</span> f empty xs <span class="kw">where</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    f e a <span class="ot">=</span> <span class="fu">foldr</span> ((<span class="op">&lt;|&gt;</span>) <span class="op">.</span> k) (wrap a) e</span></code></pre></div>
<p>For <code
class="sourceCode haskell"><span class="dt">Search</span></code> to meet
the requirements of a bunch, the paper notes that the <code
class="sourceCode haskell">f</code> must be assumed to be a bag, i.e.,
the order of its elements must be ignored.</p>
<p><span class="citation"
data-cites="kiselyov_backtracking_2005">Kiselyov et al. (<a
href="#ref-kiselyov_backtracking_2005"
role="doc-biblioref">2005</a>)</span> kind of goes the other direction,
defining a monad which has fair disjunction and conjunction.
Unfortunately, the fair conjunction loses associativity.</p>
<h1 id="distance">Distance</h1>
<p>The end of the paper on algebras for combinatorial search wonders if
notions of distance could be added to some of the algebras. I
<em>think</em> that should be as simple as supplying a suitable
near-semiring for <code class="sourceCode haskell">f</code>, but the
definition of <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code>
would need to be changed. The near-semiring I had in mind was the
probability monad. It works correctly if inlined:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Search</span> s a <span class="ot">=</span> <span class="dt">Search</span> {<span class="ot"> runSearch ::</span> [[(a,s)]] }</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">Search</span> s) <span class="kw">where</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Search</span> xs) <span class="ot">=</span> <span class="dt">Search</span> ((<span class="fu">fmap</span><span class="op">.</span><span class="fu">fmap</span><span class="op">.</span>first) f xs)</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">Search</span> s) <span class="kw">where</span></span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Search</span> [[(x,one)]]</span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>  _ <span class="op">&lt;*&gt;</span> <span class="dt">Search</span> [] <span class="ot">=</span> <span class="dt">Search</span> []</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Search</span> xs <span class="op">&lt;*&gt;</span> <span class="dt">Search</span> ys <span class="ot">=</span> <span class="dt">Search</span> (<span class="fu">foldr</span> f [] xs) <span class="kw">where</span></span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>    f x zs <span class="ot">=</span> <span class="fu">foldr</span> (g x) <span class="fu">id</span> ys (empty <span class="op">:</span> zs)</span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a>    g x y a (z<span class="op">:</span>zs) <span class="ot">=</span> (m x y <span class="op">++</span> z) <span class="op">:</span> a zs</span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a>    g x y a [] <span class="ot">=</span> (m x y) <span class="op">:</span> a []</span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a>    m ls rs <span class="ot">=</span> [(l r, lp<span class="op">&lt;.&gt;</span>rp) <span class="op">|</span> (l,lp) <span class="ot">&lt;-</span> ls, (r,rp) <span class="ot">&lt;-</span> rs]</span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> <span class="dt">Alternative</span> (<span class="dt">Search</span> s) <span class="kw">where</span></span>
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Search</span> xs <span class="op">&lt;|&gt;</span> <span class="dt">Search</span> ys <span class="ot">=</span> <span class="dt">Search</span> (go xs ys) <span class="kw">where</span></span>
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a>    go [] ys <span class="ot">=</span> ys</span>
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a>    go xs [] <span class="ot">=</span> xs</span>
<span id="cb30-19"><a href="#cb30-19" aria-hidden="true" tabindex="-1"></a>    go (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> (x <span class="op">++</span> y) <span class="op">:</span> go xs ys</span>
<span id="cb30-20"><a href="#cb30-20" aria-hidden="true" tabindex="-1"></a>  empty <span class="ot">=</span> <span class="dt">Search</span> []</span>
<span id="cb30-21"><a href="#cb30-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-22"><a href="#cb30-22" aria-hidden="true" tabindex="-1"></a><span class="ot">wrap ::</span> <span class="dt">Search</span> s a <span class="ot">-&gt;</span> <span class="dt">Search</span> s a</span>
<span id="cb30-23"><a href="#cb30-23" aria-hidden="true" tabindex="-1"></a>wrap (<span class="dt">Search</span> xs) <span class="ot">=</span> <span class="dt">Search</span> ([] <span class="op">:</span> xs)</span>
<span id="cb30-24"><a href="#cb30-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-25"><a href="#cb30-25" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> <span class="dt">Monad</span> (<span class="dt">Search</span> s) <span class="kw">where</span></span>
<span id="cb30-26"><a href="#cb30-26" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Search</span> xs <span class="op">&gt;&gt;=</span> k <span class="ot">=</span> <span class="fu">foldr</span> f empty xs <span class="kw">where</span></span>
<span id="cb30-27"><a href="#cb30-27" aria-hidden="true" tabindex="-1"></a>    f e a <span class="ot">=</span> <span class="fu">foldr</span> ((<span class="op">&lt;|&gt;</span>) <span class="op">.</span> <span class="fu">uncurry</span> (mulIn <span class="op">.</span> k)) (wrap a) e</span>
<span id="cb30-28"><a href="#cb30-28" aria-hidden="true" tabindex="-1"></a>    mulIn (<span class="dt">Search</span> x) xp <span class="ot">=</span> <span class="dt">Search</span> ((<span class="fu">fmap</span><span class="op">.</span><span class="fu">fmap</span><span class="op">.</span><span class="fu">fmap</span>) (xp<span class="op">&lt;.&gt;</span>) x)</span></code></pre></div>
<p>But I couldn’t figure out how to get it to work for a more
generalized inner monad. The above could probably be sped up, or
randomized, using the many well-known techniques for probability monad
optimization.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-dolan_fun_2013" class="csl-entry" role="listitem">
Dolan, Stephen. 2013. <span>“Fun with semirings: A functional pearl on
the abuse of linear algebra.”</span> In, 48:101. ACM Press. doi:<a
href="https://doi.org/10.1145/2500365.2500613">10.1145/2500365.2500613</a>.
<a
href="https://www.cl.cam.ac.uk/~sd601/papers/semirings.pdf">https://www.cl.cam.ac.uk/~sd601/papers/semirings.pdf</a>.
</div>
<div id="ref-kiselyov_backtracking_2005" class="csl-entry"
role="listitem">
Kiselyov, Oleg, Chung-chieh Shan, Daniel P Friedman, and Amr Sabry.
2005. <span>“Backtracking, interleaving, and terminating monad
transformers (functional pearl).”</span> <em>ACM SIGPLAN Notices</em> 40
(9): 192–203. <a
href="http://okmij.org/ftp/Computation/monads.html#LogicT">http://okmij.org/ftp/Computation/monads.html#LogicT</a>.
</div>
<div id="ref-mcbride_applicative_2008" class="csl-entry"
role="listitem">
McBride, Conor, and Ross Paterson. 2008. <span>“Applicative programming
with effects.”</span> <em>Journal of functional programming</em> 18
(01): 1–13. <a
href="http://strictlypositive.org/Idiom.pdf">http://strictlypositive.org/Idiom.pdf</a>.
</div>
<div id="ref-mcilroy_power_1999" class="csl-entry" role="listitem">
McIlroy, M. Douglas. 1999. <span>“Power <span>Series</span>,
<span>Power</span> <span>Serious</span>.”</span> <em>J. Funct.
Program.</em> 9 (3) (May): 325–337. doi:<a
href="https://doi.org/10.1017/S0956796899003299">10.1017/S0956796899003299</a>.
<a
href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.333.3156&amp;rep=rep1&amp;type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.333.3156&amp;rep=rep1&amp;type=pdf</a>.
</div>
<div id="ref-okasaki_fast_1999" class="csl-entry" role="listitem">
Okasaki, Chris. 1999. <span>“From <span>Fast</span>
<span>Exponentiation</span> to <span>Square</span>
<span>Matrices</span>: <span>An</span> <span>Adventure</span> in
<span>Types</span>.”</span> In <em>Proceedings of the <span>ACM</span>
<span>SIGPLAN</span> <span>International</span> <span>Conference</span>
on <span>Functional</span> <span>Programming</span>
(<span>ICFP</span>’99), <span>Paris</span>, <span>France</span>,
<span>September</span> 27-29, 1999</em>, 34:28. ACM. <a
href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.456.357&amp;rep=rep1&amp;type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.456.357&amp;rep=rep1&amp;type=pdf</a>.
</div>
<div id="ref-rivas_monoids_2015" class="csl-entry" role="listitem">
Rivas, Exequiel, Mauro Jaskelioff, and Tom Schrijvers. 2015. <span>“From
monoids to near-semirings: The essence of <span>MonadPlus</span> and
<span>Alternative</span>.”</span> In <em>Proceedings of the 17th
<span>International</span> <span>Symposium</span> on
<span>Principles</span> and <span>Practice</span> of
<span>Declarative</span> <span>Programming</span></em>, 196–207. ACM.
doi:<a
href="https://doi.org/10.1145/2790449.2790514">10.1145/2790449.2790514</a>.
<a
href="http://www.fceia.unr.edu.ar/~mauro/pubs/FromMonoidstoNearsemirings.pdf">http://www.fceia.unr.edu.ar/~mauro/pubs/FromMonoidstoNearsemirings.pdf</a>.
</div>
<div id="ref-spivey_algebras_2009" class="csl-entry" role="listitem">
Spivey, J. Michael. 2009. <span>“Algebras for combinatorial
search.”</span> <em>Journal of Functional Programming</em> 19 (3-4)
(July): 469–487. doi:<a
href="https://doi.org/10.1017/S0956796809007321">10.1017/S0956796809007321</a>.
<a
href="https://pdfs.semanticscholar.org/db3e/373bb6e7e7837ebc524da0a25903958554ed.pdf">https://pdfs.semanticscholar.org/db3e/373bb6e7e7837ebc524da0a25903958554ed.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Fri, 13 Oct 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-10-13-convolutions-and-semirings.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Applicative Arithmetic</title>
    <link>https://doisinkidney.com/posts/2017-09-25-applicative-arithmetic.html</link>
    <description><![CDATA[<div class="info">
    Posted on September 25, 2017
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Applicative&#39;." href="/tags/Applicative.html" rel="tag">Applicative</a>
    
</div>

<h1 id="safer-arithmetic">Safer Arithmetic</h1>
<p>There are a couple partial functions in the Haskell Prelude which
people seem to agree shouldn’t be there. <code
class="sourceCode haskell"><span class="fu">head</span></code>, for
example, will throw an error on an empty list. Most seem to agree that
it should work something more like this:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">head</span><span class="ot"> ::</span> <span class="dt">Foldable</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">head</span> <span class="ot">=</span> <span class="fu">foldr</span> (<span class="fu">const</span> <span class="op">.</span> <span class="dt">Just</span>) <span class="dt">Nothing</span></span></code></pre></div>
<p>There are other examples, like <code
class="sourceCode haskell"><span class="fu">last</span></code>, <code
class="sourceCode haskell"><span class="op">!!</span></code>, etc.</p>
<p>One which people <em>don’t</em> agree on, however, is division by
zero. In the current Prelude, the following will throw an error:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">/</span> <span class="dv">0</span></span></code></pre></div>
<p>The “safe” version might have a signature like this:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(/) ::</span> <span class="dt">Fractional</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span></code></pre></div>
<p>However, this turns out to be quite a headache for writing code
generally. So the default is the (somewhat) unsafe version.</p>
<p>Is there a way to introduce a safer version without much overhead, so
the programmer is given the option? Of course! With some newtype magic,
it’s pretty simple to write a wrapper which catches division by zero in
some arbitrary monad:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">AppNum</span> f a <span class="ot">=</span> <span class="dt">AppNum</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runAppNum ::</span> f a</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    } <span class="kw">deriving</span> (<span class="dt">Functor</span>,<span class="dt">Applicative</span>,<span class="dt">Monad</span>,<span class="dt">Alternative</span>,<span class="dt">Show</span>,<span class="dt">Eq</span>,<span class="dt">MonadFail</span>)</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Num</span> a, <span class="dt">Applicative</span> f) <span class="ot">=&gt;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Num</span> (<span class="dt">AppNum</span> f a) <span class="kw">where</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">abs</span> <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">abs</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">signum</span> <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">signum</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    (<span class="op">+</span>) <span class="ot">=</span> liftA2 (<span class="op">+</span>)</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    (<span class="op">*</span>) <span class="ot">=</span> liftA2 (<span class="op">*</span>)</span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>    (<span class="op">-</span>) <span class="ot">=</span> liftA2 (<span class="op">-</span>)</span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>    <span class="fu">negate</span> <span class="ot">=</span> <span class="fu">fmap</span> <span class="fu">negate</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fromInteger</span> <span class="ot">=</span> <span class="fu">pure</span> <span class="op">.</span> <span class="fu">fromInteger</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Fractional</span> a, <span class="dt">MonadFail</span> f, <span class="dt">Eq</span> a) <span class="ot">=&gt;</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Fractional</span> (<span class="dt">AppNum</span> f a) <span class="kw">where</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fromRational</span> <span class="ot">=</span> <span class="fu">pure</span> <span class="op">.</span> <span class="fu">fromRational</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a>    xs <span class="op">/</span> ys <span class="ot">=</span></span>
<span id="cb4-19"><a href="#cb4-19" aria-hidden="true" tabindex="-1"></a>        ys <span class="op">&gt;&gt;=</span></span>
<span id="cb4-20"><a href="#cb4-20" aria-hidden="true" tabindex="-1"></a>        \<span class="kw">case</span></span>
<span id="cb4-21"><a href="#cb4-21" aria-hidden="true" tabindex="-1"></a>            <span class="dv">0</span> <span class="ot">-&gt;</span> <span class="fu">fail</span> <span class="st">&quot;divide by zero&quot;</span></span>
<span id="cb4-22"><a href="#cb4-22" aria-hidden="true" tabindex="-1"></a>            y <span class="ot">-&gt;</span> <span class="fu">fmap</span> (<span class="op">/</span> y) xs</span></code></pre></div>
<p>I’m using the <code
class="sourceCode haskell"><span class="op">-</span><span class="dt">XLambdaCase</span></code>
extension and <code
class="sourceCode haskell"><span class="dt">MonadFail</span></code>
here.</p>
<h1 id="free-applicatives">Free Applicatives</h1>
<p>You’ll notice that you only need <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
for most of the arithmetic operations above. In fact, you only need
<code class="sourceCode haskell"><span class="dt">Monad</span></code>
when you want to examine the contents of <code
class="sourceCode haskell">f</code>. Using that fact, we can manipulate
expression trees using the free applicative from the <a
href="https://hackage.haskell.org/package/free">free</a> package. Say,
for instance, we want to have free variables in our expressions. Using
<code class="sourceCode haskell"><span class="dt">Either</span></code>,
it’s pretty easy:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">WithVars</span> <span class="ot">=</span> <span class="dt">AppNum</span> (<span class="dt">Ap</span> (<span class="dt">Either</span> <span class="dt">String</span>)) <span class="dt">Integer</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ot">var ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">WithVars</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>var <span class="ot">=</span> <span class="dt">AppNum</span> <span class="op">.</span> liftAp <span class="op">.</span> <span class="dt">Left</span></span></code></pre></div>
<p>We can collect the free variables from an expression:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">vars ::</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> [<span class="dt">String</span>]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>vars <span class="ot">=</span> runAp_ (<span class="fu">either</span> <span class="fu">pure</span> (<span class="fu">const</span> [])) <span class="op">.</span> runAppNum</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>x <span class="ot">=</span> <span class="dv">1</span><span class="ot"> ::</span> <span class="dt">WithVars</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>y <span class="ot">=</span> var <span class="st">&quot;y&quot;</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>z <span class="ot">=</span> var <span class="st">&quot;z&quot;</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>vars (x <span class="op">+</span> y <span class="op">+</span> z) <span class="co">-- [&quot;y&quot;,&quot;z&quot;]</span></span></code></pre></div>
<p>If we want to sub in, though, we’re going to run into a problem: we
can’t just pass in a <code
class="sourceCode haskell"><span class="dt">Map</span> <span class="dt">String</span> <span class="dt">Integer</span></code>
because you’re able to construct values like this:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">bad ::</span> <span class="dt">AppNum</span> (<span class="dt">Ap</span> (<span class="dt">Either</span> <span class="dt">String</span>)) (<span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span>)</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>bad <span class="ot">=</span> <span class="dt">AppNum</span> (liftAp (<span class="dt">Left</span> <span class="st">&quot;oh noes&quot;</span>))</span></code></pre></div>
<p>We’d need to pass in a <code
class="sourceCode haskell"><span class="dt">Map</span> <span class="dt">String</span> (<span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span>)</code>
as well; in fact you’d need a map for every possible type. Which isn’t
feasible.</p>
<h1 id="gadts">GADTs</h1>
<p>Luckily, we <em>can</em> constrain the types of variables in our
expression so that they’re always <code
class="sourceCode haskell"><span class="dt">Integer</span></code>, using
a GADT:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Variable</span> a <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Constant</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Variable</span> a</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Variable</span><span class="ot"> ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Variable</span> <span class="dt">Integer</span></span></code></pre></div>
<p>The type above seems useless on its own: it doesn’t have a <code
class="sourceCode haskell"><span class="dt">Functor</span></code>
instance, never mind an <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>,
so how can it fit into <code
class="sourceCode haskell"><span class="dt">AppNum</span></code>?</p>
<p>The magic comes from the free applicative, which converts any type of
kind <code
class="sourceCode haskell"><span class="dt">Type</span> <span class="ot">-&gt;</span> <span class="dt">Type</span></code>
into an applicative. With that in mind, we can change around the
previous code:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">WithVars</span> <span class="ot">=</span> <span class="dt">AppNum</span> (<span class="dt">Ap</span> <span class="dt">Variable</span>) <span class="dt">Integer</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">var ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">WithVars</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>var <span class="ot">=</span> <span class="dt">AppNum</span> <span class="op">.</span> liftAp <span class="op">.</span> <span class="dt">Variable</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="ot">vars ::</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> [<span class="dt">String</span>]</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>vars <span class="ot">=</span> runAp_ f <span class="op">.</span> runAppNum</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="ot">    f ::</span> <span class="dt">Variable</span> a <span class="ot">-&gt;</span> [<span class="dt">String</span>]</span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Constant</span> _) <span class="ot">=</span> []</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>    f (<span class="dt">Variable</span> s) <span class="ot">=</span> [s]</span></code></pre></div>
<p>And write the function to sub in for us:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>variableA</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Applicative</span> f</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (<span class="dt">String</span> <span class="ot">-&gt;</span> f <span class="dt">Integer</span>) <span class="ot">-&gt;</span> <span class="dt">Variable</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>variableA _ (<span class="dt">Constant</span> x) <span class="ot">=</span> <span class="fu">pure</span> x</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>variableA f (<span class="dt">Variable</span> s) <span class="ot">=</span> f s</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="ot">variable ::</span> (<span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span>) <span class="ot">-&gt;</span> <span class="dt">Variable</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>variable _ (<span class="dt">Constant</span> x) <span class="ot">=</span> x</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>variable f (<span class="dt">Variable</span> s) <span class="ot">=</span> f s</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a><span class="ot">replace ::</span> <span class="dt">Map</span> <span class="dt">String</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>replace m <span class="ot">=</span> runAp (variable (m <span class="op">Map.!</span>)) <span class="op">.</span> runAppNum</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>replace (Map.fromList [(<span class="st">&quot;z&quot;</span>,<span class="dv">2</span>), (<span class="st">&quot;y&quot;</span>,<span class="dv">3</span>)]) (x <span class="op">+</span> y <span class="op">+</span> z)</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- 6</span></span></code></pre></div>
<h1 id="accumulation">Accumulation</h1>
<p>This will fail if a free variable isn’t present in the map,
unfortunately. To fix it, we <em>could</em> use <code
class="sourceCode haskell"><span class="dt">Either</span></code> instead
of <code
class="sourceCode haskell"><span class="dt">Identity</span></code>:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">replace ::</span> <span class="dt">Map</span> <span class="dt">String</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">String</span> <span class="dt">Integer</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>replace m <span class="ot">=</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    runAp</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>        (variableA <span class="op">$</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>         \s <span class="ot">-&gt;</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>              <span class="fu">maybe</span> (<span class="dt">Left</span> s) <span class="dt">Right</span> (Map.lookup s m)) <span class="op">.</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    runAppNum</span></code></pre></div>
<p>But this only gives us the first missing variable encountered. We’d
like to get back <em>all</em> of the missing variables, ideally:
accumulating the <code
class="sourceCode haskell"><span class="dt">Left</span></code>s. <code
class="sourceCode haskell"><span class="dt">Either</span></code> doesn’t
accumulate values, as if it did it would <a
href="https://stackoverflow.com/a/23611068/4892417">break the monad
laws</a>.</p>
<p>There’s no issue with the <em>applicative</em> laws, though, which is
why the <a
href="https://hackage.haskell.org/package/validation-0.5.4">validation</a>
package provides a <em>non-monadic</em> either-like type, which we can
use here.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">replace ::</span> <span class="dt">Map</span> <span class="dt">String</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> <span class="dt">AccValidation</span> [<span class="dt">String</span>] <span class="dt">Integer</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>replace m <span class="ot">=</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    runAp</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>        (variableA <span class="op">$</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>         \s <span class="ot">-&gt;</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>              <span class="fu">maybe</span> (<span class="dt">AccFailure</span> [s]) <span class="fu">pure</span> (Map.lookup s m)) <span class="op">.</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>    runAppNum</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>replace (Map.fromList []) (x <span class="op">+</span> y <span class="op">+</span> z)</span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- AccFailure [&quot;y&quot;,&quot;z&quot;]</span></span></code></pre></div>
<h1 id="other-uses">Other uses</h1>
<p>There are a bunch more applicatives you could use instead of <code
class="sourceCode haskell"><span class="dt">Either</span></code>. Using
lists, for instance, you could calculate the possible outcomes from a
range of inputs:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="fu">range</span><span class="ot"> ::</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> [<span class="dt">Integer</span>]</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="fu">range</span> <span class="ot">=</span> runAp (variable (<span class="fu">const</span> [<span class="dv">1</span><span class="op">..</span><span class="dv">3</span>])) <span class="op">.</span> runAppNum</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="fu">range</span> (x <span class="op">+</span> y <span class="op">+</span> z)</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- [3,4,5,4,5,6,5,6,7]</span></span></code></pre></div>
<p>Or you could ask the user for input:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">query ::</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> <span class="dt">Integer</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>query <span class="ot">=</span> runAp (variable f) <span class="op">.</span> runAppNum</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    f s <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>      <span class="fu">putStr</span> <span class="st">&quot;Input a value for &quot;</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>      <span class="fu">putStrLn</span> s</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>      <span class="fu">fmap</span> <span class="fu">read</span> <span class="fu">getLine</span></span></code></pre></div>
<p>Finally, and this one’s a bit exotic, you could examine every
variable in turn, with defaults for the others:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>zygo</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="kw">forall</span> x<span class="op">.</span> f x <span class="ot">-&gt;</span> x)</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> (<span class="kw">forall</span> x<span class="op">.</span> f x <span class="ot">-&gt;</span> (x <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b)</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Ap</span> f a</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> [b]</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>zygo (<span class="ot">l ::</span> <span class="kw">forall</span> x<span class="op">.</span> f x <span class="ot">-&gt;</span> x) (<span class="ot">c ::</span> <span class="kw">forall</span> x<span class="op">.</span> f x <span class="ot">-&gt;</span> (x <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> b) <span class="ot">=</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fst</span> <span class="op">.</span> go <span class="fu">id</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a><span class="ot">    go ::</span> <span class="kw">forall</span> c<span class="op">.</span> (c <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> <span class="dt">Ap</span> f c <span class="ot">-&gt;</span> ([b], c)</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    go _ (<span class="dt">Pure</span> x) <span class="ot">=</span> ([], x)</span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>    go k (<span class="dt">Ap</span> x f) <span class="ot">=</span> (c x (k <span class="op">.</span> ls) <span class="op">:</span> xs, ls lx)</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>        (xs,ls) <span class="ot">=</span> go (k <span class="op">.</span> (<span class="op">$</span> lx)) f</span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>        lx <span class="ot">=</span> l x</span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a><span class="ot">examineEach ::</span> <span class="dt">WithVars</span> <span class="ot">-&gt;</span> [<span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span>]</span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>examineEach <span class="ot">=</span> zygo (variable (<span class="fu">const</span> <span class="dv">1</span>)) g <span class="op">.</span> runAppNum</span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true" tabindex="-1"></a><span class="ot">    g ::</span> <span class="dt">Variable</span> a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> b</span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true" tabindex="-1"></a>    g (<span class="dt">Constant</span> x) rhs _ <span class="ot">=</span> rhs x</span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true" tabindex="-1"></a>    g (<span class="dt">Variable</span> _) rhs i <span class="ot">=</span> rhs i</span></code></pre></div>
<p>This produces a list of functions which are equivalent to subbing in
for each variable with the rest set to 1.</p>
]]></description>
    <pubDate>Mon, 25 Sep 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-09-25-applicative-arithmetic.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Verifying Data Structures in Haskell</title>
    <link>https://doisinkidney.com/posts/2017-04-23-verifying-data-structures-in-haskell-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on April 23, 2017
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Dependent Types&#39;." href="/tags/Dependent%20Types.html" rel="tag">Dependent Types</a>, <a title="All pages tagged &#39;Data Structures&#39;." href="/tags/Data%20Structures.html" rel="tag">Data Structures</a>
    
</div>

<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DataKinds #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeOperators #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeFamilies #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE TypeInType #-}</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE KindSignatures #-}</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE GADTs #-}</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE RankNTypes #-}</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE MultiParamTypeClasses #-}</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE BangPatterns #-}</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE ScopedTypeVariables #-}</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE FlexibleInstances #-}</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE RebindableSyntax #-}</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">VerifiedDataStructures</span> <span class="kw">where</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Kind</span> <span class="kw">hiding</span> (type (*))</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Type.Equality</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Unsafe.Coerce</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">GHC.TypeLits</span> <span class="kw">hiding</span> (type (&lt;=))</span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Proxy</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Coerce</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Prelude</span></span></code></pre></div>
<p>A while ago I read <a
href="https://www.reddit.com/r/haskell/comments/63a4ea/fast_total_sorting_of_arbitrary_traversable/">this</a>
post on reddit (by David Feuer), about sorting traversables (which was a
follow-up on <a
href="http://elvishjerricco.github.io/2017/03/23/applicative-sorting.html">this</a>
post by Will Fancher), and I was inspired to write some
pseudo-dependently-typed Haskell. The post (and subsequent <a
href="https://github.com/treeowl/sort-traversable">library</a>) detailed
how to use size-indexed heaps to perform fast, total sorting on any
traversable. I ended up with a <a
href="https://github.com/oisdk/type-indexed-queues">library</a> which
has five size-indexed heaps (Braun, pairing, binomial, skew, and
leftist), each verified for structural correctness. I also included the
non-indexed implementations of each for comparison (as well as
benchmarks, tests, and all that good stuff).</p>
<p>The purpose of this post is to go through some of the tricks I used
and problems I encountered writing a lot of type-level code in modern
Haskell.</p>
<h3 id="type-level-numbers-in-haskell">Type-Level Numbers in
Haskell</h3>
<p>In order to index things by their size, we’ll need a type-level
representation of size. We’ll use <a
href="https://wiki.haskell.org/Peano_numbers">Peano</a> numbers for
now:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Peano</span> <span class="ot">=</span> <span class="dt">Z</span> <span class="op">|</span> <span class="dt">S</span> <span class="dt">Peano</span></span></code></pre></div>
<p><code class="sourceCode haskell"><span class="dt">Z</span></code>
stands for zero, and <code
class="sourceCode haskell"><span class="dt">S</span></code> for
successor. The terseness is pretty necessary here, unfortunately:
arithmetic becomes unreadable otherwise. The simplicity of this
definition is useful for proofs and manipulation; however any runtime
representation of these numbers is going to be woefully slow.</p>
<p>With the <code
class="sourceCode haskell"><span class="dt">DataKinds</span></code>
extension, the above is automatically promoted to the type-level, so we
can write type-level functions (type families) on the <code
class="sourceCode haskell"><span class="dt">Peano</span></code>
type:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Plus</span> (<span class="ot">n ::</span> <span class="dt">Peano</span>) (<span class="ot">m ::</span> <span class="dt">Peano</span>)<span class="ot"> ::</span> <span class="dt">Peano</span> <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Plus</span> <span class="dt">Z</span> m <span class="ot">=</span> m</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Plus</span> (<span class="dt">S</span> n) m <span class="ot">=</span> <span class="dt">S</span> (<span class="dt">Plus</span> n m)</span></code></pre></div>
<p>Here the <code
class="sourceCode haskell"><span class="dt">TypeFamilies</span></code>
extension is needed. I’ll try and mention every extension I’m using as
we go, but I might forget a few, so check the repository for all of the
examples (quick aside: I <em>did</em> manage to avoid using <code
class="sourceCode haskell"><span class="dt">UndecidableInstances</span></code>,
but more on that later). One pragma that’s worth mentioning is:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}</span></span></code></pre></div>
<p>This suppresses warnings on the definition of <code
class="sourceCode haskell"><span class="dt">Plus</span></code> above.
Without it, GHC would want us to write:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Plus</span> (<span class="ot">n ::</span> <span class="dt">Peano</span>) (<span class="ot">m ::</span> <span class="dt">Peano</span>)<span class="ot"> ::</span> <span class="dt">Peano</span> <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Plus</span> <span class="dt">&#39;Z</span> m <span class="ot">=</span> m</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Plus</span> (<span class="dt">&#39;S</span> n) m <span class="ot">=</span> <span class="dt">&#39;S</span> (<span class="dt">Plus</span> n m)</span></code></pre></div>
<p>I think that looks pretty ugly, and it can get much worse with more
involved arithmetic. The only thing I have found the warnings useful for
is <code class="sourceCode haskell">[]</code>: the type-level empty list
gives an error in its unticked form.</p>
<h3 id="using-the-type-level-numbers-with-a-pairing-heap">Using the
Type-Level Numbers with a Pairing Heap</h3>
<p>In the original post, a pairing heap <span class="citation"
data-cites="fredman_pairing_1986">(<a href="#ref-fredman_pairing_1986"
role="doc-biblioref">Fredman et al. 1986</a>)</span> was used, for its
simplicity and performance. The implementation looked like this:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heap</span> n a <span class="kw">where</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">E</span><span class="ot"> ::</span> <span class="dt">Heap</span> <span class="dt">Z</span> a</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">T</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dt">S</span> n) a</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">HVec</span> n a <span class="kw">where</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HNil</span><span class="ot"> ::</span> <span class="dt">HVec</span> <span class="dt">Z</span> a</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HCons</span><span class="ot"> ::</span> <span class="dt">Heap</span> m a <span class="ot">-&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">HVec</span> (<span class="dt">Plus</span> m n) a</span></code></pre></div>
<p>You immediately run into trouble when you try to define merge:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Heap</span> m a <span class="ot">-&gt;</span> <span class="dt">Heap</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dt">Plus</span> m n) a</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>merge <span class="dt">E</span> ys <span class="ot">=</span> ys</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>merge xs <span class="dt">E</span> <span class="ot">=</span> xs</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>merge h1<span class="op">@</span>(<span class="dt">T</span> x xs) h2<span class="op">@</span>(<span class="dt">T</span> y ys)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">&lt;=</span> y <span class="ot">=</span> <span class="dt">T</span> x (<span class="dt">HCons</span> h2 xs)</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">T</span> y (<span class="dt">HCons</span> h1 ys)</span></code></pre></div>
<p>Three errors show up here, but we’ll look at the first one:</p>
<blockquote>
<p><code>Could not deduce (m ~ (Plus m Z))</code></p>
</blockquote>
<p>GHC doesn’t know that
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>x</mi><mo>=</mo><mi>x</mi><mo>+</mo><mn>0</mn></mrow><annotation encoding="application/x-tex">x = x + 0</annotation></semantics></math>.
Somehow, we’ll have to <em>prove</em> that it does.</p>
<h3 id="singletons">Singletons</h3>
<p>In a language with true dependent types, proving the proposition
above is as simple as:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode idris"><code class="sourceCode idris"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">plusZeroNeutral</span> <span class="ot">:</span> (n <span class="ot">:</span> <span class="dt">Nat</span>) <span class="ot">-&gt;</span> n <span class="fu">+</span> <span class="dv">0</span> <span class="fu">=</span> n</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>plusZeroNeutral <span class="dt">Z</span> <span class="fu">=</span> <span class="dt">Refl</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>plusZeroNeutral (<span class="dt">S</span> k) <span class="fu">=</span> cong (plusZeroNeutral k)</span></code></pre></div>
<p>(this example is in Idris)</p>
<p>In Haskell, on the other hand, we can’t do the same: functions on the
value-level <code
class="sourceCode haskell"><span class="dt">Peano</span></code> have no
relationship with functions on the type-level <code
class="sourceCode haskell"><span class="dt">Peano</span></code>. There’s
no way to automatically link or promote one to the other.</p>
<p>This is where singletons come in <span class="citation"
data-cites="eisenberg_dependently_2012">(<a
href="#ref-eisenberg_dependently_2012" role="doc-biblioref">Eisenberg
and Weirich 2012</a>)</span>. A singleton is a datatype which mirrors a
type-level value exactly, except that it has a type parameter which
matches the equivalent value on the type-level. In this way, we can
write functions on the value-level which are linked to the type-level.
Here’s a potential singleton for <code
class="sourceCode haskell"><span class="dt">Peano</span></code>:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Natty</span> n <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Zy</span><span class="ot"> ::</span> <span class="dt">Natty</span> <span class="dt">Z</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Sy</span><span class="ot"> ::</span> <span class="dt">Natty</span> n <span class="ot">-&gt;</span> <span class="dt">Natty</span> (<span class="dt">S</span> n)</span></code></pre></div>
<p>(we need <code
class="sourceCode haskell"><span class="dt">GADTs</span></code> for this
example)</p>
<p>Now, when we pattern-match on <code
class="sourceCode haskell"><span class="dt">Natty</span></code>, we get
a proof of whatever its type parameter was. Here’s a trivial
example:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">isZero ::</span> <span class="dt">Natty</span> n <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (n <span class="op">:~:</span> <span class="dt">Z</span>)</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>isZero <span class="dt">Zy</span> <span class="ot">=</span> <span class="dt">Just</span> <span class="dt">Refl</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>isZero (<span class="dt">Sy</span> _) <span class="ot">=</span> <span class="dt">Nothing</span></span></code></pre></div>
<p>When we match on <code
class="sourceCode haskell"><span class="dt">Zy</span></code>, the
<em>only value</em> which <code class="sourceCode haskell">n</code>
could have been is <code
class="sourceCode haskell"><span class="dt">Z</span></code>, because the
only way to construct <code
class="sourceCode haskell"><span class="dt">Zy</span></code> is if the
type parameter is <code
class="sourceCode haskell"><span class="dt">Z</span></code>.</p>
<p>Using this technique, the <code
class="sourceCode haskell">plusZeroNeutral</code> proof looks reasonably
similar to the Idris version:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">plusZeroNeutral ::</span> <span class="dt">Natty</span> n <span class="ot">-&gt;</span> <span class="dt">Plus</span> n <span class="dt">Z</span> <span class="op">:~:</span> n</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>plusZeroNeutral <span class="dt">Zy</span> <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>plusZeroNeutral (<span class="dt">Sy</span> n) <span class="ot">=</span> <span class="kw">case</span> plusZeroNeutral n <span class="kw">of</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Refl</span> <span class="ot">-&gt;</span> <span class="dt">Refl</span></span></code></pre></div>
<p>To generalize the singletons a little, we could probably use the <a
href="https://hackage.haskell.org/package/singletons">singletons</a>
library, or we could roll our own:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="kw">family</span> <span class="dt">The</span><span class="ot"> k ::</span> k <span class="ot">-&gt;</span> <span class="dt">Type</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="kw">instance</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="kw">where</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Zy</span><span class="ot"> ::</span> <span class="dt">The</span> <span class="dt">Peano</span> <span class="dt">Z</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Sy</span><span class="ot"> ::</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Peano</span> (<span class="dt">S</span> n)</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a><span class="ot">plusZeroNeutral ::</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="ot">-&gt;</span> <span class="dt">Plus</span> n <span class="dt">Z</span> <span class="op">:~:</span> n</span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>plusZeroNeutral <span class="dt">Zy</span> <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>plusZeroNeutral (<span class="dt">Sy</span> n) <span class="ot">=</span> <span class="kw">case</span> plusZeroNeutral n <span class="kw">of</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Refl</span> <span class="ot">-&gt;</span> <span class="dt">Refl</span></span></code></pre></div>
<p>The <code
class="sourceCode haskell"><span class="dt">The</span></code> naming is
kind of cute, I think. It makes the signature look <em>almost</em> like
the Idris version (<code class="sourceCode idris">the</code> is a
function from the Idris standard library). The <code
class="sourceCode haskell"><span class="dt">The</span></code> type
family requires the <code
class="sourceCode haskell"><span class="dt">TypeInType</span></code>
extension, which I’ll talk a little more about later.</p>
<h3 id="proof-erasure-and-totality">Proof Erasure and Totality</h3>
<p>There’s an issue with these kinds of proofs: the proof code runs
<em>every time</em> it is needed. Since the same value is coming out the
other end each time (<code
class="sourceCode haskell"><span class="dt">Refl</span></code>), this
seems wasteful.</p>
<p>In a language like Idris, this problem is avoided by noticing that
you’re only using the proof for its type information, and then erasing
it at runtime. In Haskell, we can accomplish the same with a rule:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# NOINLINE plusZeroNeutral #-}</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# RULES</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="ot">&quot;plusZeroNeutral&quot; forall x. plusZeroNeutral x</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  = unsafeCoerce (Refl :: &#39;Z :~: &#39;Z)</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a><span class="ot"> #-}</span></span></code></pre></div>
<p>This basically says “if this type-checks, then the proof must exist,
and therefore the proof must be valid. So don’t bother running it”.
Unfortunately, that’s a <em>little bit</em> of a lie. It’s pretty easy
to write a proof which type-checks that <em>isn’t</em> valid:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">falseIsTrue ::</span> <span class="dt">False</span> <span class="op">:~:</span> <span class="dt">True</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>falseIsTrue <span class="ot">=</span> falseIsTrue</span></code></pre></div>
<p>We won’t be able to perform computations which rely on this proof in
Haskell, though: because the computation will never terminate, the proof
will never provide an answer. This means that, while the proof isn’t
valid, it <em>is</em> type safe. That is, of course, unless we use our
manual proof-erasure technique. The <code
class="sourceCode haskell"><span class="dt">RULES</span></code> pragma
will happily replace it with the <code
class="sourceCode haskell">unsafeCoerce</code> version, effectively
introducing unsoundness into our proofs. The reason that this doesn’t
cause a problem for language like Idris is that Idris has a totality
checker: you <em>can’t</em> write the above definition (with the
totality checker turned on) in Idris.</p>
<p>So what’s the solution? Do we have to suffer through the slower proof
code to maintain correctness? In reality, it’s usually OK to assume
termination. It’s pretty easy to see that a proof like <code
class="sourceCode haskell">plusZeroNeutral</code> is total. It’s worth
bearing in mind, though, that until Haskell gets a totality checker (<a
href="https://typesandkinds.wordpress.com/2016/07/24/dependent-types-in-haskell-progress-report/">likely
never</a>, apparently) these proofs aren’t “proper”.</p>
<h3 id="generating-singletons">Generating Singletons</h3>
<p>One extra thing: while you’re proving things in one area of your
code, you might not have the relevant singleton handy. To generate them
on-demand, you’ll need a typeclass:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">KnownSing</span> (<span class="ot">x ::</span> k) <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    sing ::</span> <span class="dt">The</span> k x</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownSing</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">Zy</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownSing</span> n <span class="ot">=&gt;</span> <span class="dt">KnownSing</span> (<span class="dt">S</span> n) <span class="kw">where</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">Sy</span> sing</span></code></pre></div>
<p>This kind of drives home the inefficiency of singleton-based proofs,
and why it’s important to erase them aggressively.</p>
<h3 id="proofs-bundled-with-the-data-structure">Proofs Bundled with the
Data Structure</h3>
<p>One other way to solve these problems is to try find a data structure
which runs the proof code anyway. As an example, consider a
length-indexed list:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> n a <span class="kw">where</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nil</span><span class="ot"> ::</span> <span class="dt">List</span> <span class="dt">Z</span> a</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    (:-) ::</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> n a <span class="ot">-&gt;</span> <span class="dt">List</span> (<span class="dt">S</span> n) a</span></code></pre></div>
<p>You might worry that concatenation of two lists requires some
expensive proof code, like <code class="sourceCode haskell">merge</code>
for the pairing heap. Maybe surprisingly, the default implementation
just works:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">++</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="ot">(++) ::</span> <span class="dt">List</span> n a <span class="ot">-&gt;</span> <span class="dt">List</span> m a <span class="ot">-&gt;</span> <span class="dt">List</span> (<span class="dt">Plus</span> n m) a</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>(<span class="op">++</span>) <span class="dt">Nil</span> ys <span class="ot">=</span> ys</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>(<span class="op">++</span>) (x <span class="op">:-</span> xs) ys <span class="ot">=</span> x <span class="op">:-</span> xs <span class="op">++</span> ys</span></code></pre></div>
<p>Why? Well, if you look back to the definition of <code
class="sourceCode haskell"><span class="dt">Plus</span></code>, it’s
almost exactly the same as the definition of <code
class="sourceCode haskell">(<span class="op">++</span>)</code>. In
effect, we’re using <em>lists</em> as the singleton for <code
class="sourceCode haskell"><span class="dt">Peano</span></code>
here.</p>
<p>The question is, then: is there a heap which performs these proofs
automatically for functions like merge? As far as I can tell:
<em>almost</em>. First though:</p>
<h3
id="small-digression-manipulating-and-using-the-length-indexed-list">Small
Digression: Manipulating and Using the Length-Indexed List</h3>
<p>The standard definition of <code
class="sourceCode haskell"><span class="op">++</span></code> on normal
lists can be cleaned up a little with <code
class="sourceCode haskell"><span class="fu">foldr</span></code></p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">(++) ::</span> [a] <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>(<span class="op">++</span>) <span class="ot">=</span> <span class="fu">flip</span> (<span class="fu">foldr</span> (<span class="op">:</span>))</span></code></pre></div>
<p>Can we get a similar definition for our length-indexed lists? Turns
out we can, but the type of <code
class="sourceCode haskell"><span class="fu">foldr</span></code> needs to
be a little different:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldrList ::</span> (<span class="kw">forall</span> x<span class="op">.</span> a <span class="ot">-&gt;</span> b x <span class="ot">-&gt;</span> b (<span class="dt">S</span> x))</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>          <span class="ot">-&gt;</span> b m <span class="ot">-&gt;</span> <span class="dt">List</span> n a <span class="ot">-&gt;</span> b (n <span class="op">+</span> m)</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>foldrList f b <span class="dt">Nil</span> <span class="ot">=</span> b</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>foldrList f b (x <span class="op">:-</span> xs) <span class="ot">=</span> f x (foldrList f b xs)</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Flip</span> (<span class="ot">f ::</span> t <span class="ot">-&gt;</span> u <span class="ot">-&gt;</span> <span class="dt">Type</span>) (<span class="ot">a ::</span> u) (<span class="ot">b ::</span> t)</span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Flip</span> {<span class="ot"> unFlip ::</span> f b a }</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a><span class="ot">foldrList1 ::</span> (<span class="kw">forall</span> x<span class="op">.</span> a <span class="ot">-&gt;</span> b x c <span class="ot">-&gt;</span> b (<span class="dt">S</span> x) c)</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>           <span class="ot">-&gt;</span> b m c <span class="ot">-&gt;</span> <span class="dt">List</span> n a <span class="ot">-&gt;</span> b (n <span class="op">+</span> m) c</span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a>foldrList1 f b</span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> unFlip <span class="op">.</span> foldrList (\e <span class="ot">-&gt;</span> <span class="dt">Flip</span> <span class="op">.</span> f e <span class="op">.</span> unFlip) (<span class="dt">Flip</span> b)</span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-14"><a href="#cb19-14" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">++</span></span>
<span id="cb19-15"><a href="#cb19-15" aria-hidden="true" tabindex="-1"></a><span class="ot">(++) ::</span> <span class="dt">List</span> n a <span class="ot">-&gt;</span> <span class="dt">List</span> m a <span class="ot">-&gt;</span> <span class="dt">List</span> (n <span class="op">+</span> m) a</span>
<span id="cb19-16"><a href="#cb19-16" aria-hidden="true" tabindex="-1"></a>(<span class="op">++</span>) <span class="ot">=</span> <span class="fu">flip</span> (foldrList1 (<span class="op">:-</span>))</span></code></pre></div>
<p>So what’s the point of this more complicated version? Well, if this
were normal Haskell, we might get some foldr-fusion or something (in
reality we would probably use <a
href="http://hackage.haskell.org/package/base-4.9.1.0/docs/GHC-Exts.html#v:augment"><code
class="sourceCode haskell">augment</code></a> if that were the
purpose).</p>
<p>With this type-level business, though, there’s a similar application:
loop unrolling. Consider the natural-number type again. We can write a
typeclass which will perform induction over them:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">KnownPeano</span> (<span class="ot">n ::</span> <span class="dt">Peano</span>)  <span class="kw">where</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    unrollRepeat ::</span> <span class="dt">Proxy</span> n <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownPeano</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>    unrollRepeat _ <span class="ot">=</span> <span class="fu">const</span> <span class="fu">id</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE unrollRepeat #-}</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownPeano</span> n <span class="ot">=&gt;</span></span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>         <span class="dt">KnownPeano</span> (<span class="dt">S</span> n) <span class="kw">where</span></span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>    unrollRepeat (<span class="ot">_ ::</span> <span class="dt">Proxy</span> (<span class="dt">S</span> n)) f x <span class="ot">=</span></span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>        f (unrollRepeat (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> n) f x)</span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE unrollRepeat #-}</span></span></code></pre></div>
<p>Because the recursion here calls a different <code
class="sourceCode haskell">unrollRepeat</code> function in the
“recursive” call, we get around the <a
href="http://stackoverflow.com/questions/42179783/is-there-any-way-to-inline-a-recursive-function">usual
hurdle</a> of not being able to inline recursive calls. That means that
the whole loop will be unrolled, at compile-time. We can do the same for
foldr:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">HasFoldr</span> (<span class="ot">n ::</span> <span class="dt">Peano</span>) <span class="kw">where</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>    unrollFoldr</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="ot">        ::</span> (<span class="kw">forall</span> x<span class="op">.</span> a <span class="ot">-&gt;</span> b x <span class="ot">-&gt;</span> b (<span class="dt">S</span> x))</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> b m</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">List</span> n a</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> b (n <span class="op">+</span> m)</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">HasFoldr</span> <span class="dt">Z</span> <span class="kw">where</span></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>    unrollFoldr _ b _ <span class="ot">=</span> b</span>
<span id="cb21-10"><a href="#cb21-10" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE unrollFoldr #-}</span></span>
<span id="cb21-11"><a href="#cb21-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-12"><a href="#cb21-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">HasFoldr</span> n <span class="ot">=&gt;</span> <span class="dt">HasFoldr</span> (<span class="dt">S</span> n) <span class="kw">where</span></span>
<span id="cb21-13"><a href="#cb21-13" aria-hidden="true" tabindex="-1"></a>    unrollFoldr f b (x <span class="op">:-</span> xs) <span class="ot">=</span> f x (unrollFoldr f b xs)</span>
<span id="cb21-14"><a href="#cb21-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE unrollFoldr #-}</span></span></code></pre></div>
<p>I can’t think of many uses for this technique, but one that comes to
mind is an n-ary uncurry (like Lisp’s <a
href="https://en.wikipedia.org/wiki/Apply#Common_Lisp_and_Scheme">apply</a>):</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">List</span> (<span class="ot">xs ::</span> [<span class="op">*</span>]) <span class="kw">where</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Nil</span><span class="ot"> ::</span> <span class="dt">List</span> &#39;[]</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a><span class="ot">        (:-) ::</span> a <span class="ot">-&gt;</span> <span class="dt">List</span> xs <span class="ot">-&gt;</span> <span class="dt">List</span> (a &#39;<span class="op">:</span> xs)</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">KnownList</span> (<span class="ot">xs ::</span> [<span class="op">*</span>])  <span class="kw">where</span></span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>    foldrT</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a><span class="ot">        ::</span> (<span class="kw">forall</span> y ys<span class="op">.</span> y <span class="ot">-&gt;</span> result ys <span class="ot">-&gt;</span> result (y &#39;<span class="op">:</span> ys))</span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> result &#39;[]</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">List</span> xs</span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> result xs</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownList</span> (&#39;[]<span class="ot"> ::</span> [<span class="op">*</span>]) <span class="kw">where</span></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>    foldrT _ <span class="ot">=</span> <span class="fu">const</span></span>
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE foldrT #-}</span></span>
<span id="cb22-16"><a href="#cb22-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-17"><a href="#cb22-17" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownList</span> xs <span class="ot">=&gt;</span></span>
<span id="cb22-18"><a href="#cb22-18" aria-hidden="true" tabindex="-1"></a>         <span class="dt">KnownList</span> (x &#39;<span class="op">:</span> xs) <span class="kw">where</span></span>
<span id="cb22-19"><a href="#cb22-19" aria-hidden="true" tabindex="-1"></a>    foldrT f b (x <span class="op">:-</span> xs) <span class="ot">=</span> f x (foldrT f b xs)</span>
<span id="cb22-20"><a href="#cb22-20" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE foldrT #-}</span></span>
<span id="cb22-21"><a href="#cb22-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-22"><a href="#cb22-22" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Func</span> (<span class="ot">xs ::</span> [<span class="op">*</span>]) (<span class="ot">y ::</span> <span class="op">*</span>) <span class="kw">where</span></span>
<span id="cb22-23"><a href="#cb22-23" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Func</span> &#39;[] y <span class="ot">=</span> y</span>
<span id="cb22-24"><a href="#cb22-24" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Func</span> (x &#39;<span class="op">:</span> xs) y <span class="ot">=</span> x <span class="ot">-&gt;</span> <span class="dt">Func</span> xs y</span>
<span id="cb22-25"><a href="#cb22-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-26"><a href="#cb22-26" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">FunType</span> y xs <span class="ot">=</span> <span class="dt">FunType</span></span>
<span id="cb22-27"><a href="#cb22-27" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runFun ::</span> <span class="dt">Func</span> xs y <span class="ot">-&gt;</span> y</span>
<span id="cb22-28"><a href="#cb22-28" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb22-29"><a href="#cb22-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-30"><a href="#cb22-30" aria-hidden="true" tabindex="-1"></a><span class="fu">uncurry</span></span>
<span id="cb22-31"><a href="#cb22-31" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">KnownList</span> xs</span>
<span id="cb22-32"><a href="#cb22-32" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Func</span> xs y <span class="ot">-&gt;</span> <span class="dt">List</span> xs <span class="ot">-&gt;</span> y</span>
<span id="cb22-33"><a href="#cb22-33" aria-hidden="true" tabindex="-1"></a><span class="fu">uncurry</span> f l <span class="ot">=</span></span>
<span id="cb22-34"><a href="#cb22-34" aria-hidden="true" tabindex="-1"></a>    runFun</span>
<span id="cb22-35"><a href="#cb22-35" aria-hidden="true" tabindex="-1"></a>        (foldrT</span>
<span id="cb22-36"><a href="#cb22-36" aria-hidden="true" tabindex="-1"></a>             (c (\x g h <span class="ot">-&gt;</span> g (h x)))</span>
<span id="cb22-37"><a href="#cb22-37" aria-hidden="true" tabindex="-1"></a>             (<span class="dt">FunType</span> <span class="fu">id</span>)</span>
<span id="cb22-38"><a href="#cb22-38" aria-hidden="true" tabindex="-1"></a>             l)</span>
<span id="cb22-39"><a href="#cb22-39" aria-hidden="true" tabindex="-1"></a>        f</span>
<span id="cb22-40"><a href="#cb22-40" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb22-41"><a href="#cb22-41" aria-hidden="true" tabindex="-1"></a><span class="ot">    c ::</span> (a <span class="ot">-&gt;</span> ((<span class="dt">Func</span> xs y <span class="ot">-&gt;</span> y) <span class="ot">-&gt;</span> (<span class="dt">Func</span> zs z <span class="ot">-&gt;</span> z)))</span>
<span id="cb22-42"><a href="#cb22-42" aria-hidden="true" tabindex="-1"></a>      <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> (<span class="dt">FunType</span> y xs <span class="ot">-&gt;</span> <span class="dt">FunType</span> z zs))</span>
<span id="cb22-43"><a href="#cb22-43" aria-hidden="true" tabindex="-1"></a>    c <span class="ot">=</span> coerce</span>
<span id="cb22-44"><a href="#cb22-44" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE c #-}</span></span>
<span id="cb22-45"><a href="#cb22-45" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE uncurry #-}</span></span></code></pre></div>
<p>I <em>think</em> that you can be guaranteed the above is inlined at
compile-time, making it essentially equivalent to a handwritten <code
class="sourceCode haskell"><span class="fu">uncurry</span></code>.</p>
<h3 id="binomial-heaps">Binomial Heaps</h3>
<p>Anyway, back to the size-indexed heaps. The reason that <code
class="sourceCode haskell">(<span class="op">++</span>)</code> worked so
easily on lists is that a list can be thought of as the data-structure
equivalent to Peano numbers. Another numeric-system-based data structure
is the binomial heap, which is based on binary numbering <span
class="citation" data-cites="hinze_functional_1999">(I’m going mainly
off of the description from <a href="#ref-hinze_functional_1999"
role="doc-biblioref">Hinze 1999</a>)</span>.</p>
<p>So, to work with binary numbers, let’s get some preliminaries on the
type-level out of the way:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="kw">instance</span> <span class="dt">The</span> <span class="dt">Bool</span> x <span class="kw">where</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Falsy</span><span class="ot"> ::</span> <span class="dt">The</span> <span class="dt">Bool</span> <span class="dt">False</span></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Truey</span><span class="ot"> ::</span> <span class="dt">The</span> <span class="dt">Bool</span> <span class="dt">True</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="kw">instance</span> <span class="dt">The</span> [k] xs <span class="kw">where</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Nily</span><span class="ot"> ::</span> <span class="dt">The</span> [k] &#39;[]</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Cony</span><span class="ot"> ::</span> <span class="dt">The</span> k x <span class="ot">-&gt;</span> <span class="dt">The</span> [k] xs <span class="ot">-&gt;</span> <span class="dt">The</span> [k] (x <span class="op">:</span> xs)</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownSing</span> <span class="dt">True</span> <span class="kw">where</span></span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">Truey</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownSing</span> <span class="dt">False</span> <span class="kw">where</span></span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">Falsy</span></span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownSing</span> &#39;[] <span class="kw">where</span></span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">Nily</span></span>
<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-18"><a href="#cb23-18" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">KnownSing</span> xs, <span class="dt">KnownSing</span> x) <span class="ot">=&gt;</span></span>
<span id="cb23-19"><a href="#cb23-19" aria-hidden="true" tabindex="-1"></a>         <span class="dt">KnownSing</span> (x <span class="op">:</span> xs) <span class="kw">where</span></span>
<span id="cb23-20"><a href="#cb23-20" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">Cony</span> sing sing</span></code></pre></div>
<p>We’ll represent a binary number as a list of Booleans:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Sum</span> (<span class="ot">x ::</span> <span class="dt">Bool</span>) (<span class="ot">y ::</span> <span class="dt">Bool</span>) (<span class="ot">cin ::</span> <span class="dt">Bool</span>)<span class="ot"> ::</span> <span class="dt">Bool</span> <span class="kw">where</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">False</span> <span class="dt">False</span> <span class="dt">False</span> <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">False</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="dt">False</span> <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="dt">False</span> <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Sum</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Carry</span> (<span class="ot">x ::</span> <span class="dt">Bool</span>) (<span class="ot">y ::</span> <span class="dt">Bool</span>) (<span class="ot">cin ::</span> <span class="dt">Bool</span>)</span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a>     (<span class="ot">xs ::</span> [<span class="dt">Bool</span>]) (<span class="ot">ys ::</span> [<span class="dt">Bool</span>])<span class="ot"> ::</span> [<span class="dt">Bool</span>] <span class="kw">where</span></span>
<span id="cb24-13"><a href="#cb24-13" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">False</span> <span class="dt">False</span> xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">False</span> xs ys</span>
<span id="cb24-14"><a href="#cb24-14" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">False</span> <span class="dt">True</span>  xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">False</span> xs ys</span>
<span id="cb24-15"><a href="#cb24-15" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="dt">False</span> xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">False</span> xs ys</span>
<span id="cb24-16"><a href="#cb24-16" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="dt">True</span>  xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">True</span>  xs ys</span>
<span id="cb24-17"><a href="#cb24-17" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="dt">False</span> xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">False</span> xs ys</span>
<span id="cb24-18"><a href="#cb24-18" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="dt">True</span>  xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">True</span>  xs ys</span>
<span id="cb24-19"><a href="#cb24-19" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="dt">False</span> xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">True</span>  xs ys</span>
<span id="cb24-20"><a href="#cb24-20" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="dt">True</span>  xs ys <span class="ot">=</span> <span class="dt">Add</span> <span class="dt">True</span>  xs ys</span>
<span id="cb24-21"><a href="#cb24-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-22"><a href="#cb24-22" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Add</span> (<span class="ot">cin ::</span> <span class="dt">Bool</span>) (<span class="ot">xs ::</span> [<span class="dt">Bool</span>]) (<span class="ot">ys ::</span> [<span class="dt">Bool</span>]) <span class="ot">::</span></span>
<span id="cb24-23"><a href="#cb24-23" aria-hidden="true" tabindex="-1"></a>     [<span class="dt">Bool</span>] <span class="kw">where</span></span>
<span id="cb24-24"><a href="#cb24-24" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> c (x <span class="op">:</span> xs) (y <span class="op">:</span> ys) <span class="ot">=</span> <span class="dt">Sum</span> x y c <span class="op">:</span> <span class="dt">Carry</span> x y c xs ys</span>
<span id="cb24-25"><a href="#cb24-25" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">False</span> &#39;[] ys <span class="ot">=</span> ys</span>
<span id="cb24-26"><a href="#cb24-26" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">False</span> xs &#39;[] <span class="ot">=</span> xs</span>
<span id="cb24-27"><a href="#cb24-27" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">True</span>  &#39;[] ys <span class="ot">=</span> <span class="dt">CarryOne</span> ys</span>
<span id="cb24-28"><a href="#cb24-28" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">True</span>  xs &#39;[] <span class="ot">=</span> <span class="dt">CarryOne</span> xs</span>
<span id="cb24-29"><a href="#cb24-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-30"><a href="#cb24-30" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">CarryOne</span> (<span class="ot">xs ::</span> [<span class="dt">Bool</span>])<span class="ot"> ::</span> [<span class="dt">Bool</span>] <span class="kw">where</span></span>
<span id="cb24-31"><a href="#cb24-31" aria-hidden="true" tabindex="-1"></a>        <span class="dt">CarryOne</span> &#39;[] <span class="ot">=</span> <span class="dt">True</span> <span class="op">:</span> &#39;[]</span>
<span id="cb24-32"><a href="#cb24-32" aria-hidden="true" tabindex="-1"></a>        <span class="dt">CarryOne</span> (<span class="dt">False</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">True</span> <span class="op">:</span> xs</span>
<span id="cb24-33"><a href="#cb24-33" aria-hidden="true" tabindex="-1"></a>        <span class="dt">CarryOne</span> (<span class="dt">True</span>  <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">False</span> <span class="op">:</span> <span class="dt">CarryOne</span> xs</span></code></pre></div>
<p>The odd definition of <code
class="sourceCode haskell"><span class="dt">Carry</span></code> is to
avoid <code
class="sourceCode haskell"><span class="dt">UndecidableInstances</span></code>:
if we had written, instead:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Carry</span> (<span class="ot">x ::</span> <span class="dt">Bool</span>) (<span class="ot">y ::</span> <span class="dt">Bool</span>) (<span class="ot">cin ::</span> <span class="dt">Bool</span>)<span class="ot"> ::</span> <span class="dt">Bool</span> <span class="kw">where</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">False</span> <span class="dt">False</span> <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">False</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="dt">False</span> <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">False</span> <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="dt">False</span> <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Carry</span> <span class="dt">True</span>  <span class="dt">True</span>  <span class="dt">True</span>  <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">Add</span> (<span class="ot">cin ::</span> <span class="dt">Bool</span>) (<span class="ot">xs ::</span> [<span class="dt">Bool</span>]) (<span class="ot">ys ::</span> [<span class="dt">Bool</span>]) <span class="ot">::</span></span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>     [<span class="dt">Bool</span>] <span class="kw">where</span></span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> c (x <span class="op">:</span> xs) (y <span class="op">:</span> ys) <span class="ot">=</span> <span class="dt">Sum</span> x y c <span class="op">:</span> <span class="dt">Add</span> (<span class="dt">Carry</span> x y c) xs ys</span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">False</span> &#39;[] ys <span class="ot">=</span> ys</span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">False</span> xs &#39;[] <span class="ot">=</span> xs</span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">True</span>  &#39;[] ys <span class="ot">=</span> <span class="dt">CarryOne</span> ys</span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Add</span> <span class="dt">True</span>  xs &#39;[] <span class="ot">=</span> <span class="dt">CarryOne</span> xs</span></code></pre></div>
<p>We would have been warned about nested type-family application.</p>
<p>Now we can base the merge function very closely on these type
families. First, though, we’ll have to implement the heap.</p>
<h3 id="almost-verified-data-structures">Almost-Verified Data
Structures</h3>
<p>There are different potential properties you can verify in a data
structure. In the sort-traversable post, the property of interest was
that the number of elements in the structure would stay the same after
adding and removing some number
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
of elements. For this post, we’ll also verify structural invariants. I
won’t, however, verify the <a
href="https://www.cs.cmu.edu/~adamchik/15-121/lectures/Binary%20Heaps/heaps.html">heap
property</a>. Maybe in a later post.</p>
<p>When indexing a data structure by its size, you encode an awful lot
of information into the type signature: the type becomes very
<em>specific</em> to the structure in question. It is possible, though,
to encode a fair few structural invariants <em>without</em> getting so
specific. Here’s a signature for “perfect leaf tree”:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BalTree</span> a <span class="ot">=</span> <span class="dt">Leaf</span> a <span class="op">|</span> <span class="dt">Node</span> (<span class="dt">BalTree</span> (a,a))</span></code></pre></div>
<p>With that signature, it’s <em>impossible</em> to create a tree with
more elements in its left branch than its right; the size of the tree,
however, remains unspecified. You can use a similar trick to implement
<a href="https://github.com/oisdk/Square">matrices which must be
square</a> <span class="citation" data-cites="okasaki_fast_1999">(from
<a href="#ref-okasaki_fast_1999" role="doc-biblioref">Okasaki
1999</a>)</span>: the usual trick (<code
class="sourceCode haskell"><span class="kw">type</span> <span class="dt">Matrix</span> n a <span class="ot">=</span> <span class="dt">List</span> n (<span class="dt">List</span> n a)</code>)
is too specific, providing size information at compile-time. If you’re
interested in this approach, there are several more examples in <span
class="citation" data-cites="hinze_manufacturing_2001">Hinze (<a
href="#ref-hinze_manufacturing_2001"
role="doc-biblioref">2001</a>)</span>.</p>
<p>It is possible to go from the size-indexed version back to the
non-indexed version, with an existential (<code
class="sourceCode haskell"><span class="dt">RankNTypes</span></code> for
this example):</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ErasedSize</span> f a <span class="ot">=</span> <span class="kw">forall</span> (<span class="ot">n ::</span> <span class="dt">Peano</span>)<span class="op">.</span> <span class="dt">ErasedSize</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> runErasedSize ::</span> f n a</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>    }</span></code></pre></div>
<p>This will let you prove invariants in your implementation using an
index, while keeping the user-facing type signature general and
non-indexed.</p>
<h3 id="a-fully-structurally-verified-binomial-heap">A
Fully-Structurally-Verified Binomial Heap</h3>
<p><span class="citation" data-cites="wasserman_playing_2010">Wasserman
(<a href="#ref-wasserman_playing_2010"
role="doc-biblioref">2010</a>)</span>, was able to encode all of the
structural invariants of the binomial heap <em>without</em> indexing by
its size (well, all invariants except truncation, which turned out to be
important a little later). I’ll be using a similar approach, except I’ll
leverage some of the newer bells and whistles in GHC. Where Wasserman’s
version used types like this for the numbering:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Zero</span> a <span class="ot">=</span> <span class="dt">Zero</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Succ</span> rk a <span class="ot">=</span> <span class="dt">BinomTree</span> rk a <span class="op">:&lt;</span> rk a</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BinomTree</span> rk a <span class="ot">=</span> <span class="dt">BinomTree</span> a (rk a)</span></code></pre></div>
<p>We can reuse the type-level Peano numbers with a GADT:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Binomial</span> xs rk a <span class="kw">where</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>       <span class="dt">Nil</span><span class="ot"> ::</span> <span class="dt">Binomial</span> &#39;[] n a</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>       <span class="dt">Skip</span><span class="ot"> ::</span> <span class="dt">Binomial</span> xs (<span class="dt">S</span> rk) a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dt">False</span> <span class="op">:</span> xs) rk a</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a><span class="ot">       (:-) ::</span> <span class="dt">Tree</span> rk a</span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">Binomial</span> xs (<span class="dt">S</span> rk) a</span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dt">True</span> <span class="op">:</span> xs) rk a</span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> rk a <span class="ot">=</span> <span class="dt">Root</span> a (<span class="dt">Node</span> rk a)</span>
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:&lt;</span></span>
<span id="cb29-12"><a href="#cb29-12" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Node</span> n a <span class="kw">where</span></span>
<span id="cb29-13"><a href="#cb29-13" aria-hidden="true" tabindex="-1"></a>       <span class="dt">NilN</span><span class="ot"> ::</span> <span class="dt">Node</span> <span class="dt">Z</span> a</span>
<span id="cb29-14"><a href="#cb29-14" aria-hidden="true" tabindex="-1"></a><span class="ot">       (:&lt;) ::</span> <span class="dt">Tree</span> n a <span class="ot">-&gt;</span> <span class="dt">Node</span> n a <span class="ot">-&gt;</span> <span class="dt">Node</span> (<span class="dt">S</span> n) a</span></code></pre></div>
<p>The definition of <code
class="sourceCode haskell"><span class="dt">Tree</span></code> here
ensures that any tree of rank
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
has
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><msup><mn>2</mn><mi>n</mi></msup><annotation encoding="application/x-tex">2^n</annotation></semantics></math>
elements. The binomial heap, then, is a list of trees, in ascending
order of size, with a <code
class="sourceCode haskell"><span class="dt">True</span></code> at every
point in its type-level list where a tree is present, and a <code
class="sourceCode haskell"><span class="dt">False</span></code> wherever
one is absent. In other words, the type-level list is a binary encoding
of the number of elements it contains.</p>
<p>And here are the merge functions:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeTree ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> rk a <span class="ot">-&gt;</span> <span class="dt">Tree</span> rk a <span class="ot">-&gt;</span> <span class="dt">Tree</span> (<span class="dt">S</span> rk) a</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>mergeTree xr<span class="op">@</span>(<span class="dt">Root</span> x xs) yr<span class="op">@</span>(<span class="dt">Root</span> y ys)</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> <span class="dt">Root</span> x (yr <span class="op">:&lt;</span> xs)</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Root</span> y (xr <span class="op">:&lt;</span> ys)</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>merge</span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> a</span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Binomial</span> xs z a</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> ys z a</span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dt">Add</span> <span class="dt">False</span> xs ys) z a</span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a>merge <span class="dt">Nil</span> ys              <span class="ot">=</span> ys</span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a>merge xs <span class="dt">Nil</span>              <span class="ot">=</span> xs</span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a>merge (<span class="dt">Skip</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (merge xs ys)</span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a>merge (<span class="dt">Skip</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> y <span class="op">:-</span> merge xs ys</span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a>merge (x <span class="op">:-</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> x <span class="op">:-</span> merge xs ys</span>
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a>merge (x <span class="op">:-</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (mergeCarry (mergeTree x y) xs ys)</span>
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a>mergeCarry</span>
<span id="cb30-19"><a href="#cb30-19" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> a</span>
<span id="cb30-20"><a href="#cb30-20" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Tree</span> rk a</span>
<span id="cb30-21"><a href="#cb30-21" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> xs rk a</span>
<span id="cb30-22"><a href="#cb30-22" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> ys rk a</span>
<span id="cb30-23"><a href="#cb30-23" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dt">Add</span> <span class="dt">True</span> xs ys) rk a</span>
<span id="cb30-24"><a href="#cb30-24" aria-hidden="true" tabindex="-1"></a>mergeCarry t <span class="dt">Nil</span> ys              <span class="ot">=</span> carryOne t ys</span>
<span id="cb30-25"><a href="#cb30-25" aria-hidden="true" tabindex="-1"></a>mergeCarry t xs <span class="dt">Nil</span>              <span class="ot">=</span> carryOne t xs</span>
<span id="cb30-26"><a href="#cb30-26" aria-hidden="true" tabindex="-1"></a>mergeCarry t (<span class="dt">Skip</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> t <span class="op">:-</span> merge xs ys</span>
<span id="cb30-27"><a href="#cb30-27" aria-hidden="true" tabindex="-1"></a>mergeCarry t (<span class="dt">Skip</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (mergeCarry (mergeTree t y) xs ys)</span>
<span id="cb30-28"><a href="#cb30-28" aria-hidden="true" tabindex="-1"></a>mergeCarry t (x <span class="op">:-</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (mergeCarry (mergeTree t x) xs ys)</span>
<span id="cb30-29"><a href="#cb30-29" aria-hidden="true" tabindex="-1"></a>mergeCarry t (x <span class="op">:-</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> t <span class="op">:-</span> mergeCarry (mergeTree x y) xs ys</span>
<span id="cb30-30"><a href="#cb30-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-31"><a href="#cb30-31" aria-hidden="true" tabindex="-1"></a>carryOne</span>
<span id="cb30-32"><a href="#cb30-32" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> a</span>
<span id="cb30-33"><a href="#cb30-33" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Tree</span> rk a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> xs rk a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dt">CarryOne</span> xs) rk a</span>
<span id="cb30-34"><a href="#cb30-34" aria-hidden="true" tabindex="-1"></a>carryOne t <span class="dt">Nil</span>       <span class="ot">=</span> t <span class="op">:-</span> <span class="dt">Nil</span></span>
<span id="cb30-35"><a href="#cb30-35" aria-hidden="true" tabindex="-1"></a>carryOne t (<span class="dt">Skip</span> xs) <span class="ot">=</span> t <span class="op">:-</span> xs</span>
<span id="cb30-36"><a href="#cb30-36" aria-hidden="true" tabindex="-1"></a>carryOne t (x <span class="op">:-</span> xs) <span class="ot">=</span> <span class="dt">Skip</span> (carryOne (mergeTree t x) xs)</span></code></pre></div>
<p>You’ll notice that no proofs are needed: that’s because the merge
function itself is the same as the type family, like the way <code
class="sourceCode haskell"><span class="op">++</span></code> for lists
was the same as the <code
class="sourceCode haskell"><span class="dt">Plus</span></code> type
family.</p>
<p>Of course, this structure is only verified insofar as you believe the
type families. It does provide a degree of double-entry, though: any
mistake in the type family will have to be mirrored in the merge
function to type-check. On top of that, we can write some proofs of
properties we might expect:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>addCommutes</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  ::</span> <span class="dt">The</span> [<span class="dt">Bool</span>] xs</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">-&gt;</span> <span class="dt">The</span> [<span class="dt">Bool</span>] ys</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">-&gt;</span> <span class="dt">Add</span> <span class="dt">False</span> xs ys <span class="op">:~:</span> <span class="dt">Add</span> <span class="dt">False</span> ys xs</span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>addCommutes <span class="dt">Nily</span> _ <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>addCommutes _ <span class="dt">Nily</span> <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>addCommutes (<span class="dt">Cony</span> <span class="dt">Falsy</span> xs) (<span class="dt">Cony</span> <span class="dt">Falsy</span> ys) <span class="ot">=</span></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutes xs ys) <span class="dt">Refl</span></span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>addCommutes (<span class="dt">Cony</span> <span class="dt">Truey</span> xs) (<span class="dt">Cony</span> <span class="dt">Falsy</span> ys) <span class="ot">=</span></span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutes xs ys) <span class="dt">Refl</span></span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a>addCommutes (<span class="dt">Cony</span> <span class="dt">Falsy</span> xs) (<span class="dt">Cony</span> <span class="dt">Truey</span> ys) <span class="ot">=</span></span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutes xs ys) <span class="dt">Refl</span></span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a>addCommutes (<span class="dt">Cony</span> <span class="dt">Truey</span> xs) (<span class="dt">Cony</span> <span class="dt">Truey</span> ys) <span class="ot">=</span></span>
<span id="cb31-14"><a href="#cb31-14" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutesCarry xs ys) <span class="dt">Refl</span></span>
<span id="cb31-15"><a href="#cb31-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-16"><a href="#cb31-16" aria-hidden="true" tabindex="-1"></a>addCommutesCarry</span>
<span id="cb31-17"><a href="#cb31-17" aria-hidden="true" tabindex="-1"></a><span class="ot">  ::</span> <span class="dt">The</span> [<span class="dt">Bool</span>] xs</span>
<span id="cb31-18"><a href="#cb31-18" aria-hidden="true" tabindex="-1"></a>  <span class="ot">-&gt;</span> <span class="dt">The</span> [<span class="dt">Bool</span>] ys</span>
<span id="cb31-19"><a href="#cb31-19" aria-hidden="true" tabindex="-1"></a>  <span class="ot">-&gt;</span> <span class="dt">Add</span> <span class="dt">True</span> xs ys <span class="op">:~:</span> <span class="dt">Add</span> <span class="dt">True</span> ys xs</span>
<span id="cb31-20"><a href="#cb31-20" aria-hidden="true" tabindex="-1"></a>addCommutesCarry <span class="dt">Nily</span> _ <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb31-21"><a href="#cb31-21" aria-hidden="true" tabindex="-1"></a>addCommutesCarry _ <span class="dt">Nily</span> <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb31-22"><a href="#cb31-22" aria-hidden="true" tabindex="-1"></a>addCommutesCarry (<span class="dt">Cony</span> <span class="dt">Falsy</span> xs) (<span class="dt">Cony</span> <span class="dt">Falsy</span> ys) <span class="ot">=</span></span>
<span id="cb31-23"><a href="#cb31-23" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutes xs ys) <span class="dt">Refl</span></span>
<span id="cb31-24"><a href="#cb31-24" aria-hidden="true" tabindex="-1"></a>addCommutesCarry (<span class="dt">Cony</span> <span class="dt">Truey</span> xs) (<span class="dt">Cony</span> <span class="dt">Falsy</span> ys) <span class="ot">=</span></span>
<span id="cb31-25"><a href="#cb31-25" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutesCarry xs ys) <span class="dt">Refl</span></span>
<span id="cb31-26"><a href="#cb31-26" aria-hidden="true" tabindex="-1"></a>addCommutesCarry (<span class="dt">Cony</span> <span class="dt">Falsy</span> xs) (<span class="dt">Cony</span> <span class="dt">Truey</span> ys) <span class="ot">=</span></span>
<span id="cb31-27"><a href="#cb31-27" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutesCarry xs ys) <span class="dt">Refl</span></span>
<span id="cb31-28"><a href="#cb31-28" aria-hidden="true" tabindex="-1"></a>addCommutesCarry (<span class="dt">Cony</span> <span class="dt">Truey</span> xs) (<span class="dt">Cony</span> <span class="dt">Truey</span> ys) <span class="ot">=</span></span>
<span id="cb31-29"><a href="#cb31-29" aria-hidden="true" tabindex="-1"></a>    gcastWith (addCommutesCarry xs ys) <span class="dt">Refl</span></span></code></pre></div>
<p>Unfortunately, though, this method <em>does</em> require proofs (ugly
proofs) for the delete-min operation. One of the issues is truncation:
since the binary digits are stored least-significant-bit first, the same
number can be represented with any number of trailing zeroes. This kept
causing problems for me when it came to subtraction, and adding the
requirement of no trailing zeroes (truncation) to the constructors for
the heap was a pain, requiring extra proofs on merge to show that it
preserves truncation.</p>
<h3 id="doubly-dependent-types">Doubly-Dependent Types</h3>
<p>Since some of these properties are much easier to verify on the
type-level Peano numbers, one approach might be to convert back and
forth between Peano numbers and binary, and use the proofs on Peano
numbers instead.</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">BintoPeano</span> (<span class="ot">xs ::</span> [<span class="dt">Bool</span>])<span class="ot"> ::</span> <span class="dt">Peano</span> <span class="kw">where</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">BintoPeano</span> &#39;[] <span class="ot">=</span> <span class="dt">Z</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">BintoPeano</span> (<span class="dt">False</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">BintoPeano</span> xs <span class="op">+</span> <span class="dt">BintoPeano</span> xs</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>        <span class="dt">BintoPeano</span> (<span class="dt">True</span> <span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">S</span> (<span class="dt">BintoPeano</span> xs <span class="op">+</span> <span class="dt">BintoPeano</span> xs)</span></code></pre></div>
<p>First problem: this requires <code
class="sourceCode haskell"><span class="dt">UndecidableInstances</span></code>.
I’d <em>really</em> rather not have that turned on, to be honest. In
Idris (and Agda), you can <em>prove</em> decidability using <a
href="https://www.idris-lang.org/docs/0.12/contrib_doc/docs/Control.WellFounded.html">a
number of different methods</a>, but this isn’t available in Haskell
yet.</p>
<p>Regardless, we can push on.</p>
<p>To go in the other direction, we’ll need to calculate the parity of
natural numbers. Taken from <a
href="http://docs.idris-lang.org/en/latest/tutorial/theorems.html#theorems-in-practice">the
Idris tutorial</a>:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Parity</span> (<span class="ot">n ::</span> <span class="dt">Peano</span>) <span class="kw">where</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Even</span><span class="ot"> ::</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="ot">-&gt;</span> <span class="dt">Parity</span> (n <span class="op">+</span> n)</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Odd</span><span class="ot">  ::</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="ot">-&gt;</span> <span class="dt">Parity</span> (<span class="dt">S</span> (n <span class="op">+</span> n))</span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a><span class="ot">parity ::</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="ot">-&gt;</span> <span class="dt">Parity</span> n</span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>parity <span class="dt">Zy</span> <span class="ot">=</span> <span class="dt">Even</span> <span class="dt">Zy</span></span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>parity (<span class="dt">Sy</span> <span class="dt">Zy</span>) <span class="ot">=</span> <span class="dt">Odd</span> <span class="dt">Zy</span></span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a>parity (<span class="dt">Sy</span> (<span class="dt">Sy</span> n)) <span class="ot">=</span> <span class="kw">case</span> parity n <span class="kw">of</span></span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Even</span> m <span class="ot">-&gt;</span> gcastWith (plusSuccDistrib m m) (<span class="dt">Even</span> (<span class="dt">Sy</span> m))</span>
<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Odd</span>  m <span class="ot">-&gt;</span> gcastWith (plusSuccDistrib m m) (<span class="dt">Odd</span> (<span class="dt">Sy</span> m))</span>
<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-12"><a href="#cb33-12" aria-hidden="true" tabindex="-1"></a><span class="ot">plusSuccDistrib ::</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="ot">-&gt;</span> proxy m <span class="ot">-&gt;</span> n <span class="op">+</span> <span class="dt">S</span> m <span class="op">:~:</span> <span class="dt">S</span> (n <span class="op">+</span> m)</span>
<span id="cb33-13"><a href="#cb33-13" aria-hidden="true" tabindex="-1"></a>plusSuccDistrib <span class="dt">Zy</span> _ <span class="ot">=</span> <span class="dt">Refl</span></span>
<span id="cb33-14"><a href="#cb33-14" aria-hidden="true" tabindex="-1"></a>plusSuccDistrib (<span class="dt">Sy</span> n) p <span class="ot">=</span> gcastWith (plusSuccDistrib n p) <span class="dt">Refl</span></span></code></pre></div>
<p>We need this function on the type-level, though, not the value-level:
here, again, we run into trouble. What does <code
class="sourceCode haskell">gcastWith</code> look like on the type-level?
As far as I can tell, it doesn’t exist (yet. Although I haven’t looked
deeply into the singletons library yet).</p>
<p>This idea of doing dependently-typed stuff on the type-level
<em>started</em> to be possible with <code
class="sourceCode haskell"><span class="dt">TypeInType</span></code>.
For instance, we could have defined our binary type as:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Binary</span><span class="ot"> ::</span> <span class="dt">Peano</span> <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">O</span><span class="ot"> ::</span> <span class="dt">Binary</span> n <span class="ot">-&gt;</span> <span class="dt">Binary</span> (n <span class="op">+</span> n)</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">I</span><span class="ot"> ::</span> <span class="dt">Binary</span> n <span class="ot">-&gt;</span> <span class="dt">Binary</span> (<span class="dt">S</span> (n <span class="op">+</span> n))</span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">E</span><span class="ot"> ::</span> <span class="dt">Binary</span> <span class="dt">Z</span></span></code></pre></div>
<p>And then the binomial heap as:</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Binomial</span> (<span class="ot">xs ::</span> <span class="dt">Binary</span> n) (<span class="ot">rk ::</span> <span class="dt">Peano</span>) (<span class="ot">a ::</span> <span class="dt">Type</span>) <span class="kw">where</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>       <span class="dt">Nil</span><span class="ot"> ::</span> <span class="dt">Binomial</span> <span class="dt">E</span> n a</span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>       <span class="dt">Skip</span><span class="ot"> ::</span> <span class="dt">Binomial</span> xs (<span class="dt">S</span> rk) a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dt">O</span> xs) rk a</span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a><span class="ot">       (:-) ::</span> <span class="dt">Tree</span> rk a</span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">Binomial</span> xs (<span class="dt">S</span> rk) a</span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dt">I</span> xs) rk a</span></code></pre></div>
<p>What we’re doing here is indexing a type <em>by an indexed type</em>.
<a href="http://stackoverflow.com/a/13241158/4892417">This wasn’t
possible in Haskell a few years ago</a>. It still doesn’t get us a nice
definition of subtraction, though.</p>
<h3 id="using-a-typechecker-plugin">Using a Typechecker Plugin</h3>
<p>It’s pretty clear that this approach gets tedious almost immediately.
What’s more, if we want the proofs to be erased, we introduce potential
for errors.</p>
<p>The solution? Beef up GHC’s typechecker with a plugin. I first came
across this approach in <a
href="https://www.youtube.com/watch?v=u_OsUlwkmBQ">Kenneth Foner’s talk
at Compose</a>. He used a plugin that called out to the <a
href="https://github.com/Z3Prover/z3">Z3 theorem prover</a> <span
class="citation" data-cites="diatchki_improving_2015">(from <a
href="#ref-diatchki_improving_2015" role="doc-biblioref">Diatchki
2015</a>)</span>; I’ll use a <a
href="https://hackage.haskell.org/package/ghc-typelits-natnormalise">simpler
plugin</a> which just normalizes type-literals.</p>
<p>From what I’ve used of these plugins so far, they seem to work really
well. They’re very unobtrusive, only requiring a pragma at the top of
your file:</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# OPTIONS_GHC -fplugin GHC.TypeLits.Normalise #-}</span></span></code></pre></div>
<p>The plugin is only called when GHC can’t unify two types: this means
you don’t get odd-looking error messages in unrelated code (in fact, the
error messages I’ve seen so far have been excellent—a real improvement
on the standard error messages for type-level arithmetic). Another
benefit is that we get to use type-level literals (<code
class="sourceCode haskell"><span class="dt">Nat</span></code> imported
from <a
href="https://hackage.haskell.org/package/base-4.9.1.0/docs/GHC-TypeLits.html">GHC.TypeLits</a>),
rather then the noisy-looking type-level Peano numbers.</p>
<div class="sourceCode" id="cb37"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> n a <span class="ot">=</span> <span class="dt">Root</span> a (<span class="dt">Node</span> n a)</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Node</span><span class="ot"> ::</span> <span class="dt">Nat</span> <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>        <span class="dt">NilN</span><span class="ot"> ::</span> <span class="dt">Node</span> <span class="dv">0</span> a</span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a><span class="ot">        (:&lt;) ::</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span>(<span class="dt">Tree</span> n a)</span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Node</span> n a</span>
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Node</span> (<span class="dv">1</span> <span class="op">+</span> n) a</span>
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeTree ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> n a <span class="ot">-&gt;</span> <span class="dt">Tree</span> n a <span class="ot">-&gt;</span> <span class="dt">Tree</span> (<span class="dv">1</span> <span class="op">+</span> n) a</span>
<span id="cb37-10"><a href="#cb37-10" aria-hidden="true" tabindex="-1"></a>mergeTree xr<span class="op">@</span>(<span class="dt">Root</span> x xs) yr<span class="op">@</span>(<span class="dt">Root</span> y ys)</span>
<span id="cb37-11"><a href="#cb37-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">&lt;=</span> y    <span class="ot">=</span> <span class="dt">Root</span> x (yr <span class="op">:&lt;</span> xs)</span>
<span id="cb37-12"><a href="#cb37-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Root</span> y (xr <span class="op">:&lt;</span> ys)</span>
<span id="cb37-13"><a href="#cb37-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-14"><a href="#cb37-14" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb37-15"><a href="#cb37-15" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Binomial</span><span class="ot"> ::</span> <span class="dt">Nat</span> <span class="ot">-&gt;</span> <span class="dt">Nat</span> <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="ot">-&gt;</span> <span class="dt">Type</span> <span class="kw">where</span></span>
<span id="cb37-16"><a href="#cb37-16" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">Binomial</span> n <span class="dv">0</span> a</span>
<span id="cb37-17"><a href="#cb37-17" aria-hidden="true" tabindex="-1"></a><span class="ot">        (:-) ::</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span>(<span class="dt">Tree</span> z a)</span>
<span id="cb37-18"><a href="#cb37-18" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Binomial</span> (<span class="dv">1</span> <span class="op">+</span> z) xs a</span>
<span id="cb37-19"><a href="#cb37-19" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z (<span class="dv">1</span> <span class="op">+</span> xs <span class="op">+</span> xs) a</span>
<span id="cb37-20"><a href="#cb37-20" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Skip</span><span class="ot"> ::</span> <span class="dt">Binomial</span> (<span class="dv">1</span> <span class="op">+</span> z) (<span class="dv">1</span> <span class="op">+</span> xs) a</span>
<span id="cb37-21"><a href="#cb37-21" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z (<span class="dv">2</span> <span class="op">+</span> xs <span class="op">+</span> xs) a</span></code></pre></div>
<p>This definition also ensures that the binomial heap has no trailing
zeroes in its binary representation: the <code
class="sourceCode haskell"><span class="dt">Skip</span></code>
constructor can only be applied to a heap bigger than zero.</p>
<p>Since we’re going to be looking at several different heaps, we’ll
need a class to represent all of them:</p>
<div class="sourceCode" id="cb38"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">IndexedQueue</span> h a <span class="kw">where</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# MINIMAL insert, empty, minViewMay, minView #-}</span></span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a>    empty</span>
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true" tabindex="-1"></a><span class="ot">        ::</span> h <span class="dv">0</span> a</span>
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-8"><a href="#cb38-8" aria-hidden="true" tabindex="-1"></a>    minView</span>
<span id="cb38-9"><a href="#cb38-9" aria-hidden="true" tabindex="-1"></a><span class="ot">        ::</span> h (<span class="dv">1</span> <span class="op">+</span> n) a <span class="ot">-&gt;</span> (a, h n a)</span>
<span id="cb38-10"><a href="#cb38-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-11"><a href="#cb38-11" aria-hidden="true" tabindex="-1"></a>    singleton</span>
<span id="cb38-12"><a href="#cb38-12" aria-hidden="true" tabindex="-1"></a><span class="ot">        ::</span> a <span class="ot">-&gt;</span> h <span class="dv">1</span> a</span>
<span id="cb38-13"><a href="#cb38-13" aria-hidden="true" tabindex="-1"></a>    singleton <span class="ot">=</span> <span class="fu">flip</span> insert empty</span>
<span id="cb38-14"><a href="#cb38-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-15"><a href="#cb38-15" aria-hidden="true" tabindex="-1"></a>    insert</span>
<span id="cb38-16"><a href="#cb38-16" aria-hidden="true" tabindex="-1"></a><span class="ot">        ::</span> a <span class="ot">-&gt;</span> h n a <span class="ot">-&gt;</span> h (<span class="dv">1</span> <span class="op">+</span> n) a</span>
<span id="cb38-17"><a href="#cb38-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-18"><a href="#cb38-18" aria-hidden="true" tabindex="-1"></a>    minViewMay</span>
<span id="cb38-19"><a href="#cb38-19" aria-hidden="true" tabindex="-1"></a><span class="ot">       ::</span> h n a</span>
<span id="cb38-20"><a href="#cb38-20" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> (n <span class="op">~</span> <span class="dv">0</span> <span class="ot">=&gt;</span> b)</span>
<span id="cb38-21"><a href="#cb38-21" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> (<span class="kw">forall</span> m<span class="op">.</span> (<span class="dv">1</span> <span class="op">+</span> m) <span class="op">~</span> n <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> h m a <span class="ot">-&gt;</span> b)</span>
<span id="cb38-22"><a href="#cb38-22" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> b</span>
<span id="cb38-23"><a href="#cb38-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-24"><a href="#cb38-24" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">IndexedQueue</span> h a <span class="ot">=&gt;</span></span>
<span id="cb38-25"><a href="#cb38-25" aria-hidden="true" tabindex="-1"></a>      <span class="dt">MeldableIndexedQueue</span> h a <span class="kw">where</span></span>
<span id="cb38-26"><a href="#cb38-26" aria-hidden="true" tabindex="-1"></a>    merge</span>
<span id="cb38-27"><a href="#cb38-27" aria-hidden="true" tabindex="-1"></a><span class="ot">        ::</span> h n a <span class="ot">-&gt;</span> h m a <span class="ot">-&gt;</span> h (n <span class="op">+</span> m) a</span></code></pre></div>
<p>You’ll need <code
class="sourceCode haskell"><span class="dt">MultiParamTypeClasses</span></code>
for this one.</p>
<div class="sourceCode" id="cb39"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a>mergeB</span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> a</span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Binomial</span> z xs a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z ys a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z (xs <span class="op">+</span> ys) a</span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a>mergeB <span class="dt">Nil</span> ys              <span class="ot">=</span> ys</span>
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a>mergeB xs <span class="dt">Nil</span>              <span class="ot">=</span> xs</span>
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a>mergeB (<span class="dt">Skip</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (mergeB xs ys)</span>
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a>mergeB (<span class="dt">Skip</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> y <span class="op">:-</span> mergeB xs ys</span>
<span id="cb39-8"><a href="#cb39-8" aria-hidden="true" tabindex="-1"></a>mergeB (x <span class="op">:-</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> x <span class="op">:-</span> mergeB xs ys</span>
<span id="cb39-9"><a href="#cb39-9" aria-hidden="true" tabindex="-1"></a>mergeB (x <span class="op">:-</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (mergeCarry (mergeTree x y) xs ys)</span>
<span id="cb39-10"><a href="#cb39-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb39-11"><a href="#cb39-11" aria-hidden="true" tabindex="-1"></a>mergeCarry</span>
<span id="cb39-12"><a href="#cb39-12" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Ord</span> a</span>
<span id="cb39-13"><a href="#cb39-13" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Tree</span> z a</span>
<span id="cb39-14"><a href="#cb39-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z xs a</span>
<span id="cb39-15"><a href="#cb39-15" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z ys a</span>
<span id="cb39-16"><a href="#cb39-16" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z (<span class="dv">1</span> <span class="op">+</span> xs <span class="op">+</span> ys) a</span>
<span id="cb39-17"><a href="#cb39-17" aria-hidden="true" tabindex="-1"></a>mergeCarry <span class="op">!</span>t <span class="dt">Nil</span> ys              <span class="ot">=</span> carryOne t ys</span>
<span id="cb39-18"><a href="#cb39-18" aria-hidden="true" tabindex="-1"></a>mergeCarry <span class="op">!</span>t xs <span class="dt">Nil</span>              <span class="ot">=</span> carryOne t xs</span>
<span id="cb39-19"><a href="#cb39-19" aria-hidden="true" tabindex="-1"></a>mergeCarry <span class="op">!</span>t (<span class="dt">Skip</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> t <span class="op">:-</span> mergeB xs ys</span>
<span id="cb39-20"><a href="#cb39-20" aria-hidden="true" tabindex="-1"></a>mergeCarry <span class="op">!</span>t (<span class="dt">Skip</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (mergeCarry (mergeTree t y) xs ys)</span>
<span id="cb39-21"><a href="#cb39-21" aria-hidden="true" tabindex="-1"></a>mergeCarry <span class="op">!</span>t (x <span class="op">:-</span> xs) (<span class="dt">Skip</span> ys) <span class="ot">=</span> <span class="dt">Skip</span> (mergeCarry (mergeTree t x) xs ys)</span>
<span id="cb39-22"><a href="#cb39-22" aria-hidden="true" tabindex="-1"></a>mergeCarry <span class="op">!</span>t (x <span class="op">:-</span> xs) (y <span class="op">:-</span> ys) <span class="ot">=</span> t <span class="op">:-</span> mergeCarry (mergeTree x y) xs ys</span>
<span id="cb39-23"><a href="#cb39-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb39-24"><a href="#cb39-24" aria-hidden="true" tabindex="-1"></a><span class="ot">carryOne ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Tree</span> z a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z xs a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z (<span class="dv">1</span> <span class="op">+</span> xs) a</span>
<span id="cb39-25"><a href="#cb39-25" aria-hidden="true" tabindex="-1"></a>carryOne <span class="op">!</span>t <span class="dt">Nil</span>       <span class="ot">=</span> t <span class="op">:-</span> <span class="dt">Nil</span></span>
<span id="cb39-26"><a href="#cb39-26" aria-hidden="true" tabindex="-1"></a>carryOne <span class="op">!</span>t (<span class="dt">Skip</span> xs) <span class="ot">=</span> t <span class="op">:-</span> xs</span>
<span id="cb39-27"><a href="#cb39-27" aria-hidden="true" tabindex="-1"></a>carryOne <span class="op">!</span>t (x <span class="op">:-</span> xs) <span class="ot">=</span> <span class="dt">Skip</span> (carryOne (mergeTree t x) xs)</span>
<span id="cb39-28"><a href="#cb39-28" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb39-29"><a href="#cb39-29" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">MeldableIndexedQueue</span> (<span class="dt">Binomial</span> <span class="dv">0</span>) a <span class="kw">where</span></span>
<span id="cb39-30"><a href="#cb39-30" aria-hidden="true" tabindex="-1"></a>    merge <span class="ot">=</span> mergeB</span>
<span id="cb39-31"><a href="#cb39-31" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE merge #-}</span></span>
<span id="cb39-32"><a href="#cb39-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb39-33"><a href="#cb39-33" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">IndexedQueue</span> (<span class="dt">Binomial</span> <span class="dv">0</span>) a <span class="kw">where</span></span>
<span id="cb39-34"><a href="#cb39-34" aria-hidden="true" tabindex="-1"></a>    empty <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb39-35"><a href="#cb39-35" aria-hidden="true" tabindex="-1"></a>    singleton x <span class="ot">=</span> <span class="dt">Root</span> x <span class="dt">NilN</span> <span class="op">:-</span> <span class="dt">Nil</span></span>
<span id="cb39-36"><a href="#cb39-36" aria-hidden="true" tabindex="-1"></a>    insert <span class="ot">=</span> merge <span class="op">.</span> singleton</span></code></pre></div>
<p>(<code
class="sourceCode haskell"><span class="dt">BangPatterns</span></code>
for this example)</p>
<p>On top of that, it’s very easy to define delete-min:</p>
<div class="sourceCode" id="cb40"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a>    minView xs <span class="ot">=</span> <span class="kw">case</span> minViewZip xs <span class="kw">of</span></span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Zipper</span> x _ ys <span class="ot">-&gt;</span> (x, ys)</span>
<span id="cb40-3"><a href="#cb40-3" aria-hidden="true" tabindex="-1"></a>    minViewMay q b f <span class="ot">=</span> <span class="kw">case</span> q <span class="kw">of</span></span>
<span id="cb40-4"><a href="#cb40-4" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Nil</span> <span class="ot">-&gt;</span> b</span>
<span id="cb40-5"><a href="#cb40-5" aria-hidden="true" tabindex="-1"></a>      _ <span class="op">:-</span> _ <span class="ot">-&gt;</span> <span class="fu">uncurry</span> f (minView q)</span>
<span id="cb40-6"><a href="#cb40-6" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Skip</span> _ <span class="ot">-&gt;</span> <span class="fu">uncurry</span> f (minView q)</span>
<span id="cb40-7"><a href="#cb40-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-8"><a href="#cb40-8" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Zipper</span> a n rk <span class="ot">=</span> <span class="dt">Zipper</span> <span class="op">!</span>a (<span class="dt">Node</span> rk a) (<span class="dt">Binomial</span> rk n a)</span>
<span id="cb40-9"><a href="#cb40-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-10"><a href="#cb40-10" aria-hidden="true" tabindex="-1"></a><span class="ot">skip ::</span> <span class="dt">Binomial</span> (<span class="dv">1</span> <span class="op">+</span> z) xs a <span class="ot">-&gt;</span> <span class="dt">Binomial</span> z (xs <span class="op">+</span> xs) a</span>
<span id="cb40-11"><a href="#cb40-11" aria-hidden="true" tabindex="-1"></a>skip x <span class="ot">=</span> <span class="kw">case</span> x <span class="kw">of</span></span>
<span id="cb40-12"><a href="#cb40-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span>    <span class="ot">-&gt;</span> <span class="dt">Nil</span></span>
<span id="cb40-13"><a href="#cb40-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Skip</span> _ <span class="ot">-&gt;</span> <span class="dt">Skip</span> x</span>
<span id="cb40-14"><a href="#cb40-14" aria-hidden="true" tabindex="-1"></a>  _ <span class="op">:-</span> _ <span class="ot">-&gt;</span> <span class="dt">Skip</span> x</span>
<span id="cb40-15"><a href="#cb40-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-16"><a href="#cb40-16" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">MinViewZipper</span> a n rk <span class="kw">where</span></span>
<span id="cb40-17"><a href="#cb40-17" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Infty</span><span class="ot"> ::</span> <span class="dt">MinViewZipper</span> a <span class="dv">0</span> rk</span>
<span id="cb40-18"><a href="#cb40-18" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Min</span><span class="ot"> ::</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span>(<span class="dt">Zipper</span> a n rk) <span class="ot">-&gt;</span> <span class="dt">MinViewZipper</span> a (n<span class="op">+</span><span class="dv">1</span>) rk</span>
<span id="cb40-19"><a href="#cb40-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-20"><a href="#cb40-20" aria-hidden="true" tabindex="-1"></a><span class="ot">slideLeft ::</span> <span class="dt">Zipper</span> a n (<span class="dv">1</span> <span class="op">+</span> rk) <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a (<span class="dv">1</span> <span class="op">+</span> n <span class="op">+</span> n) rk</span>
<span id="cb40-21"><a href="#cb40-21" aria-hidden="true" tabindex="-1"></a>slideLeft (<span class="dt">Zipper</span> m (t <span class="op">:&lt;</span> ts) hs)</span>
<span id="cb40-22"><a href="#cb40-22" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Zipper</span> m ts (t <span class="op">:-</span> hs)</span>
<span id="cb40-23"><a href="#cb40-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-24"><a href="#cb40-24" aria-hidden="true" tabindex="-1"></a>pushLeft</span>
<span id="cb40-25"><a href="#cb40-25" aria-hidden="true" tabindex="-1"></a><span class="ot">  ::</span> <span class="dt">Ord</span> a</span>
<span id="cb40-26"><a href="#cb40-26" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=&gt;</span> <span class="dt">Tree</span> rk a</span>
<span id="cb40-27"><a href="#cb40-27" aria-hidden="true" tabindex="-1"></a>  <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a n (<span class="dv">1</span> <span class="op">+</span> rk)</span>
<span id="cb40-28"><a href="#cb40-28" aria-hidden="true" tabindex="-1"></a>  <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a (<span class="dv">2</span> <span class="op">+</span> n <span class="op">+</span> n) rk</span>
<span id="cb40-29"><a href="#cb40-29" aria-hidden="true" tabindex="-1"></a>pushLeft c (<span class="dt">Zipper</span> m (t <span class="op">:&lt;</span> ts) hs)</span>
<span id="cb40-30"><a href="#cb40-30" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Zipper</span> m ts (<span class="dt">Skip</span> (carryOne (mergeTree c t) hs))</span>
<span id="cb40-31"><a href="#cb40-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-32"><a href="#cb40-32" aria-hidden="true" tabindex="-1"></a><span class="ot">minViewZip ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Binomial</span> rk (<span class="dv">1</span> <span class="op">+</span> n) a <span class="ot">-&gt;</span> <span class="dt">Zipper</span> a n rk</span>
<span id="cb40-33"><a href="#cb40-33" aria-hidden="true" tabindex="-1"></a>minViewZip (<span class="dt">Skip</span> xs) <span class="ot">=</span> slideLeft (minViewZip xs)</span>
<span id="cb40-34"><a href="#cb40-34" aria-hidden="true" tabindex="-1"></a>minViewZip (t<span class="op">@</span>(<span class="dt">Root</span> x ts) <span class="op">:-</span> f) <span class="ot">=</span> <span class="kw">case</span> minViewZipMay f <span class="kw">of</span></span>
<span id="cb40-35"><a href="#cb40-35" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Min</span> ex<span class="op">@</span>(<span class="dt">Zipper</span> minKey _ _) <span class="op">|</span> minKey <span class="op">&lt;</span> x <span class="ot">-&gt;</span> pushLeft t ex</span>
<span id="cb40-36"><a href="#cb40-36" aria-hidden="true" tabindex="-1"></a>  _                          <span class="ot">-&gt;</span> <span class="dt">Zipper</span> x ts (skip f)</span>
<span id="cb40-37"><a href="#cb40-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb40-38"><a href="#cb40-38" aria-hidden="true" tabindex="-1"></a><span class="ot">minViewZipMay ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Binomial</span> rk n a <span class="ot">-&gt;</span> <span class="dt">MinViewZipper</span> a n rk</span>
<span id="cb40-39"><a href="#cb40-39" aria-hidden="true" tabindex="-1"></a>minViewZipMay (<span class="dt">Skip</span> xs) <span class="ot">=</span> <span class="dt">Min</span> (slideLeft (minViewZip xs))</span>
<span id="cb40-40"><a href="#cb40-40" aria-hidden="true" tabindex="-1"></a>minViewZipMay <span class="dt">Nil</span> <span class="ot">=</span> <span class="dt">Infty</span></span>
<span id="cb40-41"><a href="#cb40-41" aria-hidden="true" tabindex="-1"></a>minViewZipMay (t<span class="op">@</span>(<span class="dt">Root</span> x ts) <span class="op">:-</span> f) <span class="ot">=</span> <span class="dt">Min</span> <span class="op">$</span> <span class="kw">case</span> minViewZipMay f <span class="kw">of</span></span>
<span id="cb40-42"><a href="#cb40-42" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Min</span> ex<span class="op">@</span>(<span class="dt">Zipper</span> minKey _ _) <span class="op">|</span> minKey <span class="op">&lt;</span> x <span class="ot">-&gt;</span> pushLeft t ex</span>
<span id="cb40-43"><a href="#cb40-43" aria-hidden="true" tabindex="-1"></a>  _                          <span class="ot">-&gt;</span> <span class="dt">Zipper</span> x ts (skip f)</span></code></pre></div>
<p>Similarly, compare the version of the pairing heap with the
plugin:</p>
<div class="sourceCode" id="cb41"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heap</span> n a <span class="kw">where</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">E</span><span class="ot"> ::</span> <span class="dt">Heap</span> <span class="dv">0</span> a</span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">T</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dv">1</span> <span class="op">+</span> n) a</span>
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">HVec</span> n a <span class="kw">where</span></span>
<span id="cb41-6"><a href="#cb41-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HNil</span><span class="ot"> ::</span> <span class="dt">HVec</span> <span class="dv">0</span> a</span>
<span id="cb41-7"><a href="#cb41-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HCons</span><span class="ot"> ::</span> <span class="dt">Heap</span> m a <span class="ot">-&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">HVec</span> (m <span class="op">+</span> n) a</span>
<span id="cb41-8"><a href="#cb41-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-9"><a href="#cb41-9" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Heap</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dv">1</span> <span class="op">+</span> n) a</span>
<span id="cb41-10"><a href="#cb41-10" aria-hidden="true" tabindex="-1"></a>insert x xs <span class="ot">=</span> merge (<span class="dt">T</span> x <span class="dt">HNil</span>) xs</span>
<span id="cb41-11"><a href="#cb41-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-12"><a href="#cb41-12" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Heap</span> m a <span class="ot">-&gt;</span> <span class="dt">Heap</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (m <span class="op">+</span> n) a</span>
<span id="cb41-13"><a href="#cb41-13" aria-hidden="true" tabindex="-1"></a>merge <span class="dt">E</span> ys <span class="ot">=</span> ys</span>
<span id="cb41-14"><a href="#cb41-14" aria-hidden="true" tabindex="-1"></a>merge xs <span class="dt">E</span> <span class="ot">=</span> xs</span>
<span id="cb41-15"><a href="#cb41-15" aria-hidden="true" tabindex="-1"></a>merge h1<span class="op">@</span>(<span class="dt">T</span> x xs) h2<span class="op">@</span>(<span class="dt">T</span> y ys)</span>
<span id="cb41-16"><a href="#cb41-16" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">&lt;=</span> y <span class="ot">=</span> <span class="dt">T</span> x (<span class="dt">HCons</span> h2 xs)</span>
<span id="cb41-17"><a href="#cb41-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">T</span> y (<span class="dt">HCons</span> h1 ys)</span>
<span id="cb41-18"><a href="#cb41-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-19"><a href="#cb41-19" aria-hidden="true" tabindex="-1"></a><span class="ot">minView ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Heap</span> (<span class="dv">1</span> <span class="op">+</span> n) a <span class="ot">-&gt;</span> (a, <span class="dt">Heap</span> n a)</span>
<span id="cb41-20"><a href="#cb41-20" aria-hidden="true" tabindex="-1"></a>minView (<span class="dt">T</span> x hs) <span class="ot">=</span> (x, mergePairs hs)</span>
<span id="cb41-21"><a href="#cb41-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-22"><a href="#cb41-22" aria-hidden="true" tabindex="-1"></a><span class="ot">mergePairs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> n a</span>
<span id="cb41-23"><a href="#cb41-23" aria-hidden="true" tabindex="-1"></a>mergePairs <span class="dt">HNil</span> <span class="ot">=</span> <span class="dt">E</span></span>
<span id="cb41-24"><a href="#cb41-24" aria-hidden="true" tabindex="-1"></a>mergePairs (<span class="dt">HCons</span> h <span class="dt">HNil</span>) <span class="ot">=</span> h</span>
<span id="cb41-25"><a href="#cb41-25" aria-hidden="true" tabindex="-1"></a>mergePairs (<span class="dt">HCons</span> h1 (<span class="dt">HCons</span> h2 hs)) <span class="ot">=</span></span>
<span id="cb41-26"><a href="#cb41-26" aria-hidden="true" tabindex="-1"></a>    merge (merge h1 h2) (mergePairs hs)</span></code></pre></div>
<p>To the version without the plugin:</p>
<div class="sourceCode" id="cb42"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Heap</span> n a <span class="kw">where</span></span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">E</span><span class="ot"> ::</span> <span class="dt">Heap</span> <span class="dt">Z</span> a</span>
<span id="cb42-3"><a href="#cb42-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">T</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dt">S</span> n) a</span>
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-5"><a href="#cb42-5" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">HVec</span> n a <span class="kw">where</span></span>
<span id="cb42-6"><a href="#cb42-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HNil</span><span class="ot"> ::</span> <span class="dt">HVec</span> <span class="dt">Z</span> a</span>
<span id="cb42-7"><a href="#cb42-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">HCons</span><span class="ot"> ::</span> <span class="dt">Heap</span> m a <span class="ot">-&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">HVec</span> (m <span class="op">+</span> n) a</span>
<span id="cb42-8"><a href="#cb42-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-9"><a href="#cb42-9" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Sized</span> h <span class="kw">where</span></span>
<span id="cb42-10"><a href="#cb42-10" aria-hidden="true" tabindex="-1"></a><span class="ot">  size ::</span> h n a <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Peano</span> n</span>
<span id="cb42-11"><a href="#cb42-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-12"><a href="#cb42-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Sized</span> <span class="dt">Heap</span> <span class="kw">where</span></span>
<span id="cb42-13"><a href="#cb42-13" aria-hidden="true" tabindex="-1"></a>  size <span class="dt">E</span> <span class="ot">=</span> <span class="dt">Zy</span></span>
<span id="cb42-14"><a href="#cb42-14" aria-hidden="true" tabindex="-1"></a>  size (<span class="dt">T</span> _ xs) <span class="ot">=</span> <span class="dt">Sy</span> (size xs)</span>
<span id="cb42-15"><a href="#cb42-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-16"><a href="#cb42-16" aria-hidden="true" tabindex="-1"></a><span class="ot">plus ::</span> <span class="dt">The</span> <span class="dt">Peano</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Peano</span> m <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Peano</span> (n <span class="op">+</span> m)</span>
<span id="cb42-17"><a href="#cb42-17" aria-hidden="true" tabindex="-1"></a>plus <span class="dt">Zy</span> m <span class="ot">=</span> m</span>
<span id="cb42-18"><a href="#cb42-18" aria-hidden="true" tabindex="-1"></a>plus (<span class="dt">Sy</span> n) m <span class="ot">=</span> <span class="dt">Sy</span> (plus n m)</span>
<span id="cb42-19"><a href="#cb42-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-20"><a href="#cb42-20" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Sized</span> <span class="dt">HVec</span> <span class="kw">where</span></span>
<span id="cb42-21"><a href="#cb42-21" aria-hidden="true" tabindex="-1"></a>  size <span class="dt">HNil</span> <span class="ot">=</span> <span class="dt">Zy</span></span>
<span id="cb42-22"><a href="#cb42-22" aria-hidden="true" tabindex="-1"></a>  size (<span class="dt">HCons</span> h hs) <span class="ot">=</span> size h <span class="ot">`plus`</span> size hs</span>
<span id="cb42-23"><a href="#cb42-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-24"><a href="#cb42-24" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Heap</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (<span class="dt">S</span> n) a</span>
<span id="cb42-25"><a href="#cb42-25" aria-hidden="true" tabindex="-1"></a>insert x xs <span class="ot">=</span> merge (<span class="dt">T</span> x <span class="dt">HNil</span>) xs</span>
<span id="cb42-26"><a href="#cb42-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-27"><a href="#cb42-27" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Heap</span> m a <span class="ot">-&gt;</span> <span class="dt">Heap</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> (m <span class="op">+</span> n) a</span>
<span id="cb42-28"><a href="#cb42-28" aria-hidden="true" tabindex="-1"></a>merge <span class="dt">E</span> ys <span class="ot">=</span> ys</span>
<span id="cb42-29"><a href="#cb42-29" aria-hidden="true" tabindex="-1"></a>merge xs <span class="dt">E</span> <span class="ot">=</span> <span class="kw">case</span> plusZero (size xs) <span class="kw">of</span> <span class="dt">Refl</span> <span class="ot">-&gt;</span> xs</span>
<span id="cb42-30"><a href="#cb42-30" aria-hidden="true" tabindex="-1"></a>merge h1<span class="op">@</span>(<span class="dt">T</span> x xs) h2<span class="op">@</span>(<span class="dt">T</span> y ys)</span>
<span id="cb42-31"><a href="#cb42-31" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">&lt;=</span> y <span class="ot">=</span> <span class="kw">case</span> plusCommutative (size h2) (size xs) <span class="kw">of</span></span>
<span id="cb42-32"><a href="#cb42-32" aria-hidden="true" tabindex="-1"></a>                    <span class="dt">Refl</span> <span class="ot">-&gt;</span> <span class="dt">T</span> x (<span class="dt">HCons</span> h2 xs)</span>
<span id="cb42-33"><a href="#cb42-33" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="kw">case</span> plusSuccDistrib (size xs) (size ys) <span class="kw">of</span></span>
<span id="cb42-34"><a href="#cb42-34" aria-hidden="true" tabindex="-1"></a>                    <span class="dt">Refl</span> <span class="ot">-&gt;</span> <span class="dt">T</span> y (<span class="dt">HCons</span> h1 ys)</span>
<span id="cb42-35"><a href="#cb42-35" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-36"><a href="#cb42-36" aria-hidden="true" tabindex="-1"></a><span class="ot">minView ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Heap</span> (<span class="dt">S</span> n) a <span class="ot">-&gt;</span> (a, <span class="dt">Heap</span> n a)</span>
<span id="cb42-37"><a href="#cb42-37" aria-hidden="true" tabindex="-1"></a>minView (<span class="dt">T</span> x hs) <span class="ot">=</span> (x, mergePairs hs)</span>
<span id="cb42-38"><a href="#cb42-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-39"><a href="#cb42-39" aria-hidden="true" tabindex="-1"></a><span class="ot">mergePairs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">HVec</span> n a <span class="ot">-&gt;</span> <span class="dt">Heap</span> n a</span>
<span id="cb42-40"><a href="#cb42-40" aria-hidden="true" tabindex="-1"></a>mergePairs <span class="dt">HNil</span> <span class="ot">=</span> <span class="dt">E</span></span>
<span id="cb42-41"><a href="#cb42-41" aria-hidden="true" tabindex="-1"></a>mergePairs (<span class="dt">HCons</span> h <span class="dt">HNil</span>) <span class="ot">=</span> <span class="kw">case</span> plusZero (size h) <span class="kw">of</span> <span class="dt">Refl</span> <span class="ot">-&gt;</span> h</span>
<span id="cb42-42"><a href="#cb42-42" aria-hidden="true" tabindex="-1"></a>mergePairs (<span class="dt">HCons</span> h1 (<span class="dt">HCons</span> h2 hs)) <span class="ot">=</span></span>
<span id="cb42-43"><a href="#cb42-43" aria-hidden="true" tabindex="-1"></a>  <span class="kw">case</span> plusAssoc (size h1) (size h2) (size hs) <span class="kw">of</span></span>
<span id="cb42-44"><a href="#cb42-44" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Refl</span> <span class="ot">-&gt;</span> merge (merge h1 h2) (mergePairs hs)</span></code></pre></div>
<h3 id="leftist-heaps">Leftist Heaps</h3>
<p>The typechecker plugin makes it relatively easy to implement several
other heaps: skew, Braun, etc. You’ll need one extra trick to implement
a <a
href="http://lambda.jstolarek.com/2014/10/weight-biased-leftist-heaps-verified-in-haskell-using-dependent-types/">leftist
heap</a>, though. Let’s take a look at the unverified version:</p>
<div class="sourceCode" id="cb43"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Leftist</span> a</span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Leaf</span></span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Node</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Int</span></span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a>           a</span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a>           (<span class="dt">Leftist</span> a)</span>
<span id="cb43-6"><a href="#cb43-6" aria-hidden="true" tabindex="-1"></a>           (<span class="dt">Leftist</span> a)</span>
<span id="cb43-7"><a href="#cb43-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-8"><a href="#cb43-8" aria-hidden="true" tabindex="-1"></a><span class="ot">rank ::</span> <span class="dt">Leftist</span> s <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb43-9"><a href="#cb43-9" aria-hidden="true" tabindex="-1"></a>rank <span class="dt">Leaf</span>          <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb43-10"><a href="#cb43-10" aria-hidden="true" tabindex="-1"></a>rank (<span class="dt">Node</span> r _ _ _) <span class="ot">=</span> r</span>
<span id="cb43-11"><a href="#cb43-11" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE rank #-}</span></span>
<span id="cb43-12"><a href="#cb43-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-13"><a href="#cb43-13" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeL ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Leftist</span> a <span class="ot">-&gt;</span> <span class="dt">Leftist</span> a <span class="ot">-&gt;</span> <span class="dt">Leftist</span> a</span>
<span id="cb43-14"><a href="#cb43-14" aria-hidden="true" tabindex="-1"></a>mergeL <span class="dt">Leaf</span> h2 <span class="ot">=</span> h2</span>
<span id="cb43-15"><a href="#cb43-15" aria-hidden="true" tabindex="-1"></a>mergeL h1 <span class="dt">Leaf</span> <span class="ot">=</span> h1</span>
<span id="cb43-16"><a href="#cb43-16" aria-hidden="true" tabindex="-1"></a>mergeL h1<span class="op">@</span>(<span class="dt">Node</span> w1 p1 l1 r1) h2<span class="op">@</span>(<span class="dt">Node</span> w2 p2 l2 r2)</span>
<span id="cb43-17"><a href="#cb43-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> p1 <span class="op">&lt;</span> p2 <span class="ot">=</span></span>
<span id="cb43-18"><a href="#cb43-18" aria-hidden="true" tabindex="-1"></a>      <span class="kw">if</span> ll <span class="op">&lt;=</span> lr</span>
<span id="cb43-19"><a href="#cb43-19" aria-hidden="true" tabindex="-1"></a>          <span class="kw">then</span> <span class="dt">LNode</span> (w1 <span class="op">+</span> w2) p1 l1 (mergeL r1 h2)</span>
<span id="cb43-20"><a href="#cb43-20" aria-hidden="true" tabindex="-1"></a>          <span class="kw">else</span> <span class="dt">LNode</span> (w1 <span class="op">+</span> w2) p1 (mergeL r1 h2) l1</span>
<span id="cb43-21"><a href="#cb43-21" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span></span>
<span id="cb43-22"><a href="#cb43-22" aria-hidden="true" tabindex="-1"></a>      <span class="kw">if</span> rl <span class="op">&lt;=</span> rr</span>
<span id="cb43-23"><a href="#cb43-23" aria-hidden="true" tabindex="-1"></a>          <span class="kw">then</span> <span class="dt">LNode</span> (w1 <span class="op">+</span> w2) p2 l2 (mergeL r2 h1)</span>
<span id="cb43-24"><a href="#cb43-24" aria-hidden="true" tabindex="-1"></a>          <span class="kw">else</span> <span class="dt">LNode</span> (w1 <span class="op">+</span> w2) p2 (mergeL r2 h1) l2</span>
<span id="cb43-25"><a href="#cb43-25" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb43-26"><a href="#cb43-26" aria-hidden="true" tabindex="-1"></a>    ll <span class="ot">=</span> rank r1 <span class="op">+</span> w2</span>
<span id="cb43-27"><a href="#cb43-27" aria-hidden="true" tabindex="-1"></a>    lr <span class="ot">=</span> rank l1</span>
<span id="cb43-28"><a href="#cb43-28" aria-hidden="true" tabindex="-1"></a>    rl <span class="ot">=</span> rank r2 <span class="op">+</span> w1</span>
<span id="cb43-29"><a href="#cb43-29" aria-hidden="true" tabindex="-1"></a>    rr <span class="ot">=</span> rank l2</span></code></pre></div>
<p>In a weight-biased leftist heap, the left branch in any tree must
have at least as many elements as the right branch. Ideally, we would
encode that in the representation of size-indexed leftist heap:</p>
<div class="sourceCode" id="cb44"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Leftist</span> n a <span class="kw">where</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Leaf</span><span class="ot"> ::</span> <span class="dt">Leftist</span> <span class="dv">0</span> a</span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Node</span><span class="ot"> ::</span> <span class="op">!</span>(<span class="dt">The</span> <span class="dt">Nat</span> (n <span class="op">+</span> m <span class="op">+</span> <span class="dv">1</span>))</span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> a</span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Leftist</span> n a</span>
<span id="cb44-6"><a href="#cb44-6" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Leftist</span> m a</span>
<span id="cb44-7"><a href="#cb44-7" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="op">!</span>(m <span class="op">&lt;=</span> n)</span>
<span id="cb44-8"><a href="#cb44-8" aria-hidden="true" tabindex="-1"></a>             <span class="ot">-&gt;</span> <span class="dt">Leftist</span> (n <span class="op">+</span> m <span class="op">+</span> <span class="dv">1</span>) a</span>
<span id="cb44-9"><a href="#cb44-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb44-10"><a href="#cb44-10" aria-hidden="true" tabindex="-1"></a><span class="ot">rank ::</span> <span class="dt">Leftist</span> n s <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> n</span>
<span id="cb44-11"><a href="#cb44-11" aria-hidden="true" tabindex="-1"></a>rank <span class="dt">Leaf</span>             <span class="ot">=</span> sing</span>
<span id="cb44-12"><a href="#cb44-12" aria-hidden="true" tabindex="-1"></a>rank (<span class="dt">Node</span> r _ _ _ _) <span class="ot">=</span> r</span>
<span id="cb44-13"><a href="#cb44-13" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE rank #-}</span></span></code></pre></div>
<p>Two problems, though: first of all, we need to be able to
<em>compare</em> the sizes of two heaps, in the merge function. If we
were using the type-level Peano numbers, this would be too slow. More
importantly, though, we need the comparison to provide a <em>proof</em>
of the ordering, so that we can use it in the resulting <code
class="sourceCode haskell"><span class="dt">Node</span></code>
constructor.</p>
<h3 id="integer-backed-type-level-numbers">Integer-Backed Type-Level
Numbers</h3>
<p>In Agda, the Peano type is actually backed by Haskell’s <code
class="sourceCode haskell"><span class="dt">Integer</span></code> at
runtime. This allows compile-time proofs to be written about values
which are calculated efficiently. We can mimic the same thing in Haskell
with a newtype wrapper <em>around</em> <code
class="sourceCode haskell"><span class="dt">Integer</span></code> with a
phantom <code
class="sourceCode haskell"><span class="dt">Peano</span></code>
parameter, if we promise to never put an integer in which has a
different value to its phantom value. We can make this promise a little
more trustworthy if we don’t export the newtype constructor.</p>
<div class="sourceCode" id="cb45"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="kw">instance</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="kw">where</span></span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">NatSing</span><span class="ot"> ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> n</span>
<span id="cb45-3"><a href="#cb45-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb45-4"><a href="#cb45-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">KnownNat</span> n <span class="ot">=&gt;</span> <span class="dt">KnownSing</span> n <span class="kw">where</span></span>
<span id="cb45-5"><a href="#cb45-5" aria-hidden="true" tabindex="-1"></a>    sing <span class="ot">=</span> <span class="dt">NatSing</span> <span class="op">$</span> Prelude.fromInteger <span class="op">$</span> natVal (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> n)</span></code></pre></div>
<p><code
class="sourceCode haskell"><span class="dt">FlexibleInstances</span></code>
is needed for the instance. We can also encode all the necessary
arithmetic:</p>
<div class="sourceCode" id="cb46"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">6</span> <span class="op">+.</span></span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a><span class="ot">(+.) ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> m <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> (n <span class="op">+</span> m)</span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a>(<span class="op">+.</span>) <span class="ot">=</span></span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a>    (<span class="ot">coerce ::</span> (<span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span>)</span>
<span id="cb46-5"><a href="#cb46-5" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> m <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> (n <span class="op">+</span> m))</span>
<span id="cb46-6"><a href="#cb46-6" aria-hidden="true" tabindex="-1"></a>        (<span class="op">+</span>)</span>
<span id="cb46-7"><a href="#cb46-7" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE (+.) #-}</span></span></code></pre></div>
<p>Finally, the compare function (<code
class="sourceCode haskell"><span class="dt">ScopedTypeVariables</span></code>
for this):</p>
<div class="sourceCode" id="cb47"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a>infix <span class="dv">4</span> <span class="op">&lt;=.</span></span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;=.) ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Nat</span> m <span class="ot">-&gt;</span> <span class="dt">The</span> <span class="dt">Bool</span> (n <span class="op">&lt;=?</span> m)</span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;=.</span>) (<span class="dt">NatSing</span><span class="ot"> x ::</span> <span class="dt">The</span> <span class="dt">Nat</span> n) (<span class="dt">NatSing</span><span class="ot"> y ::</span> <span class="dt">The</span> <span class="dt">Nat</span> m)</span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> x <span class="op">&lt;=</span> y <span class="ot">=</span></span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> (unsafeCoerce (<span class="dt">Refl</span><span class="ot"> ::</span> <span class="dt">True</span> <span class="op">:~:</span> <span class="dt">True</span>)<span class="ot"> ::</span> (n <span class="op">&lt;=?</span> m) <span class="op">:~:</span> <span class="dt">True</span>) <span class="kw">of</span></span>
<span id="cb47-6"><a href="#cb47-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Refl</span> <span class="ot">-&gt;</span> <span class="dt">Truey</span></span>
<span id="cb47-7"><a href="#cb47-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span></span>
<span id="cb47-8"><a href="#cb47-8" aria-hidden="true" tabindex="-1"></a>      <span class="kw">case</span> (unsafeCoerce (<span class="dt">Refl</span><span class="ot"> ::</span> <span class="dt">True</span> <span class="op">:~:</span> <span class="dt">True</span>)<span class="ot"> ::</span> (n <span class="op">&lt;=?</span> m) <span class="op">:~:</span> <span class="dt">False</span>) <span class="kw">of</span></span>
<span id="cb47-9"><a href="#cb47-9" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Refl</span> <span class="ot">-&gt;</span> <span class="dt">Falsy</span></span>
<span id="cb47-10"><a href="#cb47-10" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# INLINE (&lt;=.) #-}</span></span>
<span id="cb47-11"><a href="#cb47-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-12"><a href="#cb47-12" aria-hidden="true" tabindex="-1"></a><span class="ot">totalOrder ::</span>  p n <span class="ot">-&gt;</span> q m <span class="ot">-&gt;</span> (n <span class="op">&lt;=?</span> m) <span class="op">:~:</span> <span class="dt">False</span> <span class="ot">-&gt;</span> (m <span class="op">&lt;=?</span> n) <span class="op">:~:</span> <span class="dt">True</span></span>
<span id="cb47-13"><a href="#cb47-13" aria-hidden="true" tabindex="-1"></a>totalOrder (<span class="ot">_ ::</span> p n) (<span class="ot">_ ::</span> q m) <span class="dt">Refl</span> <span class="ot">=</span></span>
<span id="cb47-14"><a href="#cb47-14" aria-hidden="true" tabindex="-1"></a>    unsafeCoerce <span class="dt">Refl</span><span class="ot"> ::</span> (m <span class="op">&lt;=?</span> n) <span class="op">:~:</span> <span class="dt">True</span></span>
<span id="cb47-15"><a href="#cb47-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb47-16"><a href="#cb47-16" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> x <span class="op">&lt;=</span> y <span class="ot">=</span> (x <span class="op">&lt;=?</span> y) <span class="op">:~:</span> <span class="dt">True</span></span></code></pre></div>
<p>It’s worth mentioning that all of these functions are somewhat
axiomatic: there’s no checking of these definitions going on, and any
later proofs are only correct in terms of these functions.</p>
<p>If we want our merge function to <em>really</em> look like the
non-verified version, though, we’ll have to mess around with the syntax
a little.</p>
<h3 id="a-dependent-if-then-else">A Dependent if-then-else</h3>
<p>When matching on a singleton, <em>within</em> the case-match, proof
of the singleton’s type is provided. For instance:</p>
<div class="sourceCode" id="cb48"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">IfThenElse</span> (<span class="ot">c ::</span> <span class="dt">Bool</span>) (<span class="ot">true ::</span> k) (<span class="ot">false ::</span> k)<span class="ot"> ::</span> k</span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a>     <span class="kw">where</span></span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">IfThenElse</span> <span class="dt">True</span> true false <span class="ot">=</span> true</span>
<span id="cb48-4"><a href="#cb48-4" aria-hidden="true" tabindex="-1"></a>        <span class="dt">IfThenElse</span> <span class="dt">False</span> true false <span class="ot">=</span> false</span>
<span id="cb48-5"><a href="#cb48-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb48-6"><a href="#cb48-6" aria-hidden="true" tabindex="-1"></a><span class="ot">intOrString ::</span> <span class="dt">The</span> <span class="dt">Bool</span> cond <span class="ot">-&gt;</span> <span class="dt">IfThenElse</span> cond <span class="dt">Int</span> <span class="dt">String</span></span>
<span id="cb48-7"><a href="#cb48-7" aria-hidden="true" tabindex="-1"></a>intOrString <span class="dt">Truey</span> <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb48-8"><a href="#cb48-8" aria-hidden="true" tabindex="-1"></a>intOrString <span class="dt">Falsy</span> <span class="ot">=</span> <span class="st">&quot;abc&quot;</span></span></code></pre></div>
<p>In Haskell, since we can overload the if-then-else construct (with
<code
class="sourceCode haskell"><span class="dt">RebindableSyntax</span></code>),
we can provide the same syntax, while hiding the dependent nature:</p>
<div class="sourceCode" id="cb49"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="ot">ifThenElse ::</span> <span class="dt">The</span> <span class="dt">Bool</span> c <span class="ot">-&gt;</span> (c <span class="op">:~:</span> <span class="dt">True</span> <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (c <span class="op">:~:</span> <span class="dt">False</span> <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a</span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a>ifThenElse <span class="dt">Truey</span> t _ <span class="ot">=</span> t <span class="dt">Refl</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a>ifThenElse <span class="dt">Falsy</span> _ f <span class="ot">=</span> f <span class="dt">Refl</span></span></code></pre></div>
<h3 id="verified-merge">Verified Merge</h3>
<p>Finally, then, we can write the implementation for merge, which looks
almost <em>exactly</em> the same as the non-verified merge:</p>
<div class="sourceCode" id="cb50"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">IndexedQueue</span> <span class="dt">Leftist</span> a <span class="kw">where</span></span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true" tabindex="-1"></a>    minView (<span class="dt">Node</span> _ x l r _) <span class="ot">=</span> (x, merge l r)</span>
<span id="cb50-4"><a href="#cb50-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE minView #-}</span></span>
<span id="cb50-5"><a href="#cb50-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-6"><a href="#cb50-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-7"><a href="#cb50-7" aria-hidden="true" tabindex="-1"></a>    singleton x <span class="ot">=</span> <span class="dt">Node</span> sing x <span class="dt">Leaf</span> <span class="dt">Leaf</span> <span class="dt">Refl</span></span>
<span id="cb50-8"><a href="#cb50-8" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE singleton #-}</span></span>
<span id="cb50-9"><a href="#cb50-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-10"><a href="#cb50-10" aria-hidden="true" tabindex="-1"></a>    empty <span class="ot">=</span> <span class="dt">Leaf</span></span>
<span id="cb50-11"><a href="#cb50-11" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE empty #-}</span></span>
<span id="cb50-12"><a href="#cb50-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-13"><a href="#cb50-13" aria-hidden="true" tabindex="-1"></a>    insert <span class="ot">=</span> merge <span class="op">.</span> singleton</span>
<span id="cb50-14"><a href="#cb50-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE insert #-}</span></span>
<span id="cb50-15"><a href="#cb50-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-16"><a href="#cb50-16" aria-hidden="true" tabindex="-1"></a>    minViewMay <span class="dt">Leaf</span> b _             <span class="ot">=</span> b</span>
<span id="cb50-17"><a href="#cb50-17" aria-hidden="true" tabindex="-1"></a>    minViewMay (<span class="dt">Node</span> _ x l r _) _ f <span class="ot">=</span> f x (merge l r)</span>
<span id="cb50-18"><a href="#cb50-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-19"><a href="#cb50-19" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span></span>
<span id="cb50-20"><a href="#cb50-20" aria-hidden="true" tabindex="-1"></a>         <span class="dt">MeldableIndexedQueue</span> <span class="dt">Leftist</span> a <span class="kw">where</span></span>
<span id="cb50-21"><a href="#cb50-21" aria-hidden="true" tabindex="-1"></a>    merge <span class="dt">Leaf</span> h2 <span class="ot">=</span> h2</span>
<span id="cb50-22"><a href="#cb50-22" aria-hidden="true" tabindex="-1"></a>    merge h1 <span class="dt">Leaf</span> <span class="ot">=</span> h1</span>
<span id="cb50-23"><a href="#cb50-23" aria-hidden="true" tabindex="-1"></a>    merge h1<span class="op">@</span>(<span class="dt">Node</span> w1 p1 l1 r1 _) h2<span class="op">@</span>(<span class="dt">Node</span> w2 p2 l2 r2 _)</span>
<span id="cb50-24"><a href="#cb50-24" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> p1 <span class="op">&lt;</span> p2 <span class="ot">=</span></span>
<span id="cb50-25"><a href="#cb50-25" aria-hidden="true" tabindex="-1"></a>          <span class="kw">if</span> ll <span class="op">&lt;=.</span> lr</span>
<span id="cb50-26"><a href="#cb50-26" aria-hidden="true" tabindex="-1"></a>             <span class="kw">then</span> <span class="dt">Node</span> (w1 <span class="op">+.</span> w2) p1 l1 (merge r1 h2)</span>
<span id="cb50-27"><a href="#cb50-27" aria-hidden="true" tabindex="-1"></a>             <span class="kw">else</span> <span class="dt">Node</span> (w1 <span class="op">+.</span> w2) p1 (merge r1 h2) l1 <span class="op">.</span> totalOrder ll lr</span>
<span id="cb50-28"><a href="#cb50-28" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span></span>
<span id="cb50-29"><a href="#cb50-29" aria-hidden="true" tabindex="-1"></a>          <span class="kw">if</span> rl <span class="op">&lt;=.</span> rr</span>
<span id="cb50-30"><a href="#cb50-30" aria-hidden="true" tabindex="-1"></a>              <span class="kw">then</span> <span class="dt">Node</span> (w1 <span class="op">+.</span> w2) p2 l2 (merge r2 h1)</span>
<span id="cb50-31"><a href="#cb50-31" aria-hidden="true" tabindex="-1"></a>              <span class="kw">else</span> <span class="dt">Node</span> (w1 <span class="op">+.</span> w2) p2 (merge r2 h1) l2 <span class="op">.</span> totalOrder rl rr</span>
<span id="cb50-32"><a href="#cb50-32" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb50-33"><a href="#cb50-33" aria-hidden="true" tabindex="-1"></a>        ll <span class="ot">=</span> rank r1 <span class="op">+.</span> w2</span>
<span id="cb50-34"><a href="#cb50-34" aria-hidden="true" tabindex="-1"></a>        lr <span class="ot">=</span> rank l1</span>
<span id="cb50-35"><a href="#cb50-35" aria-hidden="true" tabindex="-1"></a>        rl <span class="ot">=</span> rank r2 <span class="op">+.</span> w1</span>
<span id="cb50-36"><a href="#cb50-36" aria-hidden="true" tabindex="-1"></a>        rr <span class="ot">=</span> rank l2</span>
<span id="cb50-37"><a href="#cb50-37" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE merge #-}</span></span></code></pre></div>
<p>What’s cool about this implementation is that it has the same
performance as the non-verified version (if <code
class="sourceCode haskell"><span class="dt">Integer</span></code> is
swapped out for <code
class="sourceCode haskell"><span class="dt">Int</span></code>, that is),
and it <em>looks</em> pretty much the same. This is very close to static
verification for free.</p>
<h3 id="generalizing-sort-to-parts">Generalizing Sort to Parts</h3>
<p>The <code
class="sourceCode haskell"><span class="dt">Sort</span></code> type used
in the original blog post can be generalized to <em>any</em> indexed
container.</p>
<div class="sourceCode" id="cb51"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Parts</span> f g a b r <span class="kw">where</span></span>
<span id="cb51-2"><a href="#cb51-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Parts</span><span class="ot"> ::</span> (<span class="kw">forall</span> n<span class="op">.</span> g (m <span class="op">+</span> n) b <span class="ot">-&gt;</span> (g n b, r))</span>
<span id="cb51-3"><a href="#cb51-3" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="op">!</span>(f m a)</span>
<span id="cb51-4"><a href="#cb51-4" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> <span class="dt">Parts</span> f g a b r</span>
<span id="cb51-5"><a href="#cb51-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-6"><a href="#cb51-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">Parts</span> f g a b) <span class="kw">where</span></span>
<span id="cb51-7"><a href="#cb51-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Parts</span> g h) <span class="ot">=</span></span>
<span id="cb51-8"><a href="#cb51-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Parts</span> (\h&#39; <span class="ot">-&gt;</span> <span class="kw">case</span> g h&#39; <span class="kw">of</span> (remn, r) <span class="ot">-&gt;</span> (remn, f r)) h</span>
<span id="cb51-9"><a href="#cb51-9" aria-hidden="true" tabindex="-1"></a>  <span class="ot">{-# INLINE fmap #-}</span></span>
<span id="cb51-10"><a href="#cb51-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-11"><a href="#cb51-11" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">IndexedQueue</span> f x, <span class="dt">MeldableIndexedQueue</span> f x) <span class="ot">=&gt;</span></span>
<span id="cb51-12"><a href="#cb51-12" aria-hidden="true" tabindex="-1"></a>          <span class="dt">Applicative</span> (<span class="dt">Parts</span> f g x y) <span class="kw">where</span></span>
<span id="cb51-13"><a href="#cb51-13" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Parts</span> (\h <span class="ot">-&gt;</span> (h, x)) empty</span>
<span id="cb51-14"><a href="#cb51-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINE pure #-}</span></span>
<span id="cb51-15"><a href="#cb51-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb51-16"><a href="#cb51-16" aria-hidden="true" tabindex="-1"></a>    (<span class="dt">Parts</span> f (<span class="ot">xs ::</span> f m x)<span class="ot"> ::</span> <span class="dt">Parts</span> f g x y (a <span class="ot">-&gt;</span> b)) <span class="op">&lt;*&gt;</span></span>
<span id="cb51-17"><a href="#cb51-17" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Parts</span> g (<span class="ot">ys ::</span> f n x) <span class="ot">=</span></span>
<span id="cb51-18"><a href="#cb51-18" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Parts</span> h (merge xs ys)</span>
<span id="cb51-19"><a href="#cb51-19" aria-hidden="true" tabindex="-1"></a>        <span class="kw">where</span></span>
<span id="cb51-20"><a href="#cb51-20" aria-hidden="true" tabindex="-1"></a><span class="ot">          h ::</span> <span class="kw">forall</span> o <span class="op">.</span> g ((m <span class="op">+</span> n) <span class="op">+</span> o) y <span class="ot">-&gt;</span> (g o y, b)</span>
<span id="cb51-21"><a href="#cb51-21" aria-hidden="true" tabindex="-1"></a>          h v <span class="ot">=</span> <span class="kw">case</span> f v <span class="kw">of</span> { (v&#39;, a) <span class="ot">-&gt;</span></span>
<span id="cb51-22"><a href="#cb51-22" aria-hidden="true" tabindex="-1"></a>                    <span class="kw">case</span> g v&#39; <span class="kw">of</span> { (v&#39;&#39;, b) <span class="ot">-&gt;</span></span>
<span id="cb51-23"><a href="#cb51-23" aria-hidden="true" tabindex="-1"></a>                      (v&#39;&#39;, a b)}}</span>
<span id="cb51-24"><a href="#cb51-24" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# INLINABLE (&lt;*&gt;) #-}</span></span></code></pre></div>
<p>This version doesn’t insist that you order the elements of the heap
in any particular way: we could use indexed difference lists to reverse
a container, or indexed lists to calculate permutations of a container,
for instance.</p>
<h3 id="other-uses-for-size-indexed-heaps">Other Uses For Size-Indexed
Heaps</h3>
<p>I’d be very interested to see any other uses of these indexed heaps,
if anyone has any ideas. Potentially the could be used in any place
where there is a need for some heap which is known to be of a certain
size (a true prime sieve, for instance).</p>
<h3 id="the-library">The Library</h3>
<p>I’ve explored all of these ideas <a
href="https://github.com/oisdk/type-indexed-queues">here</a>. It has
implementations of all the heaps I mentioned, as well as the
index-erasing type, and a size-indexed list, for reversing traversables.
In the future, I might add things like a Fibonacci heap, or the optimal
Brodal/Okasaki heap <span class="citation"
data-cites="brodal_optimal_1996">(<a href="#ref-brodal_optimal_1996"
role="doc-biblioref">Brodal and Okasaki 1996</a>)</span>.</p>
<hr />
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-brodal_optimal_1996" class="csl-entry" role="listitem">
Brodal, Gerth Stølting, and Chris Okasaki. 1996. <span>“Optimal
<span>Purely</span> <span>Functional</span> <span>Priority</span>
<span>Queues</span>.”</span> <em>Journal of Functional Programming</em>
6 (6) (November): 839–857. doi:<a
href="https://doi.org/10.1017/S095679680000201X">10.1017/S095679680000201X</a>.
<a
href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.973">http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.973</a>.
</div>
<div id="ref-diatchki_improving_2015" class="csl-entry" role="listitem">
Diatchki, Iavor S. 2015. <span>“Improving <span>Haskell</span>
<span>Types</span> with <span>SMT</span>.”</span> In <em>Proceedings of
the 2015 <span>ACM</span> <span>SIGPLAN</span> <span>Symposium</span> on
<span>Haskell</span></em>, 1–10. Haskell ’15. New York, NY, USA: ACM.
doi:<a
href="https://doi.org/10.1145/2804302.2804307">10.1145/2804302.2804307</a>.
<a
href="http://yav.github.io/publications/improving-smt-types.pdf">http://yav.github.io/publications/improving-smt-types.pdf</a>.
</div>
<div id="ref-eisenberg_dependently_2012" class="csl-entry"
role="listitem">
Eisenberg, Richard A., and Stephanie Weirich. 2012. <span>“Dependently
<span>Typed</span> <span>Programming</span> with
<span>Singletons</span>.”</span> In <em>Proceedings of the 2012
<span>Haskell</span> <span>Symposium</span></em>, 117–130. Haskell ’12.
New York, NY, USA: ACM. doi:<a
href="https://doi.org/10.1145/2364506.2364522">10.1145/2364506.2364522</a>.
<a
href="http://cs.brynmawr.edu/~rae/papers/2012/singletons/paper.pdf">http://cs.brynmawr.edu/~rae/papers/2012/singletons/paper.pdf</a>.
</div>
<div id="ref-fredman_pairing_1986" class="csl-entry" role="listitem">
Fredman, Michael L., Robert Sedgewick, Daniel D. Sleator, and Robert E.
Tarjan. 1986. <span>“The pairing heap: <span>A</span> new form of
self-adjusting heap.”</span> <em>Algorithmica</em> 1 (1-4) (January):
111–129. doi:<a
href="https://doi.org/10.1007/BF01840439">10.1007/BF01840439</a>. <a
href="http://www.cs.princeton.edu/courses/archive/fall09/cos521/Handouts/pairingheaps.pdf">http://www.cs.princeton.edu/courses/archive/fall09/cos521/Handouts/pairingheaps.pdf</a>.
</div>
<div id="ref-hinze_functional_1999" class="csl-entry" role="listitem">
Hinze, Ralf. 1999. <span>“Functional <span>Pearls</span>:
<span>Explaining</span> <span>Binomial</span>
<span>Heaps</span>.”</span> <em>Journal of Functional Programming</em> 9
(1) (January): 93–104. doi:<a
href="https://doi.org/10.1017/S0956796899003317">10.1017/S0956796899003317</a>.
<a
href="http://www.cs.ox.ac.uk/ralf.hinze/publications/#J1">http://www.cs.ox.ac.uk/ralf.hinze/publications/#J1</a>.
</div>
<div id="ref-hinze_manufacturing_2001" class="csl-entry"
role="listitem">
———. 2001. <span>“Manufacturing datatypes.”</span> <em>Journal of
Functional Programming</em> 11 (5) (September): 493–524. doi:<a
href="https://doi.org/10.1017/S095679680100404X">10.1017/S095679680100404X</a>.
<a
href="http://www.cs.ox.ac.uk/ralf.hinze/publications/#J6">http://www.cs.ox.ac.uk/ralf.hinze/publications/#J6</a>.
</div>
<div id="ref-okasaki_fast_1999" class="csl-entry" role="listitem">
Okasaki, Chris. 1999. <span>“From <span>Fast</span>
<span>Exponentiation</span> to <span>Square</span>
<span>Matrices</span>: <span>An</span> <span>Adventure</span> in
<span>Types</span>.”</span> In <em>Proceedings of the <span>ACM</span>
<span>SIGPLAN</span> <span>International</span> <span>Conference</span>
on <span>Functional</span> <span>Programming</span>
(<span>ICFP</span>’99), <span>Paris</span>, <span>France</span>,
<span>September</span> 27-29, 1999</em>, 34:28. ACM. <a
href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.456.357&amp;rep=rep1&amp;type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.456.357&amp;rep=rep1&amp;type=pdf</a>.
</div>
<div id="ref-wasserman_playing_2010" class="csl-entry" role="listitem">
Wasserman, Louis. 2010. <span>“Playing with <span>Priority</span>
<span>Queues</span>.”</span> <em>The Monad.Reader</em> 16 (16) (May):
37. <a
href="https://themonadreader.files.wordpress.com/2010/05/issue16.pdf">https://themonadreader.files.wordpress.com/2010/05/issue16.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Sun, 23 Apr 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-04-23-verifying-data-structures-in-haskell-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Unparsing</title>
    <link>https://doisinkidney.com/posts/2017-04-01-unparsing-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on April  1, 2017
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>
    
</div>

<p>Pretty-printing expressions with minimal parenthesis is a little
trickier than it looks. This algorithm is adapted from:</p>
<p><a
href="https://www.cs.tufts.edu/~nr/pubs/unparse-abstract.html">Ramsey,
Norman. ‘Unparsing Expressions With Prefix and Postfix Operators’.
Software—Practice &amp; Experience 28, no. 12 (1998): 1327–1356.</a></p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveFunctor #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Unparse</span> <span class="kw">where</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Semigroup</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Coerce</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Side</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">L</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">R</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> <span class="dt">Eq</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ShowExpr</span> t e</span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> <span class="dt">Lit</span>     {<span class="ot">repr ::</span> t}</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Prefix</span>  {<span class="ot">repr ::</span> t,<span class="ot"> op ::</span> <span class="dt">Op</span>,<span class="ot"> child ::</span> e}</span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Postfix</span> {<span class="ot">repr ::</span> t,<span class="ot"> op ::</span> <span class="dt">Op</span>,<span class="ot"> child ::</span> e}</span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">|</span> <span class="dt">Binary</span>  {<span class="ot">repr ::</span> t,<span class="ot"> op ::</span> <span class="dt">Op</span>,<span class="ot"> lchild ::</span> e,<span class="ot"> rchild ::</span> e}</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Op</span> <span class="ot">=</span> <span class="dt">Op</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    {<span class="ot"> prec ::</span> <span class="dt">Int</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>    ,<span class="ot"> assoc ::</span> <span class="dt">Side</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>showExpr</span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Semigroup</span> t</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (e <span class="ot">-&gt;</span> <span class="dt">ShowExpr</span> t e) <span class="ot">-&gt;</span> (t <span class="ot">-&gt;</span> t) <span class="ot">-&gt;</span> e <span class="ot">-&gt;</span> t</span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>showExpr proj prns <span class="ot">=</span> go <span class="op">.</span> <span class="fu">fmap</span> proj <span class="op">.</span> proj</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Lit</span> t) <span class="ot">=</span> t</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Prefix</span> t o y) <span class="ot">=</span> t <span class="op">&lt;&gt;</span> ifPrns <span class="dt">R</span> o (getOp y) (go (<span class="fu">fmap</span> proj y))</span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Postfix</span> t o x) <span class="ot">=</span> ifPrns <span class="dt">L</span> o (getOp x) (go (<span class="fu">fmap</span> proj x)) <span class="op">&lt;&gt;</span> t</span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>    go (<span class="dt">Binary</span> t o x y) <span class="ot">=</span></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>        ifPrns <span class="dt">L</span> o (getOp x) (go (<span class="fu">fmap</span> proj x)) <span class="op">&lt;&gt;</span> t <span class="op">&lt;&gt;</span></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a>        ifPrns <span class="dt">R</span> o (getOp y) (go (<span class="fu">fmap</span> proj y))</span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a>    ifPrns sid (<span class="dt">Op</span> op oa) (<span class="dt">Just</span> (<span class="dt">Op</span> ip ia))</span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> ip <span class="op">&lt;</span> op <span class="op">||</span> ip <span class="op">==</span> op <span class="op">&amp;&amp;</span> (ia <span class="op">/=</span> oa <span class="op">||</span> sid <span class="op">/=</span> oa) <span class="ot">=</span> prns</span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a>    ifPrns _ _ _ <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>    getOp <span class="dt">Lit</span>{} <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a>    getOp e <span class="ot">=</span> <span class="dt">Just</span> (op e)</span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a><span class="ot">showSExpr ::</span> (e <span class="ot">-&gt;</span> <span class="dt">ShowExpr</span> <span class="dt">ShowS</span> e) <span class="ot">-&gt;</span> e <span class="ot">-&gt;</span> <span class="dt">ShowS</span></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>showSExpr proj <span class="ot">=</span></span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a>    appEndo <span class="op">.</span></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a>    showExpr</span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a>        (coerce proj)</span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a>        (coerce (<span class="fu">showParen</span> <span class="dt">True</span>))</span></code></pre></div>
<p>And an example of its use:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">Number</span> <span class="dt">Integer</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="dt">Expr</span> <span class="op">:+:</span> <span class="dt">Expr</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="dt">Expr</span> <span class="op">:*:</span> <span class="dt">Expr</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>          <span class="op">|</span> <span class="dt">Expr</span> <span class="op">:^:</span> <span class="dt">Expr</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Expr</span> <span class="kw">where</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  (<span class="op">+</span>) <span class="ot">=</span> (<span class="op">:+:</span>)</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  (<span class="op">*</span>) <span class="ot">=</span> (<span class="op">:*:</span>)</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fromInteger</span> <span class="ot">=</span> <span class="dt">Number</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">abs</span> <span class="ot">=</span> <span class="fu">undefined</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">signum</span> <span class="ot">=</span> <span class="fu">undefined</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>  <span class="fu">negate</span> <span class="ot">=</span> <span class="fu">undefined</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="co">-- | &gt;&gt;&gt; default (Expr)</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; 1 + 2 + 3</span></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a><span class="co">-- 1 + 2 + 3</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; 1 * 2 * 3</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a><span class="co">-- 1 * 2 * 3</span></span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; (1 * 2) + 3</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a><span class="co">-- 1 * 2 + 3</span></span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; 1 * (2 + 3)</span></span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a><span class="co">-- 1 * (2 + 3)</span></span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; (1 :^: 2) :^: 3</span></span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a><span class="co">-- (1 ^ 2) ^ 3</span></span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a><span class="co">-- &gt;&gt;&gt; 1 :^: (2 :^: 3)</span></span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a><span class="co">-- 1 ^ 2 ^ 3</span></span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> <span class="dt">Expr</span> <span class="kw">where</span></span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>  <span class="fu">showsPrec</span> _ <span class="ot">=</span> showSExpr proj <span class="kw">where</span></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a>    proj (<span class="dt">Number</span> n) <span class="ot">=</span> <span class="dt">Lit</span> (<span class="fu">shows</span> n)</span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>    proj (x <span class="op">:+:</span> y) <span class="ot">=</span> <span class="dt">Binary</span> (<span class="fu">showString</span> <span class="st">&quot; + &quot;</span>) (<span class="dt">Op</span> <span class="dv">3</span> <span class="dt">L</span>) x y</span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>    proj (x <span class="op">:*:</span> y) <span class="ot">=</span> <span class="dt">Binary</span> (<span class="fu">showString</span> <span class="st">&quot; * &quot;</span>) (<span class="dt">Op</span> <span class="dv">4</span> <span class="dt">L</span>) x y</span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a>    proj (x <span class="op">:^:</span> y) <span class="ot">=</span> <span class="dt">Binary</span> (<span class="fu">showString</span> <span class="st">&quot; ^ &quot;</span>) (<span class="dt">Op</span> <span class="dv">5</span> <span class="dt">R</span>) x y</span></code></pre></div>
]]></description>
    <pubDate>Sat, 01 Apr 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-04-01-unparsing-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Fun with Recursion Schemes</title>
    <link>https://doisinkidney.com/posts/2017-03-30-fun-with-recursion-schemes.html</link>
    <description><![CDATA[<div class="info">
    Posted on March 30, 2017
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Recursion Schemes&#39;." href="/tags/Recursion%20Schemes.html" rel="tag">Recursion Schemes</a>
    
</div>

<h2 id="folding-algebras">Folding Algebras</h2>
<p>I saw <a
href="https://www.reddit.com/r/haskell/comments/608y0l/would_this_sugar_make_sense/">this</a>
post on reddit recently, and it got me thinking about recursion schemes.
One of the primary motivations behind them is the reduction of
boilerplate. The classic example is evaluation of arithmetic
expressions:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ExprF</span> a</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">LitF</span> <span class="dt">Integer</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="op">:+:</span>) a a</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="op">:*:</span>) a a</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">Fix</span> <span class="dt">ExprF</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="ot">eval ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>eval <span class="ot">=</span> unfix <span class="op">&gt;&gt;&gt;</span> \<span class="kw">case</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LitF</span> n <span class="ot">-&gt;</span> n</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  x <span class="op">:+:</span> y <span class="ot">-&gt;</span> eval x <span class="op">+</span> eval y</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  x <span class="op">:*:</span> y <span class="ot">-&gt;</span> eval x <span class="op">*</span> eval y</span></code></pre></div>
<p>The calls to <code class="sourceCode haskell">eval</code> are the
boilerplate: this is where the main recursion scheme, <code
class="sourceCode haskell">cata</code> can help.</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evalF ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>evalF <span class="ot">=</span> cata <span class="op">$</span> \<span class="kw">case</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LitF</span> n <span class="ot">-&gt;</span> n</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  x <span class="op">:+:</span> y <span class="ot">-&gt;</span> x <span class="op">+</span> y</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  x <span class="op">:*:</span> y <span class="ot">-&gt;</span> x <span class="op">*</span> y</span></code></pre></div>
<p>I still feel like there’s boilerplate, though. Ideally I’d like to
write this:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evalF ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>evalF <span class="ot">=</span> cata <span class="op">$</span> <span class="op">???</span> <span class="op">$</span> \<span class="kw">case</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lit</span> <span class="ot">-&gt;</span> <span class="fu">id</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Add</span> <span class="ot">-&gt;</span> (<span class="op">+</span>)</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Mul</span> <span class="ot">-&gt;</span> (<span class="op">*</span>)</span></code></pre></div>
<p>The <code
class="sourceCode haskell"><span class="op">???</span></code> needs to
be filled in. It’s a little tricky, though: the type of the algebra
changes depending on what expression it’s given. GADTs will allow us to
attach types to cases:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ExprI</span> a r f <span class="kw">where</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lit</span><span class="ot"> ::</span> <span class="dt">ExprI</span> a b (<span class="dt">Integer</span> <span class="ot">-&gt;</span> b)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Add</span><span class="ot"> ::</span> <span class="dt">ExprI</span> a b (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> b)</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Mul</span><span class="ot"> ::</span> <span class="dt">ExprI</span> a b (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> b)</span></code></pre></div>
<p>The first type parameter is the same as the first type parameter to
<code class="sourceCode haskell"><span class="dt">ExprF</span></code>.
The second is the output type of the algebra, and the third is the type
of the fold required to produce that output type. The third type
parameter <em>depends</em> on the case matched in the GADT. Using this,
we can write a function which converts a fold/pattern match to a
standard algebra:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldAlg ::</span> (<span class="kw">forall</span> f<span class="op">.</span> <span class="dt">ExprI</span> a r f <span class="ot">-&gt;</span> f) <span class="ot">-&gt;</span> (<span class="dt">ExprF</span> a <span class="ot">-&gt;</span> r)</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>foldAlg f (<span class="dt">LitF</span> i)  <span class="ot">=</span> f <span class="dt">Lit</span> i</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>foldAlg f (x <span class="op">:+:</span> y) <span class="ot">=</span> f <span class="dt">Add</span> x y</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>foldAlg f (x <span class="op">:*:</span> y) <span class="ot">=</span> f <span class="dt">Mul</span> x y</span></code></pre></div>
<p>And finally, we can write the nice evaluation algebra:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evalF ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>evalF <span class="ot">=</span> cata <span class="op">$</span> foldAlg <span class="op">$</span> \<span class="kw">case</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Lit</span> <span class="ot">-&gt;</span> <span class="fu">id</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Add</span> <span class="ot">-&gt;</span> (<span class="op">+</span>)</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Mul</span> <span class="ot">-&gt;</span> (<span class="op">*</span>)</span></code></pre></div>
<p>I hacked together some quick template Haskell to generate the
matchers over <a href="https://github.com/oisdk/pattern-folds">here</a>.
It uses a class <code
class="sourceCode haskell"><span class="dt">AsPatternFold</span></code>:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">AsPatternFold</span> x f <span class="op">|</span> x <span class="ot">-&gt;</span> f <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  foldMatch ::</span> (<span class="kw">forall</span> a<span class="op">.</span> f r a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (x <span class="ot">-&gt;</span> r)</span></code></pre></div>
<p>And you generate the extra data type, with an instance, by doing
this:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>makePatternFolds &#39;<span class="dt">&#39;ExprF</span></span></code></pre></div>
<p>The code it generates can be used like this:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">evalF ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>evalF <span class="ot">=</span> cata <span class="op">$</span> foldMatch <span class="op">$</span> \<span class="kw">case</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">LitI</span> <span class="ot">-&gt;</span> <span class="fu">id</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  (<span class="op">:+|</span>) <span class="ot">-&gt;</span> (<span class="op">+</span>)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  (<span class="op">:*|</span>) <span class="ot">-&gt;</span> (<span class="op">*</span>)</span></code></pre></div>
<p>It’s terribly hacky at the moment, I may clean it up later.</p>
<h2 id="record-case">Record Case</h2>
<p>There’s another approach to the same idea that is slightly more
sensible, using record wildcards. You define a handler for your datatype
(an algebra):</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ExprAlg</span> a r</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">ExprAlg</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> litF ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> r</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> (+:) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> r</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> (*:) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> r }</span></code></pre></div>
<p>Then, to use it, you define how to interact between the handler and
the datatype, like before. The benefit is that record wildcard syntax
allows you to piggy back on the function definition syntax, like so:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ExprF</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">LitF</span> <span class="dt">Integer</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="op">:+:</span>) a a</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="op">:*:</span>) a a</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>makeHandler &#39;<span class="dt">&#39;ExprF</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a><span class="ot">exprAlg ::</span> <span class="dt">ExprF</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>exprAlg <span class="ot">=</span> <span class="fu">index</span> <span class="dt">ExprFAlg</span> {<span class="op">..</span>} <span class="kw">where</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>  litF <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>  (<span class="op">+:</span>) <span class="ot">=</span> (<span class="op">+</span>)</span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>  (<span class="op">*:</span>) <span class="ot">=</span> (<span class="op">*</span>)</span></code></pre></div>
<p>This approach is much more principled: the <code
class="sourceCode haskell"><span class="fu">index</span></code>
function, for example, comes from the <a
href="https://hackage.haskell.org/package/adjunctions">adjunctions</a>
package, from the <a
href="https://hackage.haskell.org/package/adjunctions-4.3/docs/Data-Functor-Rep.html"><code
class="sourceCode haskell"><span class="dt">Representable</span></code></a>
class. That’s because those algebras are actually representable
functors, with their representation being the thing they match. They
also conform to a whole bunch of things automatically, letting you
combine them interesting ways.</p>
<h2 id="printing-expressions">Printing Expressions</h2>
<p>Properly printing expressions, with minimal parentheses, is a
surprisingly difficult problem. <span class="citation"
data-cites="ramsey_unparsing_1998">Ramsey (<a
href="#ref-ramsey_unparsing_1998" role="doc-biblioref">1998</a>)</span>
provides a solution of the form:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>isParens side (<span class="dt">Assoc</span> ao po) (<span class="dt">Assoc</span> ai <span class="fu">pi</span>) <span class="ot">=</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pi</span> <span class="op">&lt;=</span> po <span class="op">&amp;&amp;</span> (<span class="fu">pi</span> <span class="op">/=</span> po <span class="op">||</span> ai <span class="op">/=</span> ao <span class="op">||</span> ao <span class="op">/=</span> side)</span></code></pre></div>
<p>Using this, we can write an algebra for printing expressions. It
should work in the general case, not just on the expression type defined
above, so we need to make another unfixed functor to describe the
printing of an expression:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Side</span> <span class="ot">=</span> <span class="dt">L</span> <span class="op">|</span> <span class="dt">R</span> <span class="kw">deriving</span> <span class="dt">Eq</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ShowExpr</span> t e</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">ShowLit</span> {<span class="ot"> _repr ::</span> t }</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Prefix</span>  {<span class="ot"> _repr ::</span> t,<span class="ot"> _assoc ::</span> (<span class="dt">Int</span>,<span class="dt">Side</span>),<span class="ot"> _child  ::</span> e }</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Postfix</span> {<span class="ot"> _repr ::</span> t,<span class="ot"> _assoc ::</span> (<span class="dt">Int</span>,<span class="dt">Side</span>),<span class="ot"> _child  ::</span> e }</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Binary</span>  {<span class="ot"> _repr ::</span> t,<span class="ot"> _assoc ::</span> (<span class="dt">Int</span>,<span class="dt">Side</span>),<span class="ot"> _lchild ::</span> e</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>                                              ,<span class="ot"> _rchild ::</span> e }</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>makeLenses &#39;<span class="dt">&#39;ShowExpr</span></span></code></pre></div>
<p>The lenses are probably overkill. For printing, we need not only the
precedence of the current level, but also the precedence one level
below. Seems like the perfect case for a zygomorphism:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="ot">showExprAlg ::</span> <span class="dt">Semigroup</span> t</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>            <span class="ot">=&gt;</span> (t <span class="ot">-&gt;</span> t)</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> <span class="dt">ShowExpr</span> t (<span class="dt">Maybe</span> (<span class="dt">Int</span>,<span class="dt">Side</span>), t)</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>            <span class="ot">-&gt;</span> t</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>showExprAlg prns <span class="ot">=</span> \<span class="kw">case</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">ShowLit</span> t               <span class="ot">-&gt;</span>                   t</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Prefix</span>  t s       (q,y) <span class="ot">-&gt;</span>                   t <span class="op">&lt;&gt;</span> ifPrns <span class="dt">R</span> s q y</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Postfix</span> t s (p,x)       <span class="ot">-&gt;</span> ifPrns <span class="dt">L</span> s p x <span class="op">&lt;&gt;</span> t</span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Binary</span>  t s (p,x) (q,y) <span class="ot">-&gt;</span> ifPrns <span class="dt">L</span> s p x <span class="op">&lt;&gt;</span> t <span class="op">&lt;&gt;</span> ifPrns <span class="dt">R</span> s q y</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>    ifPrns sid (op,oa) (<span class="dt">Just</span> (ip,ia))</span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">|</span> ip <span class="op">&lt;</span> op <span class="op">||</span> ip <span class="op">==</span> op <span class="op">&amp;&amp;</span> (ia <span class="op">/=</span> oa <span class="op">||</span> sid <span class="op">/=</span> oa) <span class="ot">=</span> prns</span>
<span id="cb14-13"><a href="#cb14-13" aria-hidden="true" tabindex="-1"></a>    ifPrns _ _ _ <span class="ot">=</span> <span class="fu">id</span></span></code></pre></div>
<p>The first argument to this algebra is the parenthesizing function.
This algebra works fine for when the <code
class="sourceCode haskell"><span class="dt">ShowExpr</span></code> type
is already constructed:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">showExpr&#39; ::</span> <span class="dt">Semigroup</span> t <span class="ot">=&gt;</span> (t <span class="ot">-&gt;</span> t) <span class="ot">-&gt;</span> <span class="dt">Fix</span> (<span class="dt">ShowExpr</span> t) <span class="ot">-&gt;</span> t</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>showExpr&#39; <span class="ot">=</span> zygo (preview assoc) <span class="op">.</span> showExprAlg</span></code></pre></div>
<p>But we still need to construct the <code
class="sourceCode haskell"><span class="dt">ShowExpr</span></code> from
something else first. <code class="sourceCode haskell">hylo</code> might
be a good fit:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">hylo ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (f b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> f a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>But that performs a catamorphism after an anamorphism, and we want a
zygomorphism after an anamorphism. Luckily, the <a
href="https://hackage.haskell.org/package/recursion-schemes">recursion-schemes</a>
library is constructed in such a way that different schemes can be stuck
together relatively easily:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>hylozygo</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Functor</span> f</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (f a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (f (a, b) <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (c <span class="ot">-&gt;</span> f c) <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> b</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>hylozygo x y z <span class="ot">=</span> ghylo (distZygo x) distAna y (<span class="fu">fmap</span> <span class="dt">Identity</span> <span class="op">.</span> z)</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="ot">showExpr ::</span> <span class="dt">Semigroup</span> t</span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>         <span class="ot">=&gt;</span> (t <span class="ot">-&gt;</span> t)</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> (e <span class="ot">-&gt;</span> <span class="dt">ShowExpr</span> t e)</span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>         <span class="ot">-&gt;</span> e <span class="ot">-&gt;</span> t</span>
<span id="cb17-10"><a href="#cb17-10" aria-hidden="true" tabindex="-1"></a>showExpr <span class="ot">=</span> hylozygo (preview assoc) <span class="op">.</span> showExprAlg</span></code></pre></div>
<p>Let’s try it out, with a right-associative operator this time to make
things more difficult:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ExprF</span> a</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">LitF</span> <span class="dt">Integer</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="op">:+:</span>) a a</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="op">:*:</span>) a a</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> (<span class="op">:^:</span>) a a</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>makeHandler &#39;<span class="dt">&#39;ExprF</span></span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">Expr</span> {<span class="ot"> runExpr ::</span> <span class="dt">ExprF</span> <span class="dt">Expr</span> }</span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Expr</span> <span class="kw">where</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fromInteger</span> <span class="ot">=</span> <span class="dt">Expr</span> <span class="op">.</span> <span class="dt">LitF</span></span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>  x <span class="op">+</span> y <span class="ot">=</span> <span class="dt">Expr</span> (x <span class="op">:+:</span> y)</span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>  x <span class="op">*</span> y <span class="ot">=</span> <span class="dt">Expr</span> (x <span class="op">:*:</span> y)</span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">8</span> <span class="op">^*</span></span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a><span class="ot">(^*) ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Expr</span></span>
<span id="cb18-19"><a href="#cb18-19" aria-hidden="true" tabindex="-1"></a>x <span class="op">^*</span> y <span class="ot">=</span> <span class="dt">Expr</span> (x <span class="op">:^:</span> y)</span>
<span id="cb18-20"><a href="#cb18-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-21"><a href="#cb18-21" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> <span class="dt">Expr</span> <span class="kw">where</span></span>
<span id="cb18-22"><a href="#cb18-22" aria-hidden="true" tabindex="-1"></a>  <span class="fu">show</span> <span class="ot">=</span></span>
<span id="cb18-23"><a href="#cb18-23" aria-hidden="true" tabindex="-1"></a>    showExpr</span>
<span id="cb18-24"><a href="#cb18-24" aria-hidden="true" tabindex="-1"></a>      (\x <span class="ot">-&gt;</span> <span class="st">&quot;(&quot;</span> <span class="op">++</span> x <span class="op">++</span> <span class="st">&quot;)&quot;</span>)</span>
<span id="cb18-25"><a href="#cb18-25" aria-hidden="true" tabindex="-1"></a>      (<span class="fu">index</span> <span class="dt">ExprFAlg</span> {<span class="op">..</span>} <span class="op">.</span> runExpr)</span>
<span id="cb18-26"><a href="#cb18-26" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb18-27"><a href="#cb18-27" aria-hidden="true" tabindex="-1"></a>      litF <span class="ot">=</span> <span class="dt">ShowLit</span> <span class="op">.</span> <span class="fu">show</span></span>
<span id="cb18-28"><a href="#cb18-28" aria-hidden="true" tabindex="-1"></a>      (<span class="op">+:</span>) <span class="ot">=</span> <span class="dt">Binary</span> <span class="st">&quot; + &quot;</span> (<span class="dv">6</span>,<span class="dt">L</span>)</span>
<span id="cb18-29"><a href="#cb18-29" aria-hidden="true" tabindex="-1"></a>      (<span class="op">*:</span>) <span class="ot">=</span> <span class="dt">Binary</span> <span class="st">&quot; * &quot;</span> (<span class="dv">7</span>,<span class="dt">L</span>)</span>
<span id="cb18-30"><a href="#cb18-30" aria-hidden="true" tabindex="-1"></a>      (<span class="op">^:</span>) <span class="ot">=</span> <span class="dt">Binary</span> <span class="st">&quot; ^ &quot;</span> (<span class="dv">8</span>,<span class="dt">R</span>)</span></code></pre></div>
<p>Since we only specified <code
class="sourceCode haskell"><span class="dt">Semigroup</span></code> in
the definition of <code class="sourceCode haskell">showExpr</code>, we
can use the more efficient difference-list definition of <code
class="sourceCode haskell"><span class="dt">Show</span></code>:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> <span class="dt">Expr</span> <span class="kw">where</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">showsPrec</span> _ <span class="ot">=</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>      appEndo <span class="op">.</span> showExpr</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>        (<span class="dt">Endo</span> <span class="op">.</span> <span class="fu">showParen</span> <span class="dt">True</span> <span class="op">.</span> appEndo)</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>        (<span class="fu">index</span> <span class="dt">ExprFAlg</span> {<span class="op">..</span>} <span class="op">.</span> runExpr)</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>        litF <span class="ot">=</span> <span class="dt">ShowLit</span> <span class="op">.</span> <span class="dt">Endo</span> <span class="op">.</span> <span class="fu">shows</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>        (<span class="op">+:</span>) <span class="ot">=</span> <span class="dt">Binary</span> (<span class="dt">Endo</span> (<span class="st">&quot; + &quot;</span> <span class="op">++</span>)) (<span class="dv">6</span>,<span class="dt">L</span>)</span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>        (<span class="op">*:</span>) <span class="ot">=</span> <span class="dt">Binary</span> (<span class="dt">Endo</span> (<span class="st">&quot; * &quot;</span> <span class="op">++</span>)) (<span class="dv">7</span>,<span class="dt">L</span>)</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>        (<span class="op">^:</span>) <span class="ot">=</span> <span class="dt">Binary</span> (<span class="dt">Endo</span> (<span class="st">&quot; ^ &quot;</span> <span class="op">++</span>)) (<span class="dv">8</span>,<span class="dt">R</span>)</span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">^*</span> <span class="dv">2</span> <span class="op">^*</span> <span class="dv">3</span>         <span class="co">-- 1 ^ 2 ^ 3</span></span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a>(<span class="dv">1</span> <span class="op">^*</span> <span class="dv">2</span>) <span class="op">^*</span> <span class="dv">3</span>       <span class="co">-- (1 ^ 2) ^ 3</span></span>
<span id="cb19-14"><a href="#cb19-14" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">*</span> <span class="dv">2</span> <span class="op">+</span> <span class="dv">3</span><span class="ot">   ::</span> <span class="dt">Expr</span> <span class="co">-- 1 * 2 + 3</span></span>
<span id="cb19-15"><a href="#cb19-15" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">*</span> (<span class="dv">2</span> <span class="op">+</span> <span class="dv">3</span>)<span class="ot"> ::</span> <span class="dt">Expr</span> <span class="co">-- 1 * (2 + 3)</span></span></code></pre></div>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-ramsey_unparsing_1998" class="csl-entry" role="listitem">
Ramsey, Norman. 1998. <span>“Unparsing <span>Expressions</span>
<span>With</span> <span>Prefix</span> and <span>Postfix</span>
<span>Operators</span>.”</span> <em>Software—Practice &amp;
Experience</em> 28 (12): 1327–1356. <a
href="http://www.cs.tufts.edu/%7Enr/pubs/unparse-abstract.html">http://www.cs.tufts.edu/%7Enr/pubs/unparse-abstract.html</a>.
</div>
</div>
]]></description>
    <pubDate>Thu, 30 Mar 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-03-30-fun-with-recursion-schemes.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Constrained Applicatives</title>
    <link>https://doisinkidney.com/posts/2017-03-08-constrained-applicatives.html</link>
    <description><![CDATA[<div class="info">
    Posted on March  8, 2017
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Applicative&#39;." href="/tags/Applicative.html" rel="tag">Applicative</a>
    
</div>

<p>In Haskell restricted monads are monads which can’t contain every
type. <code
class="sourceCode haskell"><span class="dt">Set</span></code> is a good
example. If you look in the documentation for <a
href="https://hackage.haskell.org/package/containers-0.5.10.1/docs/Data-Set.html">Data.Set</a>
you’ll see several functions which correspond to functions in the
Functor/Applicative/Monad typeclass hierarchy:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span><span class="ot"> ::</span> <span class="dt">Ord</span> b <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Set</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> b</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">singleton ::</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> a</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="fu">foldMap</span><span class="ot"> ::</span> <span class="dt">Ord</span> b <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Set</span> b) <span class="ot">-&gt;</span> <span class="dt">Set</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> b <span class="co">-- specialized</span></span></code></pre></div>
<p>Unfortunately, though, <code
class="sourceCode haskell"><span class="dt">Set</span></code> can’t
conform to <code
class="sourceCode haskell"><span class="dt">Functor</span></code>,
because the signature of <code
class="sourceCode haskell"><span class="fu">fmap</span></code> looks
like this:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span><span class="ot"> ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div>
<p>It doesn’t have an <code
class="sourceCode haskell"><span class="dt">Ord</span></code>
constraint.</p>
<p>This is annoying: when using <code
class="sourceCode haskell"><span class="dt">Set</span></code>, lots of
things have to be imported qualified, and you have to remember the
slightly different names of extra functions like <code
class="sourceCode haskell"><span class="fu">map</span></code>. More
importantly, you’ve lost the ability to write generic code over <code
class="sourceCode haskell"><span class="dt">Functor</span></code> or
<code class="sourceCode haskell"><span class="dt">Monad</span></code>
which will work on <code
class="sourceCode haskell"><span class="dt">Set</span></code>.</p>
<p>There are a number of ways to get around this problem. <a
href="http://okmij.org/ftp/Haskell/set-monad.html#set-cps">Here</a>, an
approach using reflection-reification is explored. These are the types
involved:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">SetC</span> a <span class="ot">=</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>       <span class="dt">SetC</span>{<span class="ot">unSetC ::</span> <span class="kw">forall</span> r<span class="op">.</span> <span class="dt">Ord</span> r <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Set</span> r) <span class="ot">-&gt;</span> <span class="dt">Set</span> r}</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">reifySet ::</span> <span class="dt">Ord</span> r <span class="ot">=&gt;</span> <span class="dt">SetC</span> r <span class="ot">-&gt;</span> <span class="dt">Set</span> r</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>reifySet m <span class="ot">=</span> unSetC m singleton</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="ot">reflectSet ::</span> <span class="dt">Ord</span> r <span class="ot">=&gt;</span> <span class="dt">Set</span> r <span class="ot">-&gt;</span> <span class="dt">SetC</span> r</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>reflectSet s <span class="ot">=</span> <span class="dt">SetC</span> <span class="op">$</span> \k <span class="ot">-&gt;</span> S.foldr (\x r <span class="ot">-&gt;</span> k x <span class="ot">`union`</span> r) S.empty s</span></code></pre></div>
<p><code class="sourceCode haskell"><span class="dt">SetC</span></code>
is just <code
class="sourceCode haskell"><span class="dt">Cont</span></code> in
disguise. In fact, we can generalize this pattern, using Constraint
Kinds:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">FreeT</span> c m a <span class="ot">=</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>       <span class="dt">FreeT</span> {<span class="ot"> runFreeT ::</span> <span class="kw">forall</span> r<span class="op">.</span> c r <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m r) <span class="ot">-&gt;</span> m r}</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="ot">reifySet ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">FreeT</span> <span class="dt">Ord</span> <span class="dt">Set</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> a</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>reifySet m <span class="ot">=</span> runFreeT m singleton</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="ot">reflectSet ::</span> <span class="dt">Set</span> r <span class="ot">-&gt;</span> <span class="dt">FreeT</span> <span class="dt">Ord</span> <span class="dt">Set</span> r</span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>reflectSet s <span class="ot">=</span> <span class="dt">FreeT</span> <span class="op">$</span> \k <span class="ot">-&gt;</span> S.foldr (\x r <span class="ot">-&gt;</span> k x <span class="ot">`union`</span> r) S.empty s</span></code></pre></div>
<p><code class="sourceCode haskell"><span class="dt">FreeT</span></code>
looks an <em>awful lot</em> like <code
class="sourceCode haskell"><span class="dt">ContT</span></code> by now.
The type has some other interesting applications, though. For instance,
this type:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">FM</span> <span class="ot">=</span> <span class="dt">FreeT</span> <span class="dt">Monoid</span> <span class="dt">Identity</span></span></code></pre></div>
<p>Is the free monoid. If we use a transformers-style type synonym, the
naming becomes even nicer:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Free</span> c <span class="ot">=</span> <span class="dt">FreeT</span> c <span class="dt">Identity</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ot">runFree ::</span> c r <span class="ot">=&gt;</span> <span class="dt">Free</span> c a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> r) <span class="ot">-&gt;</span> r</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>runFree xs f <span class="ot">=</span> runIdentity (runFreeT xs (<span class="fu">pure</span> <span class="op">.</span> f))</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Foldable</span> (<span class="dt">Free</span> <span class="dt">Monoid</span>) <span class="kw">where</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">foldMap</span> <span class="ot">=</span> <span class="fu">flip</span> runFree</span></code></pre></div>
<p>Check out <a
href="https://hackage.haskell.org/package/free-functors">this
package</a> for an implementation of the non-transformer <code
class="sourceCode haskell"><span class="dt">Free</span></code>.</p>
<h2 id="different-classes">Different Classes</h2>
<p>This is still unsatisfying, though. Putting annotations around your
code feels inelegant. The next solution is to replace the monad class
altogether with our own, and turn on <code
class="sourceCode haskell"><span class="op">-</span><span class="dt">XRebindableSyntax</span></code>.
There are a few ways to design this new class. One option is to use <a
href="http://okmij.org/ftp/Haskell/types.html#restricted-datatypes">multi-parameter
type classes</a>. Another solution is with an associated type:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> <span class="dt">Suitable</span> f<span class="ot"> a ::</span> <span class="dt">Constraint</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  fmap ::</span> <span class="dt">Suitable</span> f b <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div>
<p>This is similar to the approach taken in the <a
href="https://hackage.haskell.org/package/rmonad">rmonad</a> library,
except that library doesn’t use constraint kinds (they weren’t available
when the library was made), so it has to make do with a <code
class="sourceCode haskell"><span class="dt">Suitable</span></code>
class. Also, the signature for <code
class="sourceCode haskell"><span class="fu">fmap</span></code> in rmonad
is:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span><span class="ot"> ::</span> (<span class="dt">Suitable</span> f a, <span class="dt">Suitable</span> f b) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div>
<p>I don’t want to constrain <code class="sourceCode haskell">a</code>:
I figure if you can get something <em>into</em> your monad, it
<em>must</em> be suitable. And I really want to reduce the syntactic
overhead of writing extra types next to your functions.</p>
<p>There’s also the <a
href="https://hackage.haskell.org/package/supermonad-0.1/docs/Control-Supermonad-Constrained.html">supermonad</a>
library out there which is much more general than any of these examples:
it supports indexed monads as well as constrained.</p>
<p>Anyway,<code
class="sourceCode haskell"><span class="dt">Monad</span></code> is
defined similarly to <code
class="sourceCode haskell"><span class="dt">Functor</span></code>:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> m <span class="ot">=&gt;</span> <span class="dt">Monad</span> m <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  return ::</span> <span class="dt">Suitable</span> m a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> m a</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&gt;&gt;=) ::</span> <span class="dt">Suitable</span> m b <span class="ot">=&gt;</span> m a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> m b) <span class="ot">-&gt;</span> m b</span></code></pre></div>
<p>Again, I want to minimize the use of <code
class="sourceCode haskell"><span class="dt">Suitable</span></code>, so
for <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code>
there’s only a constraint on <code
class="sourceCode haskell">b</code>.</p>
<p>Finally, here’s the <code
class="sourceCode haskell"><span class="dt">Set</span></code>
instance:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Set</span> <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">Suitable</span> <span class="dt">Set</span> a <span class="ot">=</span> <span class="dt">Ord</span> a</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> <span class="ot">=</span> Set.map</span></code></pre></div>
<h2 id="monomorphic">Monomorphic</h2>
<p>With equality constraints, you can actually make <em>monomorphic</em>
containers conform to these classes (or, at least, wrappers around
them).</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Text</span> <span class="kw">as</span> <span class="dt">Text</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Text</span> a <span class="kw">where</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Text</span><span class="ot"> ::</span> <span class="dt">Text.Text</span> <span class="ot">-&gt;</span> <span class="dt">Text</span> <span class="dt">Char</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Text</span> <span class="kw">where</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> <span class="dt">Suitable</span> <span class="dt">Text</span> a <span class="ot">=</span> a <span class="op">~</span> <span class="dt">Char</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Text</span> xs) <span class="ot">=</span> <span class="dt">Text</span> (Text.map f xs)</span></code></pre></div>
<p>This pattern can be generalized with some more GADT magic:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Monomorphic</span> xs a b <span class="kw">where</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Monomorphic</span><span class="ot"> ::</span> (a <span class="op">~</span> b) <span class="ot">=&gt;</span> xs <span class="ot">-&gt;</span> <span class="dt">Monomorphic</span> xs a b</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">MonoFunctor</span> xs, a <span class="op">~</span> <span class="dt">Element</span> xs) <span class="ot">=&gt;</span> <span class="dt">Functor</span> (<span class="dt">Monomorphic</span> xs a) <span class="kw">where</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> <span class="dt">Suitable</span> (<span class="dt">Monomorphic</span> xs a) b <span class="ot">=</span> a <span class="op">~</span> b</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> <span class="dt">Monomorphic</span> (omap f xs)</span></code></pre></div>
<p>Where <code class="sourceCode haskell">omap</code> comes from the <a
href="https://hackage.haskell.org/package/mono-traversable">mono-traversable</a>
package. You could go a little further, to <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">MonoFoldable</span> xs, element <span class="op">~</span> <span class="dt">Element</span> xs) <span class="ot">=&gt;</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>         <span class="dt">Foldable</span> (<span class="dt">Monomorphic</span> xs element) <span class="kw">where</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">foldr</span> f b (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> ofoldr f b xs</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">foldMap</span> f (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> ofoldMap f xs</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    foldl&#39; f b (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> ofoldl&#39; f b xs</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    toList (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> otoList xs</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="fu">null</span> (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> onull xs</span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">length</span> (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> olength xs</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">foldr1</span> f (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> ofoldr1Ex f xs</span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">elem</span> x (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> oelem x xs</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>    <span class="fu">maximum</span> (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> maximumEx xs</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>    <span class="fu">minimum</span> (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> minimumEx xs</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>    <span class="fu">sum</span> (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> osum xs</span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>    <span class="fu">product</span> (<span class="dt">Monomorphic</span> xs) <span class="ot">=</span> oproduct xs</span></code></pre></div>
<h2 id="back-to-normal">Back to normal</h2>
<p>Changing the <code
class="sourceCode haskell"><span class="dt">FreeT</span></code> type
above a little, we can go back to normal functors and monads, and write
more general reify and reflect functions:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">FreeT</span> m a <span class="ot">=</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>       <span class="dt">FreeT</span> {<span class="ot"> runFreeT ::</span> <span class="kw">forall</span> r<span class="op">.</span> <span class="dt">Suitable</span> m r <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m r) <span class="ot">-&gt;</span> m r}</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a><span class="ot">reify ::</span> (<span class="dt">Monad</span> m, <span class="dt">Suitable</span> m a) <span class="ot">=&gt;</span> <span class="dt">FreeT</span> m a <span class="ot">-&gt;</span> m a</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>reify <span class="ot">=</span> <span class="fu">flip</span> runFreeT <span class="fu">return</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="ot">reflect ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> m a <span class="ot">-&gt;</span> <span class="dt">FreeT</span> m a</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>reflect x <span class="ot">=</span> <span class="dt">FreeT</span> (x <span class="op">&gt;&gt;=</span>)</span></code></pre></div>
<p>So now our types, when wrapped, can conform to the Prelude’s <code
class="sourceCode haskell"><span class="dt">Functor</span></code>. It
would be nice if this type could be written like so:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">reify ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">FreeT</span> (<span class="dt">Suitable</span> m) m a <span class="ot">-&gt;</span> m a</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>reify <span class="ot">=</span> <span class="fu">flip</span> runFreeT <span class="fu">return</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="ot">reflect ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> m a <span class="ot">-&gt;</span> <span class="dt">FreeT</span> (<span class="dt">Suitable</span> m) m a</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>reflect x <span class="ot">=</span> <span class="dt">FreeT</span> (x <span class="op">&gt;&gt;=</span>)</span></code></pre></div>
<p>But unfortunately type families cannot be partially applied.</p>
<h2 id="applicatives">Applicatives</h2>
<p>The classes above aren’t very modern: they’re missing applicative.
This one is tricky:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> f <span class="kw">where</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  pure ::</span> <span class="dt">Suitable</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;*&gt;) ::</span> <span class="dt">Suitable</span> f b <span class="ot">=&gt;</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span></code></pre></div>
<p>The issue is <code
class="sourceCode haskell">f (a <span class="ot">-&gt;</span> b)</code>.
There’s no <em>way</em> you’re getting some type like that into <code
class="sourceCode haskell"><span class="dt">Set</span></code>. This
means that <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code> is
effectively useless. No problem, you think: define <code
class="sourceCode haskell">liftA2</code> instead:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Applicative</span> f <span class="kw">where</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  pure ::</span> <span class="dt">Suitable</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> f a</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  liftA2 ::</span> <span class="dt">Suitable</span> f c <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;*&gt;) ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Suitable</span> f b) <span class="ot">=&gt;</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;*&gt;</span>) <span class="ot">=</span> liftA2 (<span class="op">$</span>)</span></code></pre></div>
<p>Great! Now we can use it with set. However, there’s no way (that I
can see) to define the other lift functions: <code
class="sourceCode haskell">liftA3</code>, etc. Of course, if <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code> is
available, it’s as simple as:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>liftA3 f xs ys zs <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  x <span class="ot">&lt;-</span> xs</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  y <span class="ot">&lt;-</span> ys</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>  z <span class="ot">&lt;-</span> zs</span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> (f x y z)</span></code></pre></div>
<p>But now we can’t define it for non-monadic applicatives (square
matrices, ZipLists, etc.). This also forces us to use <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code> when
<code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code> <a
href="https://simonmar.github.io/posts/2015-10-20-Fun-With-Haxl-1.html">may
have been more efficient</a>.</p>
<p>The functions we’re interested in defining look like this:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftA2 ::</span> <span class="dt">Suitable</span> f c <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="ot">liftA3 ::</span> <span class="dt">Suitable</span> f d <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c <span class="ot">-&gt;</span> f d</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="ot">liftA4 ::</span> <span class="dt">Suitable</span> f e <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d <span class="ot">-&gt;</span> e) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c <span class="ot">-&gt;</span> f d <span class="ot">-&gt;</span> f e</span></code></pre></div>
<p>There’s a clear pattern, but no obvious way to abstract over it.
Type-level shenanigans to the rescue!</p>
<p>The pattern might be expressed like this:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftA ::</span> <span class="dt">Func</span> args <span class="ot">-&gt;</span> <span class="dt">Func</span> lifted args</span></code></pre></div>
<p>We can store these types as heterogeneous lists:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:-</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Vect</span> xs <span class="kw">where</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span><span class="ot">  ::</span> <span class="dt">Vect</span> &#39;[]</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:-) ::</span> x <span class="ot">-&gt;</span> <span class="dt">Vect</span> xs <span class="ot">-&gt;</span> <span class="dt">Vect</span> (x &#39;<span class="op">:</span> xs)</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">:*</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">AppVect</span> f xs <span class="kw">where</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">NilA</span><span class="ot"> ::</span> <span class="dt">AppVect</span> f &#39;[]</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:*) ::</span> f x <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f (x &#39;<span class="op">:</span> xs)</span></code></pre></div>
<p>And <code class="sourceCode haskell">liftA</code> can be represented
like this:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>liftA</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Suitable</span> f b</span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (<span class="dt">Vect</span> xs <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f b</span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>liftA2</span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Suitable</span> f c</span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c</span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a>liftA2 f xs ys <span class="ot">=</span></span>
<span id="cb22-9"><a href="#cb22-9" aria-hidden="true" tabindex="-1"></a>    liftA</span>
<span id="cb22-10"><a href="#cb22-10" aria-hidden="true" tabindex="-1"></a>        (\(x <span class="op">:-</span> y <span class="op">:-</span> <span class="dt">Nil</span>) <span class="ot">-&gt;</span></span>
<span id="cb22-11"><a href="#cb22-11" aria-hidden="true" tabindex="-1"></a>              f x y)</span>
<span id="cb22-12"><a href="#cb22-12" aria-hidden="true" tabindex="-1"></a>        (xs <span class="op">:*</span> ys <span class="op">:*</span> <span class="dt">NilA</span>)</span>
<span id="cb22-13"><a href="#cb22-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb22-14"><a href="#cb22-14" aria-hidden="true" tabindex="-1"></a>liftA3</span>
<span id="cb22-15"><a href="#cb22-15" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Suitable</span> f d</span>
<span id="cb22-16"><a href="#cb22-16" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f c <span class="ot">-&gt;</span> f d</span>
<span id="cb22-17"><a href="#cb22-17" aria-hidden="true" tabindex="-1"></a>liftA3 f xs ys zs <span class="ot">=</span></span>
<span id="cb22-18"><a href="#cb22-18" aria-hidden="true" tabindex="-1"></a>    liftA</span>
<span id="cb22-19"><a href="#cb22-19" aria-hidden="true" tabindex="-1"></a>        (\(x <span class="op">:-</span> y <span class="op">:-</span> z <span class="op">:-</span> <span class="dt">Nil</span>) <span class="ot">-&gt;</span></span>
<span id="cb22-20"><a href="#cb22-20" aria-hidden="true" tabindex="-1"></a>              f x y z)</span>
<span id="cb22-21"><a href="#cb22-21" aria-hidden="true" tabindex="-1"></a>        (xs <span class="op">:*</span> ys <span class="op">:*</span> zs <span class="op">:*</span> <span class="dt">NilA</span>)</span></code></pre></div>
<p>Cool! For unrestricted applicatives, we can define <code
class="sourceCode haskell">liftA</code> in terms of <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftAP ::</span> (<span class="dt">Prelude.Applicative</span> f)</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> (<span class="dt">Vect</span> xs <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (<span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f b)</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>liftAP f <span class="dt">NilA</span> <span class="ot">=</span> Prelude.pure (f <span class="dt">Nil</span>)</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>liftAP f (x <span class="op">:*</span> <span class="dt">NilA</span>)</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> Prelude.fmap (f <span class="op">.</span> (<span class="op">:-</span><span class="dt">Nil</span>)) x</span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>liftAP f (x <span class="op">:*</span> xs)</span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span>  ((f <span class="op">.</span>) <span class="op">.</span> (<span class="op">:-</span>)) <span class="op">Prelude.&lt;$&gt;</span> x <span class="op">Prelude.&lt;*&gt;</span> liftAP <span class="fu">id</span> xs</span></code></pre></div>
<p>And for types with a monad instance, we can define it in terms of
<code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code>:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftAM ::</span> (<span class="dt">Monad</span> f, <span class="dt">Suitable</span> f b)</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> (<span class="dt">Vect</span> xs <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (<span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f b)</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>liftAM f <span class="dt">NilA</span> <span class="ot">=</span> <span class="fu">pure</span> (f <span class="dt">Nil</span>)</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>liftAM f (x <span class="op">:*</span> <span class="dt">NilA</span>) <span class="ot">=</span> <span class="fu">fmap</span> (f <span class="op">.</span> (<span class="op">:-</span><span class="dt">Nil</span>)) x</span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>liftAM f (x <span class="op">:*</span> xs) <span class="ot">=</span> x <span class="op">&gt;&gt;=</span> \y <span class="ot">-&gt;</span> liftAM (f <span class="op">.</span> (y<span class="op">:-</span>)) xs</span></code></pre></div>
<h2 id="efficiency">Efficiency</h2>
<p>This approach is <em>really</em> slow. Every function wraps up its
arguments in a <code
class="sourceCode haskell"><span class="dt">Vect</span></code>, and it’s
just generally awful.</p>
<p>What about <em>not</em> wrapping up the function? Type families can
help here:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">FunType</span> (<span class="ot">xs ::</span> [<span class="op">*</span>]) (<span class="ot">y ::</span> <span class="op">*</span>)<span class="ot"> ::</span> <span class="op">*</span> <span class="kw">where</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FunType</span> &#39;[] y <span class="ot">=</span> y</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FunType</span> (x &#39;<span class="op">:</span> xs) y <span class="ot">=</span> x <span class="ot">-&gt;</span> <span class="dt">FunType</span> xs y</span></code></pre></div>
<p>It gets really difficult to define <code
class="sourceCode haskell">liftA</code> using <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code> now,
though. <code class="sourceCode haskell">liftAM</code>, on the other
hand, is a breeze:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftAM ::</span> <span class="dt">Monad</span> f <span class="ot">=&gt;</span> <span class="dt">FunType</span> xs a <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f a</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>liftAM f <span class="dt">Nil</span> <span class="ot">=</span> <span class="fu">pure</span> f</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>liftAM f (x <span class="op">:&lt;</span> xs) <span class="ot">=</span> x <span class="op">&gt;&gt;=</span> \y <span class="ot">-&gt;</span> liftAM (f y) xs</span></code></pre></div>
<p>And no vector constructors on the right of the bind!</p>
<p>Still, no decent definition using <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>. The
problem is that we’re using a cons-list to represent a function’s
arguments, but <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code> is
left-associative, so it builds up arguments as a snoc list. Lets try
using a snoc-list as the type family:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">5</span> <span class="op">:&gt;</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">AppVect</span> f xs <span class="kw">where</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Nil</span><span class="ot"> ::</span> <span class="dt">AppVect</span> f &#39;[]</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  (:&gt;) ::</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f x <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f (x &#39;<span class="op">:</span> xs)</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="kw">family</span> <span class="dt">FunType</span> (<span class="ot">xs ::</span> [<span class="op">*</span>]) (<span class="ot">y ::</span> <span class="op">*</span>)<span class="ot"> ::</span> <span class="op">*</span> <span class="kw">where</span></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FunType</span> &#39;[] y <span class="ot">=</span> y</span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FunType</span> (x &#39;<span class="op">:</span> xs) y <span class="ot">=</span> <span class="dt">FunType</span> xs (x <span class="ot">-&gt;</span> y)</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a>liftA</span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="dt">Suitable</span> f a</span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">FunType</span> xs a <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f a</span></code></pre></div>
<p><code class="sourceCode haskell">liftAP</code> now gets a natural
definition:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftAP ::</span> <span class="dt">Prelude.Applicative</span> f <span class="ot">=&gt;</span> <span class="dt">FunType</span> xs a <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f a</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>liftAP f <span class="dt">Nil</span> <span class="ot">=</span> Prelude.pure f</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>liftAP f (<span class="dt">Nil</span> <span class="op">:&gt;</span> xs) <span class="ot">=</span> Prelude.fmap f xs</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>liftAP f (ys <span class="op">:&gt;</span> xs) <span class="ot">=</span> liftAP f ys <span class="op">Prelude.&lt;*&gt;</span> xs</span></code></pre></div>
<p>But what about <code class="sourceCode haskell">liftAM</code>? It’s
much more difficult, fundamentally because <code
class="sourceCode haskell"><span class="op">&gt;&gt;=</span></code>
builds up arguments as a cons-list. To convert between the two
efficiently, we need to use the trick for reversing lists efficiently:
build up the reversed list as you go.</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="ot">liftAM ::</span> (<span class="dt">Monad</span> f, <span class="dt">Suitable</span> f a) <span class="ot">=&gt;</span> <span class="dt">FunType</span> xs a <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f a</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>liftAM <span class="ot">=</span> go <span class="fu">pure</span> <span class="kw">where</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  go ::</span> (<span class="dt">Suitable</span> f b, <span class="dt">Monad</span> f)</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>     <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> <span class="dt">FunType</span> xs a <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f b</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>  go f g <span class="dt">Nil</span> <span class="ot">=</span> f g</span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a>  go f g (xs <span class="op">:&gt;</span> x) <span class="ot">=</span> go (\c <span class="ot">-&gt;</span> x <span class="op">&gt;&gt;=</span> f <span class="op">.</span> c) g xs</span></code></pre></div>
<p>Using these definitions, we can make <code
class="sourceCode haskell"><span class="dt">Set</span></code>, <code
class="sourceCode haskell"><span class="dt">Text</span></code>, and all
the rest of them applicatives, while preserving the applicative
operations. Also, from my preliminary testing, there seems to be
<em>no</em> overhead in using these new definitions for <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>.</p>
<h2 id="normalized-embedding">Normalized Embedding</h2>
<p>In <span class="citation"
data-cites="sculthorpe_constrained-monad_2013">Sculthorpe et al. (<a
href="#ref-sculthorpe_constrained-monad_2013"
role="doc-biblioref">2013</a>)</span>, there’s discussion of this
type:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">NM</span><span class="ot"> ::</span> (<span class="op">*</span> <span class="ot">-&gt;</span> <span class="dt">Constraint</span>) <span class="ot">-&gt;</span> (<span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) <span class="ot">-&gt;</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span> <span class="kw">where</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Return</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">NM</span> c t a</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Bind</span><span class="ot"> ::</span> c x <span class="ot">=&gt;</span> t x <span class="ot">-&gt;</span> (x <span class="ot">-&gt;</span> <span class="dt">NM</span> c t a) <span class="ot">-&gt;</span> <span class="dt">NM</span> c t a</span></code></pre></div>
<p>This type allows constrained monads to become normal monads. It can
be used for the same purpose as the <code
class="sourceCode haskell"><span class="dt">FreeT</span></code> type
from above. In the paper, the free type is called <code
class="sourceCode haskell"><span class="dt">RCodT</span></code>.</p>
<p>One way to look at the type is as a concrete representation of the
monad class, with each method being a constructor.</p>
<p>You might wonder if there are similar constructs for functor and
applicative. Functor is simple:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">NF</span><span class="ot"> ::</span> (<span class="op">*</span> <span class="ot">-&gt;</span> <span class="dt">Constraint</span>) <span class="ot">-&gt;</span> (<span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) <span class="ot">-&gt;</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span> <span class="kw">where</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">FMap</span><span class="ot"> ::</span> c x <span class="ot">=&gt;</span> (x <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> t x <span class="ot">-&gt;</span> <span class="dt">NF</span> c t a</span></code></pre></div>
<p>Again, this can conform to functor (and <em>only</em> functor), and
can be interpreted when the final type is <code
class="sourceCode haskell"><span class="dt">Suitable</span></code>.</p>
<p>Like above, it has a continuation version, <a
href="https://hackage.haskell.org/package/kan-extensions-5.0.1/docs/Data-Functor-Yoneda.html">Yoneda</a>.</p>
<p>For applicatives, though, the situation is different. In the paper,
they weren’t able to define a transformer for applicatives that could be
interpreted in some restricted applicative. I needed one because I
wanted to use <code
class="sourceCode haskell"><span class="op">-</span><span class="dt">XApplicativeDo</span></code>
notation: the desugaring uses <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>, not
the <code class="sourceCode haskell">liftAn</code> functions, so I
wanted to construct a free applicative using <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>, and
run it using the lift functions. What I managed to cobble together
doesn’t <em>really</em> solve the problem, but it works for
<code>-XApplicativeDo</code>!</p>
<p>The key with a lot of this was realizing that <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code> is
<em>snoc</em>, not cons. Using a <a
href="https://ro-che.info/articles/2013-03-31-flavours-of-free-applicative-functors">free
applicative</a>:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Free</span> f a <span class="kw">where</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Free</span> f a</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Ap</span><span class="ot"> ::</span> <span class="dt">Free</span> f (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Free</span> f b</span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Prelude.Functor</span> (<span class="dt">Free</span> f) <span class="kw">where</span></span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Pure</span> a) <span class="ot">=</span> <span class="dt">Pure</span> (f a)</span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Ap</span> x y) <span class="ot">=</span> <span class="dt">Ap</span> ((f <span class="op">.</span>) <span class="op">Prelude.&lt;$&gt;</span> x) y</span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Prelude.Applicative</span> (<span class="dt">Free</span> f) <span class="kw">where</span></span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Pure</span></span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Pure</span> f <span class="op">&lt;*&gt;</span> y <span class="ot">=</span> Prelude.fmap f y</span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Ap</span> x y <span class="op">&lt;*&gt;</span> z <span class="ot">=</span> <span class="dt">Ap</span> (<span class="fu">flip</span> <span class="op">Prelude.&lt;$&gt;</span> x <span class="op">Prelude.&lt;*&gt;</span> z) y</span></code></pre></div>
<p>This type can conform to <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
and <code
class="sourceCode haskell"><span class="dt">Functor</span></code> no
problem. And all it needs to turn back into a constrained applicative is
for the outer type to be suitable:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lift ::</span> f a <span class="ot">-&gt;</span> <span class="dt">Free</span> f a</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>lift <span class="ot">=</span> <span class="dt">Ap</span> (<span class="dt">Pure</span> <span class="fu">id</span>)</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a>lower</span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> <span class="kw">forall</span> f a c<span class="op">.</span></span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>       <span class="dt">Free</span> f a</span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> (<span class="kw">forall</span> xs<span class="op">.</span> <span class="dt">FunType</span> xs a <span class="ot">-&gt;</span> <span class="dt">AppVect</span> f xs <span class="ot">-&gt;</span> f c)</span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a>    <span class="ot">-&gt;</span> f c</span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a>lower (<span class="dt">Pure</span> x) f <span class="ot">=</span> f x <span class="dt">Nil</span></span>
<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a>lower (<span class="dt">Ap</span> fs<span class="ot"> x ::</span> <span class="dt">Free</span> f a) f <span class="ot">=</span></span>
<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a>    lower fs (\ft av <span class="ot">-&gt;</span> f ft (av <span class="op">:&gt;</span> x))</span>
<span id="cb33-12"><a href="#cb33-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-13"><a href="#cb33-13" aria-hidden="true" tabindex="-1"></a>lowerConstrained</span>
<span id="cb33-14"><a href="#cb33-14" aria-hidden="true" tabindex="-1"></a><span class="ot">    ::</span> (<span class="dt">Constrained.Applicative</span> f, <span class="dt">Suitable</span> f a)</span>
<span id="cb33-15"><a href="#cb33-15" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> <span class="dt">Free</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb33-16"><a href="#cb33-16" aria-hidden="true" tabindex="-1"></a>lowerConstrained x <span class="ot">=</span> lower x liftA</span></code></pre></div>
<p>There’s probably a more efficient way to encode it, though.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-sculthorpe_constrained-monad_2013" class="csl-entry"
role="listitem">
Sculthorpe, Neil, Jan Bracker, George Giorgidze, and Andy Gill. 2013.
<span>“The <span>Constrained</span>-monad <span>Problem</span>.”</span>
In <em>Proceedings of the 18th <span>ACM</span> <span>SIGPLAN</span>
<span>International</span> <span>Conference</span> on
<span>Functional</span> <span>Programming</span></em>, 287–298.
<span>ICFP</span> ’13. New York, NY, USA: ACM. doi:<a
href="https://doi.org/10.1145/2500365.2500602">10.1145/2500365.2500602</a>.
<a
href="http://ku-fpg.github.io/files/Sculthorpe-13-ConstrainedMonad.pdf">http://ku-fpg.github.io/files/Sculthorpe-13-ConstrainedMonad.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Wed, 08 Mar 2017 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2017-03-08-constrained-applicatives.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Semirings</title>
    <link>https://doisinkidney.com/posts/2016-11-17-semirings-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on November 17, 2016
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Semirings&#39;." href="/tags/Semirings.html" rel="tag">Semirings</a>
    
</div>

<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE PatternSynonyms, ViewPatterns, LambdaCase #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE RankNTypes, FlexibleInstances, FlexibleContexts #-}</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# LANGUAGE OverloadedStrings, OverloadedLists, MonadComprehensions #-}</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Semirings</span> <span class="kw">where</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map.Strict</span> <span class="kw">as</span> <span class="dt">Map</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Map.Strict</span>      (<span class="dt">Map</span>)</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Monoid</span>  <span class="kw">hiding</span>  (<span class="dt">Endo</span>(..))</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Foldable</span> <span class="kw">hiding</span> (toList)</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Applicative</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Arrow</span>        (first)</span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Control.Monad.Cont</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Functor.Identity</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">GHC.Exts</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.List</span> <span class="kw">hiding</span>     (insert)</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span>           <span class="dt">Data.Maybe</span>           (mapMaybe)</span></code></pre></div>
<p>I’ve been playing around a lot with semirings recently. A semiring is
anything with addition, multiplication, zero and one. You can represent
that in Haskell as:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Semiring</span> a <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  zero ::</span> a</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  one  ::</span> a</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">infixl</span> <span class="dv">7</span> <span class="op">&lt;.&gt;</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;.&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">infixl</span> <span class="dv">6</span> <span class="op">&lt;+&gt;</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="ot">  (&lt;+&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>It’s kind of like a combination of two <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Monoid.html">monoids</a>.
It has the normal monoid laws:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;+&gt;</span> (y <span class="op">&lt;+&gt;</span> z) <span class="ot">=</span> (x <span class="op">&lt;+&gt;</span> y) <span class="op">&lt;+&gt;</span> z</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;.&gt;</span> (y <span class="op">&lt;.&gt;</span> z) <span class="ot">=</span> (x <span class="op">&lt;.&gt;</span> y) <span class="op">&lt;.&gt;</span> z</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;+&gt;</span> zero <span class="ot">=</span> zero <span class="op">&lt;+&gt;</span> x <span class="ot">=</span> x</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;.&gt;</span> one  <span class="ot">=</span> one  <span class="op">&lt;.&gt;</span> x <span class="ot">=</span> x</span></code></pre></div>
<p>And a few extra:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;+&gt;</span> y <span class="ot">=</span> y <span class="op">&lt;+&gt;</span> x</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;.&gt;</span> (y <span class="op">&lt;+&gt;</span> z) <span class="ot">=</span> (x <span class="op">&lt;.&gt;</span> y) <span class="op">&lt;+&gt;</span> (x <span class="op">&lt;.&gt;</span> z)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>(x <span class="op">&lt;+&gt;</span> y) <span class="op">&lt;.&gt;</span> z <span class="ot">=</span> (x <span class="op">&lt;.&gt;</span> z) <span class="op">&lt;+&gt;</span> (y <span class="op">&lt;.&gt;</span> z)</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>zero <span class="op">&lt;.&gt;</span> a <span class="ot">=</span> a <span class="op">&lt;.&gt;</span> zero <span class="ot">=</span> zero</span></code></pre></div>
<p>I should note that what I’m calling a semiring here is often called a
<a href="https://ncatlab.org/nlab/show/rig">rig</a>. I actually prefer
the name “rig”: a rig is a ring without <strong>n</strong>egatives
(cute!); whereas a <em>semi</em>ring is a rig without neutral elements,
which mirrors the definition of a semigroup. The nomenclature in this
area is a bit of a mess, though, so I went with the more commonly-used
name for the sake of googleability.</p>
<p>At first glance, it looks quite numeric. Indeed, <a
href="https://pursuit.purescript.org/packages/purescript-prelude/1.1.0/docs/Data.Semiring">PureScript</a>
uses it as the basis for its numeric hierarchy. (In my experience so
far, it’s nicer to use than Haskell’s <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Prelude.html#t:Num"><code
class="sourceCode haskell"><span class="dt">Num</span></code></a>)</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">Integer</span> <span class="kw">where</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  one  <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> (<span class="op">+</span>)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> (<span class="op">*</span>)</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">Double</span> <span class="kw">where</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dv">0</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>  one  <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> (<span class="op">+</span>)</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> (<span class="op">*</span>)</span></code></pre></div>
<p>However, there are far more types which can form a valid <code
class="sourceCode haskell"><span class="dt">Semiring</span></code>
instance than can form a valid <code
class="sourceCode haskell"><span class="dt">Num</span></code> instance:
the <code
class="sourceCode haskell"><span class="fu">negate</span></code> method,
for example, excludes types representing the natural numbers:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ChurchNat</span> <span class="ot">=</span> <span class="dt">ChurchNat</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> runNat ::</span> <span class="kw">forall</span> a<span class="op">.</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a}</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Nat</span> <span class="ot">=</span> <span class="dt">Zero</span> <span class="op">|</span> <span class="dt">Succ</span> <span class="dt">Nat</span></span></code></pre></div>
<p>These form perfectly sensible semirings, though:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">ChurchNat</span> <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">ChurchNat</span> (<span class="fu">const</span> <span class="fu">id</span>)</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">ChurchNat</span> (<span class="op">$</span>)</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">ChurchNat</span> n <span class="op">&lt;+&gt;</span> <span class="dt">ChurchNat</span> m <span class="ot">=</span> <span class="dt">ChurchNat</span> (\f <span class="ot">-&gt;</span> n f <span class="op">.</span> m f)</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">ChurchNat</span> n <span class="op">&lt;.&gt;</span> <span class="dt">ChurchNat</span> m <span class="ot">=</span> <span class="dt">ChurchNat</span> (n <span class="op">.</span> m)</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">Nat</span> <span class="kw">where</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">Zero</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">Succ</span> <span class="dt">Zero</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Zero</span> <span class="op">&lt;+&gt;</span> x <span class="ot">=</span> x</span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Succ</span> x <span class="op">&lt;+&gt;</span> y <span class="ot">=</span> <span class="dt">Succ</span> (x <span class="op">&lt;+&gt;</span> y)</span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Zero</span> <span class="op">&lt;.&gt;</span> _ <span class="ot">=</span> <span class="dt">Zero</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Succ</span> <span class="dt">Zero</span> <span class="op">&lt;.&gt;</span> x <span class="ot">=</span>x</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Succ</span> x <span class="op">&lt;.&gt;</span> y <span class="ot">=</span> y <span class="op">&lt;+&gt;</span> (x <span class="op">&lt;.&gt;</span> y)</span></code></pre></div>
<p>The other missing method is <code
class="sourceCode haskell"><span class="fu">fromInteger</span></code>,
which means decidedly non-numeric types are allowed:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">Bool</span> <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">False</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  one  <span class="ot">=</span> <span class="dt">True</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> (<span class="op">||</span>)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> (<span class="op">&amp;&amp;</span>)</span></code></pre></div>
<p>We can provide a more general definition of the <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Monoid.html#t:Sum"><code
class="sourceCode haskell"><span class="dt">Sum</span></code></a> and <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Monoid.html#t:Product"><code
class="sourceCode haskell"><span class="dt">Product</span></code></a>
newtypes from <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Monoid.html#g:3">Data.Monoid</a>:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Add</span> a <span class="ot">=</span> <span class="dt">Add</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> getAdd ::</span> a</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  } <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>, <span class="dt">Read</span>, <span class="dt">Show</span>, <span class="dt">Semiring</span>)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Mul</span> a <span class="ot">=</span> <span class="dt">Mul</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> getMul ::</span> a</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  } <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>, <span class="dt">Read</span>, <span class="dt">Show</span>, <span class="dt">Semiring</span>)</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Add</span> <span class="kw">where</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Add</span> x) <span class="ot">=</span> <span class="dt">Add</span> (f x)</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Add</span> <span class="kw">where</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Add</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Add</span> f <span class="op">&lt;*&gt;</span> <span class="dt">Add</span> x <span class="ot">=</span> <span class="dt">Add</span> (f x)</span></code></pre></div>
<p>I’m using <code
class="sourceCode haskell"><span class="dt">Add</span></code> and <code
class="sourceCode haskell"><span class="dt">Mul</span></code> here to
avoid name clashing.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Add</span> a) <span class="kw">where</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Add</span> zero</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Add</span> x <span class="ot">`mappend`</span> <span class="dt">Add</span> y <span class="ot">=</span> <span class="dt">Add</span> (x <span class="op">&lt;+&gt;</span> y)</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Mul</span> a) <span class="kw">where</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Mul</span> one</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Mul</span> x <span class="ot">`mappend`</span> <span class="dt">Mul</span> y <span class="ot">=</span> <span class="dt">Mul</span> (x <span class="op">&lt;.&gt;</span> y)</span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> (<span class="dt">Semiring</span> a, <span class="dt">Foldable</span> f) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> a</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>add <span class="ot">=</span> getAdd <span class="op">.</span> <span class="fu">foldMap</span> <span class="dt">Add</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="ot">mul ::</span> (<span class="dt">Semiring</span> a, <span class="dt">Foldable</span> f) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> a</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>mul <span class="ot">=</span> getMul <span class="op">.</span> <span class="fu">foldMap</span> <span class="dt">Mul</span></span></code></pre></div>
<p><code class="sourceCode haskell">add</code> and <code
class="sourceCode haskell">mul</code> are equivalent to <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Foldable.html#v:sum"><code
class="sourceCode haskell"><span class="fu">sum</span></code></a> and <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Foldable.html#v:product"><code
class="sourceCode haskell"><span class="fu">product</span></code></a>:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell literate prop"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>add xs <span class="op">==</span> <span class="fu">sum</span> (<span class="ot">xs ::</span> [<span class="dt">Integer</span>])</span></code></pre></div>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell literate prop"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>mul xs <span class="op">==</span> <span class="fu">product</span> (<span class="ot">xs ::</span> [<span class="dt">Integer</span>])</span></code></pre></div>
<p>But they now work with a wider array of types: non-negative numbers,
as we’ve seen, but specialised to <code
class="sourceCode haskell"><span class="dt">Bool</span></code> we get
the familiar <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Monoid.html#t:Any"><code
class="sourceCode haskell"><span class="dt">Any</span></code></a> and <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Monoid.html#t:All"><code
class="sourceCode haskell"><span class="dt">All</span></code></a>
newtypes (and their corresponding folds).</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell literate prop"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>add xs <span class="op">==</span> <span class="fu">or</span> (<span class="ot">xs ::</span> [<span class="dt">Bool</span>])</span></code></pre></div>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell literate prop"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>mul xs <span class="op">==</span> <span class="fu">and</span> (<span class="ot">xs ::</span> [<span class="dt">Bool</span>])</span></code></pre></div>
<p>So far, nothing amazing. We avoid a little bit of code duplication,
that’s all.</p>
<h2 id="a-semiring-map">A Semiring Map</h2>
<p>In older versions of Python, <a
href="https://www.python.org/dev/peps/pep-0218/">there was no native set
type</a>. In its place, dictionaries were used, where the values would
be booleans. In a similar fashion, before the <a
href="https://docs.python.org/2/library/collections.html#collections.Counter">Counter</a>
type was added in 2.7, the traditional way of representing a multiset
was using a dictionary where the values were integers.</p>
<p>Using semirings, both of these data structures can have the same
type:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">GeneralMap</span> a b <span class="ot">=</span> <span class="dt">GeneralMap</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> getMap ::</span> <span class="dt">Map</span> a b</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  } <span class="kw">deriving</span> (<span class="dt">Functor</span>, <span class="dt">Foldable</span>, <span class="dt">Show</span>, <span class="dt">Eq</span>, <span class="dt">Ord</span>)</span></code></pre></div>
<p>If operations are defined in terms of the <code
class="sourceCode haskell"><span class="dt">Semiring</span></code>
class, the same code will work on a set <em>and</em> a multiset:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Ord</span> a, <span class="dt">Semiring</span> b) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>insert x <span class="ot">=</span> <span class="dt">GeneralMap</span> <span class="op">.</span> Map.insertWith (<span class="op">&lt;+&gt;</span>) x one <span class="op">.</span> getMap</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="ot">delete ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>delete x <span class="ot">=</span> <span class="dt">GeneralMap</span> <span class="op">.</span> Map.delete x <span class="op">.</span> getMap</span></code></pre></div>
<p>How to get back the dictionary-like behaviour, then? Well, operations
like <code
class="sourceCode haskell"><span class="fu">lookup</span></code> and
<code class="sourceCode haskell">assoc</code> are better suited to a
<code class="sourceCode haskell"><span class="dt">Monoid</span></code>
constraint, rather than <code
class="sourceCode haskell"><span class="dt">Semiring</span></code>:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> (<span class="dt">Ord</span> a, <span class="dt">Monoid</span> b) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b <span class="ot">-&gt;</span> b</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span> x <span class="ot">=</span> fold <span class="op">.</span> Map.lookup x <span class="op">.</span> getMap</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a><span class="ot">assoc ::</span> (<span class="dt">Ord</span> a, <span class="dt">Applicative</span> f, <span class="dt">Monoid</span> (f b))</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>      <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a (f b) <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a (f b)</span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>assoc k v <span class="ot">=</span> <span class="dt">GeneralMap</span> <span class="op">.</span> Map.insertWith <span class="fu">mappend</span> k (<span class="fu">pure</span> v) <span class="op">.</span> getMap</span></code></pre></div>
<p><code
class="sourceCode haskell"><span class="fu">lookup</span></code> is a
function which should work on sets and multisets: however <code
class="sourceCode haskell"><span class="dt">Bool</span></code> and <code
class="sourceCode haskell"><span class="dt">Integer</span></code> don’t
have <code
class="sourceCode haskell"><span class="dt">Monoid</span></code>
instances. To fix this, we can use the <code
class="sourceCode haskell"><span class="dt">Add</span></code> newtype
from earlier. The interface for each of these data structures can now be
expressed like this:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Set</span>      a   <span class="ot">=</span> <span class="dt">GeneralMap</span> a (<span class="dt">Add</span> <span class="dt">Bool</span>)</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">MultiSet</span> a   <span class="ot">=</span> <span class="dt">GeneralMap</span> a (<span class="dt">Add</span> <span class="dt">Integer</span>)</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Map</span>      a b <span class="ot">=</span> <span class="dt">GeneralMap</span> a (<span class="dt">First</span> b)</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">MultiMap</span> a b <span class="ot">=</span> <span class="dt">GeneralMap</span> a [b]</span></code></pre></div>
<p>And each of the functions on the <code
class="sourceCode haskell"><span class="dt">GeneralMap</span></code>
specialises like this:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Set</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> a</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> a <span class="ot">-&gt;</span> <span class="dt">Add</span> <span class="dt">Bool</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="ot">delete ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> a <span class="ot">-&gt;</span> <span class="dt">Set</span> a</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- MultiSet</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">MultiSet</span> a <span class="ot">-&gt;</span> <span class="dt">MultiSet</span> a</span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">MultiSet</span> a <span class="ot">-&gt;</span> <span class="dt">Add</span> <span class="dt">Integer</span></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a><span class="ot">delete ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">MultiSet</span> a <span class="ot">-&gt;</span> <span class="dt">MultiSet</span> a</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a><span class="co">-- Map</span></span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a><span class="ot">assoc  ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b</span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Map</span> a b <span class="ot">-&gt;</span> <span class="dt">First</span> b</span>
<span id="cb19-14"><a href="#cb19-14" aria-hidden="true" tabindex="-1"></a><span class="ot">delete ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Map</span> a b <span class="ot">-&gt;</span> <span class="dt">Map</span> a b</span>
<span id="cb19-15"><a href="#cb19-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-16"><a href="#cb19-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- MultiMap</span></span>
<span id="cb19-17"><a href="#cb19-17" aria-hidden="true" tabindex="-1"></a><span class="ot">assoc  ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">MultiMap</span> a b <span class="ot">-&gt;</span> <span class="dt">MultiMap</span> a b</span>
<span id="cb19-18"><a href="#cb19-18" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">MultiMap</span> a b <span class="ot">-&gt;</span> [b]</span>
<span id="cb19-19"><a href="#cb19-19" aria-hidden="true" tabindex="-1"></a><span class="ot">delete ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">MultiMap</span> a b <span class="ot">-&gt;</span> <span class="dt">MultiMap</span> a b</span></code></pre></div>
<p>This was actually where I first came across semirings: I was trying
to avoid code duplication for a trie implementation. I wanted to get the
Boom Hierarchy <span class="citation" data-cites="boom_further_1981">(<a
href="#ref-boom_further_1981" role="doc-biblioref">1981</a>)</span>
(plus maps) from the same underlying implementation.</p>
<p>It works <em>okay</em>. On the one hand, it’s nice that you don’t
have to wrap the map type itself to get the different behaviour. There’s
only one <code class="sourceCode haskell">delete</code> function, which
works on sets, maps, multisets, etc. I don’t need to import the <code
class="sourceCode haskell"><span class="dt">TrieSet</span></code> module
qualified, to differentiate between the <em>four</em> <code
class="sourceCode haskell">delete</code> functions I’ve written.</p>
<p>On the other hand, the <code
class="sourceCode haskell"><span class="dt">Add</span></code> wrapper is
a pain: having <code
class="sourceCode haskell"><span class="fu">lookup</span></code> return
the wrapped values is ugly, and the <code
class="sourceCode haskell"><span class="dt">Applicative</span></code>
constraint is unwieldy (we only use it for <code
class="sourceCode haskell"><span class="fu">pure</span></code>). Both of
those problems could be solved by using something like the <a
href="https://hackage.haskell.org/package/newtype-0.2/docs/Control-Newtype.html#t:Newtype"><code
class="sourceCode haskell"><span class="dt">Newtype</span></code></a> or
<a
href="https://hackage.haskell.org/package/lens-4.15.1/docs/Control-Lens-Wrapped.html#t:Wrapped"><code
class="sourceCode haskell"><span class="dt">Wrapped</span></code></a>
class, which provide facilities for wrapping and unwrapping, but that
might be overkill.</p>
<p>While <code
class="sourceCode haskell"><span class="dt">Monoid</span></code> and
<code class="sourceCode haskell"><span class="dt">Semiring</span></code>
can take you pretty far, even to a <code
class="sourceCode haskell"><span class="dt">Monoid</span></code>
instance:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fromList ::</span> (<span class="dt">Ord</span> a, <span class="dt">Semiring</span> b, <span class="dt">Foldable</span> f) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>fromList <span class="ot">=</span> <span class="fu">foldr</span> insert (<span class="dt">GeneralMap</span> Map.empty)</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a><span class="ot">fromAssocs ::</span> (<span class="dt">Ord</span> a, <span class="dt">Applicative</span> f, <span class="dt">Monoid</span> (f b), <span class="dt">Foldable</span> t)</span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>           <span class="ot">=&gt;</span> t (a, b) <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a (f b)</span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>fromAssocs <span class="ot">=</span> <span class="fu">foldr</span> (<span class="fu">uncurry</span> assoc) (<span class="dt">GeneralMap</span> Map.empty)</span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Ord</span> a, <span class="dt">Monoid</span> b) <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">GeneralMap</span> a b) <span class="kw">where</span></span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">GeneralMap</span> Map.empty</span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> (<span class="dt">GeneralMap</span> x) (<span class="dt">GeneralMap</span> y) <span class="ot">=</span></span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">GeneralMap</span> (Map.unionWith <span class="fu">mappend</span> x y)</span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a><span class="ot">singleton ::</span> <span class="dt">Semiring</span> b <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b</span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a>singleton x <span class="ot">=</span> <span class="dt">GeneralMap</span> (Map.singleton x one)</span></code></pre></div>
<p>They seem to fall down around functions like <code
class="sourceCode haskell">intersection</code>:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">intersection ::</span> (<span class="dt">Ord</span> a, <span class="dt">Semiring</span> b)</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>             <span class="ot">=&gt;</span> <span class="dt">GeneralMap</span> a b <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> a b</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>intersection (<span class="dt">GeneralMap</span> x) (<span class="dt">GeneralMap</span> y) <span class="ot">=</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">GeneralMap</span> (Map.intersectionWith (<span class="op">&lt;.&gt;</span>) x y)</span></code></pre></div>
<p>It works for sets, but it doesn’t make sense for multisets, and it
doesn’t work for maps.</p>
<p>I couldn’t find a semiring for the map-like types which would give me
a sensible intersection. I’m probably after a different algebraic
structure.</p>
<h2 id="a-probability-semiring">A Probability Semiring</h2>
<p>While looking for a semiring to represent a valid intersection, I
came across the probability semiring. It’s just the normal semiring over
the rationals, with a lower bound of 0, and an upper of 1.</p>
<p>It’s useful in some cool ways: you can combine it with a list to get
the probability monad <span class="citation"
data-cites="erwig_functional_2006">(<a href="#ref-erwig_functional_2006"
role="doc-biblioref">Erwig and Kollmansberger 2006</a>)</span>. There’s
an example in PureScript’s <a
href="https://pursuit.purescript.org/packages/purescript-distributions/">Distributions</a>
package.</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> s a <span class="ot">=</span> <span class="dt">Prob</span> {<span class="ot"> runProb ::</span> [(a,s)] }</span></code></pre></div>
<p>There are some drawbacks to this representation, performance-wise. In
particular, there’s a combinatorial explosion on every monadic bind. One
of the strategies to reduce this explosion is to use a map:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> s a <span class="ot">=</span> <span class="dt">Prob</span> {<span class="ot"> runProb ::</span> <span class="dt">Map</span> a s }</span></code></pre></div>
<p>Because this doesn’t allow duplicate keys, it will flatten the
association list on every bind. Unfortunately, the performance gain
doesn’t always materialize, and in some cases there’s a performance
<em>loss</em> <span class="citation" data-cites="larsen_memory_2011">(<a
href="#ref-larsen_memory_2011" role="doc-biblioref">Larsen
2011</a>)</span>. Also, the <code
class="sourceCode haskell"><span class="dt">Ord</span></code> constraint
on the keys prevents it from conforming to <code
class="sourceCode haskell"><span class="dt">Monad</span></code> (at
least not without <a
href="http://okmij.org/ftp/Haskell/set-monad.html">difficulty</a>).</p>
<p>Interestingly, this type is exactly the same as the <code
class="sourceCode haskell"><span class="dt">GeneralMap</span></code>
from before. This is a theme I kept running into, actually: the <code
class="sourceCode haskell"><span class="dt">GeneralMap</span></code>
type represents not just maps, multimaps, sets, multisets, but also a
whole host of other data structures.</p>
<h2 id="cont">Cont</h2>
<p>Edward Kmett had an interesting blog post about “Free Modules and
Functional Linear Functionals” <span class="citation"
data-cites="kmett_modules_2011">(<a href="#ref-kmett_modules_2011"
role="doc-biblioref">2011b</a>)</span>. In it, he talked about this
type:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">0</span> <span class="op">$*</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Linear</span> r a <span class="ot">=</span> <span class="dt">Linear</span> {<span class="ot"> ($*) ::</span> (a <span class="ot">-&gt;</span> r) <span class="ot">-&gt;</span> r }</span></code></pre></div>
<p>Also known as <a
href="https://hackage.haskell.org/package/mtl-2.2.1/docs/Control-Monad-Cont.html#t:Cont"><code
class="sourceCode haskell"><span class="dt">Cont</span></code></a>, the
continuation monad. It can encode the probability monad:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fromProbs ::</span> (<span class="dt">Semiring</span> s, <span class="dt">Applicative</span> m) <span class="ot">=&gt;</span> [(a,s)] <span class="ot">-&gt;</span> <span class="dt">ContT</span> s m a</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>fromProbs xs <span class="ot">=</span> <span class="dt">ContT</span> <span class="op">$</span> \k <span class="ot">-&gt;</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">foldr</span> (\(x,s) a <span class="ot">-&gt;</span> liftA2 (<span class="op">&lt;+&gt;</span>) (<span class="fu">fmap</span> (s<span class="op">&lt;.&gt;</span>) (k x)) a) (<span class="fu">pure</span> zero) xs</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a><span class="ot">probOfT ::</span> (<span class="dt">Semiring</span> r, <span class="dt">Applicative</span> m) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> <span class="dt">ContT</span> r m a <span class="ot">-&gt;</span> m r</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>probOfT e c <span class="ot">=</span> runContT c (\x <span class="ot">-&gt;</span> <span class="kw">if</span> e x <span class="kw">then</span> <span class="fu">pure</span> one <span class="kw">else</span> <span class="fu">pure</span> zero)</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a><span class="ot">probOf ::</span> <span class="dt">Semiring</span> r <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> <span class="dt">Cont</span> r a <span class="ot">-&gt;</span> r</span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>probOf e <span class="ot">=</span> runIdentity <span class="op">.</span> probOfT e</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a><span class="ot">uniform ::</span> <span class="dt">Applicative</span> m <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">ContT</span> <span class="dt">Double</span> m a</span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>uniform xs <span class="ot">=</span></span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a>  <span class="kw">let</span> s <span class="ot">=</span> <span class="fl">1.0</span> <span class="op">/</span> <span class="fu">fromIntegral</span> (<span class="fu">length</span> xs)</span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a>  <span class="kw">in</span> fromProbs (<span class="fu">map</span> (<span class="fu">flip</span> (,) s) xs)</span></code></pre></div>
<p>Multiplication isn’t paid for on every bind, making this
(potentially) a more efficient implementation than both the map and the
association list.</p>
<p>You can actually make the whole thing a semiring:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Semiring</span> r, <span class="dt">Applicative</span> m) <span class="ot">=&gt;</span> <span class="dt">Semiring</span> (<span class="dt">ContT</span> r m a) <span class="kw">where</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>  one  <span class="ot">=</span> <span class="dt">ContT</span> (<span class="fu">const</span> (<span class="fu">pure</span> one))</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">ContT</span> (<span class="fu">const</span> (<span class="fu">pure</span> zero))</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>  f <span class="op">&lt;+&gt;</span> g <span class="ot">=</span> <span class="dt">ContT</span> (\k <span class="ot">-&gt;</span> liftA2 (<span class="op">&lt;+&gt;</span>) (runContT f k) (runContT g k))</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>  f <span class="op">&lt;.&gt;</span> g <span class="ot">=</span> <span class="dt">ContT</span> (\k <span class="ot">-&gt;</span> liftA2 (<span class="op">&lt;.&gt;</span>) (runContT f k) (runContT g k))</span></code></pre></div>
<p>Which gives you a lovely <code
class="sourceCode haskell"><span class="dt">Alternative</span></code>
instance:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Semiring</span> r, <span class="dt">Applicative</span> m) <span class="ot">=&gt;</span> <span class="dt">Alternative</span> (<span class="dt">ContT</span> r m) <span class="kw">where</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;|&gt;</span>) <span class="ot">=</span> (<span class="op">&lt;+&gt;</span>)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>  empty <span class="ot">=</span> zero</span></code></pre></div>
<p>This sheds some light on what was going on with the unsatisfactory
<code class="sourceCode haskell">intersection</code> function on <code
class="sourceCode haskell"><span class="dt">GeneralMap</span></code>:
it’s actually <em>multiplication</em>. If you wanted to stretch the
analogy and make <code
class="sourceCode haskell"><span class="dt">GeneralMap</span></code>
conform to <code
class="sourceCode haskell"><span class="dt">Semiring</span></code>, you
could use the empty map for <code
class="sourceCode haskell">zero</code>, <code
class="sourceCode haskell"><span class="fu">mappend</span></code> for
<code
class="sourceCode haskell"><span class="op">&lt;+&gt;</span></code>, but
you’d run into trouble for <code class="sourceCode haskell">one</code>.
<code class="sourceCode haskell">one</code> is the map where every
possible key has a value of one. In other words, you’d have to enumerate
over every possible value for the keys. Interestingly, there’s kind of
the inverse problem for Cont: while it has an easy <code
class="sourceCode haskell"><span class="dt">Semiring</span></code>
instance, in order to <em>inspect</em> the values you have to enumerate
over all the possible keys.</p>
<p>I now have a name for the probability monad / general map / Cont
thing: a <em>covector</em>.</p>
<p>I think that the transformer version of Cont has a valid
interpretation, also. If I ever understand <span class="citation"
data-cites="hirschowitz_modules_2010">Hirschowitz and Maggesi (<a
href="#ref-hirschowitz_modules_2010"
role="doc-biblioref">2010</a>)</span> I’ll put it into a later follow-up
post.</p>
<h2 id="conditional-choice">Conditional choice</h2>
<p>As a short digression, you can beef up the <code
class="sourceCode haskell"><span class="op">&lt;|&gt;</span></code>
operator a little, with something like <a
href="http://zenzike.com/posts/2011-08-01-the-conditional-choice-operator">the
conditional choice operator</a>:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BiWeighted</span> s <span class="ot">=</span> s <span class="op">:|:</span> s</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="kw">infixl</span> <span class="dv">8</span> <span class="op">:|:</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a><span class="ot">(|&gt;) ::</span> (<span class="dt">Applicative</span> m, <span class="dt">Semiring</span> s)</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>     <span class="ot">=&gt;</span> <span class="dt">BiWeighted</span> s</span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">ContT</span> s m a</span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">ContT</span> s m a</span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">ContT</span> s m a</span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>((lp <span class="op">:|:</span> rp) <span class="op">|&gt;</span> r) l <span class="ot">=</span></span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a>  (mapContT<span class="op">.</span><span class="fu">fmap</span><span class="op">.</span>(<span class="op">&lt;.&gt;</span>)) lp l <span class="op">&lt;|&gt;</span> (mapContT<span class="op">.</span><span class="fu">fmap</span><span class="op">.</span>(<span class="op">&lt;.&gt;</span>)) rp r</span>
<span id="cb28-11"><a href="#cb28-11" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span>
<span id="cb28-12"><a href="#cb28-12" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;|) ::</span> <span class="dt">ContT</span> s m a</span>
<span id="cb28-13"><a href="#cb28-13" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> (<span class="dt">ContT</span> s m a <span class="ot">-&gt;</span> <span class="dt">ContT</span> s m a)</span>
<span id="cb28-14"><a href="#cb28-14" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> <span class="dt">ContT</span> s m a</span>
<span id="cb28-15"><a href="#cb28-15" aria-hidden="true" tabindex="-1"></a>l <span class="op">&lt;|</span> r <span class="ot">=</span> r l</span>
<span id="cb28-16"><a href="#cb28-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb28-17"><a href="#cb28-17" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">0</span> <span class="op">&lt;|</span></span>
<span id="cb28-18"><a href="#cb28-18" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">0</span> <span class="op">|&gt;</span></span></code></pre></div>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>probOf (<span class="ch">&#39;a&#39;</span><span class="op">==</span>) (uniform <span class="st">&quot;a&quot;</span> <span class="op">&lt;|</span> <span class="fl">0.4</span> <span class="op">:|:</span> <span class="fl">0.6</span> <span class="op">|&gt;</span> uniform <span class="st">&quot;b&quot;</span>)</span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="fl">0.4</span></span></code></pre></div>
<h2 id="unleak">UnLeak</h2>
<p>If you fiddle around with the probability monad, you can break it
apart in interesting ways. For instance, extracting the <code
class="sourceCode haskell"><span class="dt">WriterT</span></code> monad
transformer gives you:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="dt">WriterT</span> (<span class="dt">Product</span> <span class="dt">Double</span>) []</span></code></pre></div>
<p>Eric Kidd describes it as <code
class="sourceCode haskell"><span class="dt">PerhapsT</span></code>: a
<code class="sourceCode haskell"><span class="dt">Maybe</span></code>
with attached probability in his <a
href="http://www.randomhacks.net/2007/02/21/refactoring-probability-distributions/">excellent
blog post</a> <span class="citation" data-cites="kidd_build_2007">(and
his paper in <a href="#ref-kidd_build_2007"
role="doc-biblioref">2007</a>)</span>.</p>
<p>Straight away, we can optimise this representation by transforming
the <a
href="https://mail.haskell.org/pipermail/libraries/2013-March/019528.html">leaky</a>
<code class="sourceCode haskell"><span class="dt">WriterT</span></code>
into a state monad:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">WeightedT</span> s m a <span class="ot">=</span> <span class="dt">WeightedT</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> getWeightedT ::</span> s <span class="ot">-&gt;</span> m (a, s)</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>  } <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Applicative</span> (<span class="dt">WeightedT</span> s m) <span class="kw">where</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">WeightedT</span> <span class="op">$</span> \s <span class="ot">-&gt;</span> <span class="fu">pure</span> (x,s)</span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">WeightedT</span> fs <span class="op">&lt;*&gt;</span> <span class="dt">WeightedT</span> xs <span class="ot">=</span> <span class="dt">WeightedT</span> <span class="op">$</span> \s <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>    (f, p) <span class="ot">&lt;-</span> fs s</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>    (x, t) <span class="ot">&lt;-</span> xs p</span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> (f x, t)</span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Monad</span> (<span class="dt">WeightedT</span> s m) <span class="kw">where</span></span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a>  <span class="dt">WeightedT</span> x <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="dt">WeightedT</span> <span class="op">$</span> \s <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb31-14"><a href="#cb31-14" aria-hidden="true" tabindex="-1"></a>    (x, p) <span class="ot">&lt;-</span> x s</span>
<span id="cb31-15"><a href="#cb31-15" aria-hidden="true" tabindex="-1"></a>    getWeightedT (f x) p</span></code></pre></div>
<p>I’m not sure yet, but I think this might have something to do with
the isomorphism between <code
class="sourceCode haskell"><span class="dt">Cont</span> ((<span class="ot">-&gt;</span>) s)</code>
and <code>State s</code> <span class="citation"
data-cites="kmett_free_2011">(<a href="#ref-kmett_free_2011"
role="doc-biblioref">Kmett 2011a</a>)</span>.</p>
<p>You can even make it look like a normal (non-transformer) writer with
some pattern synonyms:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Weighted</span> s <span class="ot">=</span> <span class="dt">WeightedT</span> s <span class="dt">Identity</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> <span class="dt">Weighted</span> w <span class="ot">&lt;-</span> (runIdentity <span class="op">.</span> <span class="fu">flip</span> getWeightedT zero <span class="ot">-&gt;</span> w) <span class="kw">where</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Weighted</span> (x,w) <span class="ot">=</span> <span class="dt">WeightedT</span> (\s <span class="ot">-&gt;</span> <span class="dt">Identity</span> (x, s <span class="op">&lt;.&gt;</span> w) )</span></code></pre></div>
<p>And you can pretend that you’ve just got a normal tuple:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a><span class="ot">half ::</span> a <span class="ot">-&gt;</span> <span class="dt">Weighted</span> <span class="dt">Double</span> a</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>half x <span class="ot">=</span> <span class="dt">Weighted</span> (x, <span class="fl">0.5</span>)</span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a><span class="ot">runWeighted ::</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> <span class="dt">Weighted</span> s a <span class="ot">-&gt;</span> (a, s)</span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a>runWeighted (<span class="dt">Weighted</span> w) <span class="ot">=</span> w</span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a><span class="ot">evalWeighted ::</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> <span class="dt">Weighted</span> s a <span class="ot">-&gt;</span> a</span>
<span id="cb33-8"><a href="#cb33-8" aria-hidden="true" tabindex="-1"></a>evalWeighted (<span class="dt">Weighted</span> (x,_)) <span class="ot">=</span> x</span>
<span id="cb33-9"><a href="#cb33-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-10"><a href="#cb33-10" aria-hidden="true" tabindex="-1"></a><span class="ot">execWeighted ::</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> <span class="dt">Weighted</span> s a <span class="ot">-&gt;</span> s</span>
<span id="cb33-11"><a href="#cb33-11" aria-hidden="true" tabindex="-1"></a>execWeighted (<span class="dt">Weighted</span> (_,s)) <span class="ot">=</span> s</span></code></pre></div>
<h2 id="free">Free</h2>
<p>Looking back at Cont, it is reminiscent of a particular encoding of
the free monoid from <span class="citation"
data-cites="doel_free_2015">Doel (<a href="#ref-doel_free_2015"
role="doc-biblioref">2015</a>)</span>:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">FreeMonoid</span> a <span class="ot">=</span> <span class="dt">FreeMonoid</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>  { <span class="kw">forall</span> m<span class="op">.</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m) <span class="ot">-&gt;</span> m }</span></code></pre></div>
<p>So possibly covectors represent the free semiring, in some way.</p>
<p>Another encoding which looks free-ish is one of the efficient
implementations of the probability monad from <span class="citation"
data-cites="larsen_memory_2011">Larsen (<a
href="#ref-larsen_memory_2011"
role="doc-biblioref">2011</a>)</span>:</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Dist</span> a <span class="kw">where</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Certainly</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Dist</span> a <span class="co">-- only possible value</span></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Choice</span><span class="ot"> ::</span> <span class="dt">Probability</span> <span class="ot">-&gt;</span> <span class="dt">Dist</span> a <span class="ot">-&gt;</span> <span class="dt">Dist</span> a <span class="ot">-&gt;</span> <span class="dt">Dist</span> a</span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Fmap</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Dist</span> a <span class="ot">-&gt;</span> <span class="dt">Dist</span> b</span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Join</span><span class="ot"> ::</span> <span class="dt">Dist</span> (<span class="dt">Dist</span> a) <span class="ot">-&gt;</span> <span class="dt">Dist</span> a</span></code></pre></div>
<p>This looks an awful lot like a weighted <a
href="https://hackage.haskell.org/package/free-4.12.4/docs/Control-Alternative-Free.html">free
alternative</a>. Is it a free semiring, then?</p>
<p>Maybe. There’s a parallel between the relationship between monoids
and semirings and applicatives and <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Applicative.html#t:Alternative"><code
class="sourceCode haskell"><span class="dt">Alternative</span></code></a>s
<span class="citation" data-cites="rivas_monoids_2015">(<a
href="#ref-rivas_monoids_2015" role="doc-biblioref">Rivas, Jaskelioff,
and Schrijvers 2015</a>)</span>. In a way, where monads are monoids in
the category of endofunctors, alternatives are <em>semirings</em> in the
category of endofunctors.</p>
<p>This parallel probably isn’t what I first thought it was. First of
all, the above paper uses near-semirings, not semirings. A near-semiring
is a semiring where the requirements for left distribution of
multiplication over addition and commutative addition are dropped.
Secondly, the class which most mirrors near-semirings is <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad.html#t:MonadPlus"><code
class="sourceCode haskell"><span class="dt">MonadPlus</span></code></a>,
not alternative. (alternative doesn’t have annihilation) Thirdly, right
distribution of multiplication over addition <em>isn’t</em> required
<code
class="sourceCode haskell"><span class="dt">MonadPlus</span></code>:
it’s a further law required on top of the existing laws. Fourthly, most
types in the Haskell ecosystem today which conform to <code
class="sourceCode haskell"><span class="dt">MonadPlus</span></code>
<em>don’t</em> conform to this extra law: in fact, those that do seem to
be lists of some kind or another.</p>
<p>A further class is probably needed on top of the two already there,
with the extra laws <span class="citation"
data-cites="fischer_reinventing_2009">(called <code
class="sourceCode haskell"><span class="dt">Nondet</span></code> in <a
href="#ref-fischer_reinventing_2009" role="doc-biblioref">Fischer
2009</a>)</span>.</p>
<p>An actual free near-semiring looks like this:</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Free</span> f x <span class="ot">=</span> <span class="dt">Free</span> {<span class="ot"> unFree ::</span> [<span class="dt">FFree</span> f x] }</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">FFree</span> f x <span class="ot">=</span> <span class="dt">Pure</span> x <span class="op">|</span> <span class="dt">Con</span> (f (<span class="dt">Free</span> f x))</span></code></pre></div>
<p>Specialised to the <code
class="sourceCode haskell"><span class="dt">Identity</span></code>
monad, that becomes:</p>
<div class="sourceCode" id="cb37"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Forest</span> a <span class="ot">=</span> <span class="dt">Forest</span> {<span class="ot"> unForest ::</span> [<span class="dt">Tree</span> x] }</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Tree</span> x <span class="ot">=</span> <span class="dt">Leaf</span> x <span class="op">|</span> <span class="dt">Branch</span> (<span class="dt">Forest</span> x)</span></code></pre></div>
<p>De-specialised to the <a
href="https://hackage.haskell.org/package/free-4.12.4/docs/Control-Monad-Trans-Free.html">free
monad transformer</a>, it becomes:</p>
<div class="sourceCode" id="cb38"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">FreeT</span> f m a <span class="ot">=</span> <span class="dt">FreeT</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> runFreeT ::</span> m (<span class="dt">FreeF</span> f a (<span class="dt">FreeT</span> f m a)) }</span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">FreeF</span> f a b</span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Pure</span> a</span>
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Free</span> (f b)</span>
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-8"><a href="#cb38-8" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">FreeNearSemiring</span> f <span class="ot">=</span> <span class="dt">FreeT</span> f []</span></code></pre></div>
<p>These definitions all lend themselves to combinatorial search <span
class="citation"
data-cites="spivey_algebras_2009 fischer_reinventing_2009 piponi_monad_2009">(<a
href="#ref-spivey_algebras_2009" role="doc-biblioref">Spivey 2009</a>;
<a href="#ref-fischer_reinventing_2009" role="doc-biblioref">Fischer
2009</a>; <a href="#ref-piponi_monad_2009" role="doc-biblioref">Piponi
2009</a>)</span>, with one extra operation needed: <code
class="sourceCode haskell">wrap</code>.</p>
<h2 id="odds">Odds</h2>
<p>Does the <a href="/posts/2016-09-27-odds-lhs.html">odds monad</a> fit
in to any of this?</p>
<p>While <code
class="sourceCode haskell"><span class="dt">WriterT</span> (<span class="dt">Product</span> <span class="dt">Rational</span>) []</code>
is a valid definition of the traditional probability monad, it’s
<em>not</em> the same as the odds monad. If you take the odds monad, and
parameterize it over the weight of the tail, you get this:</p>
<div class="sourceCode" id="cb39"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Odds</span> m a <span class="ot">=</span> <span class="dt">Certain</span> a <span class="op">|</span> <span class="dt">Choice</span> (m (a, <span class="dt">Odds</span> a))</span></code></pre></div>
<p>Which looks remarkably like <a
href="http://www.haskellforall.com/2016/07/list-transformer-beginner-friendly-listt.html"><code
class="sourceCode haskell"><span class="dt">ListT</span></code> done
right</a>:</p>
<div class="sourceCode" id="cb40"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ListT</span> m a <span class="ot">=</span> <span class="dt">ListT</span> {<span class="ot"> next ::</span> m (<span class="dt">Step</span> m a) }</span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Step</span> m a <span class="ot">=</span> <span class="dt">Cons</span> a (<span class="dt">ListT</span> m a) <span class="op">|</span> <span class="dt">Nil</span></span></code></pre></div>
<p>That suggests a relationship between probability and odds:</p>
<div class="sourceCode" id="cb41"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a><span class="dt">WriterT</span> (<span class="dt">Product</span>  <span class="dt">Rational</span>) [] <span class="ot">=</span> <span class="dt">Probability</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a><span class="dt">ListT</span>   (<span class="dt">Weighted</span> <span class="dt">Rational</span>)    <span class="ot">=</span> <span class="dt">Odds</span></span></code></pre></div>
<p><code class="sourceCode haskell"><span class="dt">ListT</span></code>
isn’t a perfect match, though: it allows empty lists. To correct this,
you could use the <a
href="https://hackage.haskell.org/package/free-4.12.4/docs/Control-Comonad-Cofree.html">Cofree
Comonad</a>:</p>
<div class="sourceCode" id="cb42"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb42-1"><a href="#cb42-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Cofree</span> f a <span class="ot">=</span> a <span class="op">:&lt;</span> (f (<span class="dt">Cofree</span> f a))</span></code></pre></div>
<p>Subbing in <code
class="sourceCode haskell"><span class="dt">Maybe</span></code> for
<code class="sourceCode haskell">f</code>, you get a non-empty list. A
<em>weighted</em> <code
class="sourceCode haskell"><span class="dt">Maybe</span></code> is
basically <a
href="http://www.randomhacks.net/2007/02/21/refactoring-probability-distributions/"><code
class="sourceCode haskell"><span class="dt">PerhapsT</span></code></a>,
as was mentioned earlier.</p>
<h2 id="generalizing-semirings">Generalizing Semirings</h2>
<p>Types in Haskell also form a semiring.</p>
<div class="sourceCode" id="cb43"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb43-1"><a href="#cb43-1" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> (,)</span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>one <span class="ot">=</span> ()</span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> <span class="dt">Either</span></span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a>zero <span class="ot">=</span> <span class="dt">Void</span></span></code></pre></div>
<p>There’s a subset of semirings which are <a
href="https://en.wikipedia.org/wiki/Semiring#Star_semirings">star
semirings</a>. They have an operation
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>*</mi><annotation encoding="application/x-tex">*</annotation></semantics></math>
such that:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>*</mi><mo>=</mo><mn>1</mn><mo>+</mo><mi>a</mi><mi>a</mi><mi>*</mi><mo>=</mo><mn>1</mn><mo>+</mo><mi>a</mi><mo>*</mo><mi>a</mi></mrow><annotation encoding="application/x-tex">a* = 1 + aa* = 1 + a*a</annotation></semantics></math></p>
<p>Or, as a class:</p>
<div class="sourceCode" id="cb44"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb44-1"><a href="#cb44-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span> <span class="dt">StarSemiring</span> a <span class="kw">where</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  star ::</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a>  star x <span class="ot">=</span> one <span class="op">&lt;+&gt;</span> plus x</span>
<span id="cb44-4"><a href="#cb44-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  plus ::</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb44-5"><a href="#cb44-5" aria-hidden="true" tabindex="-1"></a>  plus x <span class="ot">=</span> x <span class="op">&lt;.&gt;</span> star x</span></code></pre></div>
<p>Using this on types, you get:</p>
<div class="sourceCode" id="cb45"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb45-1"><a href="#cb45-1" aria-hidden="true" tabindex="-1"></a>star a <span class="ot">=</span> <span class="dt">Either</span> () (a, star a)</span></code></pre></div>
<p>Which is just a standard list! Some pseudo-haskell on alternatives
will give you:</p>
<div class="sourceCode" id="cb46"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb46-1"><a href="#cb46-1" aria-hidden="true" tabindex="-1"></a><span class="ot">star ::</span> (<span class="dt">Alternative</span> f, <span class="dt">Monoid</span> a) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> f a</span>
<span id="cb46-2"><a href="#cb46-2" aria-hidden="true" tabindex="-1"></a>star x <span class="ot">=</span> (x <span class="op">&lt;.&gt;</span> star x) <span class="op">&lt;+&gt;</span> <span class="fu">pure</span> <span class="fu">mempty</span> <span class="kw">where</span></span>
<span id="cb46-3"><a href="#cb46-3" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> liftA2 <span class="fu">mappend</span></span>
<span id="cb46-4"><a href="#cb46-4" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> <span class="op">&lt;|&gt;</span></span></code></pre></div>
<p>Also known as <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Applicative.html#v:many"><code
class="sourceCode haskell">many</code></a>. (although note that this
breaks all the laws)</p>
<p>The
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>*</mi><annotation encoding="application/x-tex">*</annotation></semantics></math>
for rationals is defined as <span class="citation"
data-cites="droste_semirings_2009">(<a href="#ref-droste_semirings_2009"
role="doc-biblioref">Droste and Kuich 2009, p8</a>)</span>:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mi>*</mi><mo>=</mo><mrow><mo stretchy="true" form="prefix">{</mo><mtable><mtr><mtd columnalign="left" style="text-align: left"><mfrac><mn>1</mn><mrow><mn>1</mn><mo>−</mo><mi>a</mi></mrow></mfrac></mtd><mtd columnalign="left" style="text-align: left"><mspace width="1.0em"></mspace><mrow><mtext mathvariant="normal">if </mtext><mspace width="0.333em"></mspace></mrow></mtd><mtd columnalign="left" style="text-align: left"><mn>0</mn><mo>≤</mo><mi>a</mi><mo>&lt;</mo><mn>1</mn><mo>,</mo></mtd></mtr><mtr><mtd columnalign="left" style="text-align: left"><mi>∞</mi></mtd><mtd columnalign="left" style="text-align: left"><mspace width="1.0em"></mspace><mrow><mtext mathvariant="normal">if </mtext><mspace width="0.333em"></mspace></mrow></mtd><mtd columnalign="left" style="text-align: left"><mi>a</mi><mo>≥</mo><mn>1</mn><mi>.</mi></mtd></mtr></mtable></mrow></mrow><annotation encoding="application/x-tex">a* = \begin{cases}
  \frac{1}{1 - a} &amp; \quad \text{if  } &amp; 0 \leq a \lt 1, \\
  \infty          &amp; \quad \text{if  } &amp; a \geq 1.
\end{cases}</annotation></semantics></math></p>
<p>So, combining the probability with the type-level business, the star
of <code>Writer s a</code> is:</p>
<div class="sourceCode" id="cb47"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb47-1"><a href="#cb47-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Either</span> (<span class="dv">1</span>, a) (a, s <span class="op">/</span> (<span class="dv">1</span> <span class="op">-</span> s), star (<span class="dt">Writer</span> s a))</span></code></pre></div>
<p>Or, to put it another way: the odds monad!</p>
<h2 id="endo">Endo</h2>
<p>An <a
href="https://ncatlab.org/nlab/show/endomorphism">endomorphism</a> is a
morphism from an object to itself. A less general definition (and the
one <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Monoid.html#t:Endo">most
often used</a> in Haskell) is a function of the type <code
class="sourceCode haskell">a <span class="ot">-&gt;</span> a</code>:</p>
<div class="sourceCode" id="cb48"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb48-1"><a href="#cb48-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Endo</span> a <span class="ot">=</span> <span class="dt">Endo</span> {<span class="ot"> appEndo ::</span> a <span class="ot">-&gt;</span> a }</span></code></pre></div>
<p>It forms a monoid under composition:</p>
<div class="sourceCode" id="cb49"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">Endo</span> a) <span class="kw">where</span></span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Endo</span> <span class="fu">id</span></span>
<span id="cb49-3"><a href="#cb49-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> (<span class="dt">Endo</span> f) (<span class="dt">Endo</span> g) <span class="ot">=</span> <span class="dt">Endo</span> (f <span class="op">.</span> g)</span></code></pre></div>
<p>If the underlying type is itself a commutative monoid, it also forms
a near-semiring:</p>
<div class="sourceCode" id="cb50"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span> <span class="dt">Semiring</span> (<span class="dt">Endo</span> a) <span class="kw">where</span></span>
<span id="cb50-2"><a href="#cb50-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Endo</span> f <span class="op">&lt;+&gt;</span> <span class="dt">Endo</span> g <span class="ot">=</span> <span class="dt">Endo</span> (\x <span class="ot">-&gt;</span> f x <span class="op">&lt;&gt;</span> g x)</span>
<span id="cb50-3"><a href="#cb50-3" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">Endo</span> (<span class="fu">const</span> <span class="fu">mempty</span>)</span>
<span id="cb50-4"><a href="#cb50-4" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">Endo</span> <span class="fu">id</span></span>
<span id="cb50-5"><a href="#cb50-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Endo</span> f <span class="op">&lt;.&gt;</span> <span class="dt">Endo</span> g <span class="ot">=</span> <span class="dt">Endo</span> (f <span class="op">.</span> g)</span>
<span id="cb50-6"><a href="#cb50-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb50-7"><a href="#cb50-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Monoid</span> a, <span class="dt">Eq</span> a) <span class="ot">=&gt;</span> <span class="dt">StarSemiring</span> (<span class="dt">Endo</span> a) <span class="kw">where</span></span>
<span id="cb50-8"><a href="#cb50-8" aria-hidden="true" tabindex="-1"></a>  star (<span class="dt">Endo</span> f) <span class="ot">=</span> <span class="dt">Endo</span> converge <span class="kw">where</span></span>
<span id="cb50-9"><a href="#cb50-9" aria-hidden="true" tabindex="-1"></a>    converge x <span class="ot">=</span> x <span class="op">&lt;&gt;</span> (<span class="kw">if</span> y <span class="op">==</span> <span class="fu">mempty</span> <span class="kw">then</span> y <span class="kw">else</span> converge y) <span class="kw">where</span></span>
<span id="cb50-10"><a href="#cb50-10" aria-hidden="true" tabindex="-1"></a>      y <span class="ot">=</span> f x</span></code></pre></div>
<p>Here’s something interesting: there’s a similarity here to the
semiring for church numerals. In fact, as far as I can tell, the
functions are <em>exactly</em> the same when applied to endomorphisms of
endomorphisms. To the extent that you could define church numerals with
something as simple as this:</p>
<div class="sourceCode" id="cb51"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb51-1"><a href="#cb51-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">ChurchEndoNat</span> <span class="ot">=</span> <span class="kw">forall</span> a<span class="op">.</span> <span class="dt">Endo</span> (<span class="dt">Endo</span> a)</span></code></pre></div>
<p>And it works!</p>
<div class="sourceCode" id="cb52"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a>two,<span class="ot"> three ::</span> <span class="dt">ChurchEndoNat</span></span>
<span id="cb52-2"><a href="#cb52-2" aria-hidden="true" tabindex="-1"></a>two <span class="ot">=</span> one <span class="op">&lt;+&gt;</span> one</span>
<span id="cb52-3"><a href="#cb52-3" aria-hidden="true" tabindex="-1"></a>three <span class="ot">=</span> one <span class="op">&lt;+&gt;</span> two</span>
<span id="cb52-4"><a href="#cb52-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb52-5"><a href="#cb52-5" aria-hidden="true" tabindex="-1"></a><span class="ot">unChurch ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">ChurchEndoNat</span> <span class="ot">-&gt;</span> a</span>
<span id="cb52-6"><a href="#cb52-6" aria-hidden="true" tabindex="-1"></a>unChurch f <span class="ot">=</span> appEndo (appEndo f (<span class="dt">Endo</span> (<span class="dv">1</span><span class="op">+</span>))) <span class="dv">0</span></span></code></pre></div>
<div class="sourceCode" id="cb53"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb53-1"><a href="#cb53-1" aria-hidden="true" tabindex="-1"></a>unChurch (two <span class="op">&lt;.&gt;</span> three)</span>
<span id="cb53-2"><a href="#cb53-2" aria-hidden="true" tabindex="-1"></a><span class="dv">6</span></span></code></pre></div>
<h2 id="regex">Regex</h2>
<p>One of the most important applications (and a source of much of the
notation) is regular expressions. In fact, the free semiring looks like
a haskell datatype for regular expressions:</p>
<div class="sourceCode" id="cb54"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">FreeStar</span> a</span>
<span id="cb54-2"><a href="#cb54-2" aria-hidden="true" tabindex="-1"></a> <span class="ot">=</span> <span class="dt">Gen</span> a</span>
<span id="cb54-3"><a href="#cb54-3" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="dt">Zer</span></span>
<span id="cb54-4"><a href="#cb54-4" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="dt">One</span></span>
<span id="cb54-5"><a href="#cb54-5" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="dt">FreeStar</span> a <span class="op">:&lt;+&gt;</span> <span class="dt">FreeStar</span> a</span>
<span id="cb54-6"><a href="#cb54-6" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="dt">FreeStar</span> a <span class="op">:&lt;.&gt;</span> <span class="dt">FreeStar</span> a</span>
<span id="cb54-7"><a href="#cb54-7" aria-hidden="true" tabindex="-1"></a> <span class="op">|</span> <span class="dt">Star</span> (<span class="dt">FreeStar</span> a)</span>
<span id="cb54-8"><a href="#cb54-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-9"><a href="#cb54-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> (<span class="dt">FreeStar</span> a) <span class="kw">where</span></span>
<span id="cb54-10"><a href="#cb54-10" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> (<span class="op">:&lt;+&gt;</span>)</span>
<span id="cb54-11"><a href="#cb54-11" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> (<span class="op">:&lt;.&gt;</span>)</span>
<span id="cb54-12"><a href="#cb54-12" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">Zer</span></span>
<span id="cb54-13"><a href="#cb54-13" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">One</span></span>
<span id="cb54-14"><a href="#cb54-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-15"><a href="#cb54-15" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">StarSemiring</span> (<span class="dt">FreeStar</span> a) <span class="kw">where</span></span>
<span id="cb54-16"><a href="#cb54-16" aria-hidden="true" tabindex="-1"></a>  star <span class="ot">=</span> <span class="dt">Star</span></span>
<span id="cb54-17"><a href="#cb54-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb54-18"><a href="#cb54-18" aria-hidden="true" tabindex="-1"></a><span class="ot">interpret ::</span> <span class="dt">StarSemiring</span> s <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> <span class="dt">FreeStar</span> a <span class="ot">-&gt;</span> s</span>
<span id="cb54-19"><a href="#cb54-19" aria-hidden="true" tabindex="-1"></a>interpret f <span class="ot">=</span> \<span class="kw">case</span></span>
<span id="cb54-20"><a href="#cb54-20" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Gen</span> x <span class="ot">-&gt;</span> f x</span>
<span id="cb54-21"><a href="#cb54-21" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Zer</span> <span class="ot">-&gt;</span> zero</span>
<span id="cb54-22"><a href="#cb54-22" aria-hidden="true" tabindex="-1"></a>  <span class="dt">One</span> <span class="ot">-&gt;</span> one</span>
<span id="cb54-23"><a href="#cb54-23" aria-hidden="true" tabindex="-1"></a>  l <span class="op">:&lt;+&gt;</span> r <span class="ot">-&gt;</span> interpret f l <span class="op">&lt;+&gt;</span> interpret f r</span>
<span id="cb54-24"><a href="#cb54-24" aria-hidden="true" tabindex="-1"></a>  l <span class="op">:&lt;.&gt;</span> r <span class="ot">-&gt;</span> interpret f l <span class="op">&lt;.&gt;</span> interpret f r</span>
<span id="cb54-25"><a href="#cb54-25" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Star</span> x <span class="ot">-&gt;</span> star (interpret f x)</span></code></pre></div>
<p>Then, interpreting the regex is as simple as writing an interpreter
(with some help from <code
class="sourceCode haskell"><span class="dt">Endo</span></code>):</p>
<div class="sourceCode" id="cb55"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb55-1"><a href="#cb55-1" aria-hidden="true" tabindex="-1"></a><span class="ot">asRegex ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">FreeStar</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb55-2"><a href="#cb55-2" aria-hidden="true" tabindex="-1"></a>asRegex fs <span class="ot">=</span> <span class="fu">any</span> <span class="fu">null</span> <span class="op">.</span> appEndo (interpret f fs) <span class="op">.</span> <span class="fu">pure</span> <span class="kw">where</span></span>
<span id="cb55-3"><a href="#cb55-3" aria-hidden="true" tabindex="-1"></a>  f p <span class="ot">=</span> <span class="dt">Endo</span> <span class="op">.</span> mapMaybe <span class="op">$</span> \<span class="kw">case</span></span>
<span id="cb55-4"><a href="#cb55-4" aria-hidden="true" tabindex="-1"></a>    (x<span class="op">:</span>xs) <span class="op">|</span> p x <span class="ot">-&gt;</span> <span class="dt">Just</span> xs</span>
<span id="cb55-5"><a href="#cb55-5" aria-hidden="true" tabindex="-1"></a>    _ <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span>
<span id="cb55-6"><a href="#cb55-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb55-7"><a href="#cb55-7" aria-hidden="true" tabindex="-1"></a><span class="ot">char&#39; ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">FreeStar</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>)</span>
<span id="cb55-8"><a href="#cb55-8" aria-hidden="true" tabindex="-1"></a>char&#39; c <span class="ot">=</span> <span class="dt">Gen</span> (c<span class="op">==</span>)</span></code></pre></div>
<p>Actually, you don’t need the free version at all!</p>
<div class="sourceCode" id="cb56"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a><span class="ot">runRegex ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Endo</span> [[a]] <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb56-2"><a href="#cb56-2" aria-hidden="true" tabindex="-1"></a>runRegex fs <span class="ot">=</span> <span class="fu">any</span> <span class="fu">null</span> <span class="op">.</span> appEndo fs <span class="op">.</span> <span class="fu">pure</span></span>
<span id="cb56-3"><a href="#cb56-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb56-4"><a href="#cb56-4" aria-hidden="true" tabindex="-1"></a><span class="ot">char ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Endo</span> [[a]]</span>
<span id="cb56-5"><a href="#cb56-5" aria-hidden="true" tabindex="-1"></a>char c <span class="ot">=</span> <span class="dt">Endo</span> <span class="op">.</span> mapMaybe <span class="op">$</span> \<span class="kw">case</span></span>
<span id="cb56-6"><a href="#cb56-6" aria-hidden="true" tabindex="-1"></a>  (x<span class="op">:</span>xs) <span class="op">|</span> c <span class="op">==</span> x <span class="ot">-&gt;</span> <span class="dt">Just</span> xs</span>
<span id="cb56-7"><a href="#cb56-7" aria-hidden="true" tabindex="-1"></a>  _ <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span></code></pre></div>
<p>With some <code
class="sourceCode haskell"><span class="op">-</span><span class="dt">XOverloadedStrings</span></code>
magic, you get a pretty nice interface:</p>
<div class="sourceCode" id="cb57"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">IsString</span> (<span class="dt">Endo</span> [<span class="dt">String</span>]) <span class="kw">where</span></span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a>  fromString <span class="ot">=</span> mul <span class="op">.</span> <span class="fu">map</span> char <span class="op">.</span> <span class="fu">reverse</span></span>
<span id="cb57-3"><a href="#cb57-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-4"><a href="#cb57-4" aria-hidden="true" tabindex="-1"></a><span class="ot">(&lt;^&gt;) ::</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> s <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> s</span>
<span id="cb57-5"><a href="#cb57-5" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;^&gt;</span>) <span class="ot">=</span> <span class="fu">flip</span> (<span class="op">&lt;.&gt;</span>)</span>
<span id="cb57-6"><a href="#cb57-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb57-7"><a href="#cb57-7" aria-hidden="true" tabindex="-1"></a><span class="ot">greet ::</span> <span class="dt">Endo</span> [<span class="dt">String</span>]</span>
<span id="cb57-8"><a href="#cb57-8" aria-hidden="true" tabindex="-1"></a>greet <span class="ot">=</span> <span class="st">&quot;H&quot;</span> <span class="op">&lt;^&gt;</span> (<span class="st">&quot;a&quot;</span> <span class="op">&lt;+&gt;</span> <span class="st">&quot;e&quot;</span>) <span class="op">&lt;^&gt;</span> <span class="st">&quot;llo&quot;</span></span></code></pre></div>
<div class="sourceCode" id="cb58"><pre
class="sourceCode haskell literate example hidden_source"><code class="sourceCode haskell"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true" tabindex="-1"></a><span class="op">:</span>set <span class="op">-</span><span class="dt">XOverloadedStrings</span></span></code></pre></div>
<div class="sourceCode" id="cb59"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a>runRegex greet <span class="st">&quot;Hello&quot;</span></span>
<span id="cb59-2"><a href="#cb59-2" aria-hidden="true" tabindex="-1"></a><span class="dt">True</span></span></code></pre></div>
<div class="sourceCode" id="cb60"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb60-1"><a href="#cb60-1" aria-hidden="true" tabindex="-1"></a>runRegex greet <span class="st">&quot;Hallo&quot;</span></span>
<span id="cb60-2"><a href="#cb60-2" aria-hidden="true" tabindex="-1"></a><span class="dt">True</span></span></code></pre></div>
<div class="sourceCode" id="cb61"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a>runRegex greet <span class="st">&quot;Halo&quot;</span></span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true" tabindex="-1"></a><span class="dt">False</span></span></code></pre></div>
<h2 id="efficiency">Efficiency</h2>
<p>Of course, that’s about as slow as it gets when it comes to regexes.
A faster representation is a <a
href="https://swtch.com/~rsc/regexp/regexp1.html">nondeterministic
finite automaton</a>. One such implementation in haskell is <a
href="https://github.com/Gabriel439/slides/blob/master/regex/regex.md">Gabriel
Gonzalez’s</a>.</p>
<p>The regex type in that example can be immediately made to conform to
<code class="sourceCode haskell"><span class="dt">Semiring</span></code>
and <code
class="sourceCode haskell"><span class="dt">StarSemiring</span></code>.
However, it might be more interesting to translate the
<em>implementation</em> into using semirings. The type of a regex looks
like this:</p>
<div class="sourceCode" id="cb62"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb62-1"><a href="#cb62-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">State</span> <span class="ot">=</span> <span class="dt">Int</span></span>
<span id="cb62-2"><a href="#cb62-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb62-3"><a href="#cb62-3" aria-hidden="true" tabindex="-1"></a>{<span class="ot"> _startingStates         ::</span> <span class="dt">Set</span> <span class="dt">State</span></span>
<span id="cb62-4"><a href="#cb62-4" aria-hidden="true" tabindex="-1"></a>,<span class="ot"> _transitionFunction     ::</span> <span class="dt">Char</span> <span class="ot">-&gt;</span> <span class="dt">State</span> <span class="ot">-&gt;</span> <span class="dt">Set</span> <span class="dt">State</span></span>
<span id="cb62-5"><a href="#cb62-5" aria-hidden="true" tabindex="-1"></a>,<span class="ot"> _acceptingStates        ::</span> <span class="dt">Set</span> <span class="dt">State</span> }</span></code></pre></div>
<p>The set data structure jumps out as an opportunity to sub in
arbitrary semirings. Swapping in the <code
class="sourceCode haskell"><span class="dt">GeneralMap</span></code> is
reasonably easy:</p>
<div class="sourceCode" id="cb63"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">State</span> <span class="ot">=</span> <span class="dt">Int</span></span>
<span id="cb63-2"><a href="#cb63-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-3"><a href="#cb63-3" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Regex</span> i s <span class="ot">=</span> <span class="dt">Regex</span></span>
<span id="cb63-4"><a href="#cb63-4" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> _numberOfStates     ::</span> <span class="dt">Int</span></span>
<span id="cb63-5"><a href="#cb63-5" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> _startingStates     ::</span> <span class="dt">GeneralMap</span> <span class="dt">State</span> s</span>
<span id="cb63-6"><a href="#cb63-6" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> _transitionFunction ::</span> i <span class="ot">-&gt;</span> <span class="dt">State</span> <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> <span class="dt">State</span> s</span>
<span id="cb63-7"><a href="#cb63-7" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> _acceptingStates    ::</span> <span class="dt">GeneralMap</span> <span class="dt">State</span> s }</span>
<span id="cb63-8"><a href="#cb63-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-9"><a href="#cb63-9" aria-hidden="true" tabindex="-1"></a><span class="ot">isEnd ::</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> <span class="dt">Regex</span> i s <span class="ot">-&gt;</span> s</span>
<span id="cb63-10"><a href="#cb63-10" aria-hidden="true" tabindex="-1"></a>isEnd (<span class="dt">Regex</span> _ as _ bs) <span class="ot">=</span> add (intersection as bs)</span>
<span id="cb63-11"><a href="#cb63-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-12"><a href="#cb63-12" aria-hidden="true" tabindex="-1"></a><span class="ot">match ::</span> <span class="dt">Regex</span> <span class="dt">Char</span> (<span class="dt">Add</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb63-13"><a href="#cb63-13" aria-hidden="true" tabindex="-1"></a>match r <span class="ot">=</span> getAdd <span class="op">.</span> isEnd <span class="op">.</span> foldl&#39; run r <span class="kw">where</span></span>
<span id="cb63-14"><a href="#cb63-14" aria-hidden="true" tabindex="-1"></a>  run (<span class="dt">Regex</span> n (<span class="dt">GeneralMap</span> as) f bs) i <span class="ot">=</span> <span class="dt">Regex</span> n as&#39; f bs</span>
<span id="cb63-15"><a href="#cb63-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span> as&#39; <span class="ot">=</span> <span class="fu">mconcat</span> [ <span class="fu">fmap</span> (v<span class="op">&lt;.&gt;</span>) (f i k)  <span class="op">|</span> (k,v) <span class="ot">&lt;-</span> Map.assocs as ]</span>
<span id="cb63-16"><a href="#cb63-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-17"><a href="#cb63-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-18"><a href="#cb63-18" aria-hidden="true" tabindex="-1"></a><span class="ot">satisfy ::</span> <span class="dt">Semiring</span> s <span class="ot">=&gt;</span> (i <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> <span class="dt">Regex</span> i (<span class="dt">Add</span> s)</span>
<span id="cb63-19"><a href="#cb63-19" aria-hidden="true" tabindex="-1"></a>satisfy predicate <span class="ot">=</span> <span class="dt">Regex</span> <span class="dv">2</span> as f bs</span>
<span id="cb63-20"><a href="#cb63-20" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb63-21"><a href="#cb63-21" aria-hidden="true" tabindex="-1"></a>    as <span class="ot">=</span> singleton <span class="dv">0</span></span>
<span id="cb63-22"><a href="#cb63-22" aria-hidden="true" tabindex="-1"></a>    bs <span class="ot">=</span> singleton <span class="dv">1</span></span>
<span id="cb63-23"><a href="#cb63-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-24"><a href="#cb63-24" aria-hidden="true" tabindex="-1"></a>    f i <span class="dv">0</span> <span class="ot">=</span> assoc <span class="dv">1</span> (predicate i) <span class="fu">mempty</span></span>
<span id="cb63-25"><a href="#cb63-25" aria-hidden="true" tabindex="-1"></a>    f _ _ <span class="ot">=</span> <span class="fu">mempty</span></span>
<span id="cb63-26"><a href="#cb63-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-27"><a href="#cb63-27" aria-hidden="true" tabindex="-1"></a><span class="ot">once ::</span> <span class="dt">Eq</span> i <span class="ot">=&gt;</span> i <span class="ot">-&gt;</span> <span class="dt">Regex</span> i (<span class="dt">Add</span> <span class="dt">Bool</span>)</span>
<span id="cb63-28"><a href="#cb63-28" aria-hidden="true" tabindex="-1"></a>once x <span class="ot">=</span> satisfy (<span class="op">==</span> x)</span>
<span id="cb63-29"><a href="#cb63-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-30"><a href="#cb63-30" aria-hidden="true" tabindex="-1"></a><span class="ot">shift ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> <span class="dt">State</span> s <span class="ot">-&gt;</span> <span class="dt">GeneralMap</span> <span class="dt">State</span> s</span>
<span id="cb63-31"><a href="#cb63-31" aria-hidden="true" tabindex="-1"></a>shift n <span class="ot">=</span> <span class="dt">GeneralMap</span> <span class="op">.</span> Map.fromAscList <span class="op">.</span> (<span class="fu">map</span><span class="op">.</span>first) (<span class="op">+</span> n) <span class="op">.</span> Map.toAscList <span class="op">.</span> getMap</span>
<span id="cb63-32"><a href="#cb63-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-33"><a href="#cb63-33" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Semiring</span> s, <span class="dt">Monoid</span> s) <span class="ot">=&gt;</span> <span class="dt">Semiring</span> (<span class="dt">Regex</span> i s) <span class="kw">where</span></span>
<span id="cb63-34"><a href="#cb63-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-35"><a href="#cb63-35" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">Regex</span> <span class="dv">1</span> (singleton <span class="dv">0</span>) (\_ _ <span class="ot">-&gt;</span> <span class="fu">mempty</span>) (singleton <span class="dv">0</span>)</span>
<span id="cb63-36"><a href="#cb63-36" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">Regex</span> <span class="dv">0</span> <span class="fu">mempty</span> (\_ _ <span class="ot">-&gt;</span> <span class="fu">mempty</span>) <span class="fu">mempty</span></span>
<span id="cb63-37"><a href="#cb63-37" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-38"><a href="#cb63-38" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Regex</span> nL asL fL bsL <span class="op">&lt;+&gt;</span> <span class="dt">Regex</span> nR asR fR bsR <span class="ot">=</span> <span class="dt">Regex</span> n as f bs</span>
<span id="cb63-39"><a href="#cb63-39" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb63-40"><a href="#cb63-40" aria-hidden="true" tabindex="-1"></a>      n  <span class="ot">=</span> nL <span class="op">+</span> nR</span>
<span id="cb63-41"><a href="#cb63-41" aria-hidden="true" tabindex="-1"></a>      as <span class="ot">=</span> <span class="fu">mappend</span> asL (shift nL asR)</span>
<span id="cb63-42"><a href="#cb63-42" aria-hidden="true" tabindex="-1"></a>      bs <span class="ot">=</span> <span class="fu">mappend</span> bsL (shift nL bsR)</span>
<span id="cb63-43"><a href="#cb63-43" aria-hidden="true" tabindex="-1"></a>      f i s <span class="op">|</span> s <span class="op">&lt;</span> nL    <span class="ot">=</span> fL i s</span>
<span id="cb63-44"><a href="#cb63-44" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> shift nL (fR i (s <span class="op">-</span> nL))</span>
<span id="cb63-45"><a href="#cb63-45" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-46"><a href="#cb63-46" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Regex</span> nL asL fL bsL <span class="op">&lt;.&gt;</span> <span class="dt">Regex</span> nR asR fR bsR <span class="ot">=</span> <span class="dt">Regex</span> n as f bs <span class="kw">where</span></span>
<span id="cb63-47"><a href="#cb63-47" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-48"><a href="#cb63-48" aria-hidden="true" tabindex="-1"></a>    n <span class="ot">=</span> nL <span class="op">+</span> nR</span>
<span id="cb63-49"><a href="#cb63-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-50"><a href="#cb63-50" aria-hidden="true" tabindex="-1"></a>    as <span class="ot">=</span> <span class="kw">let</span> ss <span class="ot">=</span> add (intersection asL bsL)</span>
<span id="cb63-51"><a href="#cb63-51" aria-hidden="true" tabindex="-1"></a>         <span class="kw">in</span> <span class="fu">mappend</span> asL (<span class="fu">fmap</span> (ss<span class="op">&lt;.&gt;</span>) (shift nL asR))</span>
<span id="cb63-52"><a href="#cb63-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-53"><a href="#cb63-53" aria-hidden="true" tabindex="-1"></a>    f i s <span class="ot">=</span></span>
<span id="cb63-54"><a href="#cb63-54" aria-hidden="true" tabindex="-1"></a>        <span class="kw">if</span> s <span class="op">&lt;</span> nL</span>
<span id="cb63-55"><a href="#cb63-55" aria-hidden="true" tabindex="-1"></a>        <span class="kw">then</span> <span class="kw">let</span> ss <span class="ot">=</span> add (intersection r bsL)</span>
<span id="cb63-56"><a href="#cb63-56" aria-hidden="true" tabindex="-1"></a>             <span class="kw">in</span> <span class="fu">mappend</span> r (<span class="fu">fmap</span> (ss<span class="op">&lt;.&gt;</span>) (shift nL asR))</span>
<span id="cb63-57"><a href="#cb63-57" aria-hidden="true" tabindex="-1"></a>        <span class="kw">else</span> shift nL (fR i (s <span class="op">-</span> nL))</span>
<span id="cb63-58"><a href="#cb63-58" aria-hidden="true" tabindex="-1"></a>      <span class="kw">where</span></span>
<span id="cb63-59"><a href="#cb63-59" aria-hidden="true" tabindex="-1"></a>        r <span class="ot">=</span> fL i s</span>
<span id="cb63-60"><a href="#cb63-60" aria-hidden="true" tabindex="-1"></a>    bs <span class="ot">=</span> shift nL bsR</span>
<span id="cb63-61"><a href="#cb63-61" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-62"><a href="#cb63-62" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">StarSemiring</span> s, <span class="dt">Monoid</span> s) <span class="ot">=&gt;</span> <span class="dt">StarSemiring</span> (<span class="dt">Regex</span> i s) <span class="kw">where</span></span>
<span id="cb63-63"><a href="#cb63-63" aria-hidden="true" tabindex="-1"></a>  star (<span class="dt">Regex</span> n as f bs) <span class="ot">=</span> <span class="dt">Regex</span> n as f&#39; as</span>
<span id="cb63-64"><a href="#cb63-64" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb63-65"><a href="#cb63-65" aria-hidden="true" tabindex="-1"></a>      f&#39; i s <span class="ot">=</span></span>
<span id="cb63-66"><a href="#cb63-66" aria-hidden="true" tabindex="-1"></a>          <span class="kw">let</span> r <span class="ot">=</span> f i s</span>
<span id="cb63-67"><a href="#cb63-67" aria-hidden="true" tabindex="-1"></a>              ss <span class="ot">=</span> add (intersection r bs)</span>
<span id="cb63-68"><a href="#cb63-68" aria-hidden="true" tabindex="-1"></a>          <span class="kw">in</span> <span class="fu">mappend</span> r (<span class="fu">fmap</span> (ss<span class="op">&lt;.&gt;</span>) as)</span>
<span id="cb63-69"><a href="#cb63-69" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-70"><a href="#cb63-70" aria-hidden="true" tabindex="-1"></a>  plus (<span class="dt">Regex</span> n as f bs) <span class="ot">=</span> <span class="dt">Regex</span> n as f&#39; bs</span>
<span id="cb63-71"><a href="#cb63-71" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb63-72"><a href="#cb63-72" aria-hidden="true" tabindex="-1"></a>      f&#39; i s <span class="ot">=</span></span>
<span id="cb63-73"><a href="#cb63-73" aria-hidden="true" tabindex="-1"></a>          <span class="kw">let</span> r <span class="ot">=</span> f i s</span>
<span id="cb63-74"><a href="#cb63-74" aria-hidden="true" tabindex="-1"></a>              ss <span class="ot">=</span> add (intersection r bs)</span>
<span id="cb63-75"><a href="#cb63-75" aria-hidden="true" tabindex="-1"></a>          <span class="kw">in</span> <span class="fu">mappend</span> r (<span class="fu">fmap</span> (ss<span class="op">&lt;.&gt;</span>) as)</span>
<span id="cb63-76"><a href="#cb63-76" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-77"><a href="#cb63-77" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb63-78"><a href="#cb63-78" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">IsString</span> (<span class="dt">Regex</span> <span class="dt">Char</span> (<span class="dt">Add</span> <span class="dt">Bool</span>)) <span class="kw">where</span></span>
<span id="cb63-79"><a href="#cb63-79" aria-hidden="true" tabindex="-1"></a>  fromString <span class="ot">=</span> mul <span class="op">.</span> <span class="fu">map</span> once</span></code></pre></div>
<p>This begins to show some of the real power of using semirings and
covectors. We have a normal regular expression implementation when we
use the covector over bools. Use the probability semiring, and you’ve
got probabilistic parsing.</p>
<p>Swap in the <a
href="https://ncatlab.org/nlab/show/max-plus+algebra">tropical
semiring</a>: a semiring over the reals where addition is the max
function, and multiplication is addition of reals. Now you’ve got a
depth-first parser.</p>
<p>That’s how you might swap in different interpretations. How about
swapping in different <em>implementations</em>? Well, there might be
some use to swapping in the <a
href="https://en.wikipedia.org/wiki/CYK_algorithm">CYK algorithm</a>, or
the Gauss-Jordan-Floyd-Warshall-McNaughton-Yamada algorithm <span
class="citation" data-cites="oconnor_very_2011">(<a
href="#ref-oconnor_very_2011" role="doc-biblioref">O’Connor
2011</a>)</span>.</p>
<p>Alternatively, you can swap in the underlying data structure. Instead
of a map, if you use an integer (each bit being a value, the keys being
the bit position), you have a super-fast implementation (and the final
implementation used in the original example). Finally, you could use a
different representation of the state transfer function: a matrix.</p>
<h2 id="square-matrices">Square Matrices</h2>
<p>A square matrix can be understood as a map from pairs of indices to
values. This lets us use it to represent the state transfer function.
Take, for instance, a regular expression with three possible states. Its
state transfer function might look like this:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">transfer</mtext><mo>=</mo><mrow><mo stretchy="true" form="prefix">{</mo><mtable><mtr><mtd columnalign="left" style="text-align: left"><mn>1</mn><mspace width="1.0em"></mspace></mtd><mtd columnalign="left" style="text-align: left"><mo stretchy="false" form="prefix">{</mo><mn>2</mn><mo>,</mo><mn>3</mn><mo stretchy="false" form="postfix">}</mo></mtd></mtr><mtr><mtd columnalign="left" style="text-align: left"><mn>2</mn><mspace width="1.0em"></mspace></mtd><mtd columnalign="left" style="text-align: left"><mo stretchy="false" form="prefix">{</mo><mn>1</mn><mo stretchy="false" form="postfix">}</mo></mtd></mtr><mtr><mtd columnalign="left" style="text-align: left"><mn>3</mn><mspace width="1.0em"></mspace></mtd><mtd columnalign="left" style="text-align: left"><mi>∅</mi></mtd></mtr></mtable></mrow></mrow><annotation encoding="application/x-tex">\text{transfer} = \begin{cases}
1 \quad &amp; \{ 2, 3 \} \\
2 \quad &amp; \{ 1 \} \\
3 \quad &amp; \emptyset
\end{cases}</annotation></semantics></math></p>
<p>It has the type of:</p>
<div class="sourceCode" id="cb64"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb64-1"><a href="#cb64-1" aria-hidden="true" tabindex="-1"></a><span class="dt">State</span> <span class="ot">-&gt;</span> <span class="dt">Set</span> <span class="dt">State</span></span></code></pre></div>
<p>Where <code
class="sourceCode haskell"><span class="dt">State</span></code> is an
integer. You can represent the set as a vector, where each position is a
key, and each value is whether or not that key is present:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">transfer</mtext><mo>=</mo><mrow><mo stretchy="true" form="prefix">{</mo><mtable><mtr><mtd columnalign="left" style="text-align: left"><mn>1</mn><mspace width="1.0em"></mspace></mtd><mtd columnalign="left" style="text-align: left"><mn>0</mn></mtd><mtd columnalign="left" style="text-align: left"><mn>1</mn></mtd><mtd columnalign="left" style="text-align: left"><mn>1</mn></mtd></mtr><mtr><mtd columnalign="left" style="text-align: left"><mn>2</mn><mspace width="1.0em"></mspace></mtd><mtd columnalign="left" style="text-align: left"><mn>1</mn></mtd><mtd columnalign="left" style="text-align: left"><mn>0</mn></mtd><mtd columnalign="left" style="text-align: left"><mn>0</mn></mtd></mtr><mtr><mtd columnalign="left" style="text-align: left"><mn>3</mn><mspace width="1.0em"></mspace></mtd><mtd columnalign="left" style="text-align: left"><mn>0</mn></mtd><mtd columnalign="left" style="text-align: left"><mn>0</mn></mtd><mtd columnalign="left" style="text-align: left"><mn>0</mn></mtd></mtr></mtable></mrow></mrow><annotation encoding="application/x-tex">\text{transfer} = \begin{cases}
1 \quad &amp; 0 &amp; 1 &amp; 1 \\
2 \quad &amp; 1 &amp; 0 &amp; 0 \\
3 \quad &amp; 0 &amp; 0 &amp; 0 \end{cases}</annotation></semantics></math></p>
<p>Then, the matrix representation is obvious:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">transfer</mtext><mo>=</mo><mrow><mo stretchy="true" form="prefix">(</mo><mtable><mtr><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd></mtr><mtr><mtd columnalign="center" style="text-align: center"><mn>1</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd></mtr><mtr><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd><mtd columnalign="center" style="text-align: center"><mn>0</mn></mtd></mtr></mtable><mo stretchy="true" form="postfix">)</mo></mrow></mrow><annotation encoding="application/x-tex">\text{transfer} = \left( \begin{array}{ccc}
0 &amp; 1 &amp; 1 \\
1 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 0 \end{array} \right)</annotation></semantics></math></p>
<p>This is the semiring of square matrices. It is, of course, yet
<em>another</em> covector. The “keys” are the transfers: <code
class="sourceCode haskell"><span class="dv">1</span> <span class="ot">-&gt;</span> <span class="dv">2</span></code>
or <code
class="sourceCode haskell"><span class="dv">2</span> <span class="ot">-&gt;</span> <span class="dv">3</span></code>,
represented by the indices of the matrix. The “values” are whether or
not that transfer is permitted.</p>
<p>The algorithms for the usual semiring operations on matrices like
this are well-known and well-optimized. I haven’t yet benchmarked them
in Haskell using the matrix libraries, so I don’t know how they compare
to the other approaches. In the meantime, there’s an elegant list-based
implementation in <span class="citation"
data-cites="dolan_fun_2013">Dolan (<a href="#ref-dolan_fun_2013"
role="doc-biblioref">2013</a>)</span>:</p>
<div class="sourceCode" id="cb65"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb65-1"><a href="#cb65-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Matrix</span> a <span class="ot">=</span> <span class="dt">Scalar</span> a</span>
<span id="cb65-2"><a href="#cb65-2" aria-hidden="true" tabindex="-1"></a>              <span class="op">|</span> <span class="dt">Matrix</span> [[a]]</span>
<span id="cb65-3"><a href="#cb65-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb65-4"><a href="#cb65-4" aria-hidden="true" tabindex="-1"></a><span class="ot">mjoin ::</span> (<span class="dt">Matrix</span> a, <span class="dt">Matrix</span> a, <span class="dt">Matrix</span> a, <span class="dt">Matrix</span> a) <span class="ot">-&gt;</span> <span class="dt">Matrix</span> a</span>
<span id="cb65-5"><a href="#cb65-5" aria-hidden="true" tabindex="-1"></a>mjoin (<span class="dt">Matrix</span> ws, <span class="dt">Matrix</span> xs, <span class="dt">Matrix</span> ys, <span class="dt">Matrix</span> zs) <span class="ot">=</span></span>
<span id="cb65-6"><a href="#cb65-6" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Matrix</span> ((<span class="fu">zipWith</span> (<span class="op">++</span>) ws xs) <span class="op">++</span> (<span class="fu">zipWith</span> (<span class="op">++</span>) ys zs))</span>
<span id="cb65-7"><a href="#cb65-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb65-8"><a href="#cb65-8" aria-hidden="true" tabindex="-1"></a><span class="ot">msplit ::</span> <span class="dt">Matrix</span> a <span class="ot">-&gt;</span> (<span class="dt">Matrix</span> a, <span class="dt">Matrix</span> a, <span class="dt">Matrix</span> a, <span class="dt">Matrix</span> a)</span>
<span id="cb65-9"><a href="#cb65-9" aria-hidden="true" tabindex="-1"></a>msplit (<span class="dt">Matrix</span> (row<span class="op">:</span>rows)) <span class="ot">=</span></span>
<span id="cb65-10"><a href="#cb65-10" aria-hidden="true" tabindex="-1"></a>  (<span class="dt">Matrix</span> [[first]], <span class="dt">Matrix</span> [top]</span>
<span id="cb65-11"><a href="#cb65-11" aria-hidden="true" tabindex="-1"></a>  ,<span class="dt">Matrix</span> left,      <span class="dt">Matrix</span> rest )</span>
<span id="cb65-12"><a href="#cb65-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span></span>
<span id="cb65-13"><a href="#cb65-13" aria-hidden="true" tabindex="-1"></a>    (first<span class="op">:</span>top) <span class="ot">=</span> row</span>
<span id="cb65-14"><a href="#cb65-14" aria-hidden="true" tabindex="-1"></a>    (left,rest) <span class="ot">=</span> <span class="fu">unzip</span> (<span class="fu">map</span> (\(x<span class="op">:</span>xs) <span class="ot">-&gt;</span> ([x],xs)) rows)</span>
<span id="cb65-15"><a href="#cb65-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb65-16"><a href="#cb65-16" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span> <span class="dt">Semiring</span> (<span class="dt">Matrix</span> a) <span class="kw">where</span></span>
<span id="cb65-17"><a href="#cb65-17" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="dt">Scalar</span> zero</span>
<span id="cb65-18"><a href="#cb65-18" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">Scalar</span> one</span>
<span id="cb65-19"><a href="#cb65-19" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Scalar</span> x <span class="op">&lt;+&gt;</span> <span class="dt">Scalar</span> y <span class="ot">=</span> <span class="dt">Scalar</span> (x <span class="op">&lt;+&gt;</span> y)</span>
<span id="cb65-20"><a href="#cb65-20" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Matrix</span> x <span class="op">&lt;+&gt;</span> <span class="dt">Matrix</span> y <span class="ot">=</span></span>
<span id="cb65-21"><a href="#cb65-21" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Matrix</span> (<span class="fu">zipWith</span> (<span class="fu">zipWith</span> (<span class="op">&lt;+&gt;</span>)) x y)</span>
<span id="cb65-22"><a href="#cb65-22" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Scalar</span> x <span class="op">&lt;+&gt;</span> m <span class="ot">=</span> m <span class="op">&lt;+&gt;</span> <span class="dt">Scalar</span> x</span>
<span id="cb65-23"><a href="#cb65-23" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Matrix</span> [[x]] <span class="op">&lt;+&gt;</span> <span class="dt">Scalar</span> y <span class="ot">=</span> <span class="dt">Matrix</span> [[x <span class="op">&lt;+&gt;</span> y]]</span>
<span id="cb65-24"><a href="#cb65-24" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&lt;+&gt;</span> y <span class="ot">=</span> mjoin (first <span class="op">&lt;+&gt;</span> y, top, left, rest <span class="op">&lt;+&gt;</span> y)</span>
<span id="cb65-25"><a href="#cb65-25" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span> (first, top, left, rest) <span class="ot">=</span> msplit x</span>
<span id="cb65-26"><a href="#cb65-26" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Scalar</span> x <span class="op">&lt;.&gt;</span> <span class="dt">Scalar</span> y <span class="ot">=</span> <span class="dt">Scalar</span> (x <span class="op">&lt;.&gt;</span> y)</span>
<span id="cb65-27"><a href="#cb65-27" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Scalar</span> x <span class="op">&lt;.&gt;</span> <span class="dt">Matrix</span> y <span class="ot">=</span> <span class="dt">Matrix</span> ((<span class="fu">map</span><span class="op">.</span><span class="fu">map</span>) (x<span class="op">&lt;.&gt;</span>) y)</span>
<span id="cb65-28"><a href="#cb65-28" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Matrix</span> x <span class="op">&lt;.&gt;</span> <span class="dt">Scalar</span> y <span class="ot">=</span> <span class="dt">Matrix</span> ((<span class="fu">map</span><span class="op">.</span><span class="fu">map</span>) (<span class="op">&lt;.&gt;</span>y) x)</span>
<span id="cb65-29"><a href="#cb65-29" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Matrix</span> x <span class="op">&lt;.&gt;</span> <span class="dt">Matrix</span> y <span class="ot">=</span></span>
<span id="cb65-30"><a href="#cb65-30" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Matrix</span> [ [ <span class="fu">foldl1</span> (<span class="op">&lt;+&gt;</span>) (<span class="fu">zipWith</span> (<span class="op">&lt;.&gt;</span>) row col) <span class="op">|</span> col <span class="ot">&lt;-</span> cols ]</span>
<span id="cb65-31"><a href="#cb65-31" aria-hidden="true" tabindex="-1"></a>           <span class="op">|</span> row <span class="ot">&lt;-</span> x ] <span class="kw">where</span> cols <span class="ot">=</span> transpose y</span>
<span id="cb65-32"><a href="#cb65-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb65-33"><a href="#cb65-33" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">StarSemiring</span> a <span class="ot">=&gt;</span> <span class="dt">StarSemiring</span> (<span class="dt">Matrix</span> a) <span class="kw">where</span></span>
<span id="cb65-34"><a href="#cb65-34" aria-hidden="true" tabindex="-1"></a>  star (<span class="dt">Matrix</span> [[x]]) <span class="ot">=</span> <span class="dt">Matrix</span> [[star x]]</span>
<span id="cb65-35"><a href="#cb65-35" aria-hidden="true" tabindex="-1"></a>  star m <span class="ot">=</span> mjoin (first&#39; <span class="op">&lt;+&gt;</span> top&#39; <span class="op">&lt;.&gt;</span> rest&#39; <span class="op">&lt;.&gt;</span> left&#39;</span>
<span id="cb65-36"><a href="#cb65-36" aria-hidden="true" tabindex="-1"></a>                 ,top&#39; <span class="op">&lt;.&gt;</span> rest&#39;, rest&#39; <span class="op">&lt;.&gt;</span> left&#39;, rest&#39;)</span>
<span id="cb65-37"><a href="#cb65-37" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb65-38"><a href="#cb65-38" aria-hidden="true" tabindex="-1"></a>      (first, top, left, rest) <span class="ot">=</span> msplit m</span>
<span id="cb65-39"><a href="#cb65-39" aria-hidden="true" tabindex="-1"></a>      first&#39; <span class="ot">=</span> star first</span>
<span id="cb65-40"><a href="#cb65-40" aria-hidden="true" tabindex="-1"></a>      top&#39; <span class="ot">=</span> first&#39; <span class="op">&lt;.&gt;</span> top</span>
<span id="cb65-41"><a href="#cb65-41" aria-hidden="true" tabindex="-1"></a>      left&#39; <span class="ot">=</span> left <span class="op">&lt;.&gt;</span> first&#39;</span>
<span id="cb65-42"><a href="#cb65-42" aria-hidden="true" tabindex="-1"></a>      rest&#39; <span class="ot">=</span> star (rest <span class="op">&lt;+&gt;</span> left&#39; <span class="op">&lt;.&gt;</span> top)</span></code></pre></div>
<h2 id="permutation-parsing">Permutation parsing</h2>
<p>A lot of the use from semirings comes from “attaching” them to other
values. Attaching a semiring to effects (in the form of an applicative)
can give you <em>repetition</em> of those effects. The excellent <a
href="http://hackage.haskell.org/package/ReplicateEffects">ReplicateEffects</a>
library explores this concept in depth.</p>
<p>It’s based on this type:</p>
<div class="sourceCode" id="cb66"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb66-1"><a href="#cb66-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Replicate</span> a b</span>
<span id="cb66-2"><a href="#cb66-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> <span class="dt">Nil</span></span>
<span id="cb66-3"><a href="#cb66-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">|</span> <span class="dt">Cons</span> (<span class="dt">Maybe</span> b) (<span class="dt">Replicate</span> a (a <span class="ot">-&gt;</span> b))</span></code></pre></div>
<p>This type can be made to conform to <code
class="sourceCode haskell"><span class="dt">Semiring</span></code> (and
<code
class="sourceCode haskell"><span class="dt">Starsemiring</span></code>,
etc) trivially.</p>
<p>In the simplest case, it has the same behaviour as <a
href="https://hackage.haskell.org/package/base-4.9.0.0/docs/Control-Monad.html#v:replicateM"><code
class="sourceCode haskell">replicateM</code></a>. Even the more complex
combinators, like <code class="sourceCode haskell">atLeast</code>, can
be built on <code
class="sourceCode haskell"><span class="dt">Alternative</span></code>:</p>
<div class="sourceCode" id="cb67"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb67-1"><a href="#cb67-1" aria-hidden="true" tabindex="-1"></a><span class="ot">atLeast ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f [a]</span>
<span id="cb67-2"><a href="#cb67-2" aria-hidden="true" tabindex="-1"></a>atLeast m f <span class="ot">=</span> go (<span class="fu">max</span> <span class="dv">0</span> m) <span class="kw">where</span></span>
<span id="cb67-3"><a href="#cb67-3" aria-hidden="true" tabindex="-1"></a>  go <span class="dv">0</span> <span class="ot">=</span> many f</span>
<span id="cb67-4"><a href="#cb67-4" aria-hidden="true" tabindex="-1"></a>  go n <span class="ot">=</span> liftA2 (<span class="op">:</span>) f (go (n<span class="op">-</span><span class="dv">1</span>))</span>
<span id="cb67-5"><a href="#cb67-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb67-6"><a href="#cb67-6" aria-hidden="true" tabindex="-1"></a><span class="ot">atMost ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f [a]</span>
<span id="cb67-7"><a href="#cb67-7" aria-hidden="true" tabindex="-1"></a>atMost m f <span class="ot">=</span> go (<span class="fu">max</span> <span class="dv">0</span> m) <span class="kw">where</span></span>
<span id="cb67-8"><a href="#cb67-8" aria-hidden="true" tabindex="-1"></a>  go <span class="dv">0</span> <span class="ot">=</span> <span class="fu">pure</span> []</span>
<span id="cb67-9"><a href="#cb67-9" aria-hidden="true" tabindex="-1"></a>  go n <span class="ot">=</span> liftA2 (<span class="op">:</span>) f (go (n<span class="op">-</span><span class="dv">1</span>)) <span class="op">&lt;|&gt;</span> <span class="fu">pure</span> []</span></code></pre></div>
<p>There are two main benefits over using the standard alternative
implementation. First, you can choose greedy or lazy evaluation of the
effects <em>after</em> the replication is built.</p>
<p>Secondly, the <em>order</em> of the effects doesn’t have to be
specified. This allows you to execute permutations of the effects, in a
permutation parser, for instance. The permutation is totally decoupled
from the declaration of the repetition (it’s in a totally separate
library, in fact: <a
href="http://hackage.haskell.org/package/PermuteEffects">PermuteEffects</a>).
Its construction is reminiscent of the <a
href="https://hackage.haskell.org/package/free-4.12.4/docs/Control-Alternative-Free.html#t:AltF">free
alternative</a>.</p>
<p>Having the replicate type conform to <code
class="sourceCode haskell"><span class="dt">Semiring</span></code> is
all well and good: what I’m interested in is seeing if its
implementation is another semiring-based object in disguise. I’ll
revisit this in a later post.</p>
<h2 id="algebraic-search">Algebraic Search</h2>
<p>List comprehension notation is one of my all-time favourite bits of
syntactic sugar. It seems almost <em>too</em> declarative to have a
reasonable implementation strategy. The vast majority of the time, it
actually works in a sensible way. There are exceptions, though. Take a
reasonable definition of a list of Pythagorean triples:</p>
<div class="sourceCode" id="cb68"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb68-1"><a href="#cb68-1" aria-hidden="true" tabindex="-1"></a>[ (x,y,z) <span class="op">|</span> x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>], y <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>], z <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>], x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y <span class="op">==</span> z<span class="op">*</span>z ]</span></code></pre></div>
<p>This expression will diverge without yielding a single triple. It
will search through every possible value for <code
class="sourceCode haskell">z</code> before incrementing either <code
class="sourceCode haskell">x</code> or <code
class="sourceCode haskell">y</code>. Since there are infinite values for
<code class="sourceCode haskell">z</code>, it will never find a triple.
In other words, vanilla list comprehensions in Haskell perform
depth-first search.</p>
<p>In order to express other kinds of search (either breadth-first or
depth-bounded), different monads are needed. These monads are explored
in <span class="citation" data-cites="fischer_reinventing_2009">Fischer
(<a href="#ref-fischer_reinventing_2009"
role="doc-biblioref">2009</a>)</span> and <span class="citation"
data-cites="spivey_algebras_2009">Spivey (<a
href="#ref-spivey_algebras_2009"
role="doc-biblioref">2009</a>)</span>.</p>
<p>You can actually use the <em>exact</em> same notation as above with
arbitrary alternative monads using <code
class="sourceCode haskell"><span class="op">-</span><span class="dt">XMonadComprehensions</span></code>
and <code
class="sourceCode haskell"><span class="op">-</span><span class="dt">XOverloadedLists</span></code>.</p>
<div class="sourceCode" id="cb69"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb69-1"><a href="#cb69-1" aria-hidden="true" tabindex="-1"></a><span class="ot">trips ::</span> ( <span class="dt">Alternative</span> m</span>
<span id="cb69-2"><a href="#cb69-2" aria-hidden="true" tabindex="-1"></a>         , <span class="dt">Monad</span> m</span>
<span id="cb69-3"><a href="#cb69-3" aria-hidden="true" tabindex="-1"></a>         , <span class="dt">IsList</span> (m <span class="dt">Integer</span>)</span>
<span id="cb69-4"><a href="#cb69-4" aria-hidden="true" tabindex="-1"></a>         , <span class="dt">Enum</span> (<span class="dt">Item</span> (m <span class="dt">Integer</span>))</span>
<span id="cb69-5"><a href="#cb69-5" aria-hidden="true" tabindex="-1"></a>         , <span class="dt">Num</span> (<span class="dt">Item</span> (m <span class="dt">Integer</span>)))</span>
<span id="cb69-6"><a href="#cb69-6" aria-hidden="true" tabindex="-1"></a>      <span class="ot">=&gt;</span> m (<span class="dt">Integer</span>,<span class="dt">Integer</span>,<span class="dt">Integer</span>)</span>
<span id="cb69-7"><a href="#cb69-7" aria-hidden="true" tabindex="-1"></a>trips <span class="ot">=</span> [ (x,y,z) <span class="op">|</span> x <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>], y <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>], z <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>], x<span class="op">*</span>x <span class="op">+</span> y<span class="op">*</span>y <span class="op">==</span> z<span class="op">*</span>z ]</span></code></pre></div>
<p>So then, here’s the challenge: swap in different <code
class="sourceCode haskell">m</code>s via a type annotation, and prevent
<code class="sourceCode haskell">trips</code> from diverging before
getting any triples.</p>
<p>As one example, here’s some code adapted from <span class="citation"
data-cites="fischer_reinventing_2009">Fischer (<a
href="#ref-fischer_reinventing_2009"
role="doc-biblioref">2009</a>)</span>:</p>
<div class="sourceCode" id="cb70"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb70-1"><a href="#cb70-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Monoid</span> r, <span class="dt">Applicative</span> m) <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">ContT</span> r m a) <span class="kw">where</span></span>
<span id="cb70-2"><a href="#cb70-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">ContT</span> (<span class="fu">const</span> (<span class="fu">pure</span> <span class="fu">mempty</span>))</span>
<span id="cb70-3"><a href="#cb70-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> (<span class="dt">ContT</span> f) (<span class="dt">ContT</span> g) <span class="ot">=</span> <span class="dt">ContT</span> (\x <span class="ot">-&gt;</span> liftA2 <span class="fu">mappend</span> (f x) (g x))</span>
<span id="cb70-4"><a href="#cb70-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-5"><a href="#cb70-5" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">List</span> a <span class="ot">=</span> <span class="dt">List</span></span>
<span id="cb70-6"><a href="#cb70-6" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> runList ::</span> <span class="kw">forall</span> m<span class="op">.</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> <span class="dt">Cont</span> m a } <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb70-7"><a href="#cb70-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-8"><a href="#cb70-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Foldable</span> <span class="dt">List</span> <span class="kw">where</span> <span class="fu">foldMap</span> <span class="ot">=</span> <span class="fu">flip</span> (runCont<span class="op">.</span>runList)</span>
<span id="cb70-9"><a href="#cb70-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-10"><a href="#cb70-10" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span> <span class="dt">Show</span> (<span class="dt">List</span> a) <span class="kw">where</span> <span class="fu">show</span> <span class="ot">=</span> <span class="fu">show</span> <span class="op">.</span> <span class="fu">foldr</span> (<span class="op">:</span>) []</span>
<span id="cb70-11"><a href="#cb70-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-12"><a href="#cb70-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> (<span class="dt">List</span> a) <span class="kw">where</span></span>
<span id="cb70-13"><a href="#cb70-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> (<span class="dt">List</span> x) (<span class="dt">List</span> y) <span class="ot">=</span> <span class="dt">List</span> (<span class="fu">mappend</span> x y)</span>
<span id="cb70-14"><a href="#cb70-14" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">List</span> <span class="fu">mempty</span></span>
<span id="cb70-15"><a href="#cb70-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-16"><a href="#cb70-16" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span> <span class="dt">Semiring</span> (<span class="dt">List</span> a) <span class="kw">where</span></span>
<span id="cb70-17"><a href="#cb70-17" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> <span class="fu">mempty</span></span>
<span id="cb70-18"><a href="#cb70-18" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;+&gt;</span>) <span class="ot">=</span> <span class="fu">mappend</span></span>
<span id="cb70-19"><a href="#cb70-19" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;.&gt;</span>) <span class="ot">=</span> liftA2 <span class="fu">mappend</span></span>
<span id="cb70-20"><a href="#cb70-20" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="fu">pure</span> <span class="fu">mempty</span></span>
<span id="cb70-21"><a href="#cb70-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-22"><a href="#cb70-22" aria-hidden="true" tabindex="-1"></a><span class="ot">bfs ::</span> <span class="dt">List</span> a <span class="ot">-&gt;</span> [a]</span>
<span id="cb70-23"><a href="#cb70-23" aria-hidden="true" tabindex="-1"></a>bfs <span class="ot">=</span> toList <span class="op">.</span> fold <span class="op">.</span> levels <span class="op">.</span> anyOf</span>
<span id="cb70-24"><a href="#cb70-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-25"><a href="#cb70-25" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Levels</span> a <span class="ot">=</span> <span class="dt">Levels</span> {<span class="ot"> levels ::</span> [<span class="dt">List</span> a] } <span class="kw">deriving</span> <span class="dt">Functor</span></span>
<span id="cb70-26"><a href="#cb70-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-27"><a href="#cb70-27" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Levels</span> <span class="kw">where</span></span>
<span id="cb70-28"><a href="#cb70-28" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Levels</span> [<span class="fu">pure</span> x]</span>
<span id="cb70-29"><a href="#cb70-29" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Levels</span> fs <span class="op">&lt;*&gt;</span> <span class="dt">Levels</span> xs <span class="ot">=</span> <span class="dt">Levels</span> [ f <span class="op">&lt;*&gt;</span> x <span class="op">|</span> f <span class="ot">&lt;-</span> fs, x <span class="ot">&lt;-</span> xs ]</span>
<span id="cb70-30"><a href="#cb70-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-31"><a href="#cb70-31" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Alternative</span> <span class="dt">Levels</span> <span class="kw">where</span></span>
<span id="cb70-32"><a href="#cb70-32" aria-hidden="true" tabindex="-1"></a>  empty <span class="ot">=</span> <span class="dt">Levels</span> []</span>
<span id="cb70-33"><a href="#cb70-33" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Levels</span> x <span class="op">&lt;|&gt;</span> <span class="dt">Levels</span> y <span class="ot">=</span> <span class="dt">Levels</span> (<span class="fu">mempty</span> <span class="op">:</span> merge x y)</span>
<span id="cb70-34"><a href="#cb70-34" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-35"><a href="#cb70-35" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">IsList</span> (<span class="dt">List</span> a) <span class="kw">where</span></span>
<span id="cb70-36"><a href="#cb70-36" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> <span class="dt">Item</span> (<span class="dt">List</span> a) <span class="ot">=</span> a</span>
<span id="cb70-37"><a href="#cb70-37" aria-hidden="true" tabindex="-1"></a>  fromList <span class="ot">=</span> anyOf</span>
<span id="cb70-38"><a href="#cb70-38" aria-hidden="true" tabindex="-1"></a>  toList <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">:</span>) []</span>
<span id="cb70-39"><a href="#cb70-39" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-40"><a href="#cb70-40" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">List</span> <span class="kw">where</span></span>
<span id="cb70-41"><a href="#cb70-41" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">List</span> (<span class="fu">pure</span> x)</span>
<span id="cb70-42"><a href="#cb70-42" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;*&gt;</span>) <span class="ot">=</span> ap</span>
<span id="cb70-43"><a href="#cb70-43" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-44"><a href="#cb70-44" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Alternative</span> <span class="dt">List</span> <span class="kw">where</span></span>
<span id="cb70-45"><a href="#cb70-45" aria-hidden="true" tabindex="-1"></a>  empty <span class="ot">=</span> <span class="fu">mempty</span></span>
<span id="cb70-46"><a href="#cb70-46" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&lt;|&gt;</span>) <span class="ot">=</span> <span class="fu">mappend</span></span>
<span id="cb70-47"><a href="#cb70-47" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-48"><a href="#cb70-48" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">List</span> <span class="kw">where</span></span>
<span id="cb70-49"><a href="#cb70-49" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> <span class="fu">foldMap</span> f x</span>
<span id="cb70-50"><a href="#cb70-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-51"><a href="#cb70-51" aria-hidden="true" tabindex="-1"></a><span class="ot">anyOf ::</span> (<span class="dt">Alternative</span> m, <span class="dt">Foldable</span> f) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> m a</span>
<span id="cb70-52"><a href="#cb70-52" aria-hidden="true" tabindex="-1"></a>anyOf <span class="ot">=</span> getAlt <span class="op">.</span> <span class="fu">foldMap</span> (<span class="dt">Alt</span> <span class="op">.</span> <span class="fu">pure</span>)</span>
<span id="cb70-53"><a href="#cb70-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb70-54"><a href="#cb70-54" aria-hidden="true" tabindex="-1"></a><span class="ot">merge ::</span> [<span class="dt">List</span> a] <span class="ot">-&gt;</span> [<span class="dt">List</span> a] <span class="ot">-&gt;</span> [<span class="dt">List</span> a]</span>
<span id="cb70-55"><a href="#cb70-55" aria-hidden="true" tabindex="-1"></a>merge []      ys    <span class="ot">=</span> ys</span>
<span id="cb70-56"><a href="#cb70-56" aria-hidden="true" tabindex="-1"></a>merge xs      []    <span class="ot">=</span> xs</span>
<span id="cb70-57"><a href="#cb70-57" aria-hidden="true" tabindex="-1"></a>merge (x<span class="op">:</span>xs) (y<span class="op">:</span>ys) <span class="ot">=</span> <span class="fu">mappend</span> x y <span class="op">:</span> merge xs ys</span></code></pre></div>
<div class="sourceCode" id="cb71"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb71-1"><a href="#cb71-1" aria-hidden="true" tabindex="-1"></a><span class="fu">take</span> <span class="dv">3</span> (bfs trips)</span>
<span id="cb71-2"><a href="#cb71-2" aria-hidden="true" tabindex="-1"></a>[(<span class="dv">3</span>,<span class="dv">4</span>,<span class="dv">5</span>),(<span class="dv">4</span>,<span class="dv">3</span>,<span class="dv">5</span>),(<span class="dv">6</span>,<span class="dv">8</span>,<span class="dv">10</span>)]</span></code></pre></div>
<p>The only relevance to semirings is the merge function. The semiring
over lists is the semiring over polynomials:</p>
<div class="sourceCode" id="cb72"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb72-1"><a href="#cb72-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> a <span class="ot">=&gt;</span> <span class="dt">Semiring</span> [a] <span class="kw">where</span></span>
<span id="cb72-2"><a href="#cb72-2" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> [one]</span>
<span id="cb72-3"><a href="#cb72-3" aria-hidden="true" tabindex="-1"></a>  zero <span class="ot">=</span> []</span>
<span id="cb72-4"><a href="#cb72-4" aria-hidden="true" tabindex="-1"></a>  [] <span class="op">&lt;+&gt;</span> ys <span class="ot">=</span> ys</span>
<span id="cb72-5"><a href="#cb72-5" aria-hidden="true" tabindex="-1"></a>  xs <span class="op">&lt;+&gt;</span> [] <span class="ot">=</span> xs</span>
<span id="cb72-6"><a href="#cb72-6" aria-hidden="true" tabindex="-1"></a>  (x<span class="op">:</span>xs) <span class="op">&lt;+&gt;</span> (y<span class="op">:</span>ys) <span class="ot">=</span> (x <span class="op">&lt;+&gt;</span> y) <span class="op">:</span> (xs <span class="op">&lt;+&gt;</span> ys)</span>
<span id="cb72-7"><a href="#cb72-7" aria-hidden="true" tabindex="-1"></a>  [] <span class="op">&lt;.&gt;</span> _ <span class="ot">=</span> []</span>
<span id="cb72-8"><a href="#cb72-8" aria-hidden="true" tabindex="-1"></a>  _ <span class="op">&lt;.&gt;</span> [] <span class="ot">=</span> []</span>
<span id="cb72-9"><a href="#cb72-9" aria-hidden="true" tabindex="-1"></a>  (x<span class="op">:</span>xs) <span class="op">&lt;.&gt;</span> (y<span class="op">:</span>ys) <span class="ot">=</span></span>
<span id="cb72-10"><a href="#cb72-10" aria-hidden="true" tabindex="-1"></a>    (x <span class="op">&lt;.&gt;</span> y) <span class="op">:</span> (<span class="fu">map</span> (x <span class="op">&lt;.&gt;</span>) ys <span class="op">&lt;+&gt;</span> <span class="fu">map</span> (<span class="op">&lt;.&gt;</span> y) xs <span class="op">&lt;+&gt;</span> (xs <span class="op">&lt;.&gt;</span> ys))</span></code></pre></div>
<p>The <code
class="sourceCode haskell"><span class="op">&lt;+&gt;</span></code> is
the same as the <code class="sourceCode haskell">merge</code> function.
I think the <code
class="sourceCode haskell"><span class="op">&lt;.&gt;</span></code>
might be a more valid definition of the <code
class="sourceCode haskell"><span class="op">&lt;*&gt;</span></code>
function, also.</p>
<div class="sourceCode" id="cb73"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb73-1"><a href="#cb73-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Levels</span> <span class="kw">where</span></span>
<span id="cb73-2"><a href="#cb73-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Levels</span> [<span class="fu">pure</span> x]</span>
<span id="cb73-3"><a href="#cb73-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Levels</span> [] <span class="op">&lt;*&gt;</span> _ <span class="ot">=</span> <span class="dt">Levels</span> []</span>
<span id="cb73-4"><a href="#cb73-4" aria-hidden="true" tabindex="-1"></a>  _ <span class="op">&lt;*&gt;</span> <span class="dt">Levels</span> [] <span class="ot">=</span> <span class="dt">Levels</span> []</span>
<span id="cb73-5"><a href="#cb73-5" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Levels</span> (f<span class="op">:</span>fs) <span class="op">&lt;*&gt;</span> <span class="dt">Levels</span> (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Levels</span> <span class="op">$</span></span>
<span id="cb73-6"><a href="#cb73-6" aria-hidden="true" tabindex="-1"></a>    (f <span class="op">&lt;*&gt;</span> x) <span class="op">:</span> levels (<span class="dt">Levels</span> (<span class="fu">fmap</span> (f <span class="op">&lt;*&gt;</span>) xs)</span>
<span id="cb73-7"><a href="#cb73-7" aria-hidden="true" tabindex="-1"></a>             <span class="op">&lt;|&gt;</span> <span class="dt">Levels</span> (<span class="fu">fmap</span> (<span class="op">&lt;*&gt;</span> x) fs)</span>
<span id="cb73-8"><a href="#cb73-8" aria-hidden="true" tabindex="-1"></a>             <span class="op">&lt;|&gt;</span> (<span class="dt">Levels</span> fs <span class="op">&lt;*&gt;</span> <span class="dt">Levels</span> xs))</span></code></pre></div>
<h2 id="conclusion">Conclusion</h2>
<p>I’ve only scratched the surface of this abstraction. There are
several other interesting semirings: polynomials, logs, Viterbi,
Łukasiewicz, languages, multisets, bidirectional parsers, etc. Hopefully
I’ll eventually be able to put this stuff into a library or something.
In the meantime, I definitely will write some posts on the application
to context-free parsing, bidirectional parsing (I just read <span
class="citation" data-cites="breitner_showcasing_2016">Breitner (<a
href="#ref-breitner_showcasing_2016"
role="doc-biblioref">2016</a>)</span>) and search.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-boom_further_1981" class="csl-entry" role="listitem">
Boom, H. J. 1981. <span>“Further thoughts on
<span>Abstracto</span>.”</span> <em>Working Paper ELC-9, IFIP WG
2.1</em>. <a
href="http://www.kestrel.edu/home/people/meertens/publications/papers/Abstracto_reader.pdf">http://www.kestrel.edu/home/people/meertens/publications/papers/Abstracto_reader.pdf</a>.
</div>
<div id="ref-breitner_showcasing_2016" class="csl-entry"
role="listitem">
Breitner, Joachim. 2016. <span>“Showcasing
<span>Applicative</span>.”</span> <em>Joachim Breitner’s Blog</em>. <a
href="http://www.joachim-breitner.de/blog/710-Showcasing_Applicative">http://www.joachim-breitner.de/blog/710-Showcasing_Applicative</a>.
</div>
<div id="ref-doel_free_2015" class="csl-entry" role="listitem">
Doel, Dan. 2015. <span>“Free <span>Monoids</span> in
<span>Haskell</span>.”</span> <em>The Comonad.Reader</em>. <a
href="http://comonad.com/reader/2015/free-monoids-in-haskell/">http://comonad.com/reader/2015/free-monoids-in-haskell/</a>.
</div>
<div id="ref-dolan_fun_2013" class="csl-entry" role="listitem">
Dolan, Stephen. 2013. <span>“Fun with semirings: A functional pearl on
the abuse of linear algebra.”</span> In, 48:101. ACM Press. doi:<a
href="https://doi.org/10.1145/2500365.2500613">10.1145/2500365.2500613</a>.
<a
href="https://www.cl.cam.ac.uk/~sd601/papers/semirings.pdf">https://www.cl.cam.ac.uk/~sd601/papers/semirings.pdf</a>.
</div>
<div id="ref-droste_semirings_2009" class="csl-entry" role="listitem">
Droste, Manfred, and Werner Kuich. 2009. <span>“Semirings and
<span>Formal</span> <span>Power</span> <span>Series</span>.”</span> In
<em>Handbook of <span>Weighted</span> <span>Automata</span></em>, ed by.
Manfred Droste, Werner Kuich, and Heiko Vogler, 1:3–28. Monographs in
<span>Theoretical</span> <span>Computer</span> <span>Science</span>.
<span>An</span> <span>EATCS</span> <span>Series</span>. Berlin,
Heidelberg: Springer Berlin Heidelberg. <a
href="http://staff.mmcs.sfedu.ru/~ulysses/Edu/Marktoberdorf_2009/working_material/Esparsa/Kuich.%20Semirings%20and%20FPS.pdf">http://staff.mmcs.sfedu.ru/~ulysses/Edu/Marktoberdorf_2009/working_material/Esparsa/Kuich.%20Semirings%20and%20FPS.pdf</a>.
</div>
<div id="ref-erwig_functional_2006" class="csl-entry" role="listitem">
Erwig, Martin, and Steve Kollmansberger. 2006. <span>“Functional pearls:
<span>Probabilistic</span> functional programming in
<span>Haskell</span>.”</span> <em>Journal of Functional Programming</em>
16 (1): 21–34. doi:<a
href="https://doi.org/10.1017/S0956796805005721">10.1017/S0956796805005721</a>.
<a
href="http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP06a">http://web.engr.oregonstate.edu/~erwig/papers/abstracts.html#JFP06a</a>.
</div>
<div id="ref-fischer_reinventing_2009" class="csl-entry"
role="listitem">
Fischer, Sebastian. 2009. <span>“Reinventing <span>Haskell</span>
<span>Backtracking</span>.”</span> In <em>Informatik 2009,
<span>Im</span> <span>Fokus</span> das <span>Leben</span>
(<span>ATPS</span>’09)</em>. GI Edition. <a
href="http://www-ps.informatik.uni-kiel.de/~sebf/data/pub/atps09.pdf">http://www-ps.informatik.uni-kiel.de/~sebf/data/pub/atps09.pdf</a>.
</div>
<div id="ref-hirschowitz_modules_2010" class="csl-entry"
role="listitem">
Hirschowitz, André, and Marco Maggesi. 2010. <span>“Modules over monads
and initial semantics.”</span> <em>Information and Computation</em> 208
(5). Special <span>Issue</span>: 14th <span>Workshop</span> on
<span>Logic</span>, <span>Language</span>, <span>Information</span> and
<span>Computation</span> (<span>WoLLIC</span> 2007) (May): 545–564.
doi:<a
href="https://doi.org/10.1016/j.ic.2009.07.003">10.1016/j.ic.2009.07.003</a>.
<a
href="https://pdfs.semanticscholar.org/3e0c/c79e8cda9246cb954da6fd8aaaa394fecdc3.pdf">https://pdfs.semanticscholar.org/3e0c/c79e8cda9246cb954da6fd8aaaa394fecdc3.pdf</a>.
</div>
<div id="ref-kidd_build_2007" class="csl-entry" role="listitem">
Kidd, Eric. 2007. <span>“Build your own probability monads.”</span> <a
href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.129.9502&amp;rep=rep1&amp;type=pdf">http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.129.9502&amp;rep=rep1&amp;type=pdf</a>.
</div>
<div id="ref-kmett_free_2011" class="csl-entry" role="listitem">
Kmett, Edward. 2011a. <span>“Free <span>Monads</span> for
<span>Less</span> (<span>Part</span> 2 of 3):
<span>Yoneda</span>.”</span> <em>The Comonad.Reader</em>. <a
href="http://comonad.com/reader/2011/free-monads-for-less-2/">http://comonad.com/reader/2011/free-monads-for-less-2/</a>.
</div>
<div id="ref-kmett_modules_2011" class="csl-entry" role="listitem">
———. 2011b. <span>“Modules and <span>Functional</span>
<span>Linear</span> <span>Functionals</span>.”</span> <em>The
Comonad.Reader</em>. <a
href="http://comonad.com/reader/2011/free-modules-and-functional-linear-functionals/">http://comonad.com/reader/2011/free-modules-and-functional-linear-functionals/</a>.
</div>
<div id="ref-larsen_memory_2011" class="csl-entry" role="listitem">
Larsen, Ken Friis. 2011. <span>“Memory <span>Efficient</span>
<span>Implementation</span> of <span>Probability</span>
<span>Monads</span>.”</span> <a
href="http://www.diku.dk/~kflarsen/t/ProbMonad-unpublished.pdf">http://www.diku.dk/~kflarsen/t/ProbMonad-unpublished.pdf</a>.
</div>
<div id="ref-oconnor_very_2011" class="csl-entry" role="listitem">
O’Connor, Russell. 2011. <span>“A <span>Very</span> <span>General</span>
<span>Method</span> of <span>Computing</span> <span>Shortest</span>
<span>Paths</span>.”</span> <em>Russell O’Connor’s Blog</em>. <a
href="http://r6.ca/blog/20110808T035622Z.html">http://r6.ca/blog/20110808T035622Z.html</a>.
</div>
<div id="ref-piponi_monad_2009" class="csl-entry" role="listitem">
Piponi, Dan. 2009. <span>“A <span>Monad</span> for
<span>Combinatorial</span> <span>Search</span> with
<span>Heuristics</span>.”</span> <em>A Neighborhood of Infinity</em>. <a
href="http://blog.sigfpe.com/2009/07/monad-for-combinatorial-search-with.html">http://blog.sigfpe.com/2009/07/monad-for-combinatorial-search-with.html</a>.
</div>
<div id="ref-rivas_monoids_2015" class="csl-entry" role="listitem">
Rivas, Exequiel, Mauro Jaskelioff, and Tom Schrijvers. 2015. <span>“From
monoids to near-semirings: The essence of <span>MonadPlus</span> and
<span>Alternative</span>.”</span> In <em>Proceedings of the 17th
<span>International</span> <span>Symposium</span> on
<span>Principles</span> and <span>Practice</span> of
<span>Declarative</span> <span>Programming</span></em>, 196–207. ACM.
doi:<a
href="https://doi.org/10.1145/2790449.2790514">10.1145/2790449.2790514</a>.
<a
href="http://www.fceia.unr.edu.ar/~mauro/pubs/FromMonoidstoNearsemirings.pdf">http://www.fceia.unr.edu.ar/~mauro/pubs/FromMonoidstoNearsemirings.pdf</a>.
</div>
<div id="ref-spivey_algebras_2009" class="csl-entry" role="listitem">
Spivey, J. Michael. 2009. <span>“Algebras for combinatorial
search.”</span> <em>Journal of Functional Programming</em> 19 (3-4)
(July): 469–487. doi:<a
href="https://doi.org/10.1017/S0956796809007321">10.1017/S0956796809007321</a>.
<a
href="https://pdfs.semanticscholar.org/db3e/373bb6e7e7837ebc524da0a25903958554ed.pdf">https://pdfs.semanticscholar.org/db3e/373bb6e7e7837ebc524da0a25903958554ed.pdf</a>.
</div>
</div>
]]></description>
    <pubDate>Thu, 17 Nov 2016 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2016-11-17-semirings-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Probability Trees</title>
    <link>https://doisinkidney.com/posts/2016-09-30-prob-trees-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on September 30, 2016
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Probability&#39;." href="/tags/Probability.html" rel="tag">Probability</a>
    
</div>

<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language DeriveFunctor, DeriveFoldable #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language PatternSynonyms, ViewPatterns #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">ProbTree</span> <span class="kw">where</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Monoid</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map.Strict</span> <span class="kw">as</span> <span class="dt">Map</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Map.Strict</span> (<span class="dt">Map</span>)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Arrow</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Ratio</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Foldable</span></span></code></pre></div>
<p>Previously, I tried to figure out how to make the probability monad
more “listy”. I read a little more about the topic <span
class="citation"
data-cites="erwig_functional_2006 kidd_build_2007">(especially <a
href="#ref-erwig_functional_2006" role="doc-biblioref">Erwig and
Kollmansberger 2006</a>; and <a href="#ref-kidd_build_2007"
role="doc-biblioref">Kidd 2007</a>)</span>.</p>
<p>I then thought about what a probability monad would look like if it
was based on other data structures. I feel like the standard version
really wants to be:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">ProperProb</span> a <span class="ot">=</span> <span class="dt">ProperProb</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> yes ::</span> <span class="dt">Map</span> a (<span class="dt">Product</span> <span class="dt">Rational</span>) }</span></code></pre></div>
<p>But of course a monad instance isn’t allowed.</p>
<p>Similar to a map, though, is a binary tree:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BinaryTree</span> a <span class="ot">=</span> <span class="dt">Leaf</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>                  <span class="op">|</span> <span class="dt">Node</span> (<span class="dt">BinaryTree</span> a) a (<span class="dt">BinaryTree</span> a)</span></code></pre></div>
<p>And it feels better for probability - <em>flatter</em>, somehow.
Transmuting it into a probability-thing:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Odds</span> a <span class="ot">=</span> <span class="dt">Certain</span> a</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">Choice</span> (<span class="dt">Odds</span> a) <span class="dt">Rational</span> (<span class="dt">Odds</span> a)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>            <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Functor</span>, <span class="dt">Foldable</span>, <span class="dt">Show</span>)</span></code></pre></div>
<p>That looks good to me. A choice between two different branches feels
more natural than a choice between a head and a tail.</p>
<p>The fold is similar to before, with an unfold for good measure:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldOdds ::</span> (b <span class="ot">-&gt;</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> b</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>foldOdds f b <span class="ot">=</span> r <span class="kw">where</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  r (<span class="dt">Certain</span> x) <span class="ot">=</span> b x</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  r (<span class="dt">Choice</span> xs p ys) <span class="ot">=</span> f (r xs) p (r ys)</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="ot">unfoldOdds ::</span> (b <span class="ot">-&gt;</span> <span class="dt">Either</span> a (b,<span class="dt">Rational</span>,b)) <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Odds</span> a</span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>unfoldOdds f <span class="ot">=</span> r <span class="kw">where</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  r b <span class="ot">=</span> <span class="kw">case</span> f b <span class="kw">of</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Left</span> a <span class="ot">-&gt;</span> <span class="dt">Certain</span> a</span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Right</span> (x,p,y) <span class="ot">-&gt;</span> <span class="dt">Choice</span> (r x) p (r y)</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a><span class="ot">fi ::</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>fi <span class="dt">True</span>  t _ <span class="ot">=</span> t</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>fi <span class="dt">False</span> _ f <span class="ot">=</span> f</span></code></pre></div>
<p>I changed the pattern synonym a little:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="ot">unRatio ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> (a,a)</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>unRatio <span class="ot">=</span> <span class="fu">numerator</span>   <span class="op">&amp;&amp;&amp;</span> <span class="fu">denominator</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>      <span class="op">&gt;&gt;&gt;</span> <span class="fu">fromInteger</span> <span class="op">***</span> <span class="fu">fromInteger</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> n <span class="op">:%</span> d <span class="ot">&lt;-</span> (unRatio <span class="ot">-&gt;</span> (n,d))</span></code></pre></div>
<p>Then, the <code class="sourceCode haskell">probOf</code>
function:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">probOf ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>probOf e <span class="ot">=</span> foldOdds f b <span class="kw">where</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  b x <span class="ot">=</span> fi (e <span class="op">==</span> x) <span class="dv">1</span> <span class="dv">0</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  f x (n<span class="op">:%</span>d) y <span class="ot">=</span> (x <span class="op">*</span> n <span class="op">+</span> y <span class="op">*</span> d) <span class="op">/</span> (n <span class="op">+</span> d)</span></code></pre></div>
<p>This version doesn’t have the option for short-circuiting on the
first value it finds.</p>
<p>For generating from lists, you can try to evenly divide the list
among each branch.</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">fromListOdds ::</span> (([b], <span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Integer</span>) <span class="ot">-&gt;</span> (b <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Odds</span> a)</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>fromListOdds fr e <span class="ot">=</span> r <span class="kw">where</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  r [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  r xs <span class="ot">=</span> <span class="dt">Just</span> (unfoldOdds f (xs, <span class="fu">length</span> xs))</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  f ([x],_) <span class="ot">=</span> <span class="dt">Left</span> (e x)</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  f (xs ,n) <span class="ot">=</span> <span class="dt">Right</span> ((ys,l), fr (ys,l) <span class="op">%</span> fr (zs,r), (zs,r)) <span class="kw">where</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    l <span class="ot">=</span> n <span class="ot">`div`</span> <span class="dv">2</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    r <span class="ot">=</span> n <span class="op">-</span> l</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    (ys,zs) <span class="ot">=</span> <span class="fu">splitAt</span> l xs</span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="ot">equalOdds ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Odds</span> a)</span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>equalOdds <span class="ot">=</span> fromListOdds (<span class="fu">fromIntegral</span> <span class="op">.</span> <span class="fu">snd</span>) <span class="fu">id</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a><span class="ot">fromDistrib ::</span> [(a,<span class="dt">Integer</span>)] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Odds</span> a)</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>fromDistrib <span class="ot">=</span> fromListOdds (<span class="fu">sum</span> <span class="op">.</span> <span class="fu">map</span> <span class="fu">snd</span> <span class="op">.</span> <span class="fu">fst</span>) <span class="fu">fst</span></span></code></pre></div>
<p>What’s really nice about this version is the fact that the old <code
class="sourceCode haskell">append</code> is just the <code
class="sourceCode haskell"><span class="dt">Choice</span></code>
constructor, leaving the instances to be really nice:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">flatten ::</span> <span class="dt">Odds</span> (<span class="dt">Odds</span> a) <span class="ot">-&gt;</span> <span class="dt">Odds</span> a</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>flatten <span class="ot">=</span> foldOdds <span class="dt">Choice</span> <span class="fu">id</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Odds</span> <span class="kw">where</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Certain</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  fs <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> flatten (<span class="fu">fmap</span> (<span class="op">&lt;$&gt;</span> xs) fs)</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Odds</span> <span class="kw">where</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> flatten (f <span class="op">&lt;$&gt;</span> x)</span></code></pre></div>
<p>Finally, as a bonus, to remove duplicates:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">lcd ::</span> <span class="dt">Foldable</span> f <span class="ot">=&gt;</span> f <span class="dt">Rational</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>lcd <span class="ot">=</span> foldl&#39; (\a e <span class="ot">-&gt;</span> <span class="fu">lcm</span> a (<span class="fu">denominator</span> e)) <span class="dv">1</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="ot">toDistrib ::</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> [(a,<span class="dt">Integer</span>)]</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>toDistrib <span class="ot">=</span> factorOut <span class="op">.</span> foldOdds f b <span class="kw">where</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>  b x <span class="ot">=</span> [(x,<span class="dv">1</span>)]</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  f l p r <span class="ot">=</span> (<span class="fu">map</span><span class="op">.</span><span class="fu">fmap</span>) (n<span class="op">%</span>t<span class="op">*</span>) l <span class="op">++</span> (<span class="fu">map</span><span class="op">.</span><span class="fu">fmap</span>) (d<span class="op">%</span>t<span class="op">*</span>) r <span class="kw">where</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>    n <span class="ot">=</span> <span class="fu">numerator</span> p</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    d <span class="ot">=</span> <span class="fu">denominator</span> p</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>    t <span class="ot">=</span> n <span class="op">+</span> d</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>  factorOut xs <span class="ot">=</span> (<span class="fu">map</span><span class="op">.</span><span class="fu">fmap</span>) (<span class="fu">numerator</span> <span class="op">.</span> (lcd&#39;<span class="op">*</span>)) xs <span class="kw">where</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>    lcd&#39; <span class="ot">=</span> <span class="fu">fromIntegral</span> <span class="op">.</span> lcd <span class="op">.</span> <span class="fu">map</span> <span class="fu">snd</span> <span class="op">$</span> xs</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a><span class="ot">counts ::</span> (<span class="dt">Ord</span> a, <span class="dt">Num</span> n) <span class="ot">=&gt;</span> [(a,n)] <span class="ot">-&gt;</span> [(a,n)]</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>counts <span class="ot">=</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>  Map.assocs <span class="op">.</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>  Map.fromListWith (<span class="op">+</span>)</span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a><span class="ot">compress ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Odds</span> a</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>compress xs <span class="ot">=</span> <span class="kw">let</span> <span class="dt">Just</span> ys <span class="ot">=</span> (fromDistrib <span class="op">.</span> counts <span class="op">.</span> toDistrib) xs <span class="kw">in</span> ys</span></code></pre></div>
<p>After reading yet more on this, I found that the main issue with the
monad is its performance. Two articles in particular: <span
class="citation" data-cites="larsen_memory_2011">Larsen (<a
href="#ref-larsen_memory_2011" role="doc-biblioref">2011</a>)</span>,
and <span class="citation" data-cites="scibior_practical_2015">Ścibior,
Ghahramani, and Gordon (<a href="#ref-scibior_practical_2015"
role="doc-biblioref">2015</a>)</span>, refer to a GADT implementation of
the monad which maximises laziness.</p>
<hr />
<h2 class="unnumbered" id="references">References</h2>
<div id="refs" class="references csl-bib-body hanging-indent"
data-entry-spacing="0" role="list">
<div id="ref-erwig_functional_2006" class="csl-entry" role="listitem">
Erwig, Martin, and Steve Kollmansberger. 2006. <span>“Functional pearls:
<span>Probabilistic</span> functional programming in
<span>Haskell</span>.”</span> <em>Journal of Functional Programming</em>
16 (1): 21–34. doi:<a
href="https://doi.org/10.1017/S0956796805005721">10.1017/S0956796805005721</a>.
</div>
<div id="ref-kidd_build_2007" class="csl-entry" role="listitem">
Kidd, Eric. 2007. <span>“Build your own probability monads.”</span>
</div>
<div id="ref-larsen_memory_2011" class="csl-entry" role="listitem">
Larsen, Ken Friis. 2011. <span>“Memory <span>Efficient
Implementation</span> of <span>Probability Monads</span>.”</span>
</div>
<div id="ref-scibior_practical_2015" class="csl-entry" role="listitem">
Ścibior, Adam, Zoubin Ghahramani, and Andrew D. Gordon. 2015.
<span>“Practical <span>Probabilistic Programming</span> with
<span>Monads</span>.”</span> In <em>Proceedings of the 2015 <span>ACM
SIGPLAN Symposium</span> on <span>Haskell</span></em>, 50:165–176.
Haskell ’15. New York, NY, USA: <span>ACM</span>. doi:<a
href="https://doi.org/10.1145/2804302.2804317">10.1145/2804302.2804317</a>.
</div>
</div>
]]></description>
    <pubDate>Fri, 30 Sep 2016 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2016-09-30-prob-trees-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Different Probability Monad</title>
    <link>https://doisinkidney.com/posts/2016-09-27-odds-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on September 27, 2016
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Probability&#39;." href="/tags/Probability.html" rel="tag">Probability</a>
    
</div>

<p>One of the more unusual monads is the “probability monad”:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language PatternSynonyms, ViewPatterns #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language DeriveFunctor, DeriveFoldable #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language BangPatterns #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Arrow</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Ratio</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Foldable</span></span></code></pre></div>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Probability</span> a <span class="ot">=</span> <span class="dt">Probability</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> runProb ::</span> [(a,<span class="dt">Rational</span>)] }</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Coin</span> <span class="ot">=</span> <span class="dt">Heads</span> <span class="op">|</span> <span class="dt">Tails</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="ot">toss ::</span> <span class="dt">Probability</span> <span class="dt">Coin</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>toss <span class="ot">=</span> <span class="dt">Probability</span> [(<span class="dt">Heads</span>, <span class="dv">1</span> <span class="op">%</span> <span class="dv">2</span>), (<span class="dt">Tails</span>, <span class="dv">1</span> <span class="op">%</span> <span class="dv">2</span>)]</span></code></pre></div>
<p>Although it’s a little inefficient, it’s an elegant representation.
I’ve written about it before <a
href="2015-08-03-monty-hall.html">here</a>.</p>
<p>It has some notable deficiencies, though. For instance: the user has
to constantly check that all the probabilities add up to one. Its list
can be empty, which doesn’t make sense. Also, individual outcomes can
appear more than once in the same list.</p>
<p>A first go at fixing the problem might look something like this:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Distrib</span> a <span class="ot">=</span> <span class="dt">Distrib</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> runDist ::</span> [(a,<span class="dt">Rational</span>)] }</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">tossProb ::</span> <span class="dt">Distrib</span> <span class="dt">Coin</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>tossProb <span class="ot">=</span> <span class="dt">Distrib</span> [(<span class="dt">Heads</span>, <span class="dv">1</span>), (<span class="dt">Tails</span>, <span class="dv">1</span>)]</span></code></pre></div>
<p>The type is the same as before: it’s the semantics which have
changed. The second field of the tuples no longer have to add up to one.
The list can still be empty, though, and now finding the probability of,
say, the head, looks like this:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">probHead ::</span> <span class="dt">Distrib</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>probHead (<span class="dt">Distrib</span> xs<span class="op">@</span>((_,p)<span class="op">:</span>_)) <span class="ot">=</span> p <span class="op">/</span> <span class="fu">sum</span> [ q <span class="op">|</span> (_,q) <span class="ot">&lt;-</span> xs ]</span></code></pre></div>
<p>Infinite lists aren’t possible, either.</p>
<p>One other way to look at the problem is to mimic the structure of
cons-lists. Something like this:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Odds</span> a <span class="ot">=</span> <span class="dt">Certainly</span> a</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>            <span class="op">|</span> <span class="dt">Odds</span> a <span class="dt">Rational</span> (<span class="dt">Odds</span> a)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>            <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Functor</span>, <span class="dt">Foldable</span>, <span class="dt">Show</span>)</span></code></pre></div>
<p>Here, the <code
class="sourceCode haskell"><span class="dt">Odds</span></code>
constructor (analogous to <code
class="sourceCode haskell">(<span class="op">:</span>)</code>) contains
the betting-style odds of the head element vs. <em>the rest of the
list</em>. The coin from before is represented by:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">tossOdds ::</span> <span class="dt">Odds</span> <span class="dt">Coin</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>tossOdds <span class="ot">=</span> <span class="dt">Odds</span> <span class="dt">Heads</span> (<span class="dv">1</span> <span class="op">%</span> <span class="dv">1</span>) (<span class="dt">Certainly</span> <span class="dt">Tails</span>)</span></code></pre></div>
<p>This representation has tons of nice properties. First, let’s use
some pattern-synonym magic for rationals:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span><span class="ot"> (:%) ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="kw">pattern</span> n <span class="op">:%</span> d <span class="ot">&lt;-</span> (<span class="fu">numerator</span> <span class="op">&amp;&amp;&amp;</span> <span class="fu">denominator</span> <span class="ot">-&gt;</span> (n,d)) <span class="kw">where</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  n <span class="op">:%</span> d <span class="ot">=</span> n <span class="op">%</span> d</span></code></pre></div>
<p>Then, finding the probability of the head element is this:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">probHeadOdds ::</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>probHeadOdds (<span class="dt">Certainly</span> _) <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>probHeadOdds (<span class="dt">Odds</span> _ (n <span class="op">:%</span> d) _) <span class="ot">=</span> n <span class="op">:%</span> (n <span class="op">+</span> d)</span></code></pre></div>
<p>The representation can handle infinite lists no problem:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>probHeadOdds (<span class="dt">Odds</span> <span class="ch">&#39;a&#39;</span> (<span class="dv">1</span> <span class="op">:%</span> <span class="dv">1</span>) <span class="fu">undefined</span>)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">%</span> <span class="dv">2</span></span></code></pre></div>
<p>Taking the tail preserves semantics, also. To do some more involved
manipulation, a fold helper is handy:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldOdds ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> b</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>foldOdds f b <span class="ot">=</span> r <span class="kw">where</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  r (<span class="dt">Certainly</span> x) <span class="ot">=</span> b x</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  r (<span class="dt">Odds</span> x p xs) <span class="ot">=</span> f x p (r xs)</span></code></pre></div>
<p>You can use this function to find the probability of a given
item:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">probOfEvent ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>probOfEvent e <span class="ot">=</span> foldOdds f b <span class="kw">where</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  b x <span class="ot">=</span> <span class="kw">if</span> e <span class="op">==</span> x <span class="kw">then</span> <span class="dv">1</span> <span class="kw">else</span> <span class="dv">0</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  f x n r <span class="ot">=</span> (<span class="kw">if</span> e <span class="op">==</span> x <span class="kw">then</span> n <span class="kw">else</span> r) <span class="op">/</span> (n <span class="op">+</span> <span class="dv">1</span>)</span></code></pre></div>
<p>This assumes that each item only occurs once. A function which
combines multiple events might look like this:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">probOf ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>probOf p <span class="ot">=</span> foldOdds f b <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  b x <span class="ot">=</span> <span class="kw">if</span> p x <span class="kw">then</span> <span class="dv">1</span> <span class="kw">else</span> <span class="dv">0</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  f x n r <span class="ot">=</span> (<span class="kw">if</span> p x <span class="kw">then</span> r <span class="op">+</span> n <span class="kw">else</span> r) <span class="op">/</span> (n <span class="op">+</span> <span class="dv">1</span>)</span></code></pre></div>
<p>Some utility functions to create <code
class="sourceCode haskell"><span class="dt">Odds</span></code>:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">equalOdds ::</span> <span class="dt">Foldable</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Odds</span> a)</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>equalOdds xs <span class="ot">=</span> <span class="kw">case</span> <span class="fu">length</span> xs <span class="kw">of</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="dv">0</span> <span class="ot">-&gt;</span> <span class="dt">Nothing</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  n <span class="ot">-&gt;</span> <span class="dt">Just</span> (<span class="fu">foldr</span> f <span class="fu">undefined</span> xs (n <span class="op">-</span> <span class="dv">1</span>)) <span class="kw">where</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    f y a <span class="dv">0</span> <span class="ot">=</span> <span class="dt">Certainly</span> y</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>    f y a n <span class="ot">=</span> <span class="dt">Odds</span> y (<span class="dv">1</span> <span class="op">%</span> <span class="fu">fromIntegral</span> n) (a (n <span class="op">-</span> <span class="dv">1</span>))</span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a><span class="ot">fromDistrib ::</span> [(a,<span class="dt">Integer</span>)] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Odds</span> a)</span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>fromDistrib [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>fromDistrib xs <span class="ot">=</span> <span class="dt">Just</span> <span class="op">$</span> f (tot<span class="op">*</span>lst) xs <span class="kw">where</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>  (tot,lst) <span class="ot">=</span> foldl&#39; (\(<span class="op">!</span>t,_) e <span class="ot">-&gt;</span> (t<span class="op">+</span>e,e)) (<span class="dv">0</span>,<span class="fu">undefined</span>) (<span class="fu">map</span> <span class="fu">snd</span> xs)</span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>  f _ [(x,_)] <span class="ot">=</span> <span class="dt">Certainly</span> x</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>  f n ((x,p)<span class="op">:</span>xs) <span class="ot">=</span> <span class="dt">Odds</span> x (mp <span class="op">%</span> np) (f np xs) <span class="kw">where</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>    mp <span class="ot">=</span> p <span class="op">*</span> lst</span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a>    np <span class="ot">=</span> n <span class="op">-</span> mp</span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a><span class="ot">probOfEach ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>probOfEach x xs <span class="ot">=</span> probOf (x<span class="op">==</span>) xs</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a><span class="ot">propOf ::</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Rational</span></span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a>propOf _ [] <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a>propOf x xs <span class="ot">=</span> <span class="dt">Just</span> <span class="op">.</span> <span class="fu">uncurry</span> (<span class="op">%</span>) <span class="op">$</span></span>
<span id="cb13-23"><a href="#cb13-23" aria-hidden="true" tabindex="-1"></a>  foldl&#39; (\(<span class="op">!</span>n,<span class="op">!</span>m) e <span class="ot">-&gt;</span> (<span class="kw">if</span> x <span class="op">==</span> e <span class="kw">then</span> n<span class="op">+</span><span class="dv">1</span> <span class="kw">else</span> n, m<span class="op">+</span><span class="dv">1</span>)) (<span class="dv">0</span>,<span class="dv">0</span>) xs</span></code></pre></div>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell literate prop"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>propOf x xs <span class="op">==</span> <span class="fu">fmap</span> (probOfEach x) (equalOdds xs)</span></code></pre></div>
<p>And finally, the instances:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="ot">append ::</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Rational</span> <span class="ot">-&gt;</span> <span class="dt">Odds</span> a <span class="ot">-&gt;</span> <span class="dt">Odds</span> a</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>append <span class="ot">=</span> foldOdds f <span class="dt">Odds</span> <span class="kw">where</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  f e r a p ys <span class="ot">=</span> <span class="dt">Odds</span> e ip (a op ys) <span class="kw">where</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    ip <span class="ot">=</span> p <span class="op">*</span> r <span class="op">/</span> (p <span class="op">+</span> r <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    op <span class="ot">=</span> p <span class="op">/</span> (r <span class="op">+</span> <span class="dv">1</span>)</span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a><span class="ot">flatten ::</span> <span class="dt">Odds</span> (<span class="dt">Odds</span> a) <span class="ot">-&gt;</span> <span class="dt">Odds</span> a</span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>flatten <span class="ot">=</span> foldOdds append <span class="fu">id</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Applicative</span> <span class="dt">Odds</span> <span class="kw">where</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">pure</span> <span class="ot">=</span> <span class="dt">Certainly</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>  fs <span class="op">&lt;*&gt;</span> xs <span class="ot">=</span> flatten (<span class="fu">fmap</span> (<span class="op">&lt;$&gt;</span> xs) fs)</span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Odds</span> <span class="kw">where</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>  x <span class="op">&gt;&gt;=</span> f <span class="ot">=</span> flatten (f <span class="op">&lt;$&gt;</span> x)</span></code></pre></div>
]]></description>
    <pubDate>Tue, 27 Sep 2016 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2016-09-27-odds-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Revisiting a Trie in Haskell</title>
    <link>https://doisinkidney.com/posts/2016-09-26-revisiting-trie-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on September 26, 2016
</div>
<div class="info">
    
        Part 2 of a <a href="/series/tries.html">2-part series on tries</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Data Structures&#39;." href="/tags/Data%20Structures.html" rel="tag">Data Structures</a>
    
</div>

<h1 id="conforming-to-foldable">Conforming to Foldable</h1>
<p>When I ended the last post, I had a nice <code
class="sourceCode haskell"><span class="dt">Trie</span></code> datatype,
with plenty of functions, but I couldn’t get it to conform to the
standard Haskell classes. The problem was to do with the type variables
in the Trie:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language GADTs, FlexibleInstances, TypeFamilies #-}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language DeriveFoldable, DeriveFunctor, DeriveTraversable #-}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ot">{-# language FunctionalDependencies, FlexibleInstances #-}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Tries</span> <span class="kw">where</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map.Strict</span> <span class="kw">as</span> <span class="dt">Map</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Map.Strict</span> (<span class="dt">Map</span>)</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Foldable</span> <span class="kw">hiding</span> (toList)</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> (lookup)</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Monoid</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">GHC.Exts</span> (<span class="dt">IsList</span>(..))</span></code></pre></div>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">OldTrie</span> a <span class="ot">=</span> <span class="dt">OldTrie</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> otEndHere  ::</span> <span class="dt">Bool</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> otChildren ::</span> <span class="dt">Map</span> a (<span class="dt">OldTrie</span> a) }</span></code></pre></div>
<p>Although the type variable is <code
class="sourceCode haskell">a</code>, the trie really contains
<em>lists</em> of <code class="sourceCode haskell">a</code>s. At least,
that’s what’s reflected in functions like <code
class="sourceCode haskell">insert</code>, <code
class="sourceCode haskell">member</code>, etc.:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">member ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Ord</span> a) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">OldTrie</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>member <span class="ot">=</span> <span class="fu">foldr</span> f otEndHere <span class="kw">where</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> <span class="fu">maybe</span> <span class="dt">False</span> a <span class="op">.</span> Map.lookup e <span class="op">.</span> otChildren</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="ot">otInsert ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Ord</span> a) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">OldTrie</span> a <span class="ot">-&gt;</span> <span class="dt">OldTrie</span> a</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>otInsert <span class="ot">=</span> <span class="fu">foldr</span> f b <span class="kw">where</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>  b (<span class="dt">OldTrie</span> _ c) <span class="ot">=</span> <span class="dt">OldTrie</span> <span class="dt">True</span> c</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>  f e a (<span class="dt">OldTrie</span> n c) <span class="ot">=</span> <span class="dt">OldTrie</span> n (Map.alter (<span class="dt">Just</span> <span class="op">.</span> a <span class="op">.</span> fold) e c)</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">OldTrie</span> a) <span class="kw">where</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">OldTrie</span> <span class="dt">False</span> <span class="fu">mempty</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>  <span class="dt">OldTrie</span> v c <span class="ot">`mappend`</span> <span class="dt">OldTrie</span> t d <span class="ot">=</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="dt">OldTrie</span> (v <span class="op">||</span> t) (Map.unionWith (<span class="op">&lt;&gt;</span>) c d)</span></code></pre></div>
<p>Realistically, the type which the trie contains is more like:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Foldable</span> f <span class="ot">=&gt;</span> <span class="dt">Trie</span> (f a)</span></code></pre></div>
<p>That signature strongly hints at GADTs, as was indicated by <a
href="http://stackoverflow.com/questions/33469157/foldable-instance-for-a-trie-set">this
stackoverflow answer</a>. The particular GADT which is applicable here
is this:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">TrieSet</span> a <span class="kw">where</span> <span class="dt">TrieSet</span><span class="ot"> ::</span> <span class="dt">Bool</span> <span class="ot">-&gt;</span> <span class="dt">Map</span> a (<span class="dt">TrieSet</span> [a]) <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> [a]</span></code></pre></div>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">tsEndHere ::</span> <span class="dt">TrieSet</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>tsEndHere (<span class="dt">TrieSet</span> e _) <span class="ot">=</span> e</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="ot">tsChildren ::</span> <span class="dt">TrieSet</span> [a] <span class="ot">-&gt;</span> <span class="dt">Map</span> a (<span class="dt">TrieSet</span> [a])</span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>tsChildren (<span class="dt">TrieSet</span> _ c) <span class="ot">=</span> c</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="ot">tsInsert ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Ord</span> a) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> [a] <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> [a]</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>tsInsert <span class="ot">=</span> <span class="fu">foldr</span> f b <span class="kw">where</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="ot">  b ::</span> <span class="dt">TrieSet</span> [a] <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> [a]</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="ot">  f ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> (<span class="dt">TrieSet</span> [a] <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> [a]) <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> [a] <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> [a]</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a>  b (<span class="dt">TrieSet</span> _ c) <span class="ot">=</span> <span class="dt">TrieSet</span> <span class="dt">True</span> c</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a>  f e a (<span class="dt">TrieSet</span> n c) <span class="ot">=</span> <span class="dt">TrieSet</span> n (Map.alter (<span class="dt">Just</span> <span class="op">.</span> a <span class="op">.</span> fold) e c)</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">TrieSet</span> [a]) <span class="kw">where</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">TrieSet</span> <span class="dt">False</span> Map.empty</span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a>  <span class="dt">TrieSet</span> v c <span class="ot">`mappend`</span> <span class="dt">TrieSet</span> t d <span class="ot">=</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a>    <span class="dt">TrieSet</span> (v <span class="op">||</span> t) (Map.unionWith (<span class="op">&lt;&gt;</span>) c d)</span></code></pre></div>
<p>Why lists and not a general <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>?
Well, for the particular use I had in mind (conforming to the <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>
typeclass), I need <code
class="sourceCode haskell">(<span class="op">:</span>)</code>.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Foldable</span> <span class="dt">TrieSet</span> <span class="kw">where</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">foldr</span> f b (<span class="dt">TrieSet</span> e c) <span class="ot">=</span> <span class="kw">if</span> e <span class="kw">then</span> f [] r <span class="kw">else</span> r <span class="kw">where</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    r <span class="ot">=</span> Map.foldrWithKey (<span class="fu">flip</span> <span class="op">.</span> g <span class="op">.</span> (<span class="op">:</span>)) b c</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    g k <span class="ot">=</span> <span class="fu">foldr</span> (f <span class="op">.</span> k)</span></code></pre></div>
<p>With some more helper functions, the interface becomes pretty
nice:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span> <span class="dt">Show</span> (<span class="dt">TrieSet</span> [a]) <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">showsPrec</span> d t <span class="ot">=</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">showParen</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>      (d <span class="op">&gt;</span> <span class="dv">10</span>)</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>      (<span class="fu">showString</span> <span class="st">&quot;fromList &quot;</span> <span class="op">.</span> <span class="fu">shows</span> (<span class="fu">foldr</span> (<span class="op">:</span>) [] t))</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">IsList</span> (<span class="dt">TrieSet</span> [a]) <span class="kw">where</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> <span class="dt">Item</span> (<span class="dt">TrieSet</span> [a]) <span class="ot">=</span> [a]</span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>  fromList <span class="ot">=</span> <span class="fu">foldr</span> tsInsert <span class="fu">mempty</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>  toList <span class="ot">=</span> <span class="fu">foldr</span> (<span class="op">:</span>) []</span></code></pre></div>
<p>The trie has the side-effect of lexicographically sorting what it’s
given:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell literate example hidden_source"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="op">:</span>set <span class="op">-</span><span class="dt">XGADTs</span></span></code></pre></div>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>fromList [<span class="st">&quot;ced&quot;</span>, <span class="st">&quot;abc&quot;</span>, <span class="st">&quot;ced&quot;</span>, <span class="st">&quot;cb&quot;</span>, <span class="st">&quot;ab&quot;</span>]<span class="ot"> ::</span> <span class="dt">TrieSet</span> <span class="dt">String</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>fromList [<span class="st">&quot;ab&quot;</span>,<span class="st">&quot;abc&quot;</span>,<span class="st">&quot;cb&quot;</span>,<span class="st">&quot;ced&quot;</span>]</span></code></pre></div>
<h1 id="further-generalizing">Further Generalizing</h1>
<p>Most implementations of tries that I’ve seen are map-like data
structures, rather than set-like. In other words, instead of holding a
<code class="sourceCode haskell"><span class="dt">Bool</span></code> at
the value position, it holds a <code
class="sourceCode haskell"><span class="dt">Maybe</span></code>
something.</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Trie</span> a b <span class="ot">=</span> <span class="dt">Trie</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  {<span class="ot"> endHere  ::</span> b</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  ,<span class="ot"> children ::</span> <span class="dt">Map</span> a (<span class="dt">Trie</span> a b)</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  } <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Ord</span>, <span class="dt">Show</span>, <span class="dt">Functor</span>, <span class="dt">Foldable</span>, <span class="dt">Traversable</span>)</span></code></pre></div>
<p>This is a much more straightforward datatype. <code
class="sourceCode haskell"><span class="dt">Foldable</span></code> can
even be automatically derived.</p>
<p>However, I haven’t made the <code
class="sourceCode haskell">endHere</code> field a <code
class="sourceCode haskell"><span class="dt">Maybe</span> a</code>. I
want to be able to write something like this:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">TrieSet</span> [a] <span class="ot">=</span> <span class="dt">Trie</span> a <span class="dt">Bool</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">TrieMap</span> a b <span class="ot">=</span> <span class="dt">Trie</span> a (<span class="dt">Maybe</span> b)</span></code></pre></div>
<p>And have it automatically choose the implementation of the functions
I need<a href="#fn1" class="footnote-ref" id="fnref1"
role="doc-noteref"><sup>1</sup></a>.</p>
<p>To do that, though, I’ll need to write the base functions, agnostic
of the type of <code>b</code>. I <em>can</em> rely on something like
<code class="sourceCode haskell"><span class="dt">Monoid</span></code>,
though:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Ord</span> a, <span class="dt">Monoid</span> b) <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Trie</span> a b) <span class="kw">where</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Trie</span> <span class="fu">mempty</span> Map.empty</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mappend</span> (<span class="dt">Trie</span> v k) (<span class="dt">Trie</span> t l) <span class="ot">=</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Trie</span> (v <span class="op">&lt;&gt;</span> t) (Map.unionWith (<span class="op">&lt;&gt;</span>) k l)</span></code></pre></div>
<p>In fact, quite a lot of functions naturally lend themselves to this
fold + monoid style:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> (<span class="dt">Ord</span> a, <span class="dt">Monoid</span> b, <span class="dt">Foldable</span> f)</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a b <span class="ot">-&gt;</span> b</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span> <span class="ot">=</span> <span class="fu">foldr</span> f endHere <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> <span class="fu">foldMap</span> a <span class="op">.</span> Map.lookup e <span class="op">.</span> children</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a><span class="ot">insert&#39; ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Ord</span> a, <span class="dt">Monoid</span> b)</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Trie</span> a b <span class="ot">-&gt;</span> <span class="dt">Trie</span> a b</span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>insert&#39; xs v <span class="ot">=</span> <span class="fu">foldr</span> f b xs <span class="kw">where</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>  b (<span class="dt">Trie</span> p c) <span class="ot">=</span> <span class="dt">Trie</span> (v <span class="op">&lt;&gt;</span> p) c</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  f e a (<span class="dt">Trie</span> n c) <span class="ot">=</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Trie</span> n (Map.alter (<span class="dt">Just</span> <span class="op">.</span> a <span class="op">.</span> fold) e c)</span></code></pre></div>
<p>A monoid is needed for the values, though, and neither <code
class="sourceCode haskell"><span class="dt">Bool</span></code> nor <code
class="sourceCode haskell">∀ a<span class="op">.</span> <span class="dt">Maybe</span> a</code>
conform to <code
class="sourceCode haskell"><span class="dt">Monoid</span></code>.
Looking back to the implementation of the trie-set, the <code
class="sourceCode haskell">(<span class="op">||</span>)</code> function
has been replaced by <code
class="sourceCode haskell"><span class="fu">mappend</span></code>. There
<em>is</em> a newtype wrapper in <code
class="sourceCode haskell"><span class="dt">Data.Monoid</span></code>
which has exactly this behaviour, though: <code
class="sourceCode haskell"><span class="dt">Any</span></code>.</p>
<p>Using that, the type signatures specialize to:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">TrieSet</span> a <span class="ot">=</span> <span class="dt">Trie</span> a <span class="dt">Any</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> a <span class="ot">-&gt;</span> <span class="dt">Any</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Any</span> <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> a <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> a</span></code></pre></div>
<p>Similarly, for <code
class="sourceCode haskell"><span class="dt">Maybe</span></code>, there’s
both <code
class="sourceCode haskell"><span class="dt">First</span></code> and
<code class="sourceCode haskell"><span class="dt">Last</span></code>.
They have the behaviour:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell literate prop"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="dt">First</span> (<span class="dt">Just</span> x) <span class="op">&lt;&gt;</span> <span class="dt">First</span> (<span class="dt">Just</span> y) <span class="op">==</span> <span class="dt">First</span> (<span class="dt">Just</span> x)</span></code></pre></div>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell literate prop"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Last</span>  (<span class="dt">Just</span> x) <span class="op">&lt;&gt;</span> <span class="dt">Last</span>  (<span class="dt">Just</span> y) <span class="op">==</span> <span class="dt">Last</span>  (<span class="dt">Just</span> y)</span></code></pre></div>
<p>I think it makes more sense for a value inserted into a map to
overwrite whatever was there before. Since the newer value is on the
left in the <code
class="sourceCode haskell"><span class="fu">mappend</span></code>, then,
<code class="sourceCode haskell"><span class="dt">First</span></code>
makes most sense.</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">TrieMap</span> a b <span class="ot">=</span> <span class="dt">Trie</span> a (<span class="dt">First</span> b)</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">TrieMap</span> a b <span class="ot">-&gt;</span> <span class="dt">First</span> b</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">First</span> b <span class="ot">-&gt;</span> <span class="dt">TrieMap</span> a b <span class="ot">-&gt;</span> <span class="dt">TrieMap</span> a b</span></code></pre></div>
<p>There are some other ways that you can interpret the monoid. For
instance, subbing in <code
class="sourceCode haskell"><span class="dt">Sum</span> <span class="dt">Int</span></code>
gives you a bag-like trie:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">TrieBag</span> a <span class="ot">=</span> <span class="dt">Trie</span> a (<span class="dt">Sum</span> <span class="dt">Int</span>)</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">TrieBag</span> a <span class="ot">-&gt;</span> <span class="dt">Sum</span> <span class="dt">Int</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Sum</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">TrieBag</span> a <span class="ot">-&gt;</span> <span class="dt">TrieBag</span> a</span></code></pre></div>
<p>This is a set which can store multiple copies of each member. Turned
the other way around, a map which stores many values for each key looks
like this:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">TrieBin</span> a b <span class="ot">=</span> <span class="dt">Trie</span> a [b]</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a><span class="fu">lookup</span><span class="ot"> ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">TrieBin</span> a b <span class="ot">-&gt;</span> [b]</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> <span class="dt">TrieBin</span> a b <span class="ot">-&gt;</span> <span class="dt">TrieBin</span> a b</span></code></pre></div>
<p>This method so far isn’t really satisfying, though. Really, the <code
class="sourceCode haskell">insert</code> signatures should look like
this:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">TrieMap</span> a b <span class="ot">-&gt;</span> <span class="dt">TrieMap</span> a b</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">TrieBin</span> a b <span class="ot">-&gt;</span> <span class="dt">TrieBin</span> a b</span></code></pre></div>
<p>Modifying insert slightly, you can get exactly that:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Ord</span> a, <span class="dt">Applicative</span> c, <span class="dt">Monoid</span> (c b))</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Trie</span> a (c b) <span class="ot">-&gt;</span> <span class="dt">Trie</span> a (c b)</span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>insert xs v <span class="ot">=</span> <span class="fu">foldr</span> f b xs <span class="kw">where</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>  b (<span class="dt">Trie</span> p c) <span class="ot">=</span> <span class="dt">Trie</span> (<span class="fu">pure</span> v <span class="op">&lt;&gt;</span> p) c</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>  f e a (<span class="dt">Trie</span> n c) <span class="ot">=</span> <span class="dt">Trie</span> n (Map.alter (<span class="dt">Just</span> <span class="op">.</span> a <span class="op">.</span> fold) e c)</span></code></pre></div>
<p><code class="sourceCode haskell"><span class="fu">pure</span></code>
from <code
class="sourceCode haskell"><span class="dt">Applicative</span></code> is
needed for the “embedding”.</p>
<p>Similarly, the “inserting” for the set-like types isn’t really right.
The value argument is out of place. This should be the signature:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> a <span class="ot">-&gt;</span> <span class="dt">TrieSet</span> a</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> (<span class="dt">Ord</span> a, <span class="dt">Foldable</span> f)</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">TrieBin</span> a <span class="ot">-&gt;</span> <span class="dt">TrieBin</span> a</span></code></pre></div>
<p>In particular, while we have an “empty” thing (0, False) for monoids,
we need a “one” thing (1, True) for this function. A semiring<a
href="#fn2" class="footnote-ref" id="fnref2"
role="doc-noteref"><sup>2</sup></a> gives this exact method:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span> <span class="dt">Semiring</span> a <span class="kw">where</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="ot">  one ::</span> a</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  mul ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Semiring</span> (<span class="dt">Sum</span> a) <span class="kw">where</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dv">1</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  mul <span class="ot">=</span> (<span class="op">*</span>)</span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Semiring</span> <span class="dt">Any</span> <span class="kw">where</span></span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>  one <span class="ot">=</span> <span class="dt">Any</span> <span class="dt">True</span></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Any</span> x <span class="ot">`mul`</span> <span class="dt">Any</span> y <span class="ot">=</span> <span class="dt">Any</span> (x <span class="op">&amp;&amp;</span> y)</span></code></pre></div>
<p>This class is kind of like a combination of both monoid wrappers for
both <code class="sourceCode haskell"><span class="dt">Int</span></code>
and <code
class="sourceCode haskell"><span class="dt">Bool</span></code>. You
could take advantage of that:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (<span class="dt">Monoid</span> add, <span class="dt">Monoid</span> mult)</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=&gt;</span> <span class="dt">SemiringIso</span> a add mult <span class="op">|</span> a <span class="ot">-&gt;</span> add, a <span class="ot">-&gt;</span> mult <span class="kw">where</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    toAdd    ::</span> a <span class="ot">-&gt;</span> add</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a><span class="ot">    fromAdd  ::</span> add <span class="ot">-&gt;</span> a</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a><span class="ot">    toMult   ::</span> a <span class="ot">-&gt;</span> mult</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a><span class="ot">    fromMult ::</span> mult <span class="ot">-&gt;</span> a</span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a>(<span class="op">&lt;+&gt;</span>),<span class="ot"> (&lt;.&gt;) ::</span> <span class="dt">SemiringIso</span> a add mult <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-11"><a href="#cb25-11" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;+&gt;</span> y <span class="ot">=</span> fromAdd  (toAdd  x <span class="op">&lt;&gt;</span> toAdd  y)</span>
<span id="cb25-12"><a href="#cb25-12" aria-hidden="true" tabindex="-1"></a>x <span class="op">&lt;.&gt;</span> y <span class="ot">=</span> fromMult (toMult x <span class="op">&lt;&gt;</span> toMult y)</span>
<span id="cb25-13"><a href="#cb25-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-14"><a href="#cb25-14" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">SemiringIso</span> <span class="dt">Int</span> (<span class="dt">Sum</span> <span class="dt">Int</span>) (<span class="dt">Product</span> <span class="dt">Int</span>) <span class="kw">where</span></span>
<span id="cb25-15"><a href="#cb25-15" aria-hidden="true" tabindex="-1"></a>  toAdd    <span class="ot">=</span> <span class="dt">Sum</span></span>
<span id="cb25-16"><a href="#cb25-16" aria-hidden="true" tabindex="-1"></a>  fromAdd  <span class="ot">=</span> getSum</span>
<span id="cb25-17"><a href="#cb25-17" aria-hidden="true" tabindex="-1"></a>  toMult   <span class="ot">=</span> <span class="dt">Product</span></span>
<span id="cb25-18"><a href="#cb25-18" aria-hidden="true" tabindex="-1"></a>  fromMult <span class="ot">=</span> getProduct</span>
<span id="cb25-19"><a href="#cb25-19" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-20"><a href="#cb25-20" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">SemiringIso</span> <span class="dt">Bool</span> <span class="dt">Any</span> <span class="dt">All</span> <span class="kw">where</span></span>
<span id="cb25-21"><a href="#cb25-21" aria-hidden="true" tabindex="-1"></a>  toAdd    <span class="ot">=</span> <span class="dt">Any</span></span>
<span id="cb25-22"><a href="#cb25-22" aria-hidden="true" tabindex="-1"></a>  fromAdd  <span class="ot">=</span> getAny</span>
<span id="cb25-23"><a href="#cb25-23" aria-hidden="true" tabindex="-1"></a>  toMult   <span class="ot">=</span> <span class="dt">All</span></span>
<span id="cb25-24"><a href="#cb25-24" aria-hidden="true" tabindex="-1"></a>  fromMult <span class="ot">=</span> getAll</span></code></pre></div>
<p>But it seems like overkill.</p>
<p>Anyway, assuming that we have the functions from <code
class="sourceCode haskell"><span class="dt">Semiring</span></code>,
here’s the <code>add</code> function:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="ot">add ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Ord</span> a, <span class="dt">Semiring</span> b)</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a b <span class="ot">-&gt;</span> <span class="dt">Trie</span> a b</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>add xs <span class="ot">=</span> <span class="fu">foldr</span> f b xs <span class="kw">where</span></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>  b (<span class="dt">Trie</span> p c) <span class="ot">=</span> <span class="dt">Trie</span> (one <span class="op">&lt;&gt;</span> p) c</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>  f e a (<span class="dt">Trie</span> n c) <span class="ot">=</span></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Trie</span> n (Map.alter (<span class="dt">Just</span> <span class="op">.</span> a <span class="op">.</span> fold) e c)</span></code></pre></div>
<p>Now, expressions can be built up without specifying the specific
monoid implementation, and the whole behaviour can be changed with a
type signature:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> (<span class="dt">Ord</span> a, <span class="dt">Semiring</span> b) <span class="ot">=&gt;</span> <span class="dt">IsList</span> (<span class="dt">Trie</span> a b) <span class="kw">where</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> <span class="dt">Item</span> (<span class="dt">Trie</span> a b) <span class="ot">=</span> [a]</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>  fromList <span class="ot">=</span> <span class="fu">foldr</span> add <span class="fu">mempty</span></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>  toList <span class="ot">=</span> <span class="fu">undefined</span></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a><span class="ot">ans ::</span> <span class="dt">Semiring</span> b <span class="ot">=&gt;</span> b</span></code></pre></div>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>ans <span class="ot">=</span> <span class="fu">lookup</span> <span class="st">&quot;abc&quot;</span> (fromList [<span class="st">&quot;abc&quot;</span>, <span class="st">&quot;def&quot;</span>, <span class="st">&quot;abc&quot;</span>, <span class="st">&quot;ghi&quot;</span>])</span></code></pre></div>
<div class="sourceCode" id="cb29"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a><span class="ot">ans ::</span> <span class="dt">Sum</span> <span class="dt">Int</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Sum</span> {getSum <span class="ot">=</span> <span class="dv">2</span>}</span></code></pre></div>
<div class="sourceCode" id="cb30"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a><span class="ot">ans ::</span> <span class="dt">Any</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Any</span> {getAny <span class="ot">=</span> <span class="dt">True</span>}</span></code></pre></div>
<p>Slightly fuller implementations of all of these are available <a
href="https://github.com/oisdk/hstrie">here</a>.</p>
<section id="footnotes" class="footnotes footnotes-end-of-document"
role="doc-endnotes">
<hr />
<ol>
<li id="fn1"><p>Kind of like <a
href="https://www.youtube.com/watch?v=3U3lV5VPmOU">program inference in
lieu of type inference</a><a href="#fnref1" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
<li id="fn2"><p>This isn’t really a very good definition of semiring.
While Haskell doesn’t have this class in base, <a
href="https://github.com/purescript/purescript-prelude/blob/master/src/Data/Semiring.purs">Purescript
has it in their prelude.</a><a href="#fnref2" class="footnote-back"
role="doc-backlink">↩︎</a></p></li>
</ol>
</section>
]]></description>
    <pubDate>Mon, 26 Sep 2016 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2016-09-26-revisiting-trie-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Lenses are Static Selectors</title>
    <link>https://doisinkidney.com/posts/2016-06-16-lenses-are-static-selectors.html</link>
    <description><![CDATA[<div class="info">
    Posted on June 16, 2016
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Swift&#39;." href="/tags/Swift.html" rel="tag">Swift</a>
    
</div>

<p>So I don’t really know what <a
href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueCoding/Articles/KeyValueCoding.html">KVC</a>
is, or much about <code class="sourceCode scala">performSelector</code>
functions. <a
href="http://inessential.com/2016/05/20/updating_local_objects_with_server_objec">This</a>
blogpost, from Brent Simmons, let me know a little bit about why I would
want to use them.</p>
<p>It centred around removing code repetition of this type:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> localObject<span class="op">.</span>foo <span class="op">!=</span> serverObject<span class="op">.</span>foo <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  localObject<span class="op">.</span>foo <span class="op">=</span> serverObject<span class="op">.</span>foo</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> localObject<span class="op">.</span>bar <span class="op">!=</span> serverObject<span class="op">.</span>bar <span class="op">{</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  localObject<span class="op">.</span>bar <span class="op">=</span> serverObject<span class="op">.</span>bar <span class="co">// There was an (intentional)</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span>                                    <span class="co">// bug here in the original post</span></span></code></pre></div>
<p>To clean up the code, Brent used selector methods. At first, I was a
little uncomfortable with the solution. As far as I could tell, the
basis of a lot of this machinery used functions with types like
this:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>func <span class="fu">get</span><span class="op">(</span>fromSelector<span class="op">:</span> <span class="ex">String</span><span class="op">)</span> <span class="op">-&gt;</span> AnyObject<span class="op">?</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>func <span class="fu">set</span><span class="op">(</span>forSelector<span class="op">:</span> <span class="ex">String</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="op">()</span></span></code></pre></div>
<p>Which <em>seems</em> to be extremely dynamic. Stringly-typed and all
that. Except that there are two different things going on here. One is
the dynamic stuff; the ability to get rid of types when you need to. The
other, though, has <em>nothing</em> to do with types. The other idea is
being able to pass around something which can access the property (or
method) of an object. Let’s look at the code that was being
repeated:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> localObject<span class="op">.</span>foo <span class="op">!=</span> serverObject<span class="op">.</span>foo <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  localObject<span class="op">.</span>foo <span class="op">=</span> serverObject<span class="op">.</span>foo</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> localObject<span class="op">.</span>bar <span class="op">!=</span> serverObject<span class="op">.</span>bar <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  localObject<span class="op">.</span>bar <span class="op">=</span> serverObject<span class="op">.</span>bar</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The logical, obvious thing to do here is try refactor out the common
elements. In fact, the only things that <em>differ</em> between the two
actions above are the <code class="sourceCode scala">foo</code> and
<code class="sourceCode scala">bar</code>. It would be great to be able
to write a function like this:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>func <span class="fu">checkThenUpdate</span><span class="op">(</span>selector<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> localObject<span class="op">.</span>selector <span class="op">!=</span> serverObject<span class="op">.</span>selector <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    localObject<span class="op">.</span>selector <span class="op">=</span> serverObject<span class="op">.</span>selector</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And then maybe a single line like this:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="op">[</span>foo<span class="op">,</span> bar<span class="op">,</span> baz<span class="op">].</span><span class="fu">forEach</span><span class="op">(</span>checkThenUpdate<span class="op">)</span></span></code></pre></div>
<p>That’s pretty obviously better. It’s just good programming: when
faced with repetition, find the repeated part, and abstract it out. Is
it more <em>dynamic</em> than the repetition, though? I don’t think so.
All you have to figure out is an appropriate type for the selector, and
you can keep all of your static checking. To me, it seems a lot like a
<a href="https://hackage.haskell.org/package/lens">lens</a>:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>struct Lens<span class="op">&lt;</span>Whole<span class="op">,</span> Part<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  let get<span class="op">:</span> Whole <span class="op">-&gt;</span> Part</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  let set<span class="op">:</span> <span class="op">(</span>Whole<span class="op">,</span> Part<span class="op">)</span> <span class="op">-&gt;</span> Whole</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>(This is a lens similar to the ones used in the <a
href="http://hackage.haskell.org/package/data-lens">data-lens</a>
library, in contrast to van Laarhoven lenses, or LensFamilies.
LensFamilies are used in the <a
href="https://hackage.haskell.org/package/lens">lens</a> package, and
they allow you to change the type of the <code
class="sourceCode scala">Part</code>. They’re also just normal
functions, rather than a separate type, so you can manipulate them in a
pretty standard way. Swift’s type system isn’t able to model those
lenses, though, unfortunately.) It has two things: a getter and a
setter. The getter is pretty obvious: it takes the object, and returns
the property. The setter is a little more confusing. It’s taking an
object, and the new property you want to stick in to the object, and
returns the object with that property updated. For instance, if we were
to make a <code class="sourceCode scala">Person</code>:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>struct LocalPerson <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> age<span class="op">:</span> <span class="bu">Int</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> name<span class="op">:</span> <span class="ex">String</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>We could then have a lens for the <code
class="sourceCode scala">name</code> field like this:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>let localName<span class="op">:</span> Lens<span class="op">&lt;</span>LocalPerson<span class="op">,</span><span class="ex">String</span><span class="op">&gt;</span> <span class="op">=</span> <span class="fu">Lens</span><span class="op">(</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  get<span class="op">:</span> <span class="op">{</span> p in p<span class="op">.</span>name <span class="op">},</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  set<span class="op">:</span> <span class="op">{</span> <span class="op">(</span>oldPerson<span class="op">,</span>newName<span class="op">)</span> in</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> newPerson <span class="op">=</span> oldPerson</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    newPerson<span class="op">.</span>name <span class="op">=</span> newName</span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> newPerson</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div>
<p>And you’d use it like this:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>let caoimhe <span class="op">=</span> <span class="fu">LocalPerson</span><span class="op">(</span>age<span class="op">:</span> <span class="dv">46</span><span class="op">,</span> name<span class="op">:</span> <span class="st">&quot;caoimhe&quot;</span><span class="op">)</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>localName<span class="op">.</span><span class="fu">get</span><span class="op">(</span>caoimhe<span class="op">)</span> <span class="co">// 46</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>localName<span class="op">.</span><span class="fu">set</span><span class="op">(</span>caoimhe<span class="op">,</span> <span class="st">&quot;breifne&quot;</span><span class="op">)</span> <span class="co">// LocalPerson(age: 46, name: &quot;breifne&quot;)</span></span></code></pre></div>
<p>Straight away, we’re able to do (something) like the <code
class="sourceCode scala">checkThenUpdate</code> function:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>func checkThenUpdate</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">&lt;</span>A<span class="op">:</span> Equatable<span class="op">&gt;</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">(</span>localLens<span class="op">:</span> Lens<span class="op">&lt;</span>LocalPerson<span class="op">,</span>A<span class="op">&gt;,</span> serverLens<span class="op">:</span> Lens<span class="op">&lt;</span>ServerPerson<span class="op">,</span>A<span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  let serverProp <span class="op">=</span> serverLens<span class="op">.</span><span class="fu">get</span><span class="op">(</span>serverObject<span class="op">)</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> localLens<span class="op">.</span><span class="fu">get</span><span class="op">(</span>localObject<span class="op">)</span> <span class="op">!=</span> serverProp <span class="op">{</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    localObject <span class="op">=</span> localLens<span class="op">.</span><span class="fu">set</span><span class="op">(</span>localObject<span class="op">,</span>serverProp<span class="op">)</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And it could be called pretty tersely:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">checkThenUpdate</span><span class="op">(</span>localName<span class="op">,</span> serverLens<span class="op">:</span> serverName<span class="op">)</span></span></code></pre></div>
<p>The biggest problem with this approach, obviously, is the
boilerplate. In Haskell, that’s solved with Template Haskell, so the
lens code is generated for you. (I’d love to see something like that in
Swift) There’s a protocol-oriented spin on lenses, also. One of the
variants on lenses in Haskell are called “classy-lenses”. That’s where,
instead of just generating a lens with the same name as the field it
looks into, you generate a typeclass (protocol) for anything with that
lens. In Swift, it might work something like this:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>struct Place <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> name<span class="op">:</span> <span class="ex">String</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a><span class="co">// Instead of just having a lens for the name field, have a whole protocol</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="co">// for things with a name field:</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>protocol HasName <span class="op">{</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>  associatedtype <span class="ex">Name</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>  static <span class="kw">var</span> name<span class="op">:</span> Lens<span class="op">&lt;</span>Self<span class="op">,</span><span class="ex">Name</span><span class="op">&gt;</span> <span class="op">{</span> get <span class="op">}</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> name<span class="op">:</span> <span class="ex">Name</span> <span class="op">{</span> get set <span class="op">}</span></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true" tabindex="-1"></a><span class="co">// Because the mutable property is included in the protocol, you can rely on</span></span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true" tabindex="-1"></a><span class="co">// it in extensions:</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true" tabindex="-1"></a>extension HasName <span class="op">{</span></span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true" tabindex="-1"></a>  static <span class="kw">var</span> name<span class="op">:</span> Lens<span class="op">&lt;</span>Self<span class="op">,</span><span class="ex">Name</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">Lens</span><span class="op">(</span></span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true" tabindex="-1"></a>      get<span class="op">:</span> <span class="op">{</span>$<span class="fl">0.</span>name<span class="op">},</span></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true" tabindex="-1"></a>      set<span class="op">:</span> <span class="op">{</span> <span class="op">(</span>w<span class="op">,</span>p<span class="op">)</span> in</span>
<span id="cb12-22"><a href="#cb12-22" aria-hidden="true" tabindex="-1"></a>        <span class="kw">var</span> n <span class="op">=</span> w</span>
<span id="cb12-23"><a href="#cb12-23" aria-hidden="true" tabindex="-1"></a>        n<span class="op">.</span>name <span class="op">=</span> p</span>
<span id="cb12-24"><a href="#cb12-24" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> n</span>
<span id="cb12-25"><a href="#cb12-25" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb12-26"><a href="#cb12-26" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="cb12-27"><a href="#cb12-27" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb12-28"><a href="#cb12-28" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> name<span class="op">:</span> <span class="ex">Name</span> <span class="op">{</span></span>
<span id="cb12-29"><a href="#cb12-29" aria-hidden="true" tabindex="-1"></a>    get <span class="op">{</span> <span class="cf">return</span> Self<span class="op">.</span>name<span class="op">.</span><span class="fu">get</span><span class="op">(</span>self<span class="op">)</span> <span class="op">}</span></span>
<span id="cb12-30"><a href="#cb12-30" aria-hidden="true" tabindex="-1"></a>    set <span class="op">{</span> self <span class="op">=</span> Self<span class="op">.</span>name<span class="op">.</span><span class="fu">set</span><span class="op">(</span>self<span class="op">,</span>newValue<span class="op">)</span> <span class="op">}</span></span>
<span id="cb12-31"><a href="#cb12-31" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb12-32"><a href="#cb12-32" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb12-33"><a href="#cb12-33" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-34"><a href="#cb12-34" aria-hidden="true" tabindex="-1"></a><span class="co">// This way, you can provide either the lens or the property, and you get the</span></span>
<span id="cb12-35"><a href="#cb12-35" aria-hidden="true" tabindex="-1"></a><span class="co">// other for free.</span></span>
<span id="cb12-36"><a href="#cb12-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-37"><a href="#cb12-37" aria-hidden="true" tabindex="-1"></a>extension Place<span class="op">:</span> HasName <span class="op">{}</span></span>
<span id="cb12-38"><a href="#cb12-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-39"><a href="#cb12-39" aria-hidden="true" tabindex="-1"></a><span class="co">// Then, you can rely on that protocol, and all of the types:</span></span>
<span id="cb12-40"><a href="#cb12-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-41"><a href="#cb12-41" aria-hidden="true" tabindex="-1"></a>func checkEqualOnNames</span>
<span id="cb12-42"><a href="#cb12-42" aria-hidden="true" tabindex="-1"></a>  <span class="op">&lt;</span>A<span class="op">,</span>B where A<span class="op">:</span> HasName<span class="op">,</span> B<span class="op">:</span> HasName<span class="op">,</span> A<span class="op">.</span><span class="ex">Name</span><span class="op">:</span> Equatable<span class="op">,</span> A<span class="op">.</span><span class="ex">Name</span> <span class="op">==</span> B<span class="op">.</span><span class="ex">Name</span><span class="op">&gt;</span></span>
<span id="cb12-43"><a href="#cb12-43" aria-hidden="true" tabindex="-1"></a>  <span class="op">(</span>x<span class="op">:</span> A<span class="op">,</span> _ y<span class="op">:</span> B<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb12-44"><a href="#cb12-44" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> x<span class="op">.</span>name <span class="op">==</span> y<span class="op">.</span>name</span>
<span id="cb12-45"><a href="#cb12-45" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This protocol lets you do a kind of static <code
class="sourceCode scala">respondsToSelector</code>, with all of the
types intact. Other people have spoken about the other things you can do
with lenses in Swift (<a
href="https://www.youtube.com/watch?v=ofjehH9f-CU">Brandon Williams -
Lenses in Swift</a>), like composing them together, chaining operations,
etc. (One other thing they can emulate is <a
href="https://gist.github.com/erica/6794d48d917e2084d6ed">method
cascading</a>) Unfortunately, in current Swift, the boilerplate makes
all of this a little unpleasant. Still, they’re an interesting idea, and
they show how a good type system needn’t always get in the way.</p>
]]></description>
    <pubDate>Thu, 16 Jun 2016 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2016-06-16-lenses-are-static-selectors.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Folding Two Things at Once</title>
    <link>https://doisinkidney.com/posts/2016-04-17-folding-two-at-once.html</link>
    <description><![CDATA[<div class="info">
    Posted on April 17, 2016
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Recursion Schemes&#39;." href="/tags/Recursion%20Schemes.html" rel="tag">Recursion Schemes</a>
    
</div>

<p>There’s a whole family of Haskell brainteasers surrounding one
function: <code
class="sourceCode haskell"><span class="fu">foldr</span></code>. The
general idea is to convert some function on lists which uses recursion
into one that uses <code
class="sourceCode haskell"><span class="fu">foldr</span></code>. <code
class="sourceCode haskell"><span class="fu">map</span></code>, for
instance:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b]</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span> f <span class="ot">=</span> <span class="fu">foldr</span> (\e a <span class="ot">-&gt;</span> f e <span class="op">:</span> a) []</span></code></pre></div>
<p>Some can get a little trickier. <code
class="sourceCode haskell"><span class="fu">dropWhile</span></code>, for
instance. (See <a
href="https://wiki.haskell.org/wikiupload/1/14/TMR-Issue6.pdf">here</a>
and <a href="http://www.cs.nott.ac.uk/~pszgmh/fold.pdf">here</a> for
interesting articles on that one in particular.)</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">dropWhile</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="fu">dropWhile</span> p <span class="ot">=</span> <span class="fu">fst</span> <span class="op">.</span> <span class="fu">foldr</span> f ([],[]) <span class="kw">where</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  f e <span class="op">~</span>(xs,ys) <span class="ot">=</span> (<span class="kw">if</span> p e <span class="kw">then</span> xs <span class="kw">else</span> zs, zs) <span class="kw">where</span> zs <span class="ot">=</span> e <span class="op">:</span> ys</span></code></pre></div>
<h2 id="zip">Zip</h2>
<p>One function which was a little harder to convert than it first
seemed was <code
class="sourceCode haskell"><span class="fu">zip</span></code>.</p>
<p>Here’s the first (non) solution:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="fu">const</span> []) <span class="kw">where</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  f x xs (y<span class="op">:</span>ys) <span class="ot">=</span> (x,y) <span class="op">:</span> xs ys</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  f _ _  [] <span class="ot">=</span> []</span></code></pre></div>
<p>The problem with the above isn’t that it doesn’t work: it does. The
problem is that it’s not <em>really</em> using <code
class="sourceCode haskell"><span class="fu">foldr</span></code>. It’s
only using it on the first list: there’s still a manual uncons being
performed on the second. Ideally, I would want the function to look
something like this:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs ys <span class="ot">=</span> <span class="fu">foldr</span> f (\_ _ <span class="ot">-&gt;</span> []) xs (<span class="fu">foldr</span> g (<span class="fu">const</span> []) ys)</span></code></pre></div>
<p>The best solution I found online only dealt with <code
class="sourceCode haskell"><span class="dt">Fold</span></code>s, not
<code
class="sourceCode haskell"><span class="dt">Foldable</span></code>s. You
can read it <a
href="http://okmij.org/ftp/Haskell/zip-folds.lhs">here</a>.</p>
<h2 id="recursive-types">Recursive Types</h2>
<p>Reworking the solution online for <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>s, the
initial intuition is to have the <code
class="sourceCode haskell"><span class="fu">foldr</span></code> on the
<code class="sourceCode haskell">ys</code> produce a function which
takes an element of the <code class="sourceCode haskell">xs</code>, and
returns a function which takes an element of the <code
class="sourceCode haskell">ys</code>, and so on, finally returning the
created list. The <em>problem</em> with that approach is the types
involved:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs <span class="ot">=</span> <span class="fu">foldr</span> f (<span class="fu">const</span> []) xs <span class="op">.</span> <span class="fu">foldr</span> g (\_ _ <span class="ot">-&gt;</span> []) <span class="kw">where</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  g e2 r2 e1 r1 <span class="ot">=</span> (e1,e2) <span class="op">:</span> (r1 r2)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  f e r x <span class="ot">=</span> x e r</span></code></pre></div>
<p>You get the error:</p>
<blockquote>
<p><code
class="sourceCode haskell"><span class="dt">Occurs</span> check<span class="op">:</span> cannot construct the infinite <span class="kw">type</span><span class="op">:</span> t0 <span class="op">~</span> a <span class="ot">-&gt;</span> (t0 <span class="ot">-&gt;</span> [(a, b)]) <span class="ot">-&gt;</span> [(a, b)]</code>.</p>
</blockquote>
<p>Haskell’s typechecker doesn’t allow for infinitely recursive
types.</p>
<p>You’ll be familiar with this problem if you’ve ever tried to encode
the Y-combinator, or if you’ve fiddled around with the recursion-schemes
package. You might also be familiar with the solution: a <code
class="sourceCode haskell"><span class="kw">newtype</span></code>,
encapsulating the recursion. In this case, the <code
class="sourceCode haskell"><span class="kw">newtype</span></code> looks
very similar to the signature for <code
class="sourceCode haskell"><span class="fu">foldr</span></code>:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">RecFold</span> a b <span class="ot">=</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">RecFold</span> {<span class="ot"> runRecFold ::</span> a <span class="ot">-&gt;</span> (<span class="dt">RecFold</span> a b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b }</span></code></pre></div>
<p>Now you can insert and remove the <code
class="sourceCode haskell"><span class="dt">RecFold</span></code>
wrapper, helping the typechecker to understand the recursive types as it
goes:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> xs <span class="ot">=</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">foldr</span> f (<span class="fu">const</span> []) xs <span class="op">.</span> <span class="dt">RecFold</span> <span class="op">.</span> <span class="fu">foldr</span> g (\_ _ <span class="ot">-&gt;</span> []) <span class="kw">where</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    g e2 r2 e1 r1 <span class="ot">=</span> (e1,e2) <span class="op">:</span> (r1 (<span class="dt">RecFold</span> r2))</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    f e r x <span class="ot">=</span> runRecFold x e r</span></code></pre></div>
<p>As an aside, the performance characteristics of the <code
class="sourceCode haskell"><span class="kw">newtype</span></code>
wrapper are totally opaque to me. There may be significant improvements
by using <code class="sourceCode haskell">coerce</code> from <a
href="https://hackage.haskell.org/package/base-4.8.2.0/docs/Data-Coerce.html">Data.Coerce</a>,
but I haven’t looked into it.</p>
<h2 id="generalised-zips">Generalised Zips</h2>
<p>The immediate temptation from the function above is to generalise it.
First to <code
class="sourceCode haskell"><span class="fu">zipWith</span></code>,
obviously:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zipWith</span><span class="ot"> ::</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [c]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zipWith</span> c xs <span class="ot">=</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">foldr</span> f (<span class="fu">const</span> []) xs <span class="op">.</span> <span class="dt">RecFold</span> <span class="op">.</span> <span class="fu">foldr</span> g (\_ _ <span class="ot">-&gt;</span> []) <span class="kw">where</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    g e2 r2 e1 r1 <span class="ot">=</span> c e1 e2 <span class="op">:</span> (r1 (<span class="dt">RecFold</span> r2))</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    f e r x <span class="ot">=</span> runRecFold x e r</span></code></pre></div>
<p>What’s maybe a little more interesting, though, would be a <code
class="sourceCode haskell"><span class="fu">foldr</span></code> on two
lists. Something which folds through both at once, using a supplied
combining function:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldr2 ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Foldable</span> g)</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> c)</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> g b <span class="ot">-&gt;</span> c</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>foldr2 c i xs <span class="ot">=</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">foldr</span> f (<span class="fu">const</span> i) xs <span class="op">.</span> <span class="dt">RecFold</span> <span class="op">.</span> <span class="fu">foldr</span> g (\_ _ <span class="ot">-&gt;</span> i) <span class="kw">where</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    g e2 r2 e1 r1 <span class="ot">=</span> c e1 e2 (r1 (<span class="dt">RecFold</span> r2))</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    f e r x <span class="ot">=</span> runRecFold x e r</span></code></pre></div>
<p>Of course, once you can do two, you can do three:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldr3 ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Foldable</span> g, <span class="dt">Foldable</span> h)</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>       <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> c <span class="ot">-&gt;</span> d <span class="ot">-&gt;</span> d)</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>       <span class="ot">-&gt;</span> d <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> g b <span class="ot">-&gt;</span> h c <span class="ot">-&gt;</span> d</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>foldr3 c i xs ys <span class="ot">=</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">foldr</span> f (<span class="fu">const</span> i) xs <span class="op">.</span> <span class="dt">RecFold</span> <span class="op">.</span> foldr2 g (\_ _ <span class="ot">-&gt;</span> i) ys <span class="kw">where</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>    g e2 e3 r2 e1 r1 <span class="ot">=</span> c e1 e2 e3 (r1 (<span class="dt">RecFold</span> r2))</span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    f e r x <span class="ot">=</span> runRecFold x e r</span></code></pre></div>
<p>And so on.</p>
<p>There’s the added benefit that the above functions work on much more
than just lists.</p>
<h2 id="catamorphisms">Catamorphisms</h2>
<p>Getting a little formal about the above functions, a <code
class="sourceCode haskell">fold</code> can be described as a
catamorphism. This is a name for a pattern of breaking down some
recursive structure. There’s a bunch of them in the <a
href="https://hackage.haskell.org/package/recursion-schemes-4.1.2/docs/Data-Functor-Foldable.html">recursion-schemes</a>
package. The question is, then: can you express the above as a kind of
catamorphism? Initially, using the same techniques as before, you
can:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">RecF</span> f a <span class="ot">=</span> <span class="dt">RecF</span> {<span class="ot"> unRecF ::</span> <span class="dt">Base</span> f (<span class="dt">RecF</span> f a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> a }</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="ot">zipo ::</span> (<span class="dt">Functor</span><span class="op">.</span><span class="dt">Foldable</span> f, <span class="dt">Functor</span><span class="op">.</span><span class="dt">Foldable</span> g)</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>     <span class="ot">=&gt;</span> (<span class="dt">Base</span> f (<span class="dt">RecF</span> g c) <span class="ot">-&gt;</span> <span class="dt">Base</span> g (<span class="dt">RecF</span> g c <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> c)</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> f <span class="ot">-&gt;</span> g <span class="ot">-&gt;</span> c</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>zipo alg xs ys <span class="ot">=</span> cata (<span class="fu">flip</span> unRecF) ys (cata (<span class="dt">RecF</span> <span class="op">.</span> alg) xs)</span></code></pre></div>
<p>Then, coming full circle, you get a quite nice encoding of <code
class="sourceCode haskell"><span class="fu">zip</span></code>:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> <span class="ot">=</span> zipo alg <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  alg <span class="dt">Nil</span> _ <span class="ot">=</span> []</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>  alg _ <span class="dt">Nil</span> <span class="ot">=</span> []</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  alg (<span class="dt">Cons</span> x xs) (<span class="dt">Cons</span> y ys) <span class="ot">=</span> (x, y) <span class="op">:</span> ys xs</span></code></pre></div>
<p>However, the <code
class="sourceCode haskell"><span class="dt">RecF</span></code> is a
little ugly. In fact, it’s possible to write the above without any
recursive types. (It’s possible that you could do the same with <code
class="sourceCode haskell">foldr2</code> as well, but I haven’t figured
it out yet)</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipo ::</span> (<span class="dt">Functor</span><span class="op">.</span><span class="dt">Foldable</span> f, <span class="dt">Functor</span><span class="op">.</span><span class="dt">Foldable</span> g)</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>     <span class="ot">=&gt;</span> (<span class="dt">Base</span> f (g <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> <span class="dt">Base</span> g g <span class="ot">-&gt;</span> c)</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>     <span class="ot">-&gt;</span> f <span class="ot">-&gt;</span> g <span class="ot">-&gt;</span> c</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>zipo alg <span class="ot">=</span> cata (\x <span class="ot">-&gt;</span> alg x <span class="op">.</span> project)</span></code></pre></div>
<p>And the new version of <code
class="sourceCode haskell"><span class="fu">zip</span></code> has a
slightly more natural order of arguments:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> [(a,b)]</span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span> <span class="ot">=</span> zipo alg <span class="kw">where</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  alg <span class="dt">Nil</span> _ <span class="ot">=</span> []</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  alg _ <span class="dt">Nil</span> <span class="ot">=</span> []</span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  alg (<span class="dt">Cons</span> x xs) (<span class="dt">Cons</span> y ys) <span class="ot">=</span> (x,y) <span class="op">:</span> xs ys</span></code></pre></div>
<h2 id="zipping-into">Zipping Into</h2>
<p>There’s one more issue, though, that’s slightly tangential. A lot of
the time, the attraction of rewriting functions using folds and
catamorphisms is that the function becomes more general: it no longer is
restricted to lists. For <code
class="sourceCode haskell"><span class="fu">zip</span></code>, however,
there’s still a pesky list left in the signature:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="fu">zip</span><span class="ot"> ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Foldable</span> g) <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> g b <span class="ot">-&gt;</span> [(a,b)]</span></code></pre></div>
<p>It would be a little nicer to be able to zip through something
<em>preserving</em> the structure of one of the things being zipped
through. For no reason in particular, let’s assume we’ll preserve the
structure of the first argument. The function will have to account for
the second argument running out before the first, though. A <code
class="sourceCode haskell"><span class="dt">Maybe</span></code> can
account for that:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipInto ::</span> (<span class="dt">Foldable</span> f, <span class="dt">Foldable</span> g)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b <span class="ot">-&gt;</span> c)</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> g b <span class="ot">-&gt;</span> f c</span></code></pre></div>
<p>If the second argument runs out, <code
class="sourceCode haskell"><span class="dt">Nothing</span></code> will
be passed to the combining function.</p>
<p>It’s clear that this isn’t a <em>fold</em> over the first argument,
it’s a <em>traversal</em>. A first go at the function uses the state
monad, but restricts the second argument to a list:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipInto ::</span> <span class="dt">Traversable</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> f c</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>zipInto c xs ys <span class="ot">=</span> evalState (<span class="fu">traverse</span> f xs) ys <span class="kw">where</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  f x <span class="ot">=</span> <span class="kw">do</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>    h <span class="ot">&lt;-</span> gets uncons</span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">case</span> h <span class="kw">of</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Just</span> (y,t) <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb17-7"><a href="#cb17-7" aria-hidden="true" tabindex="-1"></a>        put t</span>
<span id="cb17-8"><a href="#cb17-8" aria-hidden="true" tabindex="-1"></a>        <span class="fu">pure</span> (c x (<span class="dt">Just</span> y))</span>
<span id="cb17-9"><a href="#cb17-9" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="fu">pure</span> (c x <span class="dt">Nothing</span>)</span></code></pre></div>
<p>That code can be cleaned up a little:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="ot">zipInto ::</span> <span class="dt">Traversable</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> [b] <span class="ot">-&gt;</span> f c</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>zipInto c <span class="ot">=</span> evalState <span class="op">.</span> <span class="fu">traverse</span> (state <span class="op">.</span> f <span class="op">.</span> c) <span class="kw">where</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  f x [] <span class="ot">=</span> (x <span class="dt">Nothing</span>, [])</span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>  f x (y<span class="op">:</span>ys) <span class="ot">=</span> (x (<span class="dt">Just</span> y), ys)</span></code></pre></div>
<p>But really, the uncons needs to go. Another <code
class="sourceCode haskell"><span class="kw">newtype</span></code>
wrapper is needed, and here’s the end result:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">RecAccu</span> a b <span class="ot">=</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">RecAccu</span> {<span class="ot"> runRecAccu ::</span> a <span class="ot">-&gt;</span> (<span class="dt">RecAccu</span> a b, b) }</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="ot">zipInto ::</span> (<span class="dt">Traversable</span> t, <span class="dt">Foldable</span> f)</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> t c</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>zipInto f xs <span class="ot">=</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>  <span class="fu">snd</span> <span class="op">.</span> <span class="fu">flip</span> (mapAccumL runRecAccu) xs <span class="op">.</span> <span class="dt">RecAccu</span> <span class="op">.</span> <span class="fu">foldr</span> h i <span class="kw">where</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>    i e <span class="ot">=</span> (<span class="dt">RecAccu</span> i, f e <span class="dt">Nothing</span>)</span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>    h e2 a e1 <span class="ot">=</span> (<span class="dt">RecAccu</span> a, f e1 (<span class="dt">Just</span> e2))</span></code></pre></div>
]]></description>
    <pubDate>Sun, 17 Apr 2016 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2016-04-17-folding-two-at-once.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>2048 in Python</title>
    <link>https://doisinkidney.com/posts/2015-10-20-2048.html</link>
    <description><![CDATA[<div class="info">
    Posted on October 20, 2015
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: 
    
</div>

<p>A simple implementation of the game <a
href="https://gabrielecirulli.github.io/2048/">2048</a> in Python, using
<a href="https://www.gnu.org/s/ncurses/">ncurses</a>.</p>
<p>It supports different “bases” (other than 2) as well as colors, and
uses a kind of Python-y functional style.</p>
<p>Minus comments, the whole thing is 70 lines.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="co">#-----------------------------functional-helpers-------------------------#</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> functools <span class="im">import</span> <span class="bu">reduce</span>, partial</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> compose(<span class="op">*</span>funcs):</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="co">&quot;&quot;&quot;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="co">  Mathematical function composition.</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="co">  compose(h, g, f)(x) =&gt; h(g(f(x)))</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="co">  &quot;&quot;&quot;</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="bu">reduce</span>(<span class="kw">lambda</span> a,e: <span class="kw">lambda</span> x: a(e(x)), funcs, <span class="kw">lambda</span> x: x)</span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="co">#-----------------------------------base---------------------------------#</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co"># The base determines three things:</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a><span class="co">#  - The number of squares which need to be in a row to coalesce (= base)</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a><span class="co">#  - The length of the side of the board (= base^2)</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="co">#  - The number added to a random blank box on the board at the beginning</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="co">#    of every turn. (The seed) (90% of the time, the number added will be</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="co">#    the base, but 10% of the time, it will be the square of the base)</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="co">#  - The number of seeds added at evey turn (= 2^(base - 2))</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a><span class="co">#</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a><span class="co"># Normal 2048 has a base of 2.</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>base <span class="op">=</span> <span class="bu">int</span>(<span class="bu">input</span>(<span class="st">&quot;Choose a base. (2 for normal 2048)</span><span class="ch">\n</span><span class="st">&gt; &quot;</span>))</span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a><span class="co">#-----------------------------------rand---------------------------------#</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> addn(board):</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>  <span class="co">&quot;&quot;&quot;</span></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a><span class="co">  Inserts n seeds into random, empty positions in board. Returns board.</span></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a><span class="co">  n = 2^(base - 2)</span></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a><span class="co">  The  seed is equal to base 90% of the time. 10% of the time, it is</span></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a><span class="co">  equal to the square of the base.</span></span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a><span class="co">  &quot;&quot;&quot;</span></span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>  <span class="im">from</span> random <span class="im">import</span> randrange, sample</span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>  inds    <span class="op">=</span> <span class="bu">range</span>(base<span class="op">**</span><span class="dv">2</span>)</span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a>  empties <span class="op">=</span> [(y,x) <span class="cf">for</span> y <span class="kw">in</span> inds <span class="cf">for</span> x <span class="kw">in</span> inds <span class="cf">if</span> <span class="kw">not</span> board[y][x]]</span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> y,x <span class="kw">in</span> sample(empties,<span class="dv">2</span><span class="op">**</span>(base<span class="op">-</span><span class="dv">2</span>)):</span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a>    board[y][x] <span class="op">=</span> base <span class="cf">if</span> randrange(<span class="dv">10</span>) <span class="cf">else</span> base<span class="op">**</span><span class="dv">2</span></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> board</span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a><span class="co">#----------------------------------squish--------------------------------#</span></span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> itertools <span class="im">import</span> count, groupby, starmap</span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> squish(row):</span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a>  <span class="co">&quot;&quot;&quot;</span></span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a><span class="co">  Returns a list, the same length as row, with the contents</span></span>
<span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a><span class="co">  &quot;squished&quot; by the rules of 2048.</span></span>
<span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a><span class="co">  Boxes are coalesced by adding their values together.</span></span>
<span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a><span class="co">  Boxes will be coalesced iff:</span></span>
<span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a><span class="co">   - They are adjacent, or there are only empty boxes between them.</span></span>
<span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a><span class="co">   - The total number of boxes is equal to the base.</span></span>
<span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a><span class="co">   - All the values of the boxes are equal.</span></span>
<span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a><span class="co">  For base 2:</span></span>
<span id="cb1-62"><a href="#cb1-62" aria-hidden="true" tabindex="-1"></a><span class="co">  [2][2][ ][ ] -&gt; [4][ ][ ][ ]</span></span>
<span id="cb1-63"><a href="#cb1-63" aria-hidden="true" tabindex="-1"></a><span class="co">  [2][2][2][2] -&gt; [4][4][ ][ ]</span></span>
<span id="cb1-64"><a href="#cb1-64" aria-hidden="true" tabindex="-1"></a><span class="co">  [4][ ][4][2] -&gt; [8][2][ ][ ]</span></span>
<span id="cb1-65"><a href="#cb1-65" aria-hidden="true" tabindex="-1"></a><span class="co">  [4][2][4][2] -&gt; [4][2][4][2]</span></span>
<span id="cb1-66"><a href="#cb1-66" aria-hidden="true" tabindex="-1"></a><span class="co">  For base 3:</span></span>
<span id="cb1-67"><a href="#cb1-67" aria-hidden="true" tabindex="-1"></a><span class="co">  [3][ ][ ][3][ ][ ][3][ ][ ] -&gt; [9][ ][ ][ ][ ][ ][ ][ ][ ]</span></span>
<span id="cb1-68"><a href="#cb1-68" aria-hidden="true" tabindex="-1"></a><span class="co">  [3][3][3][3][3][3][3][3][3] -&gt; [9][9][9][ ][ ][ ][ ][ ][ ]</span></span>
<span id="cb1-69"><a href="#cb1-69" aria-hidden="true" tabindex="-1"></a><span class="co">  [3][3][3][9][9][ ][ ][ ][ ] -&gt; [9][9][9][ ][ ][ ][ ][ ][ ]</span></span>
<span id="cb1-70"><a href="#cb1-70" aria-hidden="true" tabindex="-1"></a><span class="co">  Keyword arguments:</span></span>
<span id="cb1-71"><a href="#cb1-71" aria-hidden="true" tabindex="-1"></a><span class="co">  row -- A list, containing a combination of numbers and None</span></span>
<span id="cb1-72"><a href="#cb1-72" aria-hidden="true" tabindex="-1"></a><span class="co">  (representing empty boxes)</span></span>
<span id="cb1-73"><a href="#cb1-73" aria-hidden="true" tabindex="-1"></a><span class="co">  &quot;&quot;&quot;</span></span>
<span id="cb1-74"><a href="#cb1-74" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-75"><a href="#cb1-75" aria-hidden="true" tabindex="-1"></a>  r <span class="op">=</span> []</span>
<span id="cb1-76"><a href="#cb1-76" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> n,x <span class="kw">in</span> starmap(<span class="kw">lambda</span> n, a: (n, <span class="bu">sum</span>(<span class="bu">map</span>(<span class="bu">bool</span>,a))),</span>
<span id="cb1-77"><a href="#cb1-77" aria-hidden="true" tabindex="-1"></a>                     groupby(<span class="bu">filter</span>(<span class="bu">bool</span>, row))):</span>
<span id="cb1-78"><a href="#cb1-78" aria-hidden="true" tabindex="-1"></a>    r <span class="op">+=</span> ([n<span class="op">*</span>base] <span class="op">*</span> (x<span class="op">//</span>base)) <span class="op">+</span> ([n] <span class="op">*</span> (x<span class="op">%</span>base))</span>
<span id="cb1-79"><a href="#cb1-79" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> r <span class="op">+</span> ([<span class="va">None</span>] <span class="op">*</span> (base<span class="op">**</span><span class="dv">2</span> <span class="op">-</span> <span class="bu">len</span>(r)))</span>
<span id="cb1-80"><a href="#cb1-80" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-81"><a href="#cb1-81" aria-hidden="true" tabindex="-1"></a><span class="co">#----------------------------matrix-manipulation-------------------------#</span></span>
<span id="cb1-82"><a href="#cb1-82" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-83"><a href="#cb1-83" aria-hidden="true" tabindex="-1"></a><span class="co"># Transposes an iterable of iterables</span></span>
<span id="cb1-84"><a href="#cb1-84" aria-hidden="true" tabindex="-1"></a><span class="co"># [[1, 2], -&gt; [[1, 3],</span></span>
<span id="cb1-85"><a href="#cb1-85" aria-hidden="true" tabindex="-1"></a><span class="co">#  [3, 4]]     [2, 4]]</span></span>
<span id="cb1-86"><a href="#cb1-86" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-87"><a href="#cb1-87" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> transpose(l): <span class="cf">return</span> [<span class="bu">list</span>(x) <span class="cf">for</span> x <span class="kw">in</span> <span class="bu">zip</span>(<span class="op">*</span>l)]</span>
<span id="cb1-88"><a href="#cb1-88" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-89"><a href="#cb1-89" aria-hidden="true" tabindex="-1"></a><span class="co"># Flips horizontally an iterable of lists</span></span>
<span id="cb1-90"><a href="#cb1-90" aria-hidden="true" tabindex="-1"></a><span class="co"># [[1, 2], -&gt; [[2, 1],</span></span>
<span id="cb1-91"><a href="#cb1-91" aria-hidden="true" tabindex="-1"></a><span class="co">#  [3, 4]]     [4, 3]]</span></span>
<span id="cb1-92"><a href="#cb1-92" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-93"><a href="#cb1-93" aria-hidden="true" tabindex="-1"></a>flip <span class="op">=</span> partial(<span class="bu">map</span>, <span class="bu">reversed</span>)</span>
<span id="cb1-94"><a href="#cb1-94" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-95"><a href="#cb1-95" aria-hidden="true" tabindex="-1"></a><span class="co"># transforms an iterable of iterables into a list of lists</span></span>
<span id="cb1-96"><a href="#cb1-96" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-97"><a href="#cb1-97" aria-hidden="true" tabindex="-1"></a>thunk <span class="op">=</span> compose(<span class="bu">list</span>, partial(<span class="bu">map</span>, <span class="bu">list</span>))</span>
<span id="cb1-98"><a href="#cb1-98" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-99"><a href="#cb1-99" aria-hidden="true" tabindex="-1"></a><span class="co">#----------------------------------moves---------------------------------#</span></span>
<span id="cb1-100"><a href="#cb1-100" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-101"><a href="#cb1-101" aria-hidden="true" tabindex="-1"></a><span class="co"># The move functions take a board as their argument, and return the board</span></span>
<span id="cb1-102"><a href="#cb1-102" aria-hidden="true" tabindex="-1"></a><span class="co"># &quot;squished&quot; in a given direction.</span></span>
<span id="cb1-103"><a href="#cb1-103" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-104"><a href="#cb1-104" aria-hidden="true" tabindex="-1"></a>moveLeft  <span class="op">=</span> compose(thunk, partial(<span class="bu">map</span>, squish), thunk)</span>
<span id="cb1-105"><a href="#cb1-105" aria-hidden="true" tabindex="-1"></a>moveRight <span class="op">=</span> compose(thunk, flip, moveLeft, flip)</span>
<span id="cb1-106"><a href="#cb1-106" aria-hidden="true" tabindex="-1"></a>moveUp    <span class="op">=</span> compose(transpose, moveLeft, transpose)</span>
<span id="cb1-107"><a href="#cb1-107" aria-hidden="true" tabindex="-1"></a>moveDown  <span class="op">=</span> compose(transpose, moveRight, transpose)</span>
<span id="cb1-108"><a href="#cb1-108" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-109"><a href="#cb1-109" aria-hidden="true" tabindex="-1"></a><span class="co">#-------------------------------curses-init------------------------------#</span></span>
<span id="cb1-110"><a href="#cb1-110" aria-hidden="true" tabindex="-1"></a><span class="cf">try</span>:</span>
<span id="cb1-111"><a href="#cb1-111" aria-hidden="true" tabindex="-1"></a>    <span class="im">import</span> curses</span>
<span id="cb1-112"><a href="#cb1-112" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-113"><a href="#cb1-113" aria-hidden="true" tabindex="-1"></a>    screen <span class="op">=</span> curses.initscr()</span>
<span id="cb1-114"><a href="#cb1-114" aria-hidden="true" tabindex="-1"></a>    curses.noecho()           <span class="co"># Don&#39;t print pressed keys</span></span>
<span id="cb1-115"><a href="#cb1-115" aria-hidden="true" tabindex="-1"></a>    curses.cbreak()           <span class="co"># Don&#39;t wait for enter</span></span>
<span id="cb1-116"><a href="#cb1-116" aria-hidden="true" tabindex="-1"></a>    screen.keypad(<span class="va">True</span>)</span>
<span id="cb1-117"><a href="#cb1-117" aria-hidden="true" tabindex="-1"></a>    curses.curs_set(<span class="va">False</span>)    <span class="co"># Hide cursor</span></span>
<span id="cb1-118"><a href="#cb1-118" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-119"><a href="#cb1-119" aria-hidden="true" tabindex="-1"></a><span class="co">#----------------------------------keymap--------------------------------#</span></span>
<span id="cb1-120"><a href="#cb1-120" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-121"><a href="#cb1-121" aria-hidden="true" tabindex="-1"></a>    <span class="co"># A map from the arrow keys to the movement functions</span></span>
<span id="cb1-122"><a href="#cb1-122" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-123"><a href="#cb1-123" aria-hidden="true" tabindex="-1"></a>    moves <span class="op">=</span> {curses.KEY_RIGHT: moveRight,</span>
<span id="cb1-124"><a href="#cb1-124" aria-hidden="true" tabindex="-1"></a>            curses.KEY_LEFT : moveLeft ,</span>
<span id="cb1-125"><a href="#cb1-125" aria-hidden="true" tabindex="-1"></a>            curses.KEY_UP   : moveUp   ,</span>
<span id="cb1-126"><a href="#cb1-126" aria-hidden="true" tabindex="-1"></a>            curses.KEY_DOWN : moveDown }</span>
<span id="cb1-127"><a href="#cb1-127" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-128"><a href="#cb1-128" aria-hidden="true" tabindex="-1"></a><span class="co">#----------------------------------color---------------------------------#</span></span>
<span id="cb1-129"><a href="#cb1-129" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-130"><a href="#cb1-130" aria-hidden="true" tabindex="-1"></a>    curses.start_color()</span>
<span id="cb1-131"><a href="#cb1-131" aria-hidden="true" tabindex="-1"></a>    curses.use_default_colors()</span>
<span id="cb1-132"><a href="#cb1-132" aria-hidden="true" tabindex="-1"></a>    curses.init_pair(<span class="dv">1</span>, curses.COLOR_WHITE, <span class="op">-</span><span class="dv">1</span>) <span class="co"># Border color</span></span>
<span id="cb1-133"><a href="#cb1-133" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-134"><a href="#cb1-134" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> colorfac():</span>
<span id="cb1-135"><a href="#cb1-135" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-136"><a href="#cb1-136" aria-hidden="true" tabindex="-1"></a>        <span class="co">&quot;&quot;&quot;Initializes a color pair and returns it (skips black)&quot;&quot;&quot;</span></span>
<span id="cb1-137"><a href="#cb1-137" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-138"><a href="#cb1-138" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> i,c <span class="kw">in</span> <span class="bu">zip</span>(count(<span class="dv">2</span>),(c <span class="cf">for</span> c <span class="kw">in</span> count(<span class="dv">1</span>) <span class="cf">if</span> c<span class="op">!=</span>curses.COLOR_BLACK)):</span>
<span id="cb1-139"><a href="#cb1-139" aria-hidden="true" tabindex="-1"></a>            curses.init_pair(i, c, <span class="op">-</span><span class="dv">1</span>)</span>
<span id="cb1-140"><a href="#cb1-140" aria-hidden="true" tabindex="-1"></a>            <span class="cf">yield</span> curses.color_pair(i)</span>
<span id="cb1-141"><a href="#cb1-141" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-142"><a href="#cb1-142" aria-hidden="true" tabindex="-1"></a>    colorgen <span class="op">=</span> colorfac()</span>
<span id="cb1-143"><a href="#cb1-143" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-144"><a href="#cb1-144" aria-hidden="true" tabindex="-1"></a>    <span class="im">from</span> collections <span class="im">import</span> defaultdict</span>
<span id="cb1-145"><a href="#cb1-145" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-146"><a href="#cb1-146" aria-hidden="true" tabindex="-1"></a>    <span class="co"># A cache of colors, with the keys corresponding to numbers on the board.</span></span>
<span id="cb1-147"><a href="#cb1-147" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-148"><a href="#cb1-148" aria-hidden="true" tabindex="-1"></a>    colors <span class="op">=</span> defaultdict(<span class="kw">lambda</span>: <span class="bu">next</span>(colorgen))</span>
<span id="cb1-149"><a href="#cb1-149" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-150"><a href="#cb1-150" aria-hidden="true" tabindex="-1"></a><span class="co">#---------------------------printing-the-board---------------------------#</span></span>
<span id="cb1-151"><a href="#cb1-151" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-152"><a href="#cb1-152" aria-hidden="true" tabindex="-1"></a>    size <span class="op">=</span> <span class="bu">max</span>(<span class="dv">11</span> <span class="op">-</span> base<span class="op">*</span><span class="dv">2</span>, <span class="dv">3</span>) <span class="co"># box width</span></span>
<span id="cb1-153"><a href="#cb1-153" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-154"><a href="#cb1-154" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> printBoard(board):</span>
<span id="cb1-155"><a href="#cb1-155" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-156"><a href="#cb1-156" aria-hidden="true" tabindex="-1"></a>        <span class="kw">def</span> line(b,c): <span class="cf">return</span> b <span class="op">+</span> b.join([c<span class="op">*</span>(size)]<span class="op">*</span><span class="bu">len</span>(board)) <span class="op">+</span> b</span>
<span id="cb1-157"><a href="#cb1-157" aria-hidden="true" tabindex="-1"></a>        border, gap <span class="op">=</span> line(<span class="st">&quot;+&quot;</span>,<span class="st">&quot;-&quot;</span>), line(<span class="st">&quot;|&quot;</span>,<span class="st">&quot; &quot;</span>)</span>
<span id="cb1-158"><a href="#cb1-158" aria-hidden="true" tabindex="-1"></a>        pad <span class="op">=</span> <span class="st">&quot;</span><span class="ch">\n</span><span class="st">&quot;</span> <span class="op">+</span> <span class="st">&quot;</span><span class="ch">\n</span><span class="st">&quot;</span>.join([gap]<span class="op">*</span>((size<span class="op">-</span><span class="dv">2</span>)<span class="op">//</span><span class="dv">4</span>)) <span class="cf">if</span> size <span class="op">&gt;</span> <span class="dv">5</span> <span class="cf">else</span> <span class="st">&quot;&quot;</span></span>
<span id="cb1-159"><a href="#cb1-159" aria-hidden="true" tabindex="-1"></a>        screen.addstr(<span class="dv">0</span>, <span class="dv">0</span>, border, curses.color_pair(<span class="dv">1</span>))</span>
<span id="cb1-160"><a href="#cb1-160" aria-hidden="true" tabindex="-1"></a>        <span class="cf">for</span> row <span class="kw">in</span> board:</span>
<span id="cb1-161"><a href="#cb1-161" aria-hidden="true" tabindex="-1"></a>            screen.addstr(pad <span class="op">+</span> <span class="st">&quot;</span><span class="ch">\n</span><span class="st">|&quot;</span>, curses.color_pair(<span class="dv">1</span>))</span>
<span id="cb1-162"><a href="#cb1-162" aria-hidden="true" tabindex="-1"></a>            <span class="cf">for</span> e <span class="kw">in</span> row:</span>
<span id="cb1-163"><a href="#cb1-163" aria-hidden="true" tabindex="-1"></a>                <span class="cf">if</span> e: screen.addstr(<span class="bu">str</span>(e).center(size), colors[e])</span>
<span id="cb1-164"><a href="#cb1-164" aria-hidden="true" tabindex="-1"></a>                <span class="cf">else</span>: screen.addstr(<span class="st">&quot; &quot;</span> <span class="op">*</span> size)</span>
<span id="cb1-165"><a href="#cb1-165" aria-hidden="true" tabindex="-1"></a>                screen.addstr(<span class="st">&quot;|&quot;</span>, curses.color_pair(<span class="dv">1</span>))</span>
<span id="cb1-166"><a href="#cb1-166" aria-hidden="true" tabindex="-1"></a>            screen.addstr(pad <span class="op">+</span> <span class="st">&quot;</span><span class="ch">\n</span><span class="st">&quot;</span> <span class="op">+</span> border, curses.color_pair(<span class="dv">1</span>))</span>
<span id="cb1-167"><a href="#cb1-167" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-168"><a href="#cb1-168" aria-hidden="true" tabindex="-1"></a><span class="co">#----------------------------------board---------------------------------#</span></span>
<span id="cb1-169"><a href="#cb1-169" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-170"><a href="#cb1-170" aria-hidden="true" tabindex="-1"></a>    <span class="co"># The board is a list of n lists, each of length n, where n is the base</span></span>
<span id="cb1-171"><a href="#cb1-171" aria-hidden="true" tabindex="-1"></a>    <span class="co"># squared. Empty boxes are represented by None. The starting board has</span></span>
<span id="cb1-172"><a href="#cb1-172" aria-hidden="true" tabindex="-1"></a>    <span class="co"># one seed.</span></span>
<span id="cb1-173"><a href="#cb1-173" aria-hidden="true" tabindex="-1"></a>    board <span class="op">=</span> addn([[<span class="va">None</span> <span class="cf">for</span> _ <span class="kw">in</span> <span class="bu">range</span>(base<span class="op">**</span><span class="dv">2</span>)] <span class="cf">for</span> _ <span class="kw">in</span> <span class="bu">range</span>(base<span class="op">**</span><span class="dv">2</span>)])</span>
<span id="cb1-174"><a href="#cb1-174" aria-hidden="true" tabindex="-1"></a>    printBoard(board)</span>
<span id="cb1-175"><a href="#cb1-175" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-176"><a href="#cb1-176" aria-hidden="true" tabindex="-1"></a><span class="co">#----------------------------------game-loop-----------------------------#</span></span>
<span id="cb1-177"><a href="#cb1-177" aria-hidden="true" tabindex="-1"></a>    <span class="co"># The main game loop. Continues until there are not enough empty spaces</span></span>
<span id="cb1-178"><a href="#cb1-178" aria-hidden="true" tabindex="-1"></a>    <span class="co"># on the board, or &quot;q&quot; is pressed.</span></span>
<span id="cb1-179"><a href="#cb1-179" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-180"><a href="#cb1-180" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> char <span class="kw">in</span> <span class="bu">filter</span>(moves.<span class="fu">__contains__</span>, <span class="bu">iter</span>(screen.getch, <span class="bu">ord</span>(<span class="st">&quot;q&quot;</span>))):</span>
<span id="cb1-181"><a href="#cb1-181" aria-hidden="true" tabindex="-1"></a>        moved <span class="op">=</span> moves[char](board)</span>
<span id="cb1-182"><a href="#cb1-182" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> <span class="bu">sum</span>(<span class="kw">not</span> n <span class="cf">for</span> r <span class="kw">in</span> moved <span class="cf">for</span> n <span class="kw">in</span> r) <span class="op">&lt;</span> <span class="dv">2</span><span class="op">**</span>(base<span class="op">-</span><span class="dv">2</span>): <span class="cf">break</span></span>
<span id="cb1-183"><a href="#cb1-183" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> moved <span class="op">!=</span> board: board <span class="op">=</span> addn(moved)</span>
<span id="cb1-184"><a href="#cb1-184" aria-hidden="true" tabindex="-1"></a>        printBoard(board)</span>
<span id="cb1-185"><a href="#cb1-185" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-186"><a href="#cb1-186" aria-hidden="true" tabindex="-1"></a><span class="co">#--------------------------------clean-up--------------------------------#</span></span>
<span id="cb1-187"><a href="#cb1-187" aria-hidden="true" tabindex="-1"></a><span class="cf">finally</span>:</span>
<span id="cb1-188"><a href="#cb1-188" aria-hidden="true" tabindex="-1"></a>    curses.nocbreak()     <span class="co"># Wait for enter</span></span>
<span id="cb1-189"><a href="#cb1-189" aria-hidden="true" tabindex="-1"></a>    screen.keypad(<span class="dv">0</span>)      <span class="co"># Stop arrow-key handling</span></span>
<span id="cb1-190"><a href="#cb1-190" aria-hidden="true" tabindex="-1"></a>    curses.echo()         <span class="co"># Print all keyboard input</span></span>
<span id="cb1-191"><a href="#cb1-191" aria-hidden="true" tabindex="-1"></a>    curses.curs_set(<span class="va">True</span>) <span class="co"># Show cursor</span></span>
<span id="cb1-192"><a href="#cb1-192" aria-hidden="true" tabindex="-1"></a>    curses.endwin()       <span class="co"># Return to normal prompt</span></span></code></pre></div>
]]></description>
    <pubDate>Tue, 20 Oct 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-10-20-2048.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Trie in Haskell</title>
    <link>https://doisinkidney.com/posts/2015-10-06-haskell-trie-lhs.html</link>
    <description><![CDATA[<div class="info">
    Posted on October  6, 2015
</div>
<div class="info">
    
        Part 1 of a <a href="/series/tries.html">2-part series on tries</a>
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Data Structures&#39;." href="/tags/Data%20Structures.html" rel="tag">Data Structures</a>
    
</div>

<h2 id="basic-ops">Basic Ops</h2>
<p>A Trie is one of those data structures that I find myself writing
very early on in almost every language I try to learn. It’s elegant and
interesting, and easy enough to implement.</p>
<p>I usually write a version that is a set-like data structure, rather
than a mapping type, for simplicity’s sake. It stores sequences, in a
prefix-tree structure. It has a map (dictionary) where the keys are the
first element of every sequence it stores, and the values are the Tries
which store the rest of the sequence. It also has a boolean tag,
representing whether or not the current Trie is a Trie on which a
sequence ends. Here’s what the type looks like in Haskell:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">module</span> <span class="dt">Trie</span> <span class="kw">where</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map.Strict</span> <span class="kw">as</span> <span class="dt">Map</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Map.Strict</span> (<span class="dt">Map</span>)</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> (null)</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Maybe</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Data.Foldable</span> (fold)</span></code></pre></div>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Trie</span> a <span class="ot">=</span> <span class="dt">Trie</span> {<span class="ot"> endHere ::</span> <span class="dt">Bool</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>                   ,<span class="ot"> getTrie ::</span> <span class="dt">Map</span> a (<span class="dt">Trie</span> a)</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>                   } <span class="kw">deriving</span> (<span class="dt">Eq</span>)</span></code></pre></div>
<p>Now, inserting into the Trie is easy. You just <code
class="sourceCode haskell">uncons</code> on a list, and insert the head
into the map, with the value being the tail inserted into whatever
existed at that key before:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ot">empty ::</span> <span class="dt">Trie</span> a</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>empty <span class="ot">=</span> <span class="dt">Trie</span> <span class="dt">False</span> Map.empty</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ot">insertRec ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>insertRec [] (<span class="dt">Trie</span> _ m)     <span class="ot">=</span> <span class="dt">Trie</span> <span class="dt">True</span> m</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>insertRec (x<span class="op">:</span>xs) (<span class="dt">Trie</span> e m) <span class="ot">=</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Trie</span> e (Map.alter (<span class="dt">Just</span> <span class="op">.</span> insertRec xs <span class="op">.</span> fromMaybe empty) x m)</span></code></pre></div>
<p>Searching is simple, also. For the empty list, you just check if the
Trie has its <code class="sourceCode haskell">endHere</code> tag set to
<code class="sourceCode haskell"><span class="dt">True</span></code>,
otherwise, you uncons, search the map, and query the Trie with the tail
if it was found, or just return <code
class="sourceCode haskell"><span class="dt">False</span></code> if it
was not:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ot">memberRec ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>memberRec [] (<span class="dt">Trie</span> e _)     <span class="ot">=</span> e</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>memberRec (x<span class="op">:</span>xs) (<span class="dt">Trie</span> _ m) <span class="ot">=</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  fromMaybe <span class="dt">False</span> (memberRec xs <span class="op">&lt;$&gt;</span> Map.lookup x m)</span></code></pre></div>
<p>Here’s my problem. <em>Both</em> of those functions have the same
pattern:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>f []     <span class="ot">=</span> <span class="op">...</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>f (x<span class="op">:</span>xs) <span class="ot">=</span> <span class="op">...</span></span></code></pre></div>
<p>Any good Haskeller should be <em>begging</em> for a fold at this
stage. But it proved a little trickier than I’d imagined. Take <code
class="sourceCode haskell">member</code>, for instance. You want to fold
over a list, with the base case being the tag on the Trie:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">member ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>member <span class="ot">=</span> <span class="fu">foldr</span> f base <span class="kw">where</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  base <span class="ot">=</span> <span class="op">???</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> Map.lookup e <span class="op">???</span></span></code></pre></div>
<p>Where do you get the base case from, though? You have to specify it
from the beginning, but the variable you’re looking for is nested deeply
into the Trie. How can you look into the Trie, without traversing the
list, to find the tag, <em>at the beginning of the function?</em></p>
<p>That had been my issue for a while. Every time I came back to writing
a Trie, I would see the pattern, try and write <code
class="sourceCode haskell">insert</code> and <code
class="sourceCode haskell">member</code> with a fold, and remember again
the trouble I had had with it in the past. Recently, though, I saw a
different problem, that gave me an idea for a solution.</p>
<h2 id="the-highest-order">The Highest Order</h2>
<blockquote>
<p>Rewrite <code
class="sourceCode haskell"><span class="fu">dropWhile</span></code>
using <code
class="sourceCode haskell"><span class="fu">foldr</span></code></p>
</blockquote>
<p>It’s a (semi) well-known puzzle, that’s maybe a little more difficult
than it seems at first. Here, for instance, was my first attempt at
it:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dropWhileWrong ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>dropWhileWrong p <span class="ot">=</span> <span class="fu">foldr</span> f [] <span class="kw">where</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="op">|</span> p e       <span class="ot">=</span> a</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> e<span class="op">:</span>a</span></code></pre></div>
<p>Yeah. That’s <code
class="sourceCode haskell"><span class="fu">filter</span></code>, not
<code
class="sourceCode haskell"><span class="fu">dropWhile</span></code>:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell literate example"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>dropWhileWrong (<span class="op">&lt;</span><span class="dv">5</span>) [<span class="dv">1</span>, <span class="dv">3</span>, <span class="dv">6</span>, <span class="dv">3</span>, <span class="dv">1</span>]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">6</span>]</span></code></pre></div>
<p>Here was my final solution:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dropWhileCount ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>dropWhileCount p l <span class="ot">=</span> <span class="fu">drop</span> (<span class="fu">foldr</span> f <span class="dv">0</span> l) l <span class="kw">where</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="op">|</span> p e       <span class="ot">=</span> a <span class="op">+</span> <span class="dv">1</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dv">0</span></span></code></pre></div>
<p>After the problem I found <a
href="https://wiki.haskell.org/wikiupload/1/14/TMR-Issue6.pdf">this</a>
issue of The Monad Reader, which talks about the same problem. In my
<code class="sourceCode haskell"><span class="fu">drop</span></code>
version, I had been counting the number of items to drop as I went,
adding one for every element that passed the test. The corresponding
version in the article had been building up <code
class="sourceCode haskell"><span class="fu">tail</span></code>
functions, using <code
class="sourceCode haskell"><span class="op">.</span></code> to add them
together:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dropWhileTail ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>dropWhileTail p l <span class="ot">=</span> (<span class="fu">foldr</span> f <span class="fu">id</span> l) l <span class="kw">where</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="op">|</span> p e       <span class="ot">=</span> <span class="fu">tail</span> <span class="op">.</span> a</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="fu">id</span></span></code></pre></div>
<p>A quick visit to <a href="http://pointfree.io">pointfree.io</a> can
generate some monadic pointfree magic:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dropWhilePf ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>dropWhilePf p <span class="ot">=</span> join (<span class="fu">foldr</span> f <span class="fu">id</span>) <span class="kw">where</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="op">|</span> p e       <span class="ot">=</span> <span class="fu">tail</span> <span class="op">.</span> a</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="fu">id</span></span></code></pre></div>
<p>Now, the final version in the article did <em>not</em> use this
technique, as it was very inefficient. It used some cleverness beyond
the scope of this post. The second-from-last version I quite liked,
though:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">dropWhileFp ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>dropWhileFp p l <span class="ot">=</span> <span class="fu">foldr</span> f l l <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="op">|</span> p e       <span class="ot">=</span> <span class="fu">tail</span> a</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>        <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> l</span></code></pre></div>
<p>However, the idea of building up a function in a fold gave me an idea
for adapting it to some of the Trie functions.</p>
<h2 id="folding-inwards">Folding Inwards</h2>
<p>Let’s start with <code class="sourceCode haskell">member</code>. It
needs to fold over a list, and generate a function which acts on a
Trie:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="ot">member ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>member <span class="ot">=</span> <span class="fu">foldr</span> f base</span></code></pre></div>
<p>The <code class="sourceCode haskell">base</code> is the function
being built up: the final part of the function chain. Each part of the
function is generated based on each element of the list, and then
chained with the base using <code
class="sourceCode haskell"><span class="op">.</span></code>:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>member <span class="ot">=</span> <span class="fu">foldr</span> f base <span class="kw">where</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> <span class="op">???</span> <span class="op">.</span> a</span></code></pre></div>
<p>The base here is what’s called when the list is empty. Here’s what it
looked like in the explicit recursion version:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>member [] (<span class="dt">Trie</span> e _) <span class="ot">=</span> e</span></code></pre></div>
<p>We could simplify this by using record syntax, and <code
class="sourceCode haskell">endHere</code>:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>member [] t <span class="ot">=</span> endHere t</span></code></pre></div>
<p>And this has an obvious pointfree version:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>member [] <span class="ot">=</span> endHere</span></code></pre></div>
<p>That fits for the base case. It’s just a function:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>member <span class="ot">=</span> <span class="fu">foldr</span> f endHere <span class="kw">where</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> <span class="op">???</span> <span class="op">.</span> a</span></code></pre></div>
<p>Then, how to combine it. That’s easy enough, actually. It accesses
the map, searches it for the key, and calls the accumulating function on
it. If it’s not found in the map, just return <code
class="sourceCode haskell"><span class="dt">False</span></code>. Here it
is:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a><span class="ot">member ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>member <span class="ot">=</span> <span class="fu">foldr</span> f endHere <span class="kw">where</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> fromMaybe <span class="dt">False</span> <span class="op">.</span> <span class="fu">fmap</span> a <span class="op">.</span> Map.lookup e <span class="op">.</span> getTrie</span></code></pre></div>
<p>One of the other standard functions for a Trie is returning the
“completions” for a given sequence. It’s a very similar function to
<code class="sourceCode haskell">member</code>, actually: instead of
calling <code class="sourceCode haskell">endHere</code> on the final
Trie found, though, just return the Trie itself. And the thing to return
if any given element of the sequence isn’t found is just an empty
Trie:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">complete ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a</span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>complete <span class="ot">=</span> <span class="fu">foldr</span> f <span class="fu">id</span> <span class="kw">where</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> fromMaybe empty <span class="op">.</span> <span class="fu">fmap</span> a <span class="op">.</span> Map.lookup e <span class="op">.</span> getTrie</span></code></pre></div>
<p>In fact, you could abstract out the commonality here:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="ot">follow ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> c <span class="ot">-&gt;</span> (<span class="dt">Trie</span> a <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> c</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>follow ifMiss onEnd <span class="ot">=</span> <span class="fu">foldr</span> f onEnd <span class="kw">where</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> fromMaybe ifMiss <span class="op">.</span> <span class="fu">fmap</span> a <span class="op">.</span> Map.lookup e <span class="op">.</span> getTrie</span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="ot">memberAbs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>memberAbs <span class="ot">=</span> follow <span class="dt">False</span> endHere</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="ot">completeAbs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a</span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a>completeAbs <span class="ot">=</span> follow empty <span class="fu">id</span></span></code></pre></div>
<h2 id="folding-in-and-out">Folding in and out</h2>
<p><code class="sourceCode haskell">insert</code> is another deal
entirely. In <code class="sourceCode haskell">member</code>, the fold
was tunneling into a Trie, applying the accumulator function to
successively deeper Tries, and returning a result based on the final
Trie. <code class="sourceCode haskell">insert</code> needs to do the
same tunneling - but the Trie returned needs to be the <em>outer</em>
Trie.</p>
<p>It turns out it’s not that difficult. Instead of “building up a
function” that is then applied to a Trie, here a function is “sent” into
the inner Tries. The cool thing here is that the function being sent
hasn’t been generated yet.</p>
<p>Here’s some more illustration of what I mean. Start off with the
normal <code
class="sourceCode haskell"><span class="fu">foldr</span></code>:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>insert <span class="ot">=</span> <span class="fu">foldr</span> f (\(<span class="dt">Trie</span> _ m) <span class="ot">-&gt;</span> <span class="dt">Trie</span> <span class="dt">True</span> m)</span></code></pre></div>
<p>With the final function to be applied being one that just flips the
<code class="sourceCode haskell">endHere</code> tag to <code
class="sourceCode haskell"><span class="dt">True</span></code>. Then
<code class="sourceCode haskell">f</code>: this is going to act
<em>over</em> the map of the Trie that it’s called on. It’s useful to
define a function just for that:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="ot">overMap ::</span> <span class="dt">Ord</span> b</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>        <span class="ot">=&gt;</span> (<span class="dt">Map.Map</span> a (<span class="dt">Trie</span> a)</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">Map.Map</span> b (<span class="dt">Trie</span> b))</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">Trie</span> a</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>        <span class="ot">-&gt;</span> <span class="dt">Trie</span> b</span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>overMap f (<span class="dt">Trie</span> e m) <span class="ot">=</span> <span class="dt">Trie</span> e (f m)</span></code></pre></div>
<p>Then, it will look up the next element of the sequence in the Trie,
and apply the accumulating function to it. (if it’s not found it will
provide an empty Trie instead) Simple!</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell literate hidden_source"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> (<span class="dt">Trie</span> a) <span class="kw">where</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">mempty</span> <span class="ot">=</span> <span class="dt">Trie</span> <span class="dt">False</span> Map.empty</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Trie</span> v k <span class="ot">`mappend`</span> <span class="dt">Trie</span> t l <span class="ot">=</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Trie</span> (v <span class="op">||</span> t) (Map.unionWith <span class="fu">mappend</span> k l)</span></code></pre></div>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="ot">insert ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>insert <span class="ot">=</span> <span class="fu">foldr</span> f (\(<span class="dt">Trie</span> _ m) <span class="ot">-&gt;</span> <span class="dt">Trie</span> <span class="dt">True</span> m) <span class="kw">where</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>    overMap (Map.alter (<span class="dt">Just</span> <span class="op">.</span> a <span class="op">.</span> fold) e)</span></code></pre></div>
<p>I think this is really cool: with just a <code
class="sourceCode haskell"><span class="fu">foldr</span></code>, you’re
burrowing into a Trie, changing it, and burrowing back out again.</p>
<h2 id="removal">Removal</h2>
<p>This is always the tricky one with a Trie. You <em>can</em> just
follow a given sequence down to its tag, and flip it from on to off. But
that doesn’t remove the sequence itself from the Trie. So maybe you just
delete the sequence - but that doesn’t work either. How do you know that
there are no other sequences stored below the one you were
examining?</p>
<p>What you need to do is to send a function into the Trie, and have it
report back as to whether or not it stores other sequences below it. So
this version of <code
class="sourceCode haskell"><span class="fu">foldr</span></code> is going
to burrow into the Trie, like <code
class="sourceCode haskell">member</code>; maintain the outer Trie, like
<code class="sourceCode haskell">insert</code>; but <em>also</em> send
messages back up to the outer functions. Cool!</p>
<p>The way to do the “message sending” is with <code
class="sourceCode haskell"><span class="dt">Maybe</span></code>. If the
function you send into the Trie to delete the end of the sequence
returns <code
class="sourceCode haskell"><span class="dt">Nothing</span></code>, then
it signifies that you can delete that member. Luckily, the <code
class="sourceCode haskell">alter</code> function on <code
class="sourceCode haskell"><span class="dt">Data.Map</span></code> works
well with this:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a><span class="ot">alter ::</span> <span class="dt">Ord</span> k</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>      <span class="ot">=&gt;</span> (<span class="dt">Maybe</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a)</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>      <span class="ot">-&gt;</span> k</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>      <span class="ot">-&gt;</span> <span class="dt">Map</span> k a</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>      <span class="ot">-&gt;</span> <span class="dt">Map</span> k a</span></code></pre></div>
<p>Its first argument is a function which is given the result of looking
up its <em>second</em> argument. If the function returns <code
class="sourceCode haskell"><span class="dt">Nothing</span></code>, that
key-value pair in the map is deleted (if it was there). If it returns
<code class="sourceCode haskell"><span class="dt">Just</span></code>
something, though, that key-value pair is added. In the delete function,
we can chain the accumulating function with <code
class="sourceCode haskell"><span class="op">=&lt;&lt;</span></code>.
This will skip the rest of the accumulation if any part of the sequence
isn’t found. The actual function we’re chaining on is <code
class="sourceCode haskell">nilIfEmpty</code>, which checks if a given
Trie is empty, and returns <code
class="sourceCode haskell"><span class="dt">Just</span></code> the Trie
if it’s not, or <code
class="sourceCode haskell"><span class="dt">Nothing</span></code>
otherwise.</p>
<p>Here’s the finished version:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a><span class="ot">delete ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Trie</span> a</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>delete <span class="ot">=</span> (fromMaybe empty <span class="op">.</span>) <span class="op">.</span> <span class="fu">foldr</span> f i <span class="kw">where</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>  i (<span class="dt">Trie</span> _ m) <span class="op">|</span> Map.null m  <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>               <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Just</span> (<span class="dt">Trie</span> <span class="dt">False</span> m)</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a>  f e a <span class="ot">=</span> nilIfEmpty <span class="op">.</span> overMap (Map.alter (a <span class="op">=&lt;&lt;</span>) e)</span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a><span class="fu">null</span><span class="ot"> ::</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a><span class="fu">null</span> (<span class="dt">Trie</span> e m) <span class="ot">=</span> (<span class="fu">not</span> e) <span class="op">&amp;&amp;</span> (Map.null m)</span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-10"><a href="#cb27-10" aria-hidden="true" tabindex="-1"></a><span class="ot">nilIfEmpty ::</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Trie</span> a)</span>
<span id="cb27-11"><a href="#cb27-11" aria-hidden="true" tabindex="-1"></a>nilIfEmpty t <span class="op">|</span> <span class="fu">null</span> t    <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb27-12"><a href="#cb27-12" aria-hidden="true" tabindex="-1"></a>             <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">Just</span> t</span></code></pre></div>
<h2 id="folding-the-foldable">Folding the Foldable</h2>
<p>So how about folding the Trie itself? Same trick: build up a function
with a fold. This time, a fold over the map, not a list. And the
function being built up is a cons operation. When you hit a <code
class="sourceCode haskell"><span class="dt">True</span></code> tag, fire
off an empty list to the built-up function, allowing it to evaluate:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode haskell literate"><code class="sourceCode haskell"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="ot">foldrTrie ::</span> ([a] <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> <span class="dt">Trie</span> a <span class="ot">-&gt;</span> b</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>foldrTrie f i (<span class="dt">Trie</span> a m) <span class="ot">=</span> Map.foldrWithKey ff s m <span class="kw">where</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>  s    <span class="ot">=</span> <span class="kw">if</span> a <span class="kw">then</span> f [] i <span class="kw">else</span> i</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>  ff k <span class="ot">=</span> <span class="fu">flip</span> (foldrTrie <span class="op">$</span> f <span class="op">.</span> (k <span class="op">:</span>))</span></code></pre></div>
<p>Unfortunately, <a
href="http://stackoverflow.com/questions/33469157/foldable-instance-for-a-trie-set">it’s
not easy</a> to make the Trie <em>conform</em> to <code
class="sourceCode haskell"><span class="dt">Foldable</span></code>. It
is possible, and it’s what I’m currently trying to figure out, but it’s
non-trivial.</p>
]]></description>
    <pubDate>Tue, 06 Oct 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-10-06-haskell-trie-lhs.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Faking dependent types in Swift</title>
    <link>https://doisinkidney.com/posts/2015-09-06-dependent-types.html</link>
    <description><![CDATA[<div class="info">
    Posted on September  6, 2015
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Swift&#39;." href="/tags/Swift.html" rel="tag">Swift</a>, <a title="All pages tagged &#39;Dependent Types&#39;." href="/tags/Dependent%20Types.html" rel="tag">Dependent Types</a>
    
</div>

<p><a href="https://en.wikipedia.org/wiki/Dependent_type">Dependent
types</a> are types “that depend on values”. Say you had a function
<code class="sourceCode scala">f</code> that took an integer. If you can
write that function whereby it returns a value of type <code
class="sourceCode scala">A</code> when that integer is even, or a type
<code class="sourceCode scala">B</code> if the integer is odd, then
you’re working with dependent types. (I think. I’m not sure: if I’ve got
it wrong <a href="https://twitter.com/oisdk">tweet me</a>.)</p>
<h2 id="dependent-pretendance">Dependent Pretendance</h2>
<p>As far as I can tell, this is not possible in Swift. All variables
are statically typed, and those types must be found at compile-time. As
long as you’re not messing around with casting:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>struct A <span class="op">{}</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>struct B <span class="op">{}</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>func <span class="fu">f</span><span class="op">(</span>i<span class="op">:</span> <span class="bu">Int</span><span class="op">)</span> <span class="op">-&gt;</span> AnyObject <span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> i <span class="op">%</span> <span class="dv">2</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">?</span> <span class="fu">A</span><span class="op">()</span> as<span class="op">!</span> AnyObject <span class="op">:</span> <span class="fu">B</span><span class="op">()</span> as<span class="op">!</span> AnyObject</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>You won’t be able to manage it.</p>
<p>Now, sum types can give you something that <em>looks</em> like
dependent types:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>struct A <span class="op">{}</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>struct B <span class="op">{}</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>enum SumType <span class="op">{</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="fu">Even</span><span class="op">(</span>A<span class="op">),</span> <span class="fu">Odd</span><span class="op">(</span>B<span class="op">)</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>func <span class="fu">f</span><span class="op">(</span>i<span class="op">:</span> <span class="bu">Int</span><span class="op">)</span> <span class="op">-&gt;</span> SumType <span class="op">{</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> i <span class="op">%</span> <span class="dv">2</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">?</span> <span class="op">.</span><span class="fu">Even</span><span class="op">(</span><span class="fu">A</span><span class="op">())</span> <span class="op">:</span> <span class="op">.</span><span class="fu">Odd</span><span class="op">(</span><span class="fu">B</span><span class="op">())</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>But that doesn’t fit the description: the thing returned is of type
<code class="sourceCode scala">SumType</code>, <em>not</em> <code
class="sourceCode scala">A</code> or <code
class="sourceCode scala">B</code>.</p>
<p>That’s fine, though. As with all of these highfalutin mathematical
concepts in programming, you can steal some of the cool and fun
<em>patterns</em> from your Haskells and Lisps and Idrises and implement
them in whatever language you want.</p>
<p>As it happens, implementing this stuff in Swift gets you even
<em>further</em> away from the formal definition of dependent types.
Instead of allowing types to be decided at runtime, you end up forcing
even <em>more</em> resolution and computation to happen at compile-time.
Take “numbers-as-types”, for instance:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>protocol Nat <span class="op">{</span> <span class="fu">init</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>struct Zero <span class="op">:</span> Nat <span class="op">{}</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>protocol NonZero<span class="op">:</span> Nat <span class="op">{</span> typealias Pred<span class="op">:</span> Nat <span class="op">}</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>struct Succ<span class="op">&lt;</span>N <span class="op">:</span> Nat<span class="op">&gt;</span> <span class="op">:</span> NonZero <span class="op">{</span> typealias Pred <span class="op">=</span> N <span class="op">}</span></span></code></pre></div>
<p>Once you encode some numbers by hand:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>typealias One   <span class="op">=</span> Succ<span class="op">&lt;</span>Zero<span class="op">&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>typealias Two   <span class="op">=</span> Succ<span class="op">&lt;</span>One<span class="op">&gt;</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>typealias Three <span class="op">=</span> Succ<span class="op">&lt;</span>Two<span class="op">&gt;</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>typealias Four  <span class="op">=</span> Succ<span class="op">&lt;</span>Three<span class="op">&gt;</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>typealias Five  <span class="op">=</span> Succ<span class="op">&lt;</span>Four<span class="op">&gt;</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>typealias Six   <span class="op">=</span> Succ<span class="op">&lt;</span>Five<span class="op">&gt;</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>typealias Seven <span class="op">=</span> Succ<span class="op">&lt;</span>Six<span class="op">&gt;</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>typealias Eight <span class="op">=</span> Succ<span class="op">&lt;</span>Seven<span class="op">&gt;</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>typealias Nine  <span class="op">=</span> Succ<span class="op">&lt;</span>Eight<span class="op">&gt;</span></span></code></pre></div>
<p>You get thinking about exactly <em>how much</em> computation you can
achieve at compile time:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>Sum<span class="op">&lt;</span>One<span class="op">,</span> Two<span class="op">&gt;.</span><span class="ex">Result</span>    <span class="co">// Three</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>Comp<span class="op">&lt;</span>Five<span class="op">,</span> Nine<span class="op">&gt;.</span><span class="ex">Result</span> <span class="co">// LT</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>Comp<span class="op">&lt;</span>Four<span class="op">,</span> Four<span class="op">&gt;.</span><span class="ex">Result</span> <span class="co">// EQ</span></span></code></pre></div>
<h2 id="sum-types-divide-types-multiply-types">Sum types, divide types,
multiply types</h2>
<p>What I wanted, ideally, was some basic “Algebraic data types”.
(Today. Today was the day I made the worst pun.) I wanted to be able to
add the type <code class="sourceCode scala">One</code> to the type <code
class="sourceCode scala">Two</code> and get the type <code
class="sourceCode scala">Three</code>. Once you can manage those,
multiplication, division and all kinds of silliness are possible. I set
myself some rules: all calculations must be performed at compile-time,
and all calculations must work with arbitrary values.</p>
<p>I’ve not been able to manage, unfortunately. If someone could figure
out how to do it, I would <a href="https://twitter.com/oisdk">love to
hear it</a>. I’ve been stealing ideas from <a
href="http://strictlypositive.org/faking.ps.gz">Faking It: Simulating
Dependent Types in Haskell</a> mainly.</p>
<p>Here’s the kind of code that made me think it was possible:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>let ar <span class="op">=</span> <span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">].</span><span class="fu">reverse</span><span class="op">()</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>let se <span class="op">=</span> <span class="fu">AnySequence</span><span class="op">([</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">]).</span><span class="fu">reverse</span><span class="op">()</span></span></code></pre></div>
<p>The types returned by those two methods are different. This is all to
do with that protocol-oriented-programming business: the compiler will
try to select the most specialised version of a method to use. So in the
example above, since an array can just be indexed backwards, the
compiler uses a method that returns a lazy <code
class="sourceCode scala">ReverseRandomAccessCollection</code>. However,
for the <code class="sourceCode scala">AnySequence</code>, the <code
class="sourceCode scala">reverse</code> method has to create a whole new
array.</p>
<p>With that in mind, we can make a protocol:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>protocol BinaryOp <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  typealias A<span class="op">:</span> Nat</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  typealias B<span class="op">:</span> Nat</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Then, we can extend it, like this:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>struct EQ <span class="op">{}</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>extension BinaryOp where A <span class="op">==</span> B <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  typealias <span class="ex">Result</span> <span class="op">=</span> EQ</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>So far, so good! The compiler will add that method to all types that
conform to the <code class="sourceCode scala">where</code> clause. So if
there is a concrete type that conforms to <code>BinaryOp</code>:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>struct Comp<span class="op">&lt;</span>E0<span class="op">:</span> Nat<span class="op">,</span> E1<span class="op">:</span> Nat<span class="op">&gt;</span> <span class="op">:</span> BinaryOp <span class="op">{</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  typealias A <span class="op">=</span> E0</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  typealias B <span class="op">=</span> E1</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Only instances where <code class="sourceCode scala">A</code> and
<code class="sourceCode scala">B</code> are equal will get the type
alias:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>Comp<span class="op">&lt;</span>One<span class="op">,</span> One<span class="op">&gt;.</span><span class="ex">Result</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>Comp<span class="op">&lt;</span>One<span class="op">,</span> Two<span class="op">&gt;.</span><span class="ex">Result</span> <span class="co">// Error</span></span></code></pre></div>
<p>But that’s not ideal. We want something that returns <code
class="sourceCode scala">NEQ</code> when the types are not the same.
Easy enough, right?</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>struct NEQ <span class="op">{}</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>extension BinaryOp <span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  typealias <span class="ex">Result</span> <span class="op">=</span> NEQ</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>But there’s an error: <code
class="sourceCode scala">invalid redeclaration of <span class="er">&#39;</span>Result<span class="er">&#39;</span></code>.
The compiler won’t allow polymorphism with typealiases. It <em>does</em>
allow polymorphism with properties, though:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>extension BinaryOp <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> r<span class="op">:</span> EQ <span class="op">{</span> <span class="cf">return</span> <span class="fu">EQ</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>extension BinaryOp where A <span class="op">==</span> B <span class="op">{</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> r<span class="op">:</span> NEQ <span class="op">{</span> <span class="cf">return</span> <span class="fu">NEQ</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This is already a less elegant solution than the typealiases, since
we’re going to have to initialise things. All of the type information is
available at compile-time, though, so I’ve not broken any of my
rules.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>Comp<span class="op">&lt;</span>One<span class="op">,</span> One<span class="op">&gt;().</span>r <span class="co">// EQ</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>Comp<span class="op">&lt;</span>One<span class="op">,</span> Two<span class="op">&gt;().</span>r <span class="co">// NEQ</span></span></code></pre></div>
<p>How about something more complex? Instead of <code
class="sourceCode scala">EQ</code> and <code
class="sourceCode scala">NEQ</code>, maybe <code
class="sourceCode scala">LT</code>, <code
class="sourceCode scala">GT</code>, and <code>EQ</code>?</p>
<p>It’s hard to see how it would work. Well, here’s the base case:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>extension BinaryOp where A <span class="op">==</span> B <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> r<span class="op">:</span> EQ <span class="op">{</span> <span class="cf">return</span> <span class="fu">EQ</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Then, any non-zero is bigger than zero:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>struct LT <span class="op">{}</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>extension BinaryOp where A <span class="op">==</span> Zero<span class="op">,</span> B <span class="op">:</span> NonZero <span class="op">{</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> r<span class="op">:</span> LT <span class="op">{</span> <span class="cf">return</span> <span class="fu">LT</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>struct GT <span class="op">{}</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>extension BinaryOp where A <span class="op">:</span> NonZero<span class="op">,</span> B <span class="op">==</span> Zero <span class="op">{</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> r<span class="op">:</span> GT <span class="op">{</span> <span class="cf">return</span> <span class="fu">GT</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>If both <code class="sourceCode scala">A</code> and <code
class="sourceCode scala">B</code> are nonzero, they should have a <code
class="sourceCode scala">Pred</code> typealias, which we can use,
recursively:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>extension BinaryOp where A <span class="op">:</span> NonZero<span class="op">,</span> B <span class="op">:</span> NonZero <span class="op">{</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> r<span class="op">:</span> <span class="op">??</span> <span class="op">{</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Comp<span class="op">&lt;</span>A<span class="op">.</span>Pred<span class="op">,</span> B<span class="op">.</span>Pred<span class="op">&gt;().</span>r</span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This doesn’t work. I’m fairly sure this is a definitive dead end.
Here’s the error: <code
class="sourceCode scala">ambiguous reference to member <span class="ch">&#39;r&#39;</span></code>.
The problem is that that error encapsulates exactly what I’m trying to
achieve: I <em>want</em> the reference to be ambiguous, so it
<em>depends</em> on the types of <code class="sourceCode scala">A</code>
and <code class="sourceCode scala">B</code>. Most other routes I went
down hit similar roadblocks:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>protocol BinaryOp <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  typealias A<span class="op">:</span> Nat</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>  typealias B<span class="op">:</span> Nat</span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  typealias <span class="ex">Result</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> r<span class="op">:</span> <span class="ex">Result</span> <span class="op">{</span> get <span class="op">}</span></span>
<span id="cb17-6"><a href="#cb17-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The idea here was that you could have various implementations of
<code class="sourceCode scala">r</code>, so that the <code
class="sourceCode scala"><span class="ex">Result</span></code> typealias
would be inferred. The problem is the compiler wants to figure out what
<code class="sourceCode scala"><span class="ex">Result</span></code> is
when you make a type that conforms to the protocol, so every type will
get the default implementation.</p>
<p>Yet more versions I tried all hit the <code
class="sourceCode scala">ambiguous</code> error, which makes me think
this kind of thing is fundamentally impossible in Swift’s current
form.</p>
<p>So I’ve got to break one of the rules: no more arbitrary numbers.</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>struct AddOne<span class="op">&lt;</span>N <span class="op">:</span> Nat<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  typealias <span class="ex">Result</span> <span class="op">=</span> Succ<span class="op">&lt;</span>N<span class="op">&gt;</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>struct AddTwo<span class="op">&lt;</span>N <span class="op">:</span> Nat<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>  typealias <span class="ex">Result</span> <span class="op">=</span> Succ<span class="op">&lt;</span>AddOne<span class="op">&lt;</span>N<span class="op">&gt;.</span><span class="ex">Result</span><span class="op">&gt;</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And so on. Or:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>extension Binary where A <span class="op">==</span> B <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> sub<span class="op">:</span> Zero <span class="op">{</span> <span class="cf">return</span> <span class="fu">Zero</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> com<span class="op">:</span> EQ <span class="op">{</span> <span class="cf">return</span> <span class="fu">EQ</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>extension Binary where A <span class="op">==</span> Succ<span class="op">&lt;</span>B<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> sub<span class="op">:</span> One <span class="op">{</span> <span class="cf">return</span> <span class="fu">One</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> com<span class="op">:</span> GT <span class="op">{</span> <span class="cf">return</span> <span class="fu">GT</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Which can give you subtraction.</p>
<h2 id="lets-pretend-to-be-useful">Let’s Pretend to be Useful</h2>
<p>All of that stuff is interesting, but very <em>very</em> far from
being useful.</p>
<p>The <a
href="https://bigonotetaking.wordpress.com/2015/09/04/in-which-i-misunderstand-dependent-types/">length-indexed
list from the other day</a> probably is useful, though. As well as being
kind of cool and safe, there are some (minor) optimisations it can
do.</p>
<p>The other dependent type staple is the heterogenous list.</p>
<p>Now, this isn’t just any heterogenous list: we’re not writing Python
here. This is a <em>statically typed</em> heterogenous list. Swift has a
construct very similar to this already: a tuple!</p>
<p>But tuples aren’t very extensible:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>extension Tuple where First <span class="op">:</span> <span class="ex">Comparable</span> <span class="op">{...</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>extension Tuple where Count <span class="op">==</span> Two <span class="op">{...</span></span></code></pre></div>
<p>And you can’t work with them in terms that most lists can:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a><span class="op">(</span><span class="dv">1</span><span class="op">,</span> <span class="st">&quot;a&quot;</span><span class="op">,</span> <span class="fl">2.0</span><span class="op">)</span> <span class="op">+</span> <span class="op">(</span><span class="st">&quot;b&quot;</span><span class="op">,</span> <span class="op">-</span><span class="dv">3</span><span class="op">)</span></span></code></pre></div>
<p>So that’s where another tuple type can come in. A la <a
href="https://twitter.com/rob_rix/status/633262294336729088">Rob
Rix</a>, we could make a right-recursive tuple, terminated by <code
class="sourceCode scala"><span class="op">()</span></code>. There’ll be
one overarching protocol:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>protocol _AnyTuple <span class="op">:</span> CustomStringConvertible <span class="op">{</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> tDesc<span class="op">:</span> <span class="ex">String</span> <span class="op">{</span> get <span class="op">}</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> count<span class="op">:</span> <span class="bu">Int</span> <span class="op">{</span> get <span class="op">}</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>  typealias Arity <span class="op">:</span> Nat</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And the empty tuple:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>struct EmptyTuple <span class="op">{}</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>extension EmptyTuple <span class="op">:</span> _AnyTuple <span class="op">{</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> description<span class="op">:</span> <span class="ex">String</span> <span class="op">{</span> <span class="cf">return</span> <span class="st">&quot;()&quot;</span> <span class="op">}</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> tDesc<span class="op">:</span> <span class="ex">String</span> <span class="op">{</span> <span class="cf">return</span>  <span class="st">&quot;)&quot;</span> <span class="op">}</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> count<span class="op">:</span> <span class="bu">Int</span> <span class="op">{</span> <span class="cf">return</span> <span class="dv">0</span> <span class="op">}</span></span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>  typealias Arity <span class="op">=</span> Zero</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The descriptions are just there to give us a pretty printout. Here’s
the tuple struct:</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>struct NonEmptyTuple<span class="op">&lt;</span><span class="ex">Element</span><span class="op">,</span> Tail <span class="op">:</span> _AnyTuple<span class="op">&gt;</span> <span class="op">{</span> <span class="kw">var</span> <span class="op">(</span>head<span class="op">,</span> tail<span class="op">):</span> <span class="op">(</span><span class="ex">Element</span><span class="op">,</span> Tail<span class="op">)</span> <span class="op">}</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>extension NonEmptyTuple <span class="op">:</span> _AnyTuple <span class="op">{</span></span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> count<span class="op">:</span> <span class="bu">Int</span> <span class="op">{</span> <span class="cf">return</span> tail<span class="op">.</span>count <span class="op">+</span> <span class="dv">1</span> <span class="op">}</span></span>
<span id="cb24-5"><a href="#cb24-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> description<span class="op">:</span> <span class="ex">String</span> <span class="op">{</span></span>
<span id="cb24-6"><a href="#cb24-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="st">&quot;(&quot;</span> <span class="op">+</span> <span class="ex">String</span><span class="op">(</span>reflecting<span class="op">:</span> head<span class="op">)</span> <span class="op">+</span> tail<span class="op">.</span>tDesc</span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> tDesc<span class="op">:</span> <span class="ex">String</span> <span class="op">{</span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="st">&quot;, &quot;</span> <span class="op">+</span> <span class="ex">String</span><span class="op">(</span>reflecting<span class="op">:</span> head<span class="op">)</span> <span class="op">+</span> tail<span class="op">.</span>tDesc</span>
<span id="cb24-10"><a href="#cb24-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb24-11"><a href="#cb24-11" aria-hidden="true" tabindex="-1"></a>  typealias Arity <span class="op">=</span> Succ<span class="op">&lt;</span>Tail<span class="op">.</span>Arity<span class="op">&gt;</span></span>
<span id="cb24-12"><a href="#cb24-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Now, to build a tuple. Since it’s right-recursive, it might look like
this:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span> <span class="op">,</span> <span class="st">&quot;a&quot;</span> <span class="op">,</span> <span class="fl">4.0</span> <span class="op">,</span> <span class="op">()</span></span></code></pre></div>
<p>But there are two problems with that: first, the comma is not
overloadable. That’s probably a good thing. Second, it doesn’t really
look like a tuple.</p>
<p><a href="https://twitter.com/jckarter/status/639953308401057793">Joe
Groff</a> solved the first problem (albeit by committing a mortal sin).
Just use a unicode comma! The only one I could find that works has the
delightful name of Hypodiastole.</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a>infix operator ⸒ <span class="op">{</span> associativity right precedence <span class="dv">90</span> <span class="op">}</span></span></code></pre></div>
<p>Trying to find it in the character viewer each time was a pain,
though. So I went with the boring vertical bar.</p>
<p>The second problem can be solved with some sneaky overloading. Here’s
what these functions look like:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a>infix operator <span class="op">|</span> <span class="op">{</span> associativity right precedence <span class="dv">90</span> <span class="op">}</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>func <span class="op">|&lt;</span>E<span class="op">,</span> T<span class="op">:</span>_AnyTuple<span class="op">&gt;(</span>lhs<span class="op">:</span> E<span class="op">,</span> rhs<span class="op">:</span> T<span class="op">)</span> <span class="op">-&gt;</span> NonEmptyTuple<span class="op">&lt;</span>E<span class="op">,</span> T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="fu">NonEmptyTuple</span><span class="op">(</span>head<span class="op">:</span> lhs<span class="op">,</span> tail<span class="op">:</span> rhs<span class="op">)</span></span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb27-7"><a href="#cb27-7" aria-hidden="true" tabindex="-1"></a>func <span class="op">|&lt;</span>E<span class="op">,</span> T<span class="op">&gt;(</span>lhs<span class="op">:</span> E<span class="op">,</span> rhs<span class="op">:</span> T<span class="op">)</span> <span class="op">-&gt;</span> NonEmptyTuple<span class="op">&lt;</span>E<span class="op">,</span> NonEmptyTuple<span class="op">&lt;</span>T<span class="op">,</span> EmptyTuple<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb27-8"><a href="#cb27-8" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="fu">NonEmptyTuple</span><span class="op">(</span>head<span class="op">:</span> lhs<span class="op">,</span> tail<span class="op">:</span> <span class="fu">NonEmptyTuple</span><span class="op">(</span>head<span class="op">:</span> rhs<span class="op">,</span> tail<span class="op">:</span> <span class="fu">EmptyTuple</span><span class="op">()))</span></span>
<span id="cb27-9"><a href="#cb27-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>We can now, finally, build a Tuple:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a><span class="op">(</span><span class="dv">1</span> <span class="op">|</span> <span class="fl">2.0</span> <span class="op">|</span> <span class="st">&quot;a&quot;</span> <span class="op">)</span> <span class="co">// (1, 2.0, &quot;a&quot;)</span></span></code></pre></div>
<p>One little wrinkle with protocols, though. If you try this:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>extension NonEmptyTuple where Arity <span class="op">==</span> Two <span class="op">{...</span></span></code></pre></div>
<p>There’s an error: <code
class="sourceCode scala">neither <span class="kw">type</span> in same<span class="op">-</span><span class="kw">type</span> refers to a generic parameter or associated <span class="kw">type</span></code>.
Generally speaking, <code
class="sourceCode scala"><span class="op">==</span></code> requirements
in struct extensions don’t work. However, they do work on protocols. So
a wrapper protocol is needed:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a>protocol Tuple <span class="op">:</span> _AnyTuple <span class="op">{</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>  typealias Head</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>  typealias Tail <span class="op">:</span> _AnyTuple</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>  typealias Arity <span class="op">:</span> NonZero</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> head <span class="op">:</span> Head <span class="op">{</span> get <span class="op">}</span></span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> tail <span class="op">:</span> Tail <span class="op">{</span> get <span class="op">}</span></span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a>extension NonEmptyTuple <span class="op">:</span> Tuple <span class="op">{}</span></span></code></pre></div>
<p>Alright. Time to work with it.</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>extension Tuple where</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>  Head <span class="op">:</span> IntegerArithmeticType<span class="op">,</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>  Tail <span class="op">:</span> Tuple<span class="op">,</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>  Tail<span class="op">.</span>Head <span class="op">:</span> IntegerArithmeticType<span class="op">,</span></span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>  Arity <span class="op">==</span> Two <span class="op">{</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>  func <span class="fu">matSum</span><span class="op">(</span><span class="kw">with</span><span class="op">:</span> Self<span class="op">)</span> <span class="op">-&gt;</span> NonEmptyTuple<span class="op">&lt;</span>Head<span class="op">,</span> NonEmptyTuple<span class="op">&lt;</span>Tail<span class="op">.</span>Head<span class="op">,</span> EmptyTuple<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>    let a <span class="op">=</span> head <span class="op">+</span> <span class="kw">with</span><span class="op">.</span>head</span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>    let b <span class="op">=</span> tail<span class="op">.</span>head <span class="op">+</span> <span class="kw">with</span><span class="op">.</span>tail<span class="op">.</span>head</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">(</span>a <span class="op">|</span> b<span class="op">)</span></span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a><span class="op">(</span><span class="dv">1</span> <span class="op">|</span> <span class="dv">4</span><span class="op">).</span><span class="fu">matSum</span><span class="op">(</span><span class="dv">3</span> <span class="op">|</span> <span class="dv">2</span><span class="op">)</span> <span class="co">// (4, 6)</span></span></code></pre></div>
<p>The basic advantage of this heterogenous list in Swift is its
extensibility: you can treat tuples of length 2 as a type, or tuples
where the third element is comparable as a type, and so on.</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a>extension Tuple where Tail <span class="op">:</span> Tuple<span class="op">,</span> Tail<span class="op">.</span>Head <span class="op">:</span> <span class="ex">Comparable</span> <span class="op">{</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>  func isSecondLessThan</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>T <span class="op">:</span> Tuple where T<span class="op">.</span>Tail <span class="op">:</span> Tuple<span class="op">,</span> T<span class="op">.</span>Tail<span class="op">.</span>Head <span class="op">==</span> Tail<span class="op">.</span>Head<span class="op">&gt;</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span><span class="kw">with</span><span class="op">:</span> T<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> tail<span class="op">.</span>head <span class="op">&lt;</span> <span class="kw">with</span><span class="op">.</span>tail<span class="op">.</span>head</span>
<span id="cb32-6"><a href="#cb32-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb32-7"><a href="#cb32-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb32-8"><a href="#cb32-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-9"><a href="#cb32-9" aria-hidden="true" tabindex="-1"></a>let a <span class="op">=</span> <span class="op">(</span><span class="dv">1</span> <span class="op">|</span> <span class="fl">3.0</span> <span class="op">|</span> <span class="st">&quot;a&quot;</span> <span class="op">|</span> <span class="dv">43</span><span class="op">)</span></span>
<span id="cb32-10"><a href="#cb32-10" aria-hidden="true" tabindex="-1"></a>let b <span class="op">=</span> <span class="op">(</span><span class="st">&quot;c&quot;</span> <span class="op">|</span> <span class="fl">4.0</span> <span class="op">|</span> <span class="dv">1</span><span class="op">)</span></span>
<span id="cb32-11"><a href="#cb32-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb32-12"><a href="#cb32-12" aria-hidden="true" tabindex="-1"></a>a<span class="op">.</span><span class="fu">isSecondLessThan</span><span class="op">(</span>b<span class="op">)</span></span></code></pre></div>
<p>Most of this stuff is madness. The custom infix unicode operator
should have tipped you off to that: but it’s not to say that
<em>nothing</em> here is useful. Compile-time warnings are great. I
think the fixed-length array works. But this tuple stuff is too hacky:
it only becomes useful if there are some low-level changes to the
language.</p>
<p>What’s really useful, though, is <em>thinking</em> about types with
dependency in mind. Getting familiar with what is and isn’t possible to
write between the <code class="sourceCode scala">where</code> and the
<code class="sourceCode scala"><span class="op">{</span></code> in an
extension gives you a good idea of how powerful protocols and their
specialisations are.</p>
<p>For some extra reading, check out <a
href="https://ghc.haskell.org/trac/ghc/wiki/DependentHaskell">DependentHaskell</a>,
<a href="https://wiki.haskell.org/Heterogenous_collections">Heterogenous
Collections in Haskell</a>, and <a
href="http://programmers.stackexchange.com/questions/132835/is-there-a-specific-purpose-for-heterogeneous-lists">Strongly
Typed Heterogenous Collections</a>. I’m muddling my way through seeing
what’s possible with length-indexed lists, heterogenous lists, and
numeral types <a href="https://github.com/oisdk/PretendDependSwift">over
here</a>, if you’re interested.</p>
]]></description>
    <pubDate>Sun, 06 Sep 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-09-06-dependent-types.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Using Protocols to Build a (very) Generic Deque</title>
    <link>https://doisinkidney.com/posts/2015-08-24-generic-deque.html</link>
    <description><![CDATA[<div class="info">
    Posted on August 24, 2015
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Swift&#39;." href="/tags/Swift.html" rel="tag">Swift</a>, <a title="All pages tagged &#39;Data Structures&#39;." href="/tags/Data%20Structures.html" rel="tag">Data Structures</a>
    
</div>

<p>(Download the playground to use the code and see the outputs)</p>
<p>This post is an update on a <a
href="https://bigonotetaking.wordpress.com/2015/08/09/yet-another-root-of-all-evil/">previous
implementation of a Deque</a>. A full implementation of this Deque is
available <a
href="https://github.com/oisdk/SwiftDataStructures/blob/master/SwiftDataStructures/Deque.swift">here</a>.</p>
<p>A Deque is a data structure comprised of two stacks, facing opposite
directions. In this way, operations at either end of the Deque have the
same complexity as operations on one end of the underlying stack. This
implementation uses two arrays, with the front reversed: appending,
prepending, and removal of the first and last elements are all
(amortized) O(1).</p>
<p>The standard library has three <code
class="sourceCode scala"><span class="ex">Array</span></code> structs:
<code class="sourceCode scala"><span class="ex">Array</span></code>,
<code class="sourceCode scala">ArraySlice</code>, and <code
class="sourceCode scala">ContiguousArray</code>. They all have the same
interface, with different underlying implementations. An <code
class="sourceCode scala"><span class="ex">Array</span></code> is a
standard vector-like structure, which allows O(1) amortized appending,
fast iteration, etc. A <code
class="sourceCode scala">ContiguousArray</code> has stricter rules about
contiguity, but it’s not bridged to Objective-C.</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>let array  <span class="op">=</span> <span class="op">[</span><span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">]</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>let cArray<span class="op">:</span> ContiguousArray <span class="op">=</span> <span class="op">[</span><span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">]</span></span></code></pre></div>
<p>An <code class="sourceCode scala">ArraySlice</code> is a reference
into an <code
class="sourceCode scala"><span class="ex">Array</span></code> or <code
class="sourceCode scala">ContiguousArray</code>, for more efficient
slicing. All the information an <code
class="sourceCode scala">ArraySlice</code> contains is the beginning and
end points of the slice (as well as any changes made to the slice
separate from the array)</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>let slice <span class="op">=</span> array<span class="op">[</span><span class="dv">0</span><span class="op">..&lt;</span><span class="dv">6</span><span class="op">]</span></span></code></pre></div>
<p>To replicate these semantics in a Deque requires three separate
structs: one with an <code
class="sourceCode scala"><span class="ex">Array</span></code> as the
stack, another with an <code class="sourceCode scala">ArraySlice</code>
as the stack, and a third with a <code
class="sourceCode scala">ContiguousArray</code>. The standard library
seems to duplicate the structs, along with their methods and
properties.</p>
<p>It would be much nicer to just define a protocol that represented the
<em>difference</em> between the deque types: then you could just write
the methods and properties once, on top of it. Something like this:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>protocol DequeType <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  typealias <span class="ex">Container</span> <span class="op">:</span> RangeReplaceableCollectionType<span class="op">,</span> MutableSliceable</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> front<span class="op">:</span> <span class="ex">Container</span> <span class="op">{</span> get set <span class="op">}</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> back <span class="op">:</span> <span class="ex">Container</span> <span class="op">{</span> get set <span class="op">}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">init</span><span class="op">()</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>There’s one problem with this: both stacks need to be made public. It
would be much nicer to hide the stacks (especially since an invariant
needs to be checked and maintained on every mutation). If anyone has an
idea of how to accomplish that, <a
href="https://twitter.com/oisdk">tweet me</a>.</p>
<p>The first method to implement is a subscript. Indexing is difficult,
because the front stack will be reversed, so the index used to get in to
the Deque will need to be translated into an equivalent index in the
array.</p>
<p>Any (valid) index will point into either the front or back queue, and
the transformations applied to it in each case is different. If it’s in
the front, the end result will look like <code
class="sourceCode scala">front<span class="op">[</span>front<span class="op">.</span>endIndex <span class="op">-</span> <span class="dv">1</span> <span class="op">-</span> i<span class="op">]</span></code>,
whereas if it’s in the back, it should be <code
class="sourceCode scala">back<span class="op">[</span>i <span class="op">-</span> front<span class="op">.</span>endIndex<span class="op">]</span></code>.
There’s nothing specified about the Containers except that they’re <code
class="sourceCode scala">RangeReplaceableCollectionType</code> and <code
class="sourceCode scala">MutableSliceable</code>, so the index types
will have to be as generic as possible. (you could specify <code
class="sourceCode scala">where Index <span class="op">==</span> <span class="bu">Int</span></code>,
but that’s more specific than needed, and not very extensible.)</p>
<p>Both of those transformations are subtractions, an operation that’s
possible on <code>RandomAccessIndexType</code>s with the <code
class="sourceCode scala">advancedBy</code> method. <code
class="sourceCode scala">advancedBy</code> takes the associated <code
class="sourceCode scala">Distance</code> type of the <code
class="sourceCode scala">RandomAccessIndexType</code>. That’s enough
information to figure out that the Deque’s index type must be the same
as the Distance of the Index of the Container.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>extension DequeType <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  typealias Index <span class="op">=</span> <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The method that will translate an index into the relevant index in
the stacks will return an enum:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>public enum IndexLocation<span class="op">&lt;</span>I<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="fu">Front</span><span class="op">(</span>I<span class="op">),</span> <span class="fu">Back</span><span class="op">(</span>I<span class="op">)</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Then, the translate method itself:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>extension DequeType where</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="ex">Container</span><span class="op">.</span>Index <span class="op">:</span> RandomAccessIndexType<span class="op">,</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance <span class="op">:</span> ForwardIndexType <span class="op">{</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> func <span class="fu">translate</span><span class="op">(</span>i<span class="op">:</span> <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance<span class="op">)</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> IndexLocation<span class="op">&lt;</span><span class="ex">Container</span><span class="op">.</span>Index<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> i <span class="op">&lt;</span> front<span class="op">.</span>count <span class="op">?</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span><span class="fu">Front</span><span class="op">(</span>front<span class="op">.</span>endIndex<span class="op">.</span><span class="fu">predecessor</span><span class="op">().</span><span class="fu">advancedBy</span><span class="op">(-</span>i<span class="op">))</span> <span class="op">:</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span><span class="fu">Back</span><span class="op">(</span>back<span class="op">.</span>startIndex<span class="op">.</span><span class="fu">advancedBy</span><span class="op">(</span>i <span class="op">-</span> front<span class="op">.</span>count<span class="op">))</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This performs two steps: 1. Check which stack it’s in. 2. Subtract in
the appropriate order</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>let d<span class="op">:</span> <span class="ex">Deque</span> <span class="op">=</span> <span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">]</span> <span class="co">// [1, 2, 3 | 4, 5, 6]</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>d<span class="op">.</span><span class="fu">translate</span><span class="op">(</span><span class="dv">0</span><span class="op">)</span> <span class="co">// Front: 2</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>d<span class="op">.</span><span class="fu">translate</span><span class="op">(</span><span class="dv">4</span><span class="op">)</span> <span class="co">// Back: 1</span></span></code></pre></div>
<p>This means that the logic for converting distance to index is
separated from the logic for actual indexing. Great! Here’s the
indexing:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>extension DequeType where</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="ex">Container</span><span class="op">.</span>Index <span class="op">:</span> RandomAccessIndexType<span class="op">,</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance <span class="op">:</span> ForwardIndexType <span class="op">{</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> startIndex<span class="op">:</span> <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance <span class="op">{</span> <span class="cf">return</span> <span class="dv">0</span> <span class="op">}</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> endIndex  <span class="op">:</span> <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance <span class="op">{</span> <span class="cf">return</span> front<span class="op">.</span>count <span class="op">+</span> back<span class="op">.</span>count <span class="op">}</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  <span class="fu">subscript</span><span class="op">(</span>i<span class="op">:</span> <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance<span class="op">)</span> <span class="op">-&gt;</span> <span class="ex">Container</span><span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">{</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>    get <span class="op">{</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>      switch <span class="fu">translate</span><span class="op">(</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">case</span> let <span class="op">.</span><span class="fu">Front</span><span class="op">(</span>i<span class="op">):</span> <span class="cf">return</span> front<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">case</span> let <span class="op">.</span><span class="fu">Back</span><span class="op">(</span>i<span class="op">):</span> <span class="cf">return</span> back<span class="op">[</span>i<span class="op">]</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> set <span class="op">{</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>      switch <span class="fu">translate</span><span class="op">(</span>i<span class="op">)</span> <span class="op">{</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a>      <span class="cf">case</span> let <span class="op">.</span><span class="fu">Front</span><span class="op">(</span>i<span class="op">):</span> front<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> newValue</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">case</span> let <span class="op">.</span><span class="fu">Back</span><span class="op">(</span>i<span class="op">):</span> back<span class="op">[</span>i<span class="op">]</span> <span class="op">=</span> newValue</span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This makes things much easier to test and debug.</p>
<p>Here’s where the power of protocols becomes obvious. If you go back
to the original definition of <code
class="sourceCode scala">DequeType</code>, you can add <code
class="sourceCode scala">Indexable</code>. It may seem like now only
indexable things can conform, but what happens in practice is that when
<code class="sourceCode scala">Indexable</code> looks for its
requirements, <em>it can use the implementations in DequeType</em>. That
means that we’ve just made anything that can conform to <code
class="sourceCode scala">DequeType</code> indexable. That’s awesome.</p>
<p>Next job is ranged indices. This is a good bit more complicated than
the individual indices, so it definitely will benefit from being
separated into a translate method:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>extension DequeType where</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  <span class="ex">Container</span><span class="op">.</span>Index <span class="op">:</span> RandomAccessIndexType<span class="op">,</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  <span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance <span class="op">:</span> BidirectionalIndexType <span class="op">{</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> func translate</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span>i<span class="op">:</span> Range<span class="op">&lt;</span><span class="ex">Container</span><span class="op">.</span>Index<span class="op">.</span>Distance<span class="op">&gt;)</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">-&gt;</span> IndexRangeLocation<span class="op">&lt;</span><span class="ex">Container</span><span class="op">.</span>Index<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> i<span class="op">.</span>endIndex <span class="op">&lt;=</span> front<span class="op">.</span>count <span class="op">{</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a>        let s <span class="op">=</span> front<span class="op">.</span>endIndex<span class="op">.</span><span class="fu">advancedBy</span><span class="op">(-</span>i<span class="op">.</span>endIndex<span class="op">)</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">if</span> s <span class="op">==</span> front<span class="op">.</span>startIndex <span class="op">&amp;&amp;</span> i<span class="op">.</span>isEmpty <span class="op">{</span> <span class="cf">return</span> <span class="op">.</span>Between <span class="op">}</span></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a>        let e <span class="op">=</span> front<span class="op">.</span>endIndex<span class="op">.</span><span class="fu">advancedBy</span><span class="op">(-</span>i<span class="op">.</span>startIndex<span class="op">)</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">.</span><span class="fu">Front</span><span class="op">(</span>s<span class="op">..&lt;</span>e<span class="op">)</span></span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> i<span class="op">.</span>startIndex <span class="op">&gt;=</span> front<span class="op">.</span>count <span class="op">{</span></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a>        let s <span class="op">=</span> back<span class="op">.</span>startIndex<span class="op">.</span><span class="fu">advancedBy</span><span class="op">(</span>i<span class="op">.</span>startIndex <span class="op">-</span> front<span class="op">.</span>count<span class="op">)</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a>        let e <span class="op">=</span> back<span class="op">.</span>startIndex<span class="op">.</span><span class="fu">advancedBy</span><span class="op">(</span>i<span class="op">.</span>endIndex <span class="op">-</span> front<span class="op">.</span>count<span class="op">)</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">.</span><span class="fu">Back</span><span class="op">(</span>s<span class="op">..&lt;</span>e<span class="op">)</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true" tabindex="-1"></a>      let f <span class="op">=</span> front<span class="op">.</span>startIndex<span class="op">..&lt;</span>front<span class="op">.</span>endIndex<span class="op">.</span><span class="fu">advancedBy</span><span class="op">(-</span>i<span class="op">.</span>startIndex<span class="op">)</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true" tabindex="-1"></a>      let b <span class="op">=</span> back<span class="op">.</span>startIndex<span class="op">..&lt;</span>back<span class="op">.</span>startIndex<span class="op">.</span><span class="fu">advancedBy</span><span class="op">(</span>i<span class="op">.</span>endIndex <span class="op">-</span> front<span class="op">.</span>count<span class="op">)</span></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> <span class="op">.</span><span class="fu">Over</span><span class="op">(</span>f<span class="op">,</span> b<span class="op">)</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true" tabindex="-1"></a>let otherDeque<span class="op">:</span> <span class="ex">Deque</span> <span class="op">=</span> <span class="op">[</span><span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">]</span> <span class="co">// [0, 1, 2 | 3, 4, 5]</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true" tabindex="-1"></a>otherDeque<span class="op">.</span><span class="fu">translate</span><span class="op">(</span><span class="dv">0</span><span class="op">...</span><span class="dv">2</span><span class="op">)</span> <span class="co">// Front: 0..&lt;3</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true" tabindex="-1"></a>otherDeque<span class="op">.</span><span class="fu">translate</span><span class="op">(</span><span class="dv">4</span><span class="op">...</span><span class="dv">5</span><span class="op">)</span> <span class="co">// Back: 1..&lt;3</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true" tabindex="-1"></a>otherDeque<span class="op">.</span><span class="fu">translate</span><span class="op">(</span><span class="dv">2</span><span class="op">...</span><span class="dv">5</span><span class="op">)</span> <span class="co">// Over: 0..&lt;1, 0..&lt;3</span></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true" tabindex="-1"></a>otherDeque<span class="op">.</span><span class="fu">translate</span><span class="op">(</span><span class="dv">3</span><span class="op">..&lt;</span><span class="dv">3</span><span class="op">)</span> <span class="co">// Between</span></span></code></pre></div>
<p>The invariant that must be maintained in the deque is this: if either
stack has more than one element, the other cannot be empty. If the
invariant is violated, the longer stack is reversed, and put in place of
the shorter.</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>public enum Balance <span class="op">{</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> FrontEmpty<span class="op">,</span> BackEmpty<span class="op">,</span> Balanced</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>extension DequeType <span class="op">{</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> balance<span class="op">:</span> Balance <span class="op">{</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">let</span> <span class="op">(</span>f<span class="op">,</span> b<span class="op">)</span> <span class="op">=</span> <span class="op">(</span>front<span class="op">.</span>count<span class="op">,</span> back<span class="op">.</span>count<span class="op">)</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> f <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> b <span class="op">&gt;</span> <span class="dv">1</span> <span class="op">{</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">.</span>FrontEmpty</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="cf">if</span> b <span class="op">==</span> <span class="dv">0</span> <span class="op">{</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> f <span class="op">&gt;</span> <span class="dv">1</span> <span class="op">{</span></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">.</span>BackEmpty</span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">.</span>Balanced</span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> isBalanced<span class="op">:</span> Bool <span class="op">{</span></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> balance <span class="op">==</span> <span class="op">.</span>Balanced</span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>A deque is a good data structure for certain uses, especially those
that require popping and appending from either end. <code
class="sourceCode scala"><span class="fu">popFirst</span><span class="op">()</span></code>
and <code
class="sourceCode scala"><span class="fu">popLast</span><span class="op">()</span></code>
aren’t included in the standard <code
class="sourceCode scala">RangeReplaceableCollectionType</code>, though,
so we’ll have to add our own.</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>extension RangeReplaceableCollectionType where Index <span class="op">:</span> BidirectionalIndexType <span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> mutating func <span class="fu">popLast</span><span class="op">()</span> <span class="op">-&gt;</span> Generator<span class="op">.</span><span class="ex">Element</span><span class="op">?</span> <span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> isEmpty <span class="op">?</span> nil <span class="op">:</span> <span class="fu">removeLast</span><span class="op">()</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> mutableDeque<span class="op">:</span> <span class="ex">Deque</span> <span class="op">=</span> <span class="op">[</span><span class="dv">0</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">]</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>mutableDeque<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="co">// 5</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>mutableDeque           <span class="co">// [0, 1, 2 | 3, 4]</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>extension DequeType where <span class="ex">Container</span><span class="op">.</span>Index <span class="op">:</span> BidirectionalIndexType <span class="op">{</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>  public mutating func <span class="fu">popLast</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Container</span><span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">?</span> <span class="op">{</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> back<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The method needs to include <code
class="sourceCode scala"><span class="fu">check</span><span class="op">()</span></code>,
which we can do with <code>defer</code></p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>mutating func <span class="fu">popLast</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Container</span><span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">?</span> <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  defer <span class="op">{</span> <span class="fu">check</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> back<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>mutableDeque<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="co">// 4</span></span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>mutableDeque           <span class="co">// [0, 1, 2 | 3]</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>mutableDeque<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="co">// 3</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>mutableDeque           <span class="co">// [0 | 1, 2]</span></span></code></pre></div>
<p>You also can’t just pop from the back queue in <code
class="sourceCode scala"><span class="fu">popLast</span><span class="op">()</span></code>,
because it may be the case that the front stack has one element left</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>mutating func <span class="fu">popLast</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Container</span><span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">?</span> <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  defer <span class="op">{</span> <span class="fu">check</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> back<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="op">??</span> front<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>mutableDeque<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="co">// 2</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>mutableDeque<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="co">// 1</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>mutableDeque           <span class="co">// [0|]</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a>mutableDeque<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="co">// 0</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>mutableDeque           <span class="co">// [|]</span></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>mutableDeque<span class="op">.</span><span class="fu">popLast</span><span class="op">()</span> <span class="co">// nil</span></span></code></pre></div>
<p>The rest of the Deque was easy, with little to no repetition. Using
protocols in this way was really surprisingly powerful: now, you can
define a <code class="sourceCode scala">DequeType</code>, with full
access to all of the collection methods, all the way up to <code
class="sourceCode scala">RangeReplaceableCollectionType</code>, in five
lines:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>public struct <span class="ex">Deque</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">:</span> DequeType <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> front<span class="op">,</span> back<span class="op">:</span> <span class="op">[</span><span class="ex">Element</span><span class="op">]</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  public typealias SubSequence <span class="op">=</span> DequeSlice<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  public <span class="fu">init</span><span class="op">()</span> <span class="op">{</span> <span class="op">(</span>front<span class="op">,</span> back<span class="op">)</span> <span class="op">=</span> <span class="op">([],</span> <span class="op">[])</span> <span class="op">}</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>public struct DequeSlice<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">:</span> DequeType <span class="op">{</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> front<span class="op">,</span> back<span class="op">:</span> ArraySlice<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a>  public typealias SubSequence <span class="op">=</span> DequeSlice</span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a>  public <span class="fu">init</span><span class="op">()</span> <span class="op">{</span> <span class="op">(</span>front<span class="op">,</span> back<span class="op">)</span> <span class="op">=</span> <span class="op">([],</span> <span class="op">[])</span> <span class="op">}</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>There’s no performance hit, there’s no safety problems. I only have
one version of code to test, one version to change, one version to read.
It’s completely extensible: you could use any kind of stack for the
front and back. Even another Deque, if you were so inclined:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>struct DequeDeque<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">:</span> DequeType <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> front<span class="op">,</span> back<span class="op">:</span> <span class="ex">Deque</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  typealias SubSequence <span class="op">=</span> DequeDequeSlice<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">init</span><span class="op">()</span> <span class="op">{</span> front <span class="op">=</span> <span class="ex">Deque</span><span class="op">();</span> back <span class="op">=</span> <span class="ex">Deque</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>struct DequeDequeSlice<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">:</span> DequeType <span class="op">{</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> front<span class="op">,</span> back<span class="op">:</span> DequeSlice<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>  typealias SubSequence <span class="op">=</span> DequeDequeSlice</span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">init</span><span class="op">()</span> <span class="op">{</span> front <span class="op">=</span> <span class="fu">DequeSlice</span><span class="op">();</span> back <span class="op">=</span> <span class="fu">DequeSlice</span><span class="op">()</span> <span class="op">}</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>let dd<span class="op">:</span> DequeDeque <span class="op">=</span> <span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">,</span> <span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">]</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>dd<span class="op">.</span>front <span class="co">// [4 | 3, 2, 1]</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>dd<span class="op">.</span>back  <span class="co">// [5 | 6, 7, 8]</span></span></code></pre></div>
<p>Woo protocols!</p>
]]></description>
    <pubDate>Mon, 24 Aug 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-08-24-generic-deque.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Trie in Swift</title>
    <link>https://doisinkidney.com/posts/2015-08-11-swift-trie.html</link>
    <description><![CDATA[<div class="info">
    Posted on August 11, 2015
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Swift&#39;." href="/tags/Swift.html" rel="tag">Swift</a>, <a title="All pages tagged &#39;Data Structures&#39;." href="/tags/Data%20Structures.html" rel="tag">Data Structures</a>
    
</div>

<p>If you google “cool data structures” you’ll get <a
href="http://stackoverflow.com/questions/500607/what-are-the-lesser-known-but-useful-data-structures">this</a>
as your first result. It’s a stackoverflow question: “What are the
lesser known but useful data structures?”. And the top answer is a Trie.
I read up on them, and found out a lot of cool things about their use
(as well as finding out that I’m now the kind of person who
googles “cool data structures”). So I rocked on up to my playground, and
got writing.</p>
<p>A Trie is a prefix tree. It’s another recursive data structure: each
Trie contains other children Tries, identifiable by their prefixes.</p>
<p>It’s a bit of a hipster data structure, not very widely used, but
it’s got some useful applications. It’s got set-like operations, with
insertion and searching each at
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mi>n</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(n)</annotation></semantics></math>,
where
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>n</mi><annotation encoding="application/x-tex">n</annotation></semantics></math>
is the length of the sequence being searched for. A Set is the only way
to go for hashable, unordered elements. But, if you’ve got
<em>sequences</em> of hashable elements, a Trie might be for you. (one
thing to note is that Sets are hashable themselves, so if the sequences
you want to store are unordered, a Set of Sets is more applicable)</p>
<figure>
<img
src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/be/Trie_example.svg/1092px-Trie_example.svg.png"
alt="A trie for keys" />
<figcaption aria-hidden="true">A trie for keys</figcaption>
</figure>
<p>In Swift, we can do this by having every Trie contain a dictionary of
prefixes and Tries. Something like this:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>public struct Trie<span class="op">&lt;</span><span class="ex">Element</span> <span class="op">:</span> Hashable<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> children<span class="op">:</span> <span class="op">[</span><span class="ex">Element</span><span class="op">:</span>Trie<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;]</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>We don’t run into the problem of structs not being allowed to be
recursive here, because we don’t directly store a Trie within a Trie -
we store a <em>dictionary</em>, and therefore a reference to the child
Tries. In this dictionary, the keys correspond to the prefixes. So how
do we fill it up? Like lists, we can use the decomposition properties of
generators:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> init<span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>      children <span class="op">=</span> <span class="op">[</span>head<span class="op">:</span><span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span>gen<span class="op">)]</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>      children <span class="op">=</span> <span class="op">[:]</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>  public init</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>S <span class="op">:</span> SequenceType where S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span>_ seq<span class="op">:</span> S<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>      self<span class="op">.</span><span class="fu">init</span><span class="op">(</span>gen<span class="op">:</span> seq<span class="op">.</span><span class="fu">generate</span><span class="op">())</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>That’s not really enough. That can store one sequence, but we need an
<code class="sourceCode scala">insert</code> function. Here ya go:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> mutating func insert</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>        children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">insert</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">??</span> <span class="op">{</span>children<span class="op">[</span>head<span class="op">]</span> <span class="op">=</span> <span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)}()</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>  public mutating func insert</span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>S <span class="op">:</span> SequenceType where S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span>seq<span class="op">:</span> S<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>      <span class="fu">insert</span><span class="op">(</span>seq<span class="op">.</span><span class="fu">generate</span><span class="op">())</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>There’s a line in there that some may find offensive:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">insert</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">??</span> <span class="op">{</span>children<span class="op">[</span>head<span class="op">]</span> <span class="op">=</span> <span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)}()</span></span></code></pre></div>
<p>And, to be honest, I’m not a huge fan of it myself. It’s making use
of the fact that you can call mutating methods on optionals with
chaining. When you do it in this example, the optional is returned by
the dictionary lookup: we then want to mutate that value, if it’s there,
with an insertion.</p>
<p>If it’s <em>not</em> there, though, we want to add it in, so we’ve
got to have some way of understanding and dealing with that. We could
try and extract the child Trie, like this:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> <span class="kw">var</span> child <span class="op">=</span> children<span class="op">[</span>head<span class="op">]</span> <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    child<span class="op">.</span><span class="fu">insert</span><span class="op">(</span>gen<span class="op">)</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    children<span class="op">[</span>head<span class="op">]</span> <span class="op">=</span> <span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>But the child there is just a copy of the actual child in the Trie we
want to mutate. We could then set it back to the dictionary entry - but
at this stage it feels like a lot of extra, inefficient work.</p>
<p>So, you can make use of the fact the functions which don’t return
anything actually <em>do</em> return something: a special value called
<code class="sourceCode scala"><span class="ex">Void</span></code>, or
<code class="sourceCode scala"><span class="op">()</span></code>. Except
that, in this case, it’s <code
class="sourceCode scala"><span class="op">()?</span></code> (or <code
class="sourceCode scala">Optional<span class="op">&amp;</span>lt<span class="op">;</span><span class="ex">Void</span><span class="op">&amp;</span>gt<span class="op">;</span></code>).
We’re not interested in the void itself, obviously, just whether or not
it’s <code class="sourceCode scala">nil</code>. So, one way you could
use it would be like this:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> let _ <span class="op">=</span> children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">insert</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">{</span> <span class="cf">return</span> <span class="op">}</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>children<span class="op">[</span>head<span class="op">]</span> <span class="op">=</span> <span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)</span></span></code></pre></div>
<p>Or, to use <code class="sourceCode scala">guard</code>:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>guard let _ <span class="op">=</span> children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">insert</span><span class="op">(</span>gen<span class="op">)</span> <span class="cf">else</span> <span class="op">{</span> children<span class="op">[</span>head<span class="op">]</span> <span class="op">=</span> <span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)</span> <span class="op">}</span></span></code></pre></div>
<p>But I think the nil coalescing operator is a little clearer, without
the distraction of <code class="sourceCode scala">let</code> or <code
class="sourceCode scala">_</code>.</p>
<p>This data structure, as you can see, has a very different feel to the
list. For a start, it’s much more mutable, with in-place mutating
methods being a little easier than methods that return a new Trie. Also,
laziness is pretty much out of the question: almost every imaginable
useful method would involve evaluation of the entire Trie. (if anyone
<em>does</em> have a useful way of thinking about Tries lazily, I’d love
to hear it)</p>
<p>The contains function, the most important of them all, is here:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> func contains</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">().</span>map<span class="op">{</span>self<span class="op">.</span>children<span class="op">[</span>$<span class="dv">0</span><span class="op">]?.</span><span class="fu">contains</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">??</span> <span class="kw">false</span><span class="op">}</span> <span class="op">??</span> <span class="kw">true</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>  public func contains</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>S <span class="op">:</span> SequenceType where S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span>seq<span class="op">:</span> S<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> <span class="fu">contains</span><span class="op">(</span>seq<span class="op">.</span><span class="fu">generate</span><span class="op">())</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>So this uses more generators. If the generator is empty (<code
class="sourceCode scala">gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span></code>
returns <code class="sourceCode scala">nil</code>), then the Trie
contains that sequence, as we have not yet found a dictionary without
that element. Within the <code
class="sourceCode scala"><span class="fu">map</span><span class="op">()</span></code>
we search for the next element from the generator. If <em>that</em>
returns <code class="sourceCode scala">nil</code>, then the Trie doesn’t
contain that sequence. Finally, if none of that works, return whether or
not the child Trie contains the rest of the generator. Let’s try it
out:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> jo <span class="op">=</span> <span class="fu">Trie</span><span class="op">([</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">])</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>jo<span class="op">.</span><span class="fu">insert</span><span class="op">([</span><span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">])</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>jo<span class="op">.</span><span class="fu">insert</span><span class="op">([</span><span class="dv">7</span><span class="op">,</span> <span class="dv">8</span><span class="op">,</span> <span class="dv">9</span><span class="op">])</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>jo<span class="op">.</span><span class="fu">contains</span><span class="op">([</span><span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">])</span> <span class="co">// true</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>jo<span class="op">.</span><span class="fu">contains</span><span class="op">([</span><span class="dv">2</span><span class="op">,</span> <span class="dv">1</span><span class="op">,</span> <span class="dv">3</span><span class="op">])</span> <span class="co">// false</span></span></code></pre></div>
<p>There’s a catch. The <code class="sourceCode scala">contains</code>
method doesn’t work as we’d like it to:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>jo<span class="op">.</span><span class="fu">contains</span><span class="op">([</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">])</span> <span class="co">// true</span></span></code></pre></div>
<p>Because we return <code
class="sourceCode scala"><span class="kw">true</span></code>
<em>whenever</em> the generator runs out, our Trie “contains” every
prefix of the sequences that have been inserted. This is not what we
want. One way to solve this may be to return <code
class="sourceCode scala"><span class="kw">true</span></code> only if the
last Trie found has no children. Something like this:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> func contains</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">().</span>map<span class="op">{</span>self<span class="op">.</span>children<span class="op">[</span>$<span class="dv">0</span><span class="op">]?.</span><span class="fu">contains</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">??</span> <span class="kw">false</span><span class="op">}</span> <span class="op">??</span> children<span class="op">.</span>isEmpty</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>But this doesn’t really work either. what if we did <code
class="sourceCode scala">jo<span class="op">.</span><span class="fu">insert</span><span class="op">([</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">])</span></code>?
Now, if we check if the Trie contains <code
class="sourceCode scala"><span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">]</span></code>,
we’ll get back <code
class="sourceCode scala"><span class="kw">false</span></code>.</p>
<p>It’s time for flags. We need to add an extra variable to our Trie: a
Boolean, which describes whether or not that Trie represents the end of
a sequence.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>public struct Trie<span class="op">&lt;</span><span class="ex">Element</span> <span class="op">:</span> Hashable<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> children<span class="op">:</span> <span class="op">[</span><span class="ex">Element</span><span class="op">:</span>Trie<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;]</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> endHere <span class="op">:</span> Bool</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>We’ll also need to change our <code
class="sourceCode scala">insert</code> and <code
class="sourceCode scala">init</code> functions, so that when the
generator returns <code class="sourceCode scala">nil</code>, <code
class="sourceCode scala">endHere</code> gets initialised to <code
class="sourceCode scala"><span class="kw">true</span></code>.</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> init<span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>      <span class="op">(</span>children<span class="op">,</span> endHere<span class="op">)</span> <span class="op">=</span> <span class="op">([</span>head<span class="op">:</span><span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span>gen<span class="op">)],</span> <span class="kw">false</span><span class="op">)</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">(</span>children<span class="op">,</span> endHere<span class="op">)</span> <span class="op">=</span> <span class="op">([:],</span> <span class="kw">true</span><span class="op">)</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> mutating func insert</span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb13-16"><a href="#cb13-16" aria-hidden="true" tabindex="-1"></a>        children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">insert</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">??</span> <span class="op">{</span>children<span class="op">[</span>head<span class="op">]</span> <span class="op">=</span> <span class="fu">Trie</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)}()</span></span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>        endHere <span class="op">=</span> <span class="kw">true</span></span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And the contains function now returns <code
class="sourceCode scala">endHere</code>, instead of true:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>public extension Trie <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> func contains</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">().</span>map<span class="op">{</span>self<span class="op">.</span>children<span class="op">[</span>$<span class="dv">0</span><span class="op">]?.</span><span class="fu">contains</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">??</span> <span class="kw">false</span><span class="op">}</span> <span class="op">??</span> endHere</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>While we’re improving the <code
class="sourceCode scala">contains</code> function, we could use <code
class="sourceCode scala">guard</code> to make it much more readable:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>public extension Trie <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> func contains<span class="op">&lt;</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">&gt;(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>      guard let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="cf">else</span> <span class="op">{</span> <span class="cf">return</span> endHere <span class="op">}</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">contains</span><span class="op">(</span>gen<span class="op">)</span> <span class="op">??</span> <span class="kw">false</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><a
href="https://twitter.com/chriseidhof/status/629215881843884032">Chris
Eidhof gave me this idea.</a> (Apparently there’s a Trie implementation
in <a href="http://www.objc.io/books/fpinswift/">Functional Programming
in Swift</a>, his book. I’ve not read it, but it’s on my list. If <a
href="http://www.objc.io/books/advanced-swift/">Advanced Swift</a> is
anything to go by, it should be fantastic.)</p>
<p>The objective of this Trie is to replicate all of the Set methods:
Union, Intersect, etc. Most of those are manageable to build from just
<code class="sourceCode scala">insert</code>, <code
class="sourceCode scala">init</code>, and <code
class="sourceCode scala">contains</code>, but there’s one other function
that comes in handy: <code class="sourceCode scala">remove</code>.</p>
<p>Remove is deceptively difficult. You could just walk to the end of
your given sequence to remove, and switch <code
class="sourceCode scala">endHere</code> from <code
class="sourceCode scala"><span class="kw">true</span></code> to <code
class="sourceCode scala"><span class="kw">false</span></code>, but
that’s kind of cheating. I mean, you’ll be storing the same amount of
information that way after a removal. No, what you need is something
that deletes branches of a tree that aren’t being used any more.</p>
<p>Again, this is a little complicated. You can’t just find the head of
the sequence you want to remove, and then delete all children: you may
be deleting other entries along with that. You <em>also</em> can’t just
delete when a given Trie only contains one child: that child may branch
off subsequently, or it may contain prefixes for the sequence you want
to remove.</p>
<p>Crucially, all of the information telling you whether or not you can
delete a given entry in a given Trie will come from the
<em>children</em> of that Trie. What I decided to go with was this: I’ll
have some mutating method that does the work recursively. However, this
method also <em>returns</em> a value, representing some important
information for whatever called it. In this case, the <code
class="sourceCode scala">remove</code> method would remove, as you’d
imagine, but it will also return a Boolean, signifying whether the Trie
it was called on can be removed. Since I used the normal structure of
having a private method take a generator, and then a public wrapper
method take a sequence, I could have the public method just discard the
Boolean.</p>
<p>Let’s go through it. Here’s the signature:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> mutating func remove<span class="op">&lt;</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>  G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">&gt;(</span><span class="kw">var</span> g<span class="op">:</span> G<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span></code></pre></div>
<p>No surprises there. Similar to the other methods. Then, get the head
from the generator:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a><span class="cf">if</span> let head <span class="op">=</span> g<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span></code></pre></div>
<p>Within that if block is the meat of the logic, so I might skip to
what happens if <code
class="sourceCode scala">g<span class="op">.</span><span class="fu">next</span><span class="op">()</span></code>
returns <code class="sourceCode scala">nil</code> for the start:</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">private</span> mutating func remove<span class="op">&lt;</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">&gt;(</span><span class="kw">var</span> g<span class="op">:</span> G<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> let head <span class="op">=</span> g<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{...}</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>    endHere <span class="op">=</span> <span class="kw">false</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> children<span class="op">.</span>isEmpty</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>So the sequence being removed has ended. That means that whatever
Trie you’re on should have its <code
class="sourceCode scala">endHere</code> set to <code
class="sourceCode scala"><span class="kw">false</span></code>. To the
user of the Trie, that’s all that matters: from now on, if the contains
method on that Trie is used with that sequence, it will return
false.</p>
<p>However, to find out if you can delete the data itself, it returns
<code
class="sourceCode scala">children<span class="op">.</span>isEmpty</code>.
If it has no children, it does not hold any other sequences or
information, so it can be deleted.</p>
<p>Now for inside the if block:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>guard children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">remove</span><span class="op">(</span>g<span class="op">)</span> <span class="op">==</span> <span class="kw">true</span> <span class="cf">else</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">false</span> <span class="op">}</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>children<span class="op">.</span><span class="fu">removeValueForKey</span><span class="op">(</span>head<span class="op">)</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="cf">return</span> <span class="op">!</span>endHere <span class="op">&amp;&amp;</span> children<span class="op">.</span>isEmpty</span></code></pre></div>
<p>So it calls <code class="sourceCode scala">remove</code> on the child
Trie corresponding to <code class="sourceCode scala">head</code>. That
guard statement will fail for two distinct reasons: if <code
class="sourceCode scala">children</code> doesn’t contain <code
class="sourceCode scala">head</code>, then the sequence being removed
wasn’t in the Trie in the first place. The method will then return
false, so that no removal or mutation is done.</p>
<p>If it <em>does</em> contain <code
class="sourceCode scala">head</code>, but the Bool returned from the
remove method is <code
class="sourceCode scala"><span class="kw">false</span></code>, that
means that its <em>child</em> is not removable, so it is also not
removable, so it should return <code
class="sourceCode scala"><span class="kw">false</span></code>.</p>
<p>Otherwise, it will remove that member (<code
class="sourceCode scala">children<span class="op">.</span><span class="fu">removeValueForKey</span><span class="op">(</span>head<span class="op">)</span></code>).
Then, the Trie can decide whether or not it itself is removable: <code
class="sourceCode scala"><span class="cf">return</span> <span class="op">!</span>endHere <span class="op">&amp;</span>amp<span class="op">;&amp;</span>amp<span class="op">;</span> children<span class="op">.</span>isEmpty</code>.
If the <code class="sourceCode scala">endHere</code> is set to true,
then it is the end of some sequence: it is not removable. Otherwise,
it’s removable if it has no children. Here’s the whole thing, with its
public version:</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> mutating func remove<span class="op">&lt;</span></span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>    G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>    <span class="op">&gt;(</span><span class="kw">var</span> g<span class="op">:</span> G<span class="op">)</span> <span class="op">-&gt;</span> Bool <span class="op">{</span> <span class="co">// Return value signifies whether or not it can be removed</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> let head <span class="op">=</span> g<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>        guard children<span class="op">[</span>head<span class="op">]?.</span><span class="fu">remove</span><span class="op">(</span>g<span class="op">)</span> <span class="op">==</span> <span class="kw">true</span> <span class="cf">else</span> <span class="op">{</span> <span class="cf">return</span> <span class="kw">false</span> <span class="op">}</span></span>
<span id="cb20-7"><a href="#cb20-7" aria-hidden="true" tabindex="-1"></a>        children<span class="op">.</span><span class="fu">removeValueForKey</span><span class="op">(</span>head<span class="op">)</span></span>
<span id="cb20-8"><a href="#cb20-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">!</span>endHere <span class="op">&amp;&amp;</span> children<span class="op">.</span>isEmpty</span>
<span id="cb20-9"><a href="#cb20-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb20-10"><a href="#cb20-10" aria-hidden="true" tabindex="-1"></a>      endHere <span class="op">=</span> <span class="kw">false</span></span>
<span id="cb20-11"><a href="#cb20-11" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> children<span class="op">.</span>isEmpty</span>
<span id="cb20-12"><a href="#cb20-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb20-13"><a href="#cb20-13" aria-hidden="true" tabindex="-1"></a>  public mutating func remove<span class="op">&lt;</span></span>
<span id="cb20-14"><a href="#cb20-14" aria-hidden="true" tabindex="-1"></a>    S <span class="op">:</span> SequenceType where S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span></span>
<span id="cb20-15"><a href="#cb20-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">&gt;(</span>seq<span class="op">:</span> S<span class="op">)</span> <span class="op">{</span></span>
<span id="cb20-16"><a href="#cb20-16" aria-hidden="true" tabindex="-1"></a>      <span class="fu">remove</span><span class="op">(</span>seq<span class="op">.</span><span class="fu">generate</span><span class="op">())</span></span>
<span id="cb20-17"><a href="#cb20-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb20-18"><a href="#cb20-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>That was a little heavy. And kind of ugly. Let’s lighten things up
for a second, with one of the loveliest <code
class="sourceCode scala">count</code> properties I’ve seen:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> count<span class="op">:</span> <span class="bu">Int</span> <span class="op">{</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> children<span class="op">.</span>values<span class="op">.</span><span class="fu">reduce</span><span class="op">(</span>endHere <span class="op">?</span> <span class="dv">1</span> <span class="op">:</span> <span class="dv">0</span><span class="op">)</span> <span class="op">{</span> $<span class="dv">0</span> <span class="op">+</span> $<span class="fl">1.</span>count <span class="op">}</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>All it’s really doing is counting the instances of a <code
class="sourceCode scala"><span class="kw">true</span></code> <code
class="sourceCode scala">endHere</code>. If the current Trie is an end,
then it knows that it adds one to the count (<code
class="sourceCode scala">endHere <span class="op">?</span> <span class="dv">1</span> <span class="op">:</span> <span class="dv">0</span></code>),
and it adds that to the sum of the counts of its children.</p>
<p>Now then. <code class="sourceCode scala">SequenceType</code>. <a
href="http://airspeedvelocity.net/2015/07/22/a-persistent-tree-using-indirect-enums-in-swift/">Getting
tree-like structures to conform to <code
class="sourceCode scala">SequenceType</code> is a bit of a pain</a>,
mainly because of their recursiveness. Getting a linear representation
is easy enough:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>extension Trie <span class="op">{</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> contents<span class="op">:</span> <span class="op">[[</span><span class="ex">Element</span><span class="op">]]</span> <span class="op">{</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> children<span class="op">.</span>flatMap <span class="op">{</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>      <span class="op">(</span>head<span class="op">:</span> <span class="ex">Element</span><span class="op">,</span> child<span class="op">:</span> Trie<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span> <span class="op">-&gt;</span> <span class="op">[[</span><span class="ex">Element</span><span class="op">]]</span> in</span>
<span id="cb22-5"><a href="#cb22-5" aria-hidden="true" tabindex="-1"></a>      child<span class="op">.</span>contents<span class="op">.</span>map <span class="op">{</span> <span class="op">[</span>head<span class="op">]</span> <span class="op">+</span> $<span class="dv">0</span> <span class="op">}</span> <span class="op">+</span> <span class="op">(</span>child<span class="op">.</span>endHere <span class="op">?</span> <span class="op">[[</span>head<span class="op">]]</span> <span class="op">:</span> <span class="op">[])</span></span>
<span id="cb22-6"><a href="#cb22-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb22-7"><a href="#cb22-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb22-8"><a href="#cb22-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And then you could just return the generate method from that for your
Trie’s generate method.</p>
<p>The problem is that it’s not very proper: you’re translating your
data structure into another data structure just to iterate through it.
What you really want is something that generates each element on
demand.</p>
<p>But it gets ugly quick. You’ve got to do a lot of stuff by hand which
it isn’t nice to do by hand, and you’ve got to employ some dirty tricks
(like using closures as a kind of homemade <code
class="sourceCode scala">indirect</code>). At any rate, here it is:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>public struct TrieGenerator<span class="op">&lt;</span><span class="ex">Element</span> <span class="op">:</span> Hashable<span class="op">&gt;</span> <span class="op">:</span> GeneratorType <span class="op">{</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> children<span class="op">:</span> DictionaryGenerator<span class="op">&lt;</span><span class="ex">Element</span><span class="op">,</span> Trie<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;&gt;</span></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> curHead <span class="op">:</span> <span class="ex">Element</span><span class="op">?</span></span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> curEnd  <span class="op">:</span> Bool <span class="op">=</span> <span class="kw">false</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> innerGen<span class="op">:</span> <span class="op">(()</span> <span class="op">-&gt;</span> <span class="op">[</span><span class="ex">Element</span><span class="op">]?)?</span></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> mutating func <span class="fu">update</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb23-7"><a href="#cb23-7" aria-hidden="true" tabindex="-1"></a>    guard <span class="fu">let</span> <span class="op">(</span>head<span class="op">,</span> child<span class="op">)</span> <span class="op">=</span> children<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="cf">else</span> <span class="op">{</span> innerGen <span class="op">=</span> nil<span class="op">;</span> <span class="cf">return</span> <span class="op">}</span></span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>    curHead <span class="op">=</span> head</span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> g <span class="op">=</span> child<span class="op">.</span><span class="fu">generate</span><span class="op">()</span></span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a>    innerGen <span class="op">=</span> <span class="op">{</span>g<span class="op">.</span><span class="fu">next</span><span class="op">()}</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>    curEnd <span class="op">=</span> child<span class="op">.</span>endHere</span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a>  public mutating func <span class="fu">next</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="op">[</span><span class="ex">Element</span><span class="op">]?</span> <span class="op">{</span></span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">;</span> innerGen <span class="op">!=</span> nil<span class="op">;</span> <span class="fu">update</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> let next <span class="op">=</span> innerGen<span class="op">!()</span> <span class="op">{</span></span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">[</span>curHead<span class="op">!]</span> <span class="op">+</span> next</span>
<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span> <span class="cf">else</span> <span class="cf">if</span> curEnd <span class="op">{</span></span>
<span id="cb23-18"><a href="#cb23-18" aria-hidden="true" tabindex="-1"></a>        curEnd <span class="op">=</span> <span class="kw">false</span></span>
<span id="cb23-19"><a href="#cb23-19" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="op">[</span>curHead<span class="op">!]</span></span>
<span id="cb23-20"><a href="#cb23-20" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb23-21"><a href="#cb23-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb23-22"><a href="#cb23-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> nil</span>
<span id="cb23-23"><a href="#cb23-23" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb23-24"><a href="#cb23-24" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="fu">init</span><span class="op">(</span>_ from<span class="op">:</span> Trie<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb23-25"><a href="#cb23-25" aria-hidden="true" tabindex="-1"></a>    children <span class="op">=</span> from<span class="op">.</span>children<span class="op">.</span><span class="fu">generate</span><span class="op">()</span></span>
<span id="cb23-26"><a href="#cb23-26" aria-hidden="true" tabindex="-1"></a>    <span class="fu">update</span><span class="op">()</span></span>
<span id="cb23-27"><a href="#cb23-27" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb23-28"><a href="#cb23-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>It’s got a similar logic to the lazy flatMap I did from a while
ago.</p>
<p>The code is all available <a
href="https://github.com/oisdk/SwiftTrie">here</a>, as a playground, or
<a href="https://github.com/oisdk/SwiftSequence">here</a>, in
SwiftSequence, where it’s accompanied by some tests.</p>
]]></description>
    <pubDate>Tue, 11 Aug 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-08-11-swift-trie.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Monty Hall</title>
    <link>https://doisinkidney.com/posts/2015-08-03-monty-hall.html</link>
    <description><![CDATA[<div class="info">
    Posted on August  3, 2015
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Haskell&#39;." href="/tags/Haskell.html" rel="tag">Haskell</a>, <a title="All pages tagged &#39;Swift&#39;." href="/tags/Swift.html" rel="tag">Swift</a>, <a title="All pages tagged &#39;Probability&#39;." href="/tags/Probability.html" rel="tag">Probability</a>
    
</div>

<p>The Monty Hall problem is a great example of how counter-intuitive
probability can sometimes be. It goes something like this: say you’re on
a gameshow, with the chance to win a car. You’re shown three doors, and
the car is behind one, goats behind the other two. You pick a door, say
the leftmost, but then the host of the gameshow stops you before it’s
opened. He opens one of the two doors you didn’t pick, revealing a goat.
He then asks you if you’d like to change your decision. So? Do you?</p>
<p>Perhaps surprisingly, you <em>should</em> change your decision. Your
chances of winning a car go from 1/3 to 2/3.</p>
<p>If you’ve not thought for a while about the problem, the answer above
might sound instinctively wrong. A few <a
href="http://www.thomashanning.com/swift-playground-the-monty-hall-problem/">blog
posts</a> over the past few weeks have made an effort to put some
concrete numbers to the statistics, running simulations of each
possibility, and counting up the amount of wins and losses.</p>
<p>I was still a little unsatisfied, though. I mean, showing me the
actual numbers is fine, but I’d like something a little more
<em>proof</em>-y. You can get close with a diagram:</p>
<p><img src="/images/monty-hall-tree.png" /></p>
<p>Which makes it pretty clear what’s going on: since the host
<em>has</em> to show a goat when he opens a door, if you’ve picked a
goat, then the only door left after the host opens one is the car. That
means that if you switch and pick a goat, you <em>have</em> to win. So
if you decide to switch, then what you want to do is pick a
<em>goat</em> first, and the chances of that are 2/3.</p>
<p>It would be far cooler if you could get some representation of that
diagram in code, though.</p>
<p>Turns out we can! In Swift and Haskell (I’m branching out) you can
represent probability in a list-like structure, with each element of the
list being a tuple of some value and that value’s probability. All the
probabilities in the list itself should add up to one. Here’s what it
looks like in Swift:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>struct Prob<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> let contents<span class="op">:</span> <span class="op">[(</span><span class="ex">Element</span><span class="op">,</span> <span class="ex">Double</span><span class="op">)]</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>and Haskell:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Prob</span> a <span class="ot">=</span> <span class="dt">Prob</span> {<span class="ot"> getProb ::</span> [(a,<span class="dt">Rational</span>)] } <span class="kw">deriving</span> <span class="dt">Show</span></span></code></pre></div>
<p>Being a list kind of thing, ideally you’d want to be able to
transform the elements, with a map kind of thing:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>extension Prob <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  func fmap<span class="op">&lt;</span>T<span class="op">&gt;(</span>f<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> T<span class="op">)</span> <span class="op">-&gt;</span> Prob<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Prob<span class="op">&lt;</span>T<span class="op">&gt;(</span>contents<span class="op">.</span>map <span class="op">{</span> <span class="op">(</span>v<span class="op">,</span>p<span class="op">)</span> <span class="fu">in</span> <span class="op">(</span><span class="fu">f</span><span class="op">(</span>v<span class="op">),</span> p<span class="op">)</span> <span class="op">})</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb4"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">fmap</span> f (<span class="dt">Prob</span> xs) <span class="ot">=</span> <span class="dt">Prob</span> [(f x,p)<span class="op">|</span>(x,p) <span class="ot">&lt;-</span> xs]</span></code></pre></div>
<p>So far, though, the probability information is kind of superfluous.
There’s not even a decent way to generate it. How about we get it from a
list, where we assume all things in the list have equal chances of
happening:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>extension CollectionType where Index<span class="op">.</span>Distance <span class="op">==</span> <span class="bu">Int</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> equalProbs<span class="op">:</span> Prob<span class="op">&lt;</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    let p <span class="op">=</span> <span class="fl">1.0</span> <span class="op">/</span> <span class="ex">Double</span><span class="op">(</span>count<span class="op">)</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Prob<span class="op">&lt;</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">&gt;(</span>map <span class="op">{</span> v <span class="fu">in</span> <span class="op">(</span>v<span class="op">,</span>p<span class="op">)</span> <span class="op">})</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb6"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="ot">equalProbs ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Prob</span> a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>equalProbs x <span class="ot">=</span> <span class="dt">Prob</span> <span class="op">$</span> <span class="fu">map</span> (<span class="fu">flip</span> (,) (<span class="dv">1</span><span class="op">%</span>n))  x</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">where</span> n <span class="ot">=</span> <span class="fu">fromIntegral</span> (<span class="fu">length</span> x)</span></code></pre></div>
<p>Which is <em>fine</em>, I suppose, but still not very interesting.
What we want is the idea of “branching” - like in the diagram. “If event
A happens, then event B has X chance of happening, and event C has Y
chance of happening”.</p>
<p>The normal rules of probability apply: the <em>overall</em>
probability of B happening is equal to the probability of A multiplied
by X. You could have several layers of branching from B and C onwards,
with this multiplication happening at each stage.</p>
<p>You could represent this in code with a function <code>f</code>,
which takes an event (A) and returns a new bunch of probabilities (B and
C). Then, to get the overall probability of each, you’d have to
<em>flatten</em> it. What you want, then, is a function that travels
over a list of events and their probabilities, applying <code>f</code>
to each, and flattening the result, by <em>multiplying</em> the
probabilities of the inner lists by the probability of the event which
generated it.</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>extension Prob <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  func flatMap<span class="op">&lt;</span>T<span class="op">&gt;(</span>f<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> Prob<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">-&gt;</span> Prob<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Prob<span class="op">&lt;</span>T<span class="op">&gt;(</span>contents<span class="op">.</span>flatMap <span class="op">{</span> <span class="op">(</span>v<span class="op">,</span>p<span class="op">)</span> in</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>      <span class="fu">f</span><span class="op">(</span>v<span class="op">).</span>contents<span class="op">.</span>map <span class="op">{</span> <span class="op">(</span>x<span class="op">,</span>ip<span class="op">)</span> <span class="fu">in</span> <span class="op">(</span>x<span class="op">,</span>p<span class="op">*</span>ip<span class="op">)</span> <span class="op">}</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">})</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb8"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Monad</span> <span class="dt">Prob</span> <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">return</span> <span class="ot">=</span> <span class="fu">pure</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Prob</span> xs <span class="op">&gt;&gt;=</span> f <span class="ot">=</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Prob</span> [(y,px<span class="op">*</span>py)<span class="op">|</span>(x,px) <span class="ot">&lt;-</span> xs, (y,py) <span class="ot">&lt;-</span> getProb(f x)]</span></code></pre></div>
<p>Hey look! The M-word. Never mind that. Anyway…</p>
<p>Now we have enough tools to stimulate some basic probabilities. Let’s
say you’re playing a game, which begins with a coin flip. If you get
heads on the coin flip, it confers some advantage, and you have a 70%
chance of winning. Otherwise, you’ve a 50% chance.</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>enum Coin<span class="op">:</span> <span class="ex">String</span>   <span class="op">{</span> <span class="cf">case</span> H<span class="op">,</span> T <span class="op">}</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>enum <span class="ex">Result</span><span class="op">:</span> <span class="ex">String</span> <span class="op">{</span> <span class="cf">case</span> Win<span class="op">,</span> Lose <span class="op">}</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>func <span class="fu">play</span><span class="op">(</span>c<span class="op">:</span> Coin<span class="op">)</span> <span class="op">-&gt;</span> Prob<span class="op">&lt;</span><span class="ex">Result</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  switch c <span class="op">{</span></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="op">.</span>H<span class="op">:</span> <span class="cf">return</span> <span class="fu">Prob</span><span class="op">([(.</span>Win<span class="op">,</span><span class="fl">0.7</span><span class="op">),(.</span>Lose<span class="op">,</span><span class="fl">0.3</span><span class="op">)])</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="op">.</span>T<span class="op">:</span> <span class="cf">return</span> <span class="op">[.</span>Win<span class="op">,.</span>Lose<span class="op">].</span>equalProbs</span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true" tabindex="-1"></a><span class="op">[</span>Coin<span class="op">.</span>H<span class="op">,.</span>T<span class="op">]</span></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span>equalProbs</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">flatMap</span><span class="op">(</span>play<span class="op">)</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.35: Result.Win</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.15: Result.Lose</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.25: Result.Win</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.25: Result.Lose</span></span></code></pre></div>
<div class="sourceCode" id="cb10"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Coin</span>   <span class="ot">=</span> <span class="dt">H</span> <span class="op">|</span> <span class="dt">T</span> <span class="kw">deriving</span> <span class="dt">Show</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Result</span> <span class="ot">=</span> <span class="dt">Win</span> <span class="op">|</span> <span class="dt">Lose</span> <span class="kw">deriving</span> <span class="dt">Show</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> play <span class="dt">H</span> <span class="ot">=</span> <span class="dt">Prob</span> [(<span class="dt">Win</span>,<span class="dv">7</span><span class="op">%</span><span class="dv">10</span>),(<span class="dt">Lose</span>,<span class="dv">3</span><span class="op">%</span><span class="dv">10</span>)]</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>    play <span class="dt">T</span> <span class="ot">=</span> equalProbs [<span class="dt">Win</span>,<span class="dt">Lose</span>]</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>equalProbs [<span class="dt">H</span>,<span class="dt">T</span>] <span class="op">&gt;&gt;=</span> play</span></code></pre></div>
<p>There’s an obvious problem: duplicates. We need some way to
<em>combine</em> the results by adding their probabilities together. To
be honest, this was the least interesting part, so I’ll just dump the
code here:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>public enum Ordering <span class="op">{</span> <span class="cf">case</span> LT<span class="op">,</span> EQ<span class="op">,</span> GT <span class="op">}</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>extension SequenceType <span class="op">{</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> typealias A <span class="op">=</span> Generator<span class="op">.</span><span class="ex">Element</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>  public func <span class="fu">mergeBy</span><span class="op">(</span> comp<span class="op">:</span> <span class="op">(</span>A<span class="op">,</span> A<span class="op">)</span> <span class="op">-&gt;</span> Ordering</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>                     <span class="op">,</span> _ merge<span class="op">:</span> <span class="op">(</span>A<span class="op">,</span> A<span class="op">)</span> <span class="op">-&gt;</span> A<span class="op">)</span> <span class="op">-&gt;</span> <span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> result<span class="op">:</span> <span class="op">[</span>A<span class="op">]</span> <span class="op">=</span> <span class="op">[]</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> h in <span class="fu">sort</span><span class="op">({</span> e in <span class="fu">comp</span><span class="op">(</span>e<span class="op">)</span> <span class="op">==</span> <span class="op">.</span>LT <span class="op">})</span> <span class="op">{</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="cf">case</span> <span class="op">.</span>EQ<span class="op">?</span> <span class="op">=</span> result<span class="op">.</span>last<span class="op">.</span><span class="fu">map</span><span class="op">({</span>e in <span class="fu">comp</span><span class="op">(</span>h<span class="op">,</span>e<span class="op">)})</span> <span class="op">{</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>        result<span class="op">.</span><span class="fu">append</span><span class="op">(</span><span class="fu">merge</span><span class="op">(</span>result<span class="op">.</span><span class="fu">removeLast</span><span class="op">(),</span>h<span class="op">))</span></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>        result<span class="op">.</span><span class="fu">append</span><span class="op">(</span>h<span class="op">)</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> result</span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a>extension Prob <span class="op">{</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a>  public func mergeProbs</span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span>comp<span class="op">:</span> <span class="op">(</span><span class="ex">Element</span><span class="op">,</span><span class="ex">Element</span><span class="op">)</span> <span class="op">-&gt;</span> Ordering<span class="op">)</span> <span class="op">-&gt;</span> Prob <span class="op">{</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> <span class="fu">Prob</span><span class="op">(</span>contents<span class="op">:</span></span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a>        contents<span class="op">.</span><span class="fu">mergeBy</span><span class="op">(</span> <span class="op">{(</span>a<span class="op">,</span>b<span class="op">)</span> in <span class="fu">comp</span><span class="op">(</span>a<span class="fl">.0</span><span class="op">,</span>b<span class="fl">.0</span><span class="op">)}</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a>                        <span class="op">,</span> <span class="op">{(</span>a<span class="op">,</span>b<span class="op">)</span> <span class="fu">in</span> <span class="op">(</span>a<span class="fl">.0</span><span class="op">,</span>a<span class="fl">.1</span><span class="op">+</span>b<span class="fl">.1</span><span class="op">)})</span></span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb12"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a><span class="ot">eqing ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Ordering</span>) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span>)</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>eqing c <span class="ot">=</span> (\a b <span class="ot">-&gt;</span> <span class="kw">case</span> c a b <span class="kw">of</span> <span class="dt">EQ</span> <span class="ot">-&gt;</span> <span class="dt">True</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>                                 _  <span class="ot">-&gt;</span> <span class="dt">False</span>)</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeBy ::</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Ordering</span>) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>mergeBy m c <span class="ot">=</span> (foldl1&#39; m <span class="op">&lt;$&gt;</span>) <span class="op">.</span> groupBy (eqing c) <span class="op">.</span> sortBy c</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a><span class="ot">mergeProbs ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Prob</span> a <span class="ot">-&gt;</span> <span class="dt">Prob</span> a</span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a>mergeProbs <span class="ot">=</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Prob</span> <span class="op">.</span> mergeBy (<span class="fu">fmap</span> <span class="op">.</span> (<span class="op">+</span>) <span class="op">.</span> <span class="fu">snd</span>) (comparing <span class="fu">fst</span>) <span class="op">.</span> getProb</span></code></pre></div>
<p>Now we get some nicer probabilities, though:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>func <span class="fu">comp</span><span class="op">(</span>a<span class="op">:</span> <span class="ex">Result</span><span class="op">,</span> b<span class="op">:</span><span class="ex">Result</span><span class="op">)</span> <span class="op">-&gt;</span> Ordering <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">switch</span> <span class="op">(</span>a<span class="op">,</span>b<span class="op">)</span> <span class="op">{</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="op">(.</span>Win<span class="op">,.</span>Win<span class="op">),(.</span>Lose<span class="op">,.</span>Lose<span class="op">):</span> <span class="cf">return</span> <span class="op">.</span>EQ</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="op">(.</span>Lose<span class="op">,.</span>Win<span class="op">):</span> <span class="cf">return</span> <span class="op">.</span>LT</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="op">(.</span>Win<span class="op">,.</span>Lose<span class="op">):</span> <span class="cf">return</span> <span class="op">.</span>GT</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb13-7"><a href="#cb13-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb13-8"><a href="#cb13-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a><span class="op">[</span>Coin<span class="op">.</span>H<span class="op">,.</span>T<span class="op">]</span></span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span>equalProbs</span>
<span id="cb13-11"><a href="#cb13-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">flatMap</span><span class="op">(</span>play<span class="op">)</span></span>
<span id="cb13-12"><a href="#cb13-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">mergeProbs</span><span class="op">(</span>comp<span class="op">)</span></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.4: Result.Lose</span></span>
<span id="cb13-15"><a href="#cb13-15" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.6: Result.Win</span></span></code></pre></div>
<div class="sourceCode" id="cb14"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Ord</span> <span class="dt">Result</span> <span class="kw">where</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">compare</span> <span class="dt">Win</span> <span class="dt">Lose</span> <span class="ot">=</span> <span class="dt">GT</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">compare</span> <span class="dt">Lose</span> <span class="dt">Win</span> <span class="ot">=</span> <span class="dt">LT</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">compare</span> _    _   <span class="ot">=</span> <span class="dt">EQ</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>mergeProbs ( equalProbs [<span class="dt">H</span>,<span class="dt">T</span>] <span class="op">&gt;&gt;=</span> play )</span></code></pre></div>
<p>And you can see what effect a loaded coin would have on your
chances:</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="fu">Prob</span><span class="op">([(</span>Coin<span class="op">.</span>H<span class="op">,</span><span class="fl">0.7</span><span class="op">),(.</span>T<span class="op">,</span><span class="fl">0.3</span><span class="op">)])</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">flatMap</span><span class="op">(</span>play<span class="op">)</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">.</span><span class="fu">mergeProbs</span><span class="op">(</span>comp<span class="op">)</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.36: Result.Lose</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.64: Result.Win</span></span></code></pre></div>
<div class="sourceCode" id="cb16"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>mergeProbs ( <span class="dt">Prob</span> [(<span class="dt">H</span>,<span class="dv">7</span><span class="op">%</span><span class="dv">10</span>),(<span class="dt">T</span>,<span class="dv">3</span><span class="op">%</span><span class="dv">10</span>)] <span class="op">&gt;&gt;=</span> play )</span></code></pre></div>
<p>So how does this apply to Monty Hall? Well, we’ve actually done most
of the work already. We’ll represent the doors as an Int, and the choice
by an enum.</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>public enum <span class="ex">Choice</span> <span class="op">{</span> <span class="cf">case</span> Switch<span class="op">,</span> Stick <span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb18"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Choice</span> <span class="ot">=</span> <span class="dt">Switch</span> <span class="op">|</span> <span class="dt">Stick</span></span></code></pre></div>
<p>Then, a <code class="sourceCode scala">chances</code> function. The
logic here is a bit dense. First of all, if you’re going to stick, it
doesn’t matter how many doors the host opens: your chance of getting a
car is <code>1/n</code>, where <code>n</code> is the number of doors.
However, if you’re going to switch, two things need to happen: you need
to <em>not</em> pick the car on your first choice, <em>and</em> you need
to pick the car on your second choice. The chance of picking the car on
your second choice (if the one you picked on your first choice
<em>wasn’t</em> the car) is the one over the number of doors, minus the
number of doors the host opens, minus one.</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>public func <span class="fu">chances</span><span class="op">(</span>n<span class="op">:</span> <span class="bu">Int</span><span class="op">,</span> _ p<span class="op">:</span> <span class="bu">Int</span><span class="op">,</span> _ c<span class="op">:</span> <span class="ex">Choice</span><span class="op">)(</span>_ d<span class="op">:</span> <span class="bu">Int</span><span class="op">)</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> Prob<span class="op">&lt;</span>Bool<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>    switch c <span class="op">{</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Stick <span class="op">:</span> <span class="cf">return</span> <span class="op">(</span><span class="dv">1</span><span class="op">...</span>n<span class="op">).</span>equalProbs<span class="op">.</span><span class="fu">fmap</span><span class="op">(==</span>d<span class="op">)</span></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Switch<span class="op">:</span></span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>      let notFirst <span class="op">=</span> <span class="fu">chances</span><span class="op">(</span>n<span class="op">,</span>p<span class="op">,.</span>Stick<span class="op">)(</span>d<span class="op">).</span><span class="fu">fmap</span><span class="op">(!)</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>      let second <span class="op">=</span></span>
<span id="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>        <span class="fu">Repeat</span><span class="op">(</span>count<span class="op">:</span> <span class="op">(</span>n<span class="op">-</span>p<span class="op">)-</span><span class="dv">2</span><span class="op">,</span> repeatedValue<span class="op">:</span> <span class="kw">false</span><span class="op">)</span> <span class="op">+</span> <span class="op">[</span><span class="kw">true</span><span class="op">]</span></span>
<span id="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> notFirst<span class="op">.</span>flatMap <span class="op">{</span> f in</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>        second<span class="op">.</span>equalProbs<span class="op">.</span>fmap <span class="op">{</span> s in f <span class="op">&amp;&amp;</span> s <span class="op">}</span></span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb20"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a><span class="ot">chances ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Choice</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Prob</span> <span class="dt">Bool</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>chances n _ <span class="dt">Stick</span>  d <span class="ot">=</span> <span class="fu">fmap</span> (<span class="op">==</span>d) (equalProbs [<span class="dv">1</span><span class="op">..</span>n])</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>chances n p <span class="dt">Switch</span> d <span class="ot">=</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>  (<span class="op">&amp;&amp;</span>) <span class="op">.</span> <span class="fu">not</span>          <span class="op">&lt;$&gt;</span></span>
<span id="cb20-5"><a href="#cb20-5" aria-hidden="true" tabindex="-1"></a>  chances n p <span class="dt">Stick</span> d <span class="op">&lt;*&gt;</span></span>
<span id="cb20-6"><a href="#cb20-6" aria-hidden="true" tabindex="-1"></a>  (equalProbs <span class="op">$</span> <span class="dt">True</span> <span class="op">:</span> <span class="fu">replicate</span> (n<span class="op">-</span>p<span class="op">-</span><span class="dv">2</span>) <span class="dt">False</span>)</span></code></pre></div>
<p>Finally, the <code>chanceOfCar</code> function:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>public func chanceOfCar</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  <span class="op">(</span>n<span class="op">:</span> <span class="bu">Int</span><span class="op">,</span> _ p<span class="op">:</span> <span class="bu">Int</span><span class="op">,</span> _ s<span class="op">:</span> <span class="ex">Choice</span><span class="op">)</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>  <span class="op">-&gt;</span> Prob<span class="op">&lt;</span>Bool<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">(</span><span class="dv">1</span><span class="op">...</span>n<span class="op">)</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span>equalProbs</span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span><span class="fu">flatMap</span><span class="op">(</span><span class="fu">chances</span><span class="op">(</span>n<span class="op">,</span>p<span class="op">,</span>s<span class="op">))</span></span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span><span class="fu">mergeProbs</span><span class="op">(</span>comp<span class="op">)</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<div class="sourceCode" id="cb22"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a><span class="ot">chanceOfCar ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Choice</span> <span class="ot">-&gt;</span> <span class="dt">Prob</span> <span class="dt">Bool</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>chanceOfCar n p s <span class="ot">=</span> mergeProbs <span class="op">$</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a>                    equalProbs [<span class="dv">1</span><span class="op">..</span>n] <span class="op">&gt;&gt;=</span></span>
<span id="cb22-4"><a href="#cb22-4" aria-hidden="true" tabindex="-1"></a>                    chances n p s</span></code></pre></div>
<p>Which returns, as you’d expect, 1/3 chance of car if you stick, and
2/3 if you switch.</p>
<p>One of the final cool things you can do with this is change the
number of doors, and the number of doors the host opens, and see what
happens:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a><span class="fu">chanceOfCar</span><span class="op">(</span><span class="dv">6</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="op">.</span>Switch<span class="op">)</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="co">// 0.833333333333334: false, 0.166666666666667: true</span></span></code></pre></div>
<div class="sourceCode" id="cb24"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>chanceOfCar <span class="dv">8</span> <span class="dv">3</span> <span class="dt">Switch</span> <span class="op">//</span> <span class="dv">7</span> <span class="op">%</span> <span class="dv">32</span></span></code></pre></div>
<p>The advantage gets less and less, but never goes away.</p>
<p>If you check out the <a
href="https://en.wikipedia.org/wiki/Monty_Hall_problem#N_doors">Wikipedia</a>
entry on the problem, the formula for
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>N</mi><annotation encoding="application/x-tex">N</annotation></semantics></math>-doors
is given:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mfrac><mrow><mi>N</mi><mo>−</mo><mn>1</mn></mrow><mrow><mi>N</mi><mo stretchy="false" form="prefix">(</mo><mi>N</mi><mo>−</mo><mi>p</mi><mo>−</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow></mfrac><annotation encoding="application/x-tex">\frac{N−1}{N(N−p−1)}</annotation></semantics></math>.</p>
<p>We can plug that straight in to our versions, to see if they’re
correct:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> sample <span class="ot">=</span> [(n,p)<span class="op">|</span> n <span class="ot">&lt;-</span> [<span class="dv">3</span><span class="op">..</span><span class="dv">20</span>], p <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>(n<span class="op">-</span><span class="dv">2</span>)]]</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> expect <span class="ot">=</span> <span class="fu">fmap</span> frmla sample</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>             <span class="kw">where</span><span class="ot"> frmla ::</span> (<span class="dt">Integer</span>,<span class="dt">Integer</span>) <span class="ot">-&gt;</span> <span class="dt">Rational</span></span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>                   frmla (n,p) <span class="ot">=</span> (n <span class="op">-</span> <span class="dv">1</span>)<span class="op">%</span>(n<span class="op">*</span>(n<span class="op">-</span>p<span class="op">-</span><span class="dv">1</span>))</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a><span class="kw">let</span> actual <span class="ot">=</span> <span class="fu">fmap</span> t sample <span class="kw">where</span></span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>  t (n,p) <span class="ot">=</span> truePrb <span class="op">$</span> getProb <span class="op">$</span> chanceOfCar n p <span class="dt">Switch</span></span>
<span id="cb25-8"><a href="#cb25-8" aria-hidden="true" tabindex="-1"></a>  truePrb <span class="ot">=</span> fromJust <span class="op">.</span> (<span class="fu">fmap</span> <span class="fu">snd</span>) <span class="op">.</span> (find <span class="fu">fst</span>)</span>
<span id="cb25-9"><a href="#cb25-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb25-10"><a href="#cb25-10" aria-hidden="true" tabindex="-1"></a>expect <span class="op">==</span> actual</span></code></pre></div>
<p>And it works! (I didn’t try the Swift version, because of
floating-point inaccuracies)</p>
<p>You can see the code used <a
href="https://github.com/oisdk/Monty-Hall">here</a>.</p>
]]></description>
    <pubDate>Mon, 03 Aug 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-08-03-monty-hall.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>Deques, Queues, and Lists in Swift with Indirect</title>
    <link>https://doisinkidney.com/posts/2015-07-29-swift-queues.html</link>
    <description><![CDATA[<div class="info">
    Posted on July 29, 2015
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Swift&#39;." href="/tags/Swift.html" rel="tag">Swift</a>, <a title="All pages tagged &#39;Data Structures&#39;." href="/tags/Data%20Structures.html" rel="tag">Data Structures</a>
    
</div>

<p>Recursive enums have finally arrived. Woo! The first thing to do with
these is to make a recursive list:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>public enum <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> Nil</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  indirect <span class="cf">case</span> <span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="ex">Element</span><span class="op">,</span> tail<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The <code class="sourceCode scala">head</code> stores the element,
and <code class="sourceCode scala">tail</code> is a reference to the
rest of the list. As you can imagine, getting at the <code
class="sourceCode scala">head</code> is pretty easy, while accessing
elements further along is more difficult. There’s a common pattern for
dealing with these recursive structures: if you have a function that
performs some transformation on a list, it will take the <code
class="sourceCode scala">head</code>, perform that transformation on it,
and then call itself recursively on the <code
class="sourceCode scala">tail</code>. If it’s given an empty list, it
returns an empty list. For instance, here’s the <code
class="sourceCode haskell"><span class="fu">map</span></code> function,
defined in Haskell:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span> _ []     <span class="ot">=</span> []</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="fu">map</span> f (x<span class="op">:</span>xs) <span class="ot">=</span> f x <span class="op">:</span> <span class="fu">map</span> f xs</span></code></pre></div>
<p>The two lines are analogous to a switch statement in Swift. The
parameters for <code
class="sourceCode haskell"><span class="fu">map</span></code> are a
transformation function and a list. So, the first line has <code
class="sourceCode haskell">_</code> (wildcard) for the function, and
<code class="sourceCode haskell">[]</code> (empty) for the list, meaning
it will match any function and an empty list. It returns an empty
list.</p>
<p>The second line matches a function (which it assigns the name <code
class="sourceCode scala">f</code>) and then decomposes the list it’s
given into a head (<code class="sourceCode scala">x</code>) and tail
(<code class="sourceCode scala">xs</code>). It then calls <code
class="sourceCode scala">f</code> on the head, and prepends (the <code
class="sourceCode scala"><span class="op">:</span></code> operator is
prepends, also called “cons” by convention) the result to itself called
recursively on the tail.</p>
<p>With switch statements and the <code
class="sourceCode scala">indirect</code> keyword, we’re getting pretty
close to that level of brevity (terseness?) in Swift:</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  public func map<span class="op">&lt;</span>T<span class="op">&gt;(</span>@noescape transform<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> T<span class="op">)</span> <span class="op">-&gt;</span> <span class="ex">List</span><span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    switch self <span class="op">{</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="cf">return</span> <span class="op">.</span>Nil</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">):</span> <span class="cf">return</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="fu">transform</span><span class="op">(</span>head<span class="op">),</span> tail<span class="op">:</span> tail<span class="op">.</span><span class="fu">map</span><span class="op">(</span>transform<span class="op">))</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>We can define our own “cons”, to clean it up a little. We’re not
allowed to use <code
class="sourceCode scala"><span class="op">:</span></code>, so I went
with <code
class="sourceCode scala"><span class="op">|&gt;</span></code>, which is,
in my mind, reasonably representative of “cons”.</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>infix operator <span class="op">|&gt;</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  associativity right</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>  precedence <span class="dv">100</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>public func <span class="op">|&gt;</span> <span class="op">&lt;</span>T<span class="op">&gt;(</span>lhs<span class="op">:</span> T<span class="op">,</span> rhs<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">-&gt;</span> <span class="ex">List</span><span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> lhs<span class="op">,</span> tail<span class="op">:</span> rhs<span class="op">)</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>  public func map<span class="op">&lt;</span>T<span class="op">&gt;(</span>@noescape transform<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> T<span class="op">)</span> <span class="op">-&gt;</span> <span class="ex">List</span><span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a>    switch self <span class="op">{</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="cf">return</span> <span class="op">.</span>Nil</span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">):</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> <span class="fu">transform</span><span class="op">(</span>head<span class="op">)</span> <span class="op">|&gt;</span> tail<span class="op">.</span><span class="fu">map</span><span class="op">(</span>transform<span class="op">)</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb4-18"><a href="#cb4-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Pretty soon you can start doing some elegant and exciting things with
lists. The recursive pattern is <em>very</em> well suited to
higher-order functions and other FP staples. Take, for instance, the
<code class="sourceCode scala">reduce</code> function:</p>
<div class="sourceCode" id="cb5"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  public func reduce<span class="op">&lt;</span>T<span class="op">&gt;(</span>initial<span class="op">:</span> T<span class="op">,</span> @noescape combine<span class="op">:</span> <span class="op">(</span>T<span class="op">,</span> <span class="ex">Element</span><span class="op">)</span> <span class="op">-&gt;</span> T<span class="op">)</span> <span class="op">-&gt;</span> T <span class="op">{</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>    switch self <span class="op">{</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="cf">return</span> initial</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>h<span class="op">,</span> t<span class="op">):</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> t<span class="op">.</span><span class="fu">reduce</span><span class="op">(</span><span class="fu">combine</span><span class="op">(</span>initial<span class="op">,</span> h<span class="op">),</span> combine<span class="op">:</span> combine<span class="op">)</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Or a transposing function:</p>
<div class="sourceCode" id="cb6"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>func transpose<span class="op">&lt;</span>T<span class="op">&gt;(</span>mat<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">List</span><span class="op">&lt;</span>T<span class="op">&gt;&gt;)</span> <span class="op">-&gt;</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">List</span><span class="op">&lt;</span>T<span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  switch mat <span class="op">{</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>x<span class="op">,</span> xs<span class="op">)</span> where x<span class="op">.</span>isEmpty<span class="op">:</span> <span class="cf">return</span> <span class="fu">transpose</span><span class="op">(</span>xs<span class="op">)</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(.</span><span class="fu">Cons</span><span class="op">(</span>x<span class="op">,</span> xs<span class="op">),</span> xss<span class="op">):</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">(</span>x <span class="op">|&gt;</span> xss<span class="op">.</span>flatMap<span class="op">{</span>$<span class="fl">0.f</span>irst<span class="op">})</span> <span class="op">|&gt;</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>      <span class="fu">transpose</span><span class="op">(</span>xs <span class="op">|&gt;</span> xss<span class="op">.</span>map<span class="op">{</span>$<span class="fl">0.</span>tail<span class="op">})</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>  default<span class="op">:</span> <span class="cf">return</span> <span class="op">.</span>Nil</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a>let jo<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">List</span><span class="op">&lt;</span><span class="bu">Int</span><span class="op">&gt;&gt;</span> <span class="op">=</span> <span class="op">[[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">],</span> <span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">],</span> <span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">]]</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a><span class="fu">transpose</span><span class="op">(</span>jo<span class="op">)</span> <span class="co">// [[1, 1, 1], [2, 2, 2], [3, 3, 3]]</span></span></code></pre></div>
<p>You can do <code class="sourceCode scala">foldr</code>, which is like
<code class="sourceCode scala">reduce</code>, but works in reverse:</p>
<div class="sourceCode" id="cb7"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  func foldr<span class="op">&lt;</span>T<span class="op">&gt;(</span>initial<span class="op">:</span> T<span class="op">,</span> @noescape combine<span class="op">:</span> <span class="op">(</span>element<span class="op">:</span> <span class="ex">Element</span><span class="op">,</span> accumulator<span class="op">:</span> T<span class="op">)</span> <span class="op">-&gt;</span> T<span class="op">)</span> <span class="op">-&gt;</span> T <span class="op">{</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    switch self <span class="op">{</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="cf">return</span> initial</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>x<span class="op">,</span> xs<span class="op">):</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> <span class="fu">combine</span><span class="op">(</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>        element<span class="op">:</span> x<span class="op">,</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>        accumulator<span class="op">:</span> xs<span class="op">.</span><span class="fu">foldr</span><span class="op">(</span>initial<span class="op">,</span> combine<span class="op">:</span> combine<span class="op">)</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">)</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Using <code class="sourceCode scala">foldr</code>, you can get all of
the non-empty subsequences of a list:</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">var</span> subsequences<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;&gt;</span> <span class="op">{</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    switch self <span class="op">{</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="cf">return</span> <span class="op">.</span>Nil</span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>x<span class="op">,</span> xs<span class="op">):</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> <span class="op">[</span>x<span class="op">]</span> <span class="op">|&gt;</span> xs<span class="op">.</span>subsequences<span class="op">.</span><span class="fu">foldr</span><span class="op">([])</span> <span class="op">{</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a>        <span class="op">(</span>ys<span class="op">,</span> r<span class="op">)</span> in ys <span class="op">|&gt;</span> <span class="op">(</span>x <span class="op">|&gt;</span> ys<span class="op">)</span> <span class="op">|&gt;</span> r</span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>let jo<span class="op">:</span> <span class="ex">List</span> <span class="op">=</span> <span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">]</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a>jo<span class="op">.</span>subsequences <span class="co">// [[1], [2], [1, 2], [1, 3], [2, 3], [1, 2, 3]]</span></span></code></pre></div>
<p>(these examples are all translated from the Haskell standard library)
Lists are extremely fun, and some functions you would have found
yourself writing on 10-15 lines can be got into 2-3. To get a better
feel for playing around with lists, it’s useful to have them conform to
some protocols that make them easier to work with in a playground.</p>
<p>For instance, making a list currently looks like this:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>let jo<span class="op">:</span> <span class="ex">List</span> <span class="op">=</span> <span class="dv">1</span> <span class="op">|&gt;</span> <span class="dv">2</span> <span class="op">|&gt;</span> <span class="dv">3</span> <span class="op">|&gt;</span> <span class="op">.</span>Nil</span></code></pre></div>
<p>Which is fine, and better than:</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>let jo<span class="op">:</span> <span class="ex">List</span> <span class="op">=</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="dv">1</span><span class="op">,</span> tail<span class="op">:</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="dv">2</span><span class="op">,</span> tail<span class="op">:</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="dv">3</span><span class="op">,</span> tail<span class="op">:</span> <span class="op">.</span>Nil<span class="op">)))</span></span></code></pre></div>
<p>but still not fantastic. The obvious next step is making <code
class="sourceCode scala"><span class="ex">List</span></code> <code
class="sourceCode scala">ArrayLiteralConvertible</code>, but there’s a
small catch. We don’t have an <code
class="sourceCode scala">append</code> function for lists (yet). So we
can’t, off the bat, do something like this:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">:</span> ArrayLiteralConvertible <span class="op">{</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  public <span class="fu">init</span><span class="op">(</span>arrayLiteral<span class="op">:</span> <span class="ex">Element</span><span class="op">...)</span> <span class="op">{</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> ret<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">=</span> <span class="op">.</span>Nil</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> el in arrayLiteral <span class="op">{</span> ret<span class="op">.</span><span class="fu">append</span><span class="op">(</span>el<span class="op">)</span> <span class="op">}</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>    self <span class="op">=</span> ret</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And nor do I think we’d want to. Operations on the end of lists are
slow: you have to walk along the entire list every time.</p>
<p>We could <em>reverse</em> the sequence we want to turn into a list,
and prepend as we go. But… that’s inefficient too. Sure, <code
class="sourceCode scala"><span class="ex">Array</span></code>s are fast
to reverse, but other sequences aren’t. For those that can’t be reversed
lazily, you’re storing an extra sequence in memory unnecessarily.</p>
<p>But there’s something that we can use: generators. In Swift,
generators are like super-imperative, crazy-unsafe recursive lists. When
you call the <code
class="sourceCode scala"><span class="fu">next</span><span class="op">()</span></code>
method on a generator, you get the “head” back. Crucially, though:
<em>the generator is left with the tail</em>. Making use of this fact
too often will lead to bugs, but if we wrap it up in <code
class="sourceCode scala"><span class="kw">private</span></code>, it’s a
perfect fit:</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> init<span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">{</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>      self <span class="op">=</span> head <span class="op">|&gt;</span> <span class="ex">List</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true" tabindex="-1"></a>      self <span class="op">=</span> <span class="op">.</span>Nil</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The potential bug here is kind of interesting. If, instead of an
infix operator for cons, we’d had a method on <code
class="sourceCode scala"><span class="ex">List</span></code> that did
the same thing:</p>
<div class="sourceCode" id="cb13"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  public func <span class="fu">prepended</span><span class="op">(</span><span class="kw">with</span><span class="op">:</span> <span class="ex">Element</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="kw">with</span><span class="op">,</span> tail<span class="op">:</span> self<span class="op">)</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>We’d be able to curry that function in a <code
class="sourceCode scala"><span class="fu">map</span><span class="op">()</span></code>,
and get an <code class="sourceCode scala">init</code> function that’s
very pretty:</p>
<div class="sourceCode" id="cb14"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> init<span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;(</span><span class="kw">var</span> g<span class="op">:</span> G<span class="op">)</span> <span class="op">{</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    self <span class="op">=</span> g<span class="op">.</span><span class="fu">next</span><span class="op">().</span><span class="fu">map</span><span class="op">(</span><span class="ex">List</span><span class="op">(</span>g<span class="op">:</span> g<span class="op">).</span>prepended<span class="op">)</span> <span class="op">??</span> <span class="op">.</span>Nil</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>But it won’t run. Since the recursive call to the function is
curried, it’s resolved before the <code
class="sourceCode scala">g<span class="op">.</span><span class="fu">next</span><span class="op">()</span></code>
part. Which means that, regardless of whether <code
class="sourceCode scala">g</code> returns <code
class="sourceCode scala">nil</code> or not, the call will be made,
causing an infinite loop of sadness. To fix it, you have to make the
order of operations clear: <em>do not</em> make a recursive call if
<code
class="sourceCode scala">g<span class="op">.</span><span class="fu">next</span><span class="op">()</span></code>
returns <code class="sourceCode scala">nil</code>.</p>
<div class="sourceCode" id="cb15"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> init<span class="op">&lt;</span>G <span class="op">:</span> GeneratorType where G<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;(</span><span class="kw">var</span> gen<span class="op">:</span> G<span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> let head <span class="op">=</span> gen<span class="op">.</span><span class="fu">next</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>      self <span class="op">=</span> head <span class="op">|&gt;</span> <span class="ex">List</span><span class="op">(</span>gen<span class="op">:</span> gen<span class="op">)</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>      self <span class="op">=</span> <span class="op">.</span>Nil</span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a>  public init<span class="op">&lt;</span>S <span class="op">:</span> SequenceType where S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;(</span>_ seq<span class="op">:</span> S<span class="op">)</span> <span class="op">{</span></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    self <span class="op">=</span> <span class="ex">List</span><span class="op">(</span>gen<span class="op">:</span> seq<span class="op">.</span><span class="fu">generate</span><span class="op">())</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">:</span> ArrayLiteralConvertible <span class="op">{</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>  public <span class="fu">init</span><span class="op">(</span>arrayLiteral<span class="op">:</span> <span class="ex">Element</span><span class="op">...)</span> <span class="op">{</span></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>    self <span class="op">=</span> <span class="ex">List</span><span class="op">(</span>arrayLiteral<span class="op">.</span><span class="fu">generate</span><span class="op">())</span></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This all makes it easy to initialise a list. Being able to
<em>see</em> the list and its contents is also important. Currently,
we’ve got this mess:</p>
<p><img class="aligncenter size-full wp-image-404" src="https://bigonotetaking.files.wordpress.com/2015/07/screen-shot-2015-07-29-at-12-12-56.png" alt="Screen Shot 2015-07-29 at 12.12.56" width="660" height="39" /></p>
<p>When what we really want is a comma-separated list of the contents.
We also probably want some demarcation at either end, so it’s easier to
recognise nested lists. I’m not sure what the best demarcation would be:
ideally it should be different to an Array’s square brackets, but not
confusing either. I went with <code
class="sourceCode scala"><span class="op">[:</span></code> and <code
class="sourceCode scala"><span class="op">:]</span></code> in the end,
though I’m not terribly happy about it:</p>
<p><img class="aligncenter size-full wp-image-406" src="https://bigonotetaking.files.wordpress.com/2015/07/screen-shot-2015-07-29-at-12-27-53.png" alt="Screen Shot 2015-07-29 at 12.27.53" width="522" height="32" /></p>
<p>To get that printout on the right-hand-side of your playground, you
need to make your type <code
class="sourceCode scala">CustomDebugStringConvertible</code>. There’s
one interesting problem with this: how do you know the contents of your
list are printable? You can’t extend your struct to have conditional
conformance, like this:</p>
<div class="sourceCode" id="cb16"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">(</span>where <span class="ex">Element</span> <span class="op">:</span> CustomDebugStringConvertible<span class="op">)</span> <span class="op">:</span> CustomDebugStringConvertible <span class="op">{...</span></span></code></pre></div>
<p>However, you can’t just get a string representation of something that
doesn’t have one. Luckily, <code
class="sourceCode scala"><span class="ex">String</span></code> has an
initialiser that takes <em>anything</em>. It uses runtime reflection to
do so. Here’s what the extension ends up looking like:</p>
<div class="sourceCode" id="cb17"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb17-1"><a href="#cb17-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">:</span> CustomDebugStringConvertible <span class="op">{</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> debugDescription<span class="op">:</span> <span class="ex">String</span> <span class="op">{</span></span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>    return<span class="st">&quot;[:&quot;</span> <span class="op">+</span> <span class="st">&quot;, &quot;</span><span class="op">.</span><span class="fu">join</span><span class="op">(</span>map<span class="op">{</span><span class="ex">String</span><span class="op">(</span>reflecting<span class="op">:</span> $<span class="dv">0</span><span class="op">)})</span> <span class="op">+</span> <span class="st">&quot;:]&quot;</span></span>
<span id="cb17-4"><a href="#cb17-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb17-5"><a href="#cb17-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>To use the <code
class="sourceCode scala"><span class="fu">join</span><span class="op">()</span></code>
function, of course, <code
class="sourceCode scala"><span class="ex">List</span></code> needs to
conform to <code class="sourceCode scala">SequenceType</code>. We’ll
need some generator that swaps out the current <code
class="sourceCode scala"><span class="ex">List</span></code> struct on
each iteration, and returns the head. You <em>could</em> just use <code
class="sourceCode scala">anyGenerator</code> but, since it’s a class,
it’s significantly slower than defining a new struct.</p>
<div class="sourceCode" id="cb18"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb18-1"><a href="#cb18-1" aria-hidden="true" tabindex="-1"></a>public struct ListGenerator<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">:</span> GeneratorType<span class="op">,</span> SequenceType <span class="op">{</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> list<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>  public mutating func <span class="fu">next</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Element</span><span class="op">?</span> <span class="op">{</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>    switch list <span class="op">{</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="cf">return</span> nil</span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">):</span></span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>      list <span class="op">=</span> tail</span>
<span id="cb18-8"><a href="#cb18-8" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> head</span>
<span id="cb18-9"><a href="#cb18-9" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb18-10"><a href="#cb18-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb18-11"><a href="#cb18-11" aria-hidden="true" tabindex="-1"></a>  public func <span class="fu">generate</span><span class="op">()</span> <span class="op">-&gt;</span> ListGenerator <span class="op">{</span> <span class="cf">return</span> self <span class="op">}</span></span>
<span id="cb18-12"><a href="#cb18-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb18-13"><a href="#cb18-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb18-14"><a href="#cb18-14" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">:</span> SequenceType <span class="op">{</span></span>
<span id="cb18-15"><a href="#cb18-15" aria-hidden="true" tabindex="-1"></a>  public func <span class="fu">generate</span><span class="op">()</span> <span class="op">-&gt;</span> ListGenerator<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb18-16"><a href="#cb18-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">ListGenerator</span><span class="op">(</span>list<span class="op">:</span> self<span class="op">)</span></span>
<span id="cb18-17"><a href="#cb18-17" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb18-18"><a href="#cb18-18" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And you’ve got a <code class="sourceCode scala">SequenceType</code>
that’s normal-looking and easy to work with.</p>
<h3 id="laziness">Laziness</h3>
<p>I’m not sure if this is entirely relevant here, but I <em>do</em>
like laziness, so I thought I’d make a version of <code
class="sourceCode scala"><span class="ex">List</span></code> that was
lazy. It turns out it’s easy to do: in fact, it was possible before
<code class="sourceCode scala">indirect</code> enums. So, starting with
the standard <code
class="sourceCode scala"><span class="ex">List</span></code>
definition:</p>
<div class="sourceCode" id="cb19"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb19-1"><a href="#cb19-1" aria-hidden="true" tabindex="-1"></a>public enum LazyList<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> Nil</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>  indirect <span class="cf">case</span> <span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="ex">Element</span><span class="op">,</span> tail<span class="op">:</span> LazyList<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Let’s make it lazy. The main idea would be to defer the resolution of
<code class="sourceCode scala">tail</code>. What we really want is for
tail to be a function that <em>returns</em> a list, rather than a list
itself.</p>
<div class="sourceCode" id="cb20"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb20-1"><a href="#cb20-1" aria-hidden="true" tabindex="-1"></a>public enum LazyList<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> Nil</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">case</span> <span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> <span class="ex">Element</span><span class="op">,</span> tail<span class="op">:</span> <span class="op">()</span> <span class="op">-&gt;</span> LazyList<span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span></span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This is the reason that <code
class="sourceCode scala">indirect</code> isn’t needed: because tail
isn’t a list, all that’s stored in the enum is the reference to the
function. This is what <code class="sourceCode scala">indirect</code>
does automatically, or what the <code
class="sourceCode scala"><span class="ex">Box</span></code> struct did
manually.</p>
<p>There are some more wrinkles with laziness. For instance, our old
infix operator won’t work:</p>
<div class="sourceCode" id="cb21"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb21-1"><a href="#cb21-1" aria-hidden="true" tabindex="-1"></a>public func <span class="op">|&gt;</span> <span class="op">&lt;</span>T<span class="op">&gt;(</span>lhs<span class="op">:</span> T<span class="op">,</span> rhs<span class="op">:</span> LazyList<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">-&gt;</span> LazyList<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> lhs<span class="op">,</span> tail<span class="op">:</span> rhs<span class="op">)</span></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Again, because tail is meant to be a function that returns a list,
not a list itself. This <em>would</em> work, but not in the way we
intend it:</p>
<div class="sourceCode" id="cb22"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb22-1"><a href="#cb22-1" aria-hidden="true" tabindex="-1"></a>public func <span class="op">|&gt;</span> <span class="op">&lt;</span>T<span class="op">&gt;(</span>lhs<span class="op">:</span> T<span class="op">,</span> rhs<span class="op">:</span> LazyList<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">-&gt;</span> LazyList<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> lhs<span class="op">,</span> tail<span class="op">:</span> <span class="op">{</span>rhs<span class="op">})</span></span>
<span id="cb22-3"><a href="#cb22-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Whatever’s to the right-hand-side of the operator will get resolved,
and <em>then</em> put into the closure, which we don’t want. For
instance, this:</p>
<div class="sourceCode" id="cb23"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb23-1"><a href="#cb23-1" aria-hidden="true" tabindex="-1"></a>func <span class="fu">printAndGiveList</span><span class="op">()</span> <span class="op">-&gt;</span> LazyList<span class="op">&lt;</span><span class="bu">Int</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">print</span><span class="op">(</span><span class="dv">2</span><span class="op">)</span></span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">.</span>Nil</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-6"><a href="#cb23-6" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span> <span class="op">|&gt;</span> <span class="dv">1</span> <span class="op">|&gt;</span> <span class="fu">printAndGiveList</span><span class="op">()</span></span></code></pre></div>
<p>Will give you a “<code class="sourceCode scala">LazyList</code>”, but
2 gets printed, meaning that it’s not <em>really</em> behaving
lazily.</p>
<p><code class="sourceCode scala">@autoclosure</code> to the rescue!
This is a little annotation you put before your parameters that can let
you decide when to evaluate the argument.</p>
<div class="sourceCode" id="cb24"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb24-1"><a href="#cb24-1" aria-hidden="true" tabindex="-1"></a>public func <span class="op">|&gt;</span> <span class="op">&lt;</span>T<span class="op">&gt;(</span>lhs<span class="op">:</span> T<span class="op">,</span> @<span class="fu">autoclosure</span><span class="op">(</span>escaping<span class="op">)</span> rhs<span class="op">:</span> <span class="op">()</span> <span class="op">-&gt;</span> LazyList<span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">-&gt;</span> LazyList<span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">:</span> lhs<span class="op">,</span> tail<span class="op">:</span> rhs<span class="op">)</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The <code class="sourceCode scala">escaping</code> in the brackets is
needed to signify that the closure will last longer than the lifetime of
the scope it is declared in. If you test this new version with the <code
class="sourceCode scala"><span class="fu">printAndGiveList</span><span class="op">()</span></code>
function, you’ll see that 2 does <em>not</em> get printed. In fact, the
behaviour of this operator lets us use a lot of the same code from the
strict list, <em>without</em> the strictness. (The generator
initialiser, for instance: the same code, if used to initialise a lazy
list, will work. In fact, if the underlying sequence that the generator
comes from is lazy, <em>that laziness is maintained in the lazy
list</em>. That’s pretty cool.)</p>
<p>There’s an interesting point to be made, here. The usual definition
for a lazy programming language is one in which functions do not
evaluate their arguments until they need to. In contrast, eager
languages evaluate function arguments before the body of the function.
This kind of makes it seem that you could treat Swift as a totally lazy
language…</p>
<p>At any rate, this new-and-improved operator works exactly as we want
it. It’s properly lazy. The rest is easy: every time <code
class="sourceCode scala">tail</code> was used in <code
class="sourceCode scala"><span class="ex">List</span></code>, replace it
with <code
class="sourceCode scala"><span class="fu">tail</span><span class="op">()</span></code>.</p>
<h3 id="the-deque">The Deque</h3>
<p>Lists are useful. They let you operate on their first element in
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(1)</annotation></semantics></math>
time, which makes a lot of sense, since you often find yourself starting
there.</p>
<p>They’ve got some disadvantages, though: for one, to get to the nth
element, you have to walk along n elements in the list. So while
operations of the <em>start</em> are fast, operations on the end are
painfully slow. And forget about efficient indexing.</p>
<p>This is where a Deque comes in. When you need to operate on two ends
of a collection, a Deque is what you want to be using. Removal of the
first and last element, prepending, and appending are all
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>O</mi><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">O(1)</annotation></semantics></math>.</p>
<p>It’s made up of two lists: one for the front half, and one, in
reverse, for the back half. With that information we’ve enough to get a
definition down:</p>
<div class="sourceCode" id="cb25"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb25-1"><a href="#cb25-1" aria-hidden="true" tabindex="-1"></a>public struct <span class="ex">Deque</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> front<span class="op">,</span> back<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span></span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>You’ve got to do similar things that you did to the list to get an
easy-to-work-with struct. <code
class="sourceCode scala">CustomDebugStringConvertible</code>, <code
class="sourceCode scala">ArrayLiteralConvertible</code>, etc. It’s not
tremendously interesting, so here it is:</p>
<div class="sourceCode" id="cb26"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb26-1"><a href="#cb26-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">:</span> CustomDebugStringConvertible <span class="op">{</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>  public <span class="kw">var</span> debugDescription<span class="op">:</span> <span class="ex">String</span> <span class="op">{</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>      <span class="st">&quot;, &quot;</span><span class="op">.</span><span class="fu">join</span><span class="op">(</span>front<span class="op">.</span>map<span class="op">{</span><span class="ex">String</span><span class="op">(</span>reflecting<span class="op">:</span> $<span class="dv">0</span><span class="op">)})</span> <span class="op">+</span></span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>      <span class="st">&quot; | &quot;</span> <span class="op">+</span></span>
<span id="cb26-6"><a href="#cb26-6" aria-hidden="true" tabindex="-1"></a>      <span class="st">&quot;, &quot;</span><span class="op">.</span><span class="fu">join</span><span class="op">(</span>back<span class="op">.</span><span class="fu">reverse</span><span class="op">().</span>map<span class="op">{</span><span class="ex">String</span><span class="op">(</span>reflecting<span class="op">:</span> $<span class="dv">0</span><span class="op">)})</span></span>
<span id="cb26-7"><a href="#cb26-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb26-9"><a href="#cb26-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-10"><a href="#cb26-10" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb26-11"><a href="#cb26-11" aria-hidden="true" tabindex="-1"></a>  public <span class="fu">init</span><span class="op">(</span>array<span class="op">:</span> <span class="op">[</span><span class="ex">Element</span><span class="op">])</span> <span class="op">{</span></span>
<span id="cb26-12"><a href="#cb26-12" aria-hidden="true" tabindex="-1"></a>    let half <span class="op">=</span> array<span class="op">.</span>endIndex <span class="op">/</span> <span class="dv">2</span></span>
<span id="cb26-13"><a href="#cb26-13" aria-hidden="true" tabindex="-1"></a>    front <span class="op">=</span> <span class="ex">List</span><span class="op">(</span>array<span class="op">[</span><span class="dv">0</span><span class="op">..&lt;</span>half<span class="op">])</span></span>
<span id="cb26-14"><a href="#cb26-14" aria-hidden="true" tabindex="-1"></a>    back <span class="op">=</span> <span class="ex">List</span><span class="op">(</span>array<span class="op">[</span>half<span class="op">..&lt;</span>array<span class="op">.</span>endIndex<span class="op">].</span><span class="fu">reverse</span><span class="op">())</span></span>
<span id="cb26-15"><a href="#cb26-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb26-16"><a href="#cb26-16" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb26-17"><a href="#cb26-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-18"><a href="#cb26-18" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">:</span> ArrayLiteralConvertible <span class="op">{</span></span>
<span id="cb26-19"><a href="#cb26-19" aria-hidden="true" tabindex="-1"></a>  public <span class="fu">init</span><span class="op">(</span>arrayLiteral<span class="op">:</span> <span class="ex">Element</span><span class="op">...)</span> <span class="op">{</span></span>
<span id="cb26-20"><a href="#cb26-20" aria-hidden="true" tabindex="-1"></a>    self<span class="op">.</span><span class="fu">init</span><span class="op">(</span>array<span class="op">:</span> arrayLiteral<span class="op">)</span></span>
<span id="cb26-21"><a href="#cb26-21" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb26-22"><a href="#cb26-22" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb26-23"><a href="#cb26-23" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-24"><a href="#cb26-24" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb26-25"><a href="#cb26-25" aria-hidden="true" tabindex="-1"></a>  public init<span class="op">&lt;</span>S <span class="op">:</span> SequenceType where S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> <span class="ex">Element</span><span class="op">&gt;(</span>_ seq<span class="op">:</span> S<span class="op">)</span> <span class="op">{</span></span>
<span id="cb26-26"><a href="#cb26-26" aria-hidden="true" tabindex="-1"></a>    self<span class="op">.</span><span class="fu">init</span><span class="op">(</span>array<span class="op">:</span> <span class="ex">Array</span><span class="op">(</span>seq<span class="op">))</span></span>
<span id="cb26-27"><a href="#cb26-27" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb26-28"><a href="#cb26-28" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The debug output puts a <code
class="sourceCode scala"><span class="op">|</span></code> between the
two lists:</p>
<p><img class="aligncenter size-full wp-image-395" src="https://bigonotetaking.files.wordpress.com/2015/07/screen-shot-2015-07-28-at-21-32-44.png" alt="Screen Shot 2015-07-28 at 21.32.44" width="660" height="29" /></p>
<p>This makes it clear how the performance characteristics come about:
because the second half is a reversed list, all of the operations on the
end of the Deque are operations on the beginning of a list. And that’s
where lists are fast.</p>
<p>But there’s an obvious issue. Say we take that list, and start
removing the first element from it:</p>
<div class="sourceCode" id="cb27"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb27-1"><a href="#cb27-1" aria-hidden="true" tabindex="-1"></a>let a <span class="op">=</span> an<span class="op">.</span>tail <span class="co">// 2, 3 | 4, 5, 6</span></span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>let b <span class="op">=</span> a<span class="op">.</span>tail  <span class="co">// 3 | 4, 5, 6</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>let c <span class="op">=</span> b<span class="op">.</span>tail  <span class="co">// | 4, 5, 6</span></span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>let d <span class="op">=</span> c<span class="op">.</span>tail  <span class="co">// ?????</span></span></code></pre></div>
<p>The front will end up being empty. The solution to this is the second
important element to a Deque. It needs an invariant: if its number of
elements is greater than one, neither the front list nor the back will
be empty. When the invariant gets violated, it needs to fix it. We can
check that the invariant has been upheld with a <code
class="sourceCode scala">switch</code> statement:</p>
<div class="sourceCode" id="cb28"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb28-1"><a href="#cb28-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> mutating func <span class="fu">check</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">switch</span> <span class="op">(</span>front<span class="op">,</span> back<span class="op">)</span> <span class="op">{</span></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">(.</span>Nil<span class="op">,</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">))</span> where <span class="op">!</span>tail<span class="op">.</span>isEmpty<span class="op">:</span> <span class="fu">fix</span><span class="op">()</span></span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">(</span>let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">),</span> <span class="op">.</span>Nil<span class="op">)</span> where <span class="op">!</span>tail<span class="op">.</span>isEmpty<span class="op">:</span> <span class="fu">fix</span><span class="op">()</span></span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>    default<span class="op">:</span></span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span></span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The first case is the front is empty, and the back has more than one
element, and the second case is the back is empty, and the front has
more than one element. To fix it, just chop off the tail of the
non-empty list, reverse it, and assign it to the empty list:</p>
<div class="sourceCode" id="cb29"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb29-1"><a href="#cb29-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> mutating func <span class="fu">check</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">switch</span> <span class="op">(</span>front<span class="op">,</span> back<span class="op">)</span> <span class="op">{</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">(.</span>Nil<span class="op">,</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">))</span> where <span class="op">!</span>tail<span class="op">.</span>isEmpty<span class="op">:</span></span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a>      <span class="op">(</span>front<span class="op">,</span> back<span class="op">)</span> <span class="op">=</span> <span class="op">(</span>tail<span class="op">.</span><span class="fu">reverse</span><span class="op">(),</span> <span class="op">[</span>head<span class="op">])</span></span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">(</span>let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">),</span> <span class="op">.</span>Nil<span class="op">)</span> where <span class="op">!</span>tail<span class="op">.</span>isEmpty<span class="op">:</span></span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a>      <span class="op">(</span>back<span class="op">,</span> front<span class="op">)</span> <span class="op">=</span> <span class="op">(</span>tail<span class="op">.</span><span class="fu">reverse</span><span class="op">(),</span> <span class="op">[</span>head<span class="op">])</span></span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a>    default<span class="op">:</span></span>
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span></span>
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb29-12"><a href="#cb29-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Now, wherever we have a mutating method that may cause a violation of
the invariant, this <code class="sourceCode scala">check</code> is
called. One particularly cool way to do this is by using <code
class="sourceCode scala">didSet</code>:</p>
<div class="sourceCode" id="cb30"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb30-1"><a href="#cb30-1" aria-hidden="true" tabindex="-1"></a>public struct <span class="ex">Deque</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> front<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span> didSet <span class="op">{</span> <span class="fu">check</span><span class="op">()</span> <span class="op">}</span> <span class="op">}</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="kw">var</span> back <span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span> didSet <span class="op">{</span> <span class="fu">check</span><span class="op">()</span> <span class="op">}</span> <span class="op">}</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This will call <code
class="sourceCode scala"><span class="fu">check</span><span class="op">()</span></code>
whenever either list is mutated, ensuring you can’t forget. If a
<em>new</em> Deque is initialised, though, it won’t be called. I don’t
trust myself to remember the <code
class="sourceCode scala"><span class="fu">check</span><span class="op">()</span></code>
on every init, so we can put it into the initialiser:</p>
<div class="sourceCode" id="cb31"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb31-1"><a href="#cb31-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="fu">init</span><span class="op">(</span>_ front<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;,</span> _ back<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span>self<span class="op">.</span>front<span class="op">,</span> self<span class="op">.</span>back<span class="op">)</span> <span class="op">=</span> <span class="op">(</span>front<span class="op">,</span> back<span class="op">)</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">check</span><span class="op">()</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span></code></pre></div>
<p>This is the only initialiser so far, so it’s the only one I’m allowed
to call. However, there may be some cases where I <em>know</em> that the
front and back are balanced. So I want a separate initialiser for those,
for efficiency’s sake. But it’s got to be called <code
class="sourceCode scala">init</code> no matter what, so how can I
specify that I want to use the non-checking initialiser, over the
checking one? I could have a function called something like <code
class="sourceCode scala">initialiseFromBalanced</code> that returns a
Deque, but I don’t like that. You could use labelled arguments. <a
href="http://ericasadun.com/2015/06/01/swift-safe-array-indexing-my-favorite-thing-of-the-new-week/">Erica
Sadun has a cool post on using them with subscripts</a>, and here’s what
it would look like with <code class="sourceCode scala">init</code>:</p>
<div class="sourceCode" id="cb32"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb32-1"><a href="#cb32-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> <span class="fu">init</span><span class="op">(</span>balancedFront<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;,</span> balancedBack<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span> <span class="op">{</span></span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    <span class="op">(</span>front<span class="op">,</span> back<span class="op">)</span> <span class="op">=</span> <span class="op">(</span>balancedFront<span class="op">,</span> balancedBack<span class="op">)</span></span>
<span id="cb32-4"><a href="#cb32-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb32-5"><a href="#cb32-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>So now we have a default initialiser that automatically balances the
Deque, and a specialised one that takes two lists already balanced.</p>
<p>There is an extra function on lists in the <code
class="sourceCode scala"><span class="fu">check</span><span class="op">()</span></code>
function: <code
class="sourceCode scala"><span class="fu">reverse</span><span class="op">()</span></code>.
There are a load of different ways to do it. If you’re in the mood for
golf:</p>
<div class="sourceCode" id="cb33"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb33-1"><a href="#cb33-1" aria-hidden="true" tabindex="-1"></a>let joanne<span class="op">:</span> <span class="ex">List</span> <span class="op">=</span> <span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">,</span> <span class="dv">6</span><span class="op">]</span></span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>joanne<span class="op">.</span><span class="fu">reduce</span><span class="op">(.</span>Nil<span class="op">)</span> <span class="op">{</span> $<span class="dv">1</span> <span class="op">|&gt;</span> $<span class="dv">0</span> <span class="op">}</span> <span class="co">// 6, 5, 4, 3, 2, 1</span></span></code></pre></div>
<p>Or, if you’d like to keep it recursive:</p>
<div class="sourceCode" id="cb34"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb34-1"><a href="#cb34-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">private</span> func <span class="fu">reverse</span><span class="op">(</span>other<span class="op">:</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;)</span> <span class="op">-&gt;</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>    switch self <span class="op">{</span></span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="cf">return</span> other</span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">):</span> <span class="cf">return</span> tail<span class="op">.</span><span class="fu">reverse</span><span class="op">(</span>head <span class="op">|&gt;</span> other<span class="op">)</span></span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a>  public func <span class="fu">reverse</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">List</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">reverse</span><span class="op">(.</span>Nil<span class="op">)</span></span>
<span id="cb34-10"><a href="#cb34-10" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb34-11"><a href="#cb34-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Obviously, you want to avoid this operation as much as possible.
We’ll have to bear that in mind when we’re adding other functions.</p>
<p>So what kind of operations do we want on Deques? Well, <code
class="sourceCode scala"><span class="fu">removeFirst</span><span class="op">()</span></code>
and <code
class="sourceCode scala"><span class="fu">removeLast</span><span class="op">()</span></code>
would be a start:</p>
<div class="sourceCode" id="cb35"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb35-1"><a href="#cb35-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>  public mutating func <span class="fu">removeFirst</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Element</span> <span class="op">{</span></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> front<span class="op">.</span><span class="fu">removeFirst</span><span class="op">()</span></span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>  public mutating func <span class="fu">removeLast</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Element</span> <span class="op">{</span></span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> back<span class="op">.</span><span class="fu">removeFirst</span><span class="op">()</span></span>
<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb35-8"><a href="#cb35-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And the function on lists:</p>
<div class="sourceCode" id="cb36"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb36-1"><a href="#cb36-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">List</span> <span class="op">{</span></span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>  public mutating func <span class="fu">removeFirst</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Element</span> <span class="op">{</span></span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>    switch self <span class="op">{</span></span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">.</span>Nil<span class="op">:</span> <span class="fu">fatalError</span><span class="op">(</span><span class="st">&quot;Cannot call removeFirst() on an empty list&quot;</span><span class="op">)</span></span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> let <span class="op">.</span><span class="fu">Cons</span><span class="op">(</span>head<span class="op">,</span> tail<span class="op">):</span></span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a>      self <span class="op">=</span> tail</span>
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> head</span>
<span id="cb36-8"><a href="#cb36-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb36-9"><a href="#cb36-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb36-10"><a href="#cb36-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The other functions are easy enough to figure out: <code
class="sourceCode scala"><span class="fu">dropFirst</span><span class="op">()</span></code>,
<code
class="sourceCode scala"><span class="fu">dropLast</span><span class="op">()</span></code>,
etc. And, since it conforms to <code
class="sourceCode scala">SequenceType</code>, it gets all of the
sequence methods from the standard library, as well. However, those
methods are designed for other kinds of sequences - <code
class="sourceCode scala"><span class="ex">Array</span></code>s, <code
class="sourceCode scala"><span class="ex">String</span><span class="op">.</span>CharacterView</code>s,
etc. There are <em>much</em> more efficient ways to do most of them.
<code class="sourceCode scala">reverse</code>, for instance, is just
this:</p>
<div class="sourceCode" id="cb37"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb37-1"><a href="#cb37-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>  public func <span class="fu">reverse</span><span class="op">()</span> <span class="op">-&gt;</span> <span class="ex">Deque</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="ex">Deque</span><span class="op">(</span>balancedFront<span class="op">:</span> back<span class="op">,</span> balancedBack<span class="op">:</span> front<span class="op">)</span></span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>(Since reverse can’t change the number of elements in either list, we
can use the initialiser that takes a balanced front and back.) Other
methods like <code
class="sourceCode scala"><span class="fu">map</span><span class="op">()</span></code>,
<code
class="sourceCode scala"><span class="fu">filter</span><span class="op">()</span></code>,
etc., will just give you back an array. If we wanted to keep the Deque,
we’d have to convert it back, which involves reversing, which is
expensive. So we should do our own methods for those:</p>
<div class="sourceCode" id="cb38"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb38-1"><a href="#cb38-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a>  public func map<span class="op">&lt;</span>T<span class="op">&gt;(</span>@noescape transform<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> T<span class="op">)</span> <span class="op">-&gt;</span> <span class="ex">Deque</span><span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="ex">Deque</span><span class="op">&lt;</span>T<span class="op">&gt;(</span></span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a>      balancedFront<span class="op">:</span> front<span class="op">.</span><span class="fu">map</span><span class="op">(</span>transform<span class="op">),</span></span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a>      balancedBack <span class="op">:</span> back <span class="op">.</span><span class="fu">map</span><span class="op">(</span>transform<span class="op">)</span></span>
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb38-8"><a href="#cb38-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb38-9"><a href="#cb38-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb38-10"><a href="#cb38-10" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb38-11"><a href="#cb38-11" aria-hidden="true" tabindex="-1"></a>  public func <span class="fu">filter</span><span class="op">(</span>@noescape includeElement<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> Bool<span class="op">)</span> <span class="op">-&gt;</span> <span class="ex">Deque</span><span class="op">&lt;</span><span class="ex">Element</span><span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb38-12"><a href="#cb38-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="ex">Deque</span><span class="op">(</span>front<span class="op">.</span><span class="fu">filter</span><span class="op">(</span>includeElement<span class="op">),</span> back<span class="op">.</span><span class="fu">filter</span><span class="op">(</span>includeElement<span class="op">))</span></span>
<span id="cb38-13"><a href="#cb38-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb38-14"><a href="#cb38-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p><code
class="sourceCode scala"><span class="fu">filter</span><span class="op">()</span></code>
changes the number of elements in each list, which could cause violation
of the invariant. So we use the unlabelled initialiser, which
automatically <code
class="sourceCode scala"><span class="fu">check</span><span class="op">()</span></code>s.</p>
<p>Notice that we don’t have to do any reversing here. This is a huge
efficiency gain, but you’ve got to bear in mind that we’re assuming the
order of execution of the closures for <code
class="sourceCode scala">filter</code> and <code
class="sourceCode scala">map</code> don’t matter. This isn’t always the
case. Take this function, which is supposed to skip two elements of a
sequence:</p>
<div class="sourceCode" id="cb39"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb39-1"><a href="#cb39-1" aria-hidden="true" tabindex="-1"></a><span class="kw">var</span> i <span class="op">=</span> <span class="dv">0</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a><span class="op">[</span><span class="bu">Int</span><span class="op">](</span><span class="dv">1</span><span class="op">...</span><span class="dv">10</span><span class="op">).</span>filter <span class="op">{</span> _ in i<span class="op">++</span> <span class="op">%</span> <span class="dv">3</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">}</span> <span class="co">// [1, 4, 7, 10]</span></span></code></pre></div>
<p>It won’t work for a Deque:</p>
<div class="sourceCode" id="cb40"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb40-1"><a href="#cb40-1" aria-hidden="true" tabindex="-1"></a><span class="ex">Deque</span><span class="op">(</span><span class="dv">1</span><span class="op">...</span><span class="dv">10</span><span class="op">).</span>filter <span class="op">{</span> _ in i<span class="op">++</span> <span class="op">%</span> <span class="dv">3</span> <span class="op">==</span> <span class="dv">0</span> <span class="op">}</span> <span class="co">// 1, 4 | 6, 9</span></span></code></pre></div>
<p>There’s been talk of a <code class="sourceCode scala">@pure</code>
attribute. The idea is this: put it before your function or closure
name, and the compiler will verify that it has no side effects. It can
only use its arguments as variables, or call other <code
class="sourceCode scala">@pure</code> functions. It would be very useful
here, as it wouldn’t allow the <code class="sourceCode scala">i</code>
to be used by <code class="sourceCode scala">filter</code>. Without it,
you’ll probably just have to mention in the docs that the order of
execution is not knowable.</p>
<p>For completeness’ sake, there are also <code
class="sourceCode scala"><span class="fu">flatMap</span><span class="op">()</span></code>s
for the Deque, implemented in a similar fashion to the functions
above:</p>
<div class="sourceCode" id="cb41"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb41-1"><a href="#cb41-1" aria-hidden="true" tabindex="-1"></a>extension <span class="ex">Deque</span> <span class="op">{</span></span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a>  public func flatMap<span class="op">&lt;</span>T<span class="op">&gt;(</span>@noescape transform<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> <span class="ex">Deque</span><span class="op">&lt;</span>T<span class="op">&gt;)</span> <span class="op">-&gt;</span> <span class="ex">Deque</span><span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb41-3"><a href="#cb41-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="ex">Deque</span><span class="op">&lt;</span>T<span class="op">&gt;(</span></span>
<span id="cb41-4"><a href="#cb41-4" aria-hidden="true" tabindex="-1"></a>      front<span class="op">.</span>flatMap<span class="op">{</span><span class="ex">List</span><span class="op">(</span><span class="fu">transform</span><span class="op">(</span>$<span class="dv">0</span><span class="op">))},</span></span>
<span id="cb41-5"><a href="#cb41-5" aria-hidden="true" tabindex="-1"></a>      back <span class="op">.</span>flatMap<span class="op">{</span><span class="ex">List</span><span class="op">(</span><span class="fu">transform</span><span class="op">(</span>$<span class="dv">0</span><span class="op">).</span><span class="fu">reverse</span><span class="op">())}</span></span>
<span id="cb41-6"><a href="#cb41-6" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="cb41-7"><a href="#cb41-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb41-8"><a href="#cb41-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb41-9"><a href="#cb41-9" aria-hidden="true" tabindex="-1"></a>  public func flatMap<span class="op">&lt;</span>T<span class="op">&gt;(</span>@noescape transform<span class="op">:</span> <span class="ex">Element</span> <span class="op">-&gt;</span> T<span class="op">?)</span> <span class="op">-&gt;</span> <span class="ex">Deque</span><span class="op">&lt;</span>T<span class="op">&gt;</span> <span class="op">{</span></span>
<span id="cb41-10"><a href="#cb41-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="ex">Deque</span><span class="op">&lt;</span>T<span class="op">&gt;(</span></span>
<span id="cb41-11"><a href="#cb41-11" aria-hidden="true" tabindex="-1"></a>      front<span class="op">.</span><span class="fu">flatMap</span><span class="op">(</span>transform<span class="op">),</span></span>
<span id="cb41-12"><a href="#cb41-12" aria-hidden="true" tabindex="-1"></a>      back <span class="op">.</span><span class="fu">flatMap</span><span class="op">(</span>transform<span class="op">)</span></span>
<span id="cb41-13"><a href="#cb41-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">)</span></span>
<span id="cb41-14"><a href="#cb41-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb41-15"><a href="#cb41-15" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>All of this code is available as a playground, <a
href="https://github.com/oisdk/Deques-Queues-and-Lists-in-Swift-with-indirect">here</a>.
These two structs are also implemented a little more fully in <a
href="https://github.com/oisdk/SwiftSequence">SwiftSequence</a>.</p>
<p>Since the only real constitutive part of the Deque is a list, it’s
probably possible to implement it lazily, by just substituting in <code
class="sourceCode scala">LazyList</code>s. Or, if you were feeling
adventurous, you could have one of the lists lazy, and one strict. This
isn’t as crazy as it sounds: <code
class="sourceCode scala"><span class="fu">reverse</span><span class="op">()</span></code>
can <em>only</em> be performed eagerly, since the entire list needs to
be walked to get to the last element. So the front and back lists have
different functions (slightly). Also, because of the lazy initialisation
of <code class="sourceCode scala">LazyList</code>, swapping between lazy
and strict needn’t be very expensive. I’ll leave it up to someone else
to try, though.</p>
]]></description>
    <pubDate>Wed, 29 Jul 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-07-29-swift-queues.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>
<item>
    <title>A Strategy for Swift Protocols</title>
    <link>https://doisinkidney.com/posts/2015-07-17-swift-protocols-a-strategy.html</link>
    <description><![CDATA[<div class="info">
    Posted on July 17, 2015
</div>
<div class="info">
    
</div>
<div class="info">
    
        Tags: <a title="All pages tagged &#39;Swift&#39;." href="/tags/Swift.html" rel="tag">Swift</a>
    
</div>

<h3 id="a-misguided-over-simplified-strategy">A Misguided,
Over-Simplified Strategy</h3>
<h1 id="it-makes-sense-to-me-so">It Makes Sense to Me, so…</h1>
<p>So I’ve been drinking the Protocol-Oriented-Programming gatorade for
a while now. I’ve taken it to the extreme a little: you won’t find a
class in pretty much any of my code these days. So, before I pull it
back a little, I thought I’d put down my strategy so far for how to
handle these protocol things.</p>
<p>To give you an idea of where I’m coming from: I never really
understood object-oriented programming. It never clicked with me. I
mean, I know the basic ideas, but they were never internalised. On the
other hand, functional programming was a breeze (by comparison). I
should be clear: by FP I don’t really mean monads or functors or
applicative functors and monoids and commands and arrows and lenses and
flux capacitors. I think everyone has a relatively difficult time
wrapping their heads around that stuff.</p>
<p>I mean the <em>patterns</em> you see in FP. Pure functions - of
course - but other things, also. Things that aren’t strictly FP, but
just tend to be found among the FP: type classes, currying,
immutability, declarative-ness, laziness, higher-order functions.
Contrast that to the patterns you find in OOP: the delegate pattern,
class inheritance, single-dependency whatnot (I can’t even name them
because I’m sure I’m mixing up and misunderstanding them).</p>
<p>Now, there are probably good reasons why I understand FP a little
easier than OOP (or I think I do). OOP was what I saw first: when I
began coding, it was in OOP. By the time I tried to understand, say,
higher-order functions, I had already gotten my head around functions,
types, variables, etc. Whereas when I first read “Python is
an <em>object-oriented</em> programming language”, I had written my
first hello world a few weeks before.</p>
<p>On top of that, I’m a hobbyist - I don’t like making things that
really work, because that’s annoying. I am <em>very good</em> at finding
you Fibonacci numbers. I don’t need to know about state, or IO, so I’m
perfectly fine in the clean, pleasant world of FP (or semi-FP).</p>
<p>So what about protocols, then? Well, now that you know what kind of
person you’re listening to, it might make sense when I say this:
protocols are <em>awesome</em>. They make <em>so much</em> sense. I
can’t believe we were ever doing things any other way.</p>
<p>Are protocols FP? Kind of. The first implementation of something
protocol-like was probably in Haskell, with type classes. But OOP had a
very similar system soon after, in the form of generics. And Dave
Abrahams, who works on Swift, was the main guy for templates in C++ for
a long time. They’re not FP in the traditional sense, but
they <em>are</em> FP in the sense that I understand it: they’re a
certain kind of style/technique. And they fit right in with the rest of
the styles and techniques of FP.</p>
<h1 id="how-to-do-it">How to do it</h1>
<p>Anyway, I should get to my strategy for using them. Here’s my
ridiculously oversimplified (mis)understanding of how you should see
them: protocols describe <em>abilities</em> and <em>talents</em>. God
that’s pretentious. Lemme try again: a protocol represents something a
type <em>can</em> do, and <em>how well</em> it can do it. That’s a bit
better.</p>
<p>Let’s look to the standard library for our examples here. Say you
want to make a method that emulates Python’s slicing, where you can hop
over elements of a sequence. Something like:</p>
<div class="sourceCode" id="cb1"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>public extension SequenceType <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  func <span class="fu">hop</span><span class="op">(</span>n<span class="op">:</span> <span class="bu">Int</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="op">[</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">]</span> <span class="op">{</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> i <span class="op">=</span> n <span class="op">-</span> <span class="dv">1</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> self<span class="op">.</span>filter <span class="op">{</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>      _ <span class="op">-&gt;</span> Bool in</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>      <span class="cf">if</span> <span class="op">++</span>i <span class="op">==</span> n <span class="op">{</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>        i <span class="op">=</span> <span class="dv">0</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="kw">true</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span> <span class="cf">else</span> <span class="op">{</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="kw">false</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="op">[</span><span class="dv">1</span><span class="op">,</span> <span class="dv">2</span><span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="dv">4</span><span class="op">,</span> <span class="dv">5</span><span class="op">].</span><span class="fu">hop</span><span class="op">(</span><span class="dv">2</span><span class="op">)</span> <span class="co">// [1, 3, 5]</span></span></code></pre></div>
<p>We’re in protocol-land right away: <code
class="sourceCode scala">SequenceType</code>. This is an “ability”. The
method exists on everything with the <em>ability</em> to act like a
sequence. That means arrays, sets, dictionaries, strings. Actually, a
better example of the “ability” would be this:</p>
<div class="sourceCode" id="cb2"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>extension IntegerArithmeticType <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  func <span class="dt">double</span><span class="op">()</span> <span class="op">-&gt;</span> Self <span class="op">{</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> self <span class="op">+</span> self</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="fl">2.d</span>ouble<span class="op">()</span> <span class="co">// 4</span></span></code></pre></div>
<p>Goodness gracious that’s contrived. But anyway, you get the idea.
Anything that can do integer arithmetic gets that method.</p>
<p>Now, back to the hop method. Maybe it’s very expensive to actually
retrieve every intermediate element and then discard it - that’s what
filter is doing, after all. Why not just do an index lookup?</p>
<div class="sourceCode" id="cb3"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>public extension CollectionType <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  func <span class="fu">hop</span><span class="op">(</span>n<span class="op">:</span> Index<span class="op">.</span>Distance<span class="op">)</span> <span class="op">-&gt;</span> <span class="op">[</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">]</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">var</span> ar<span class="op">:</span> <span class="op">[</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">]</span> <span class="op">=</span> <span class="op">[]</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="kw">var</span> i <span class="op">=</span> startIndex<span class="op">;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>        indices<span class="op">.</span><span class="fu">contains</span><span class="op">(</span>i<span class="op">);</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>        i <span class="op">=</span> <span class="fu">advance</span><span class="op">(</span>i<span class="op">,</span> n<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>          ar<span class="op">.</span><span class="fu">append</span><span class="op">(</span>self<span class="op">[</span>i<span class="op">])</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> ar</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>There we go! Everything can <em>do</em> the hop method, but <code
class="sourceCode scala">CollectionType</code>s can do it <em>well</em>.
In fact, some <code class="sourceCode scala">CollectionType</code>s can
do it very well indeed:</p>
<div class="sourceCode" id="cb4"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>public extension CollectionType where Index <span class="op">:</span> RandomAccessIndexType <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  func <span class="fu">hop</span><span class="op">(</span>n<span class="op">:</span> Index<span class="op">.</span>Stride<span class="op">)</span> <span class="op">-&gt;</span> <span class="op">[</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">]</span> <span class="op">{</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="fu">stride</span><span class="op">(</span>from<span class="op">:</span> startIndex<span class="op">,</span> to<span class="op">:</span> endIndex<span class="op">,</span> by<span class="op">:</span> n<span class="op">).</span>map<span class="op">{</span>self<span class="op">[</span>$<span class="dv">0</span><span class="op">]}</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>You see this kind of thing all around the standard library, but most
prominently with the index types. If something is able to do something,
it gets the bare-bones, inefficient implementation. Then, for types with
all the bells and whistles, you get the clever, blazing-fast version.
And to the user, all you see is some easy-looking <code
class="sourceCode scala"><span class="fu">indexOf</span><span class="op">()</span></code>
function.</p>
<p>So here’s how I think you should be doing your APIs: if at all
possible, write your function as a method. Write the most bare-bones,
slow version of it you possibly can that still makes sense. Then,
specialise where it suits.</p>
<p>(I realise now that I may have just described a design pattern that
was very obvious to everyone but me. Ah, well)</p>
<h1 id="the-why">The Why</h1>
<p>There are pretty major advantages to this. Your two other options are
generally class inheritance, or global functions with generics. <a
href="https://developer.apple.com/videos/wwdc/2015/?id=408">The best
video from WWDC</a> talks about class inheritance, so I’ll stay away
from that. In contrast to global functions, here are the advantages:</p>
<h2 id="more-discoverable">More discoverable</h2>
<p>Hit dot after whatever thing you’re interested in, and the little
list of available goodies pops up. It’s also easy to find in the
documentation (what kind of methods do I have on sequences? vs. Right,
here’s the page for the global functions, cmd-f “Sequence”… hmm, <code
class="sourceCode scala">indexOf</code> isn’t here…)</p>
<h2 id="function-compositionish">Function composition(ish)</h2>
<p>We currently have this:</p>
<pre><code>g(f(x))</code></pre>
<p>Now, if we were in Haskell-land, you could write:</p>
<pre><code>(g . f) x</code></pre>
<p>But we’re not. However, if f is a method on x, and g is a method on
whatever is returned by f, you can have:</p>
<pre><code>x.f().g()</code></pre>
<p>Maybe a bit of a bad example, but <a
href="http://airspeedvelocity.net/2015/06/23/protocol-extensions-and-the-death-of-the-pipe-forward-operator/">combine
that with <code class="sourceCode scala">flatMap</code> and laziness and
you’ve got some handsome-looking, powerful functions right
there.</a></p>
<h2 id="easy-to-build-hierarchies">Easy-to-build hierarchies</h2>
<p>I find myself often getting a bit philosophical around all of these
protocols (“yeah, but what does it <em>mean</em> to be <code
class="sourceCode scala">IntegerLiteralConvertible</code>? I mean,
aren’t we <em>all</em> <code
class="sourceCode scala">IntegerLiteralConvertible</code>, in a way?”,
“Woah”). I see places where I can extend a previous method to things I
hadn’t even thought of applying it to. And with the quicklook, and the
way the documentation is structured, none of this stuff becomes
complicated.</p>
<p>Obviously this is a little bit of a straw man - there are some
obvious cases where protocol extensions don’t make a lot of sense.
Having “double” as an extension on <code
class="sourceCode scala">IntegerArithmeticType</code> is sheer silliness
- but I think something like <code
class="sourceCode scala"><span class="fu">sqrt</span><span class="op">()</span></code>
would be odd, as well. If only because it decreases readability, I’m not
sure that those kinds of things are good ideas. At the end of the day,
you’re a reasonable, intelligent person, and you know where this stuff
works. Just have it knocking around in your brain, so when you come
across something that doesn’t work <em>quite right</em>, you’ll have
protocol extensions as one of your other options.</p>
<p>If you want to see an example of protocols taken to the nth degree,
the examples I’ve had here are taken from my library, <a
href="https://github.com/oisdk/SwiftSequence">SwiftSequence</a>.</p>
<p>If you’ve kept reading this far, I’m going to really test your
patience with this next bit:</p>
<h1 id="what-do-i-want">What do I want?</h1>
<h2 id="beef-up-some-of-the-meta-language">Beef up some of the
meta-language</h2>
<p>You know the tiny little meta-language for protocol extensions? The
one that exists between the angle brackets, after the where?</p>
<div class="sourceCode" id="cb8"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>extension SomeProtocol <span class="fu">where</span> <span class="op">(</span>This bit<span class="op">)</span> <span class="op">{...</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a>func f<span class="op">&lt;</span>T <span class="op">:</span> SomeProtocol <span class="fu">where</span> <span class="op">(</span>This bit<span class="op">,</span> also<span class="op">)...</span></span></code></pre></div>
<p>That needs to get more powerful. Swift is big on doing loads of stuff
at compile-time, and that little meta-language is effectively a script
that runs as your code compiles. When it’s between the angle brackets
it’s ugly, and it seems like too small a place for a lot of code, but if
you start doing anything complex with it, you hit its limits quickly.
Say you want to write a recursive function that works with slices. This
is the absolute minimum in the angle brackets you need:</p>
<div class="sourceCode" id="cb9"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="op">&lt;</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  S <span class="op">:</span> Sliceable where S<span class="op">.</span>SubSlice <span class="op">:</span> Sliceable<span class="op">,</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>SubSlice<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">,</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>SubSlice<span class="op">.</span>SubSlice <span class="op">==</span> S<span class="op">.</span>SubSlice</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">&gt;</span></span></code></pre></div>
<p>And if you need anything complex, well…</p>
<div class="sourceCode" id="cb10"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>func bSearch<span class="op">&lt;</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>  S <span class="op">:</span> Sliceable where S<span class="op">.</span>SubSlice <span class="op">:</span> Sliceable<span class="op">,</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>SubSlice<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">,</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>SubSlice<span class="op">.</span>SubSlice <span class="op">==</span> S<span class="op">.</span>SubSlice<span class="op">,</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">:</span> <span class="ex">Comparable</span><span class="op">,</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>Index <span class="op">:</span> IntegerArithmeticType<span class="op">,</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>Index <span class="op">:</span> IntegerLiteralConvertible<span class="op">,</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>SubSlice<span class="op">.</span>Index <span class="op">==</span> S<span class="op">.</span>Index</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">&gt;(</span>el<span class="op">:</span> S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">,</span> list<span class="op">:</span> S<span class="op">)</span> <span class="op">-&gt;</span> S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span><span class="op">?</span> <span class="op">{</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> list<span class="op">.</span>isEmpty <span class="op">{</span> <span class="cf">return</span> nil <span class="op">}</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>    let midInd <span class="op">=</span> list<span class="op">.</span>endIndex <span class="op">/</span> <span class="dv">2</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a>    let midEl<span class="op">:</span> S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">=</span> list<span class="op">[</span>midInd<span class="op">]</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">// type inference giving me some bugs here</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> midEl <span class="op">==</span> el <span class="op">{</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a>      <span class="cf">return</span> el</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> midEl <span class="op">&lt;</span> el <span class="op">?</span></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a>      <span class="fu">bSearch</span><span class="op">(</span>el<span class="op">,</span> list<span class="op">:</span> list<span class="op">[</span>midInd<span class="op">+</span><span class="dv">1</span><span class="op">..&lt;</span>list<span class="op">.</span>endIndex<span class="op">])</span> <span class="op">:</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>      <span class="fu">bSearch</span><span class="op">(</span>el<span class="op">,</span> list<span class="op">:</span> list<span class="op">[</span><span class="dv">0</span><span class="op">..&lt;</span>midInd<span class="op">])</span></span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Yeah. And it’s only going to get more and more complex: with every
new beta, more functions become methods. This protocol business is going
to cause more and more function signatures to end up looking like that.
With that in mind, two things, in particular, need to go into the
meta-language:</p>
<ul>
<li><p>A way to summarise all of those protocols into one. Like, I
should be able to declare a protocol that’s just other protocols put
together:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>protocol RecursiveSliceable<span class="op">:</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  Sliceable where SubSlice <span class="op">:</span> Sliceable<span class="op">,</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>  SubSlice<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">==</span> Generator<span class="op">.</span><span class="ex">Element</span><span class="op">,</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  SubSlice<span class="op">.</span>SubSlice <span class="op">==</span> SubSlice</span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>protocol RecursiveSliceableIntegerIndices<span class="op">:</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>  RecursiveSliceable where</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>  Index <span class="op">:</span> IntegerArithmeticType<span class="op">,</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>  Index <span class="op">:</span> IntegerLiteralConvertible<span class="op">,</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>  SubSlice<span class="op">.</span>Index <span class="op">==</span> Index</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>func bSearch<span class="op">&lt;</span></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>  S <span class="op">:</span> RecursiveSliceableIntegerIndices where</span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>  S<span class="op">.</span>Generator<span class="op">.</span><span class="ex">Element</span> <span class="op">:</span> <span class="ex">Comparable</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a>  <span class="op">&gt;(</span>seq<span class="op">:</span> S<span class="op">)...</span></span></code></pre></div></li>
<li><p>Support for expressions, statements and whatnot, all of which get
evaluated at compile-time.</p></li>
</ul>
<h2 id="more-pop-in-the-standard-library">More POP in the Standard
Library</h2>
<p>The standard library, at the moment, still has not fully crossed over
to the protocol way of doing things. It’s probably more to do with
resource pressure than anything else, but I’m worried that some areas
may not get the full protocol treatment. I’m talking about sequences.
Currently, there are structs like <code
class="sourceCode scala">AnySequence</code>, which represent the old,
dark days of Swift 1.2. In its description:</p>
<blockquote>
<p>A type-erased sequence.</p>
</blockquote>
<blockquote>
<p>Forwards operations to an arbitrary underlying sequence having the
same <code>Element</code> type, hiding the specifics of the
underlying <code class="sourceCode scala">SequenceType</code>.</p>
</blockquote>
<p>That’s no good. You shouldn’t have to erase types - your methods and
functions should act on <code
class="sourceCode scala">SequenceType</code>, regardless of which <code
class="sourceCode scala">SequenceType</code> it is. I’m not suggesting
you should get rid of that struct - it’s trivial to come up with cases
where it’s needed - I’m saying you shouldn’t be using it if you don’t
have to. And in one particular area of the Swift standard library, they
use structs where (I feel) they should be using protocols: <code
class="sourceCode scala">LazySequence</code>. It’s a wrapper struct,
mainly used for functional-style methods like <code
class="sourceCode scala">map</code> and <code
class="sourceCode scala">filter</code> that can act lazily. <em>Why
isn’t it a protocol</em>?! Currently, the lazy versions of <code
class="sourceCode scala">map</code> and <code
class="sourceCode scala">filter</code> are defined as methods on <code
class="sourceCode scala">LazySequence</code>. What they return is a
<code class="sourceCode scala">MapSequenceView</code> <em>wrapped</em>
in <code class="sourceCode scala">LazySequence</code>. That way, you can
chain map and filter, keeping things lazy. But why not make <code
class="sourceCode scala">LazySequenceType</code> a protocol, and have
<code class="sourceCode scala">MapSequenceView</code> conform to it?
There’s more - <code
class="sourceCode scala">LazyRandomAccessCollection</code>, <code
class="sourceCode scala">LazyForwardCollection</code>, etc. <em>These
should all be protocols</em>. It’s a nightmare to try and deal with
these things: if you want to write a lazy method on a sequence, you have
to write one for <code class="sourceCode scala">LazySequence</code>,
then one for <code
class="sourceCode scala">LazyForwardCollection</code>, and so on. It
would be so much easier to have.</p>
<div class="sourceCode" id="cb12"><pre
class="sourceCode scala"><code class="sourceCode scala"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>extension LazySequenceType where</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  Self<span class="op">:</span> CollectionType<span class="op">,</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>  Index<span class="op">:</span> RandomAccessIndexType</span></code></pre></div>
<p>I really don’t know why it’s not this way. Again, the Swift team may
well <em>want</em> to do it, but just hasn’t got round to it. I hope so.
A very optimistic voice in my mind does keep whispering, though:
“<em>they’re just waiting for recursive enums, so they can introduce
lazy lists… they’ve been working on a whole load of lazy sequence
functions… pattern matching… uncons…</em>”</p>
]]></description>
    <pubDate>Fri, 17 Jul 2015 00:00:00 UT</pubDate>
    <guid>https://doisinkidney.com/posts/2015-07-17-swift-protocols-a-strategy.html</guid>
    <dc:creator>Donnacha Oisín Kidney</dc:creator>
</item>

    </channel>
</rss>
