<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.3.1">Jekyll</generator><link href="https://matthew.brecknell.net/atom.xml" rel="self" type="application/atom+xml" /><link href="https://matthew.brecknell.net/" rel="alternate" type="text/html" hreflang="en" /><updated>2022-12-11T02:00:00+00:00</updated><id>https://matthew.brecknell.net/atom.xml</id><title type="html">Matthew Brecknell</title><subtitle>Programming and formal software verification</subtitle><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><entry><title type="html">Introduction to the seL4 integrity theorems</title><link href="https://matthew.brecknell.net/posts/sel4-integrity-theorems/" rel="alternate" type="text/html" title="Introduction to the seL4 integrity theorems" /><published>2022-12-11T01:30:00+00:00</published><updated>2022-12-11T01:30:00+00:00</updated><id>https://matthew.brecknell.net/posts/sel4-integrity-theorems</id><content type="html" xml:base="https://matthew.brecknell.net/posts/sel4-integrity-theorems/"><![CDATA[<p>This talk, presented at the seL4 Summit, October 2022, gives an
introduction to the <a href="https://github.com/seL4/l4v/tree/master/proof/access-control">seL4 integrity theorems</a>. The integrity
theorems were first <a href="https://trustworthy.systems/publications/nictaabstracts/Sewell_WGMAK_11.abstract">published in 2011</a>, and they show how seL4
can enforce access control policies. The talk explains what the theorems
mean, and how to apply them to both static and dynamic seL4-based
systems.</p>

<p>Also on <a href="https://youtu.be/fyF9w_CsCEU">YouTube</a>. MP4 downloads are available from <a href="https://vimeo.com/mbrcknl/sel4-integrity-theorems">Vimeo</a>. Slides
are available in <a href="/posts/sel4-integrity-theorems/sel4-integrity-theorems.pdf">PDF</a> and <a href="/posts/sel4-integrity-theorems/sel4-integrity-theorems.key">Keynote</a>.</p>

<p class="vimeo-embed">
  <iframe src="https://player.vimeo.com/video/769652806?byline=0&amp;portrait=0&amp;title=0" allow="fullscreen" frameborder="0" title="Introduction to the seL4 proofs">
  </iframe>
</p>

<p>Also on <a href="https://youtu.be/fyF9w_CsCEU">YouTube</a>. MP4 downloads are available from <a href="https://vimeo.com/mbrcknl/sel4-integrity-theorems">Vimeo</a>. There are
slides in <a href="/posts/sel4-integrity-theorems/sel4-integrity-theorems.pdf">PDF</a> and <a href="/posts/sel4-integrity-theorems/sel4-integrity-theorems.key">Keynote</a>.</p>]]></content><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><category term="sel4" /><category term="verification" /><category term="talk" /><summary type="html"><![CDATA[This talk, presented at the seL4 Summit, October 2022, gives an introduction to the seL4 integrity theorems. The integrity theorems were first published in 2011, and they show how seL4 can enforce access control policies. The talk explains what the theorems mean, and how to apply them to both static and dynamic seL4-based systems. Also on YouTube. MP4 downloads are available from Vimeo. Slides are available in PDF and Keynote. Also on YouTube. MP4 downloads are available from Vimeo. There are slides in PDF and Keynote.]]></summary></entry><entry><title type="html">Introduction to the seL4 proofs</title><link href="https://matthew.brecknell.net/posts/intro-sel4-proofs/" rel="alternate" type="text/html" title="Introduction to the seL4 proofs" /><published>2021-12-28T01:30:00+00:00</published><updated>2021-12-28T01:30:00+00:00</updated><id>https://matthew.brecknell.net/posts/intro-sel4-proofs</id><content type="html" xml:base="https://matthew.brecknell.net/posts/intro-sel4-proofs/"><![CDATA[<p>This screencast gives a guided tour of the <a href="https://github.com/seL4/l4v">Isabelle/HOL proofs</a> about
the <a href="https://sel4.systems/">seL4 microkernel</a>, focussing mainly on the abstract specification and
some of the properties we prove about it. It was given as a pre-recorded talk
for the third seL4 Summit, held virtually in November 2020. The talk assumes
some familiarity with seL4, but aims to be accessible to people without previous
experience of formal software verification or interactive theorem proving.</p>

<p class="vimeo-embed">
  <iframe src="https://player.vimeo.com/video/479842100?byline=0&amp;portrait=0&amp;title=0" allow="fullscreen" frameborder="0" title="Introduction to the seL4 proofs">
  </iframe>
</p>

<p>Also on <a href="https://youtu.be/AdakDMYu4lM">YouTube</a>. MP4 downloads are available from <a href="https://vimeo.com/mbrcknl/intro-sel4-proofs">Vimeo</a>. There are
<a href="/posts/intro-sel4-proofs/intro-sel4-proofs.pdf">slides</a>, and a rough <a href="https://docs.google.com/document/d/1Gqg-fQV8uX9v8CvWCr6wkYDx1qF5GD354GFBYTjknGA/edit?usp=sharing">transcript</a>.</p>]]></content><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><category term="sel4" /><category term="verification" /><category term="screencast" /><summary type="html"><![CDATA[This screencast gives a guided tour of the Isabelle/HOL proofs about the seL4 microkernel, focussing mainly on the abstract specification and some of the properties we prove about it. It was given as a pre-recorded talk for the third seL4 Summit, held virtually in November 2020. The talk assumes some familiarity with seL4, but aims to be accessible to people without previous experience of formal software verification or interactive theorem proving. Also on YouTube. MP4 downloads are available from Vimeo. There are slides, and a rough transcript.]]></summary></entry><entry><title type="html">Pattern-matching dependent types in Coq</title><link href="https://matthew.brecknell.net/posts/pattern-matching-dependent-types-in-coq/" rel="alternate" type="text/html" title="Pattern-matching dependent types in Coq" /><published>2015-05-21T01:30:00+00:00</published><updated>2015-05-21T01:30:00+00:00</updated><id>https://matthew.brecknell.net/posts/pattern-matching-dependent-types-in-coq</id><content type="html" xml:base="https://matthew.brecknell.net/posts/pattern-matching-dependent-types-in-coq/"><![CDATA[<p>Pattern matching with dependent types in Coq can be awkward, while equivalent
programs in Agda might be straightforward and elegant. Yet despite the
awkwardness, there may still be reasons to choose Coq for your next
dependently-typed development, for example if you want a tactic language to
develop domain-specific proof-search procedures.</p>

<p>In this talk, we show how to <code class="language-plaintext highlighter-rouge">match</code> in Coq, using techniques described by
<a href="http://adam.chlipala.net/">Adam Chlipala</a> in his book, <a href="http://adam.chlipala.net/cpdt/">Certified Programming with Dependent
Types</a>.</p>

<p>We first review what it means to pattern-match on inductive families,
contrasting Coq with Agda, and examine what it is about Coq that complicates
pattern matching. Using a simple running example, we’ll show how to use Coq
<code class="language-plaintext highlighter-rouge">match</code> annotations to eliminate nonsense cases, and the <em>convoy</em> pattern for
refining the types of things already in scope. Finally, we’ll show that by
equipping an inductive family with some well-chosen combinators, it is often
possible to regain some semblance of elegance.</p>

<p>This is a recording of a practice run for a talk at <a href="http://lambdajam.yowconference.com.au/">YOW! Lambda Jam</a>.
You can download the video as MP4 from <a href="https://vimeo.com/mbrcknl/coq-pattern-match">Vimeo</a>. There
are <a href="/posts/pattern-matching-dependent-types-in-coq/ylj15-coq-pattern-match.pdf">slides</a>, and some code on <a href="https://github.com/mbrcknl/ylj15-coq-pattern-match">GitHub</a>. Also on <a href="https://youtu.be/z_kaJ4CQztw">YouTube</a>.</p>

<p class="vimeo-embed">
  <iframe src="https://player.vimeo.com/video/660532407?byline=0&amp;portrait=0&amp;title=0" allow="fullscreen" frameborder="0" title="Introduction to the seL4 proofs">
  </iframe>
</p>]]></content><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><category term="coq" /><category term="dependent-types" /><category term="screencast" /><summary type="html"><![CDATA[Pattern matching with dependent types in Coq can be awkward, while equivalent programs in Agda might be straightforward and elegant. Yet despite the awkwardness, there may still be reasons to choose Coq for your next dependently-typed development, for example if you want a tactic language to develop domain-specific proof-search procedures. In this talk, we show how to match in Coq, using techniques described by Adam Chlipala in his book, Certified Programming with Dependent Types. We first review what it means to pattern-match on inductive families, contrasting Coq with Agda, and examine what it is about Coq that complicates pattern matching. Using a simple running example, we’ll show how to use Coq match annotations to eliminate nonsense cases, and the convoy pattern for refining the types of things already in scope. Finally, we’ll show that by equipping an inductive family with some well-chosen combinators, it is often possible to regain some semblance of elegance. This is a recording of a practice run for a talk at YOW! Lambda Jam. You can download the video as MP4 from Vimeo. There are slides, and some code on GitHub. Also on YouTube.]]></summary></entry><entry><title type="html">Difference lists</title><link href="https://matthew.brecknell.net/posts/difference-lists/" rel="alternate" type="text/html" title="Difference lists" /><published>2014-09-23T08:00:00+00:00</published><updated>2014-09-23T08:00:00+00:00</updated><id>https://matthew.brecknell.net/posts/difference-lists</id><content type="html" xml:base="https://matthew.brecknell.net/posts/difference-lists/"><![CDATA[<p>This post is an extended version of a lightning talk I gave at the <a href="https://www.meetup.com/Brisbane-Functional-Programming-Group/events/173409512/">Brisbane
Functional Programming Group</a>. It introduces the <a href="https://doi.org/10.1016/0020-0190(86)90059-1">difference</a>
<a href="https://wiki.haskell.org/Difference_list">list</a>, a simple trick for improving the performance of certain kinds of
list-building functions in Haskell, and goes on to explore the connections to
monoids and folds.</p>

<p>The first half is aimed at Haskell novices, while the latter parts might
be interesting to intermediates.</p>

<h2 id="a-first-example">A first example</h2>

<p>Let’s reverse some lists. I’m sure you’ve seen this before:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="kt">[]</span> <span class="o">=</span> <span class="kt">[]</span>
<span class="n">reverse</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">reverse</span> <span class="n">xs</span> <span class="o">++</span> <span class="p">[</span><span class="n">x</span><span class="p">]</span></code></pre></figure>

<p>It’s a simple and clear definition, but it performs badly. List concatenation,
<code class="language-plaintext highlighter-rouge">(++)</code>, traverses its left argument, and since that’s a recursive call, this
version takes <em>quadratic</em> time overall.</p>

<p>We can get to <em>linear</em> time by introducing an accumulator:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="kt">[]</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="n">acc</span> <span class="o">=</span> <span class="n">acc</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="n">acc</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">acc</span><span class="p">)</span></code></pre></figure>

<p>This is a <a href="https://wiki.haskell.org/Worker_wrapper">worker-wrapper</a>, where the wrapper initialises the accumulator to
the empty list, <code class="language-plaintext highlighter-rouge">[]</code>. The worker, <code class="language-plaintext highlighter-rouge">go</code>, is tail recursive, and accumulates the
result in reverse order as it forward-traverses the input.</p>

<p>Although efficient, this is less clear. Let’s tidy up the worker by eliminating
the accumulator parameter, <code class="language-plaintext highlighter-rouge">acc</code>:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="kt">[]</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="nf">\</span><span class="n">acc</span> <span class="o">-&gt;</span> <span class="n">acc</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="nf">\</span><span class="n">acc</span> <span class="o">-&gt;</span> <span class="n">go</span> <span class="n">xs</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">acc</span><span class="p">)</span></code></pre></figure>

<p>The first case (line 5) is just the identity function, <code class="language-plaintext highlighter-rouge">id</code>, while we can write
the second case as a function composition:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="kt">[]</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="o">.</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="p">)</span></code></pre></figure>

<p>If we now compare the worker, <code class="language-plaintext highlighter-rouge">go</code>, with our original version of <code class="language-plaintext highlighter-rouge">reverse</code>, we
see a similar structure, with some differences:</p>

<ul>
  <li>The empty list, <code class="language-plaintext highlighter-rouge">[]</code>, becomes the identity function, <code class="language-plaintext highlighter-rouge">id</code>.</li>
  <li>List concatenation, <code class="language-plaintext highlighter-rouge">(++)</code>, becomes function composition, <code class="language-plaintext highlighter-rouge">(.)</code>.</li>
  <li>The singleton list, <code class="language-plaintext highlighter-rouge">[x]</code>, becomes a function, <code class="language-plaintext highlighter-rouge">(x:)</code>, which prepends <code class="language-plaintext highlighter-rouge">x</code> to
its argument.</li>
  <li>The list type, <code class="language-plaintext highlighter-rouge">[a]</code>, becomes the function type, <code class="language-plaintext highlighter-rouge">[a] -&gt; [a]</code>, in the result.</li>
</ul>

<p>For the last point, recall that <code class="language-plaintext highlighter-rouge">a -&gt; b -&gt; c</code> parses as <code class="language-plaintext highlighter-rouge">a -&gt; (b -&gt; c)</code>.</p>

<h2 id="tree-flattening">Tree flattening</h2>

<p>For a second example, let’s take a binary tree and flatten it to a list of
elements in left-to-right order. Again, this version is clear, but since there
is a recursive call to <code class="language-plaintext highlighter-rouge">flatten</code> on the left of list append, <code class="language-plaintext highlighter-rouge">(++)</code>, it takes
quadratic time in the worst case:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="kr">data</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">=</span> <span class="kt">Leaf</span> <span class="o">|</span> <span class="kt">Branch</span> <span class="p">(</span><span class="kt">Tree</span> <span class="n">a</span><span class="p">)</span> <span class="n">a</span> <span class="p">(</span><span class="kt">Tree</span> <span class="n">a</span><span class="p">)</span>

<span class="n">flatten</span> <span class="o">::</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">flatten</span> <span class="kt">Leaf</span> <span class="o">=</span> <span class="kt">[]</span>
<span class="n">flatten</span> <span class="p">(</span><span class="kt">Branch</span> <span class="n">l</span> <span class="n">x</span> <span class="n">r</span><span class="p">)</span> <span class="o">=</span> <span class="n">flatten</span> <span class="n">l</span> <span class="o">++</span> <span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="o">++</span> <span class="n">flatten</span> <span class="n">r</span></code></pre></figure>

<p>As before, the linear-time version uses an accumulator to build the result in
reverse:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">flatten</span> <span class="o">::</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">flatten</span> <span class="n">t</span> <span class="o">=</span> <span class="n">go</span> <span class="n">t</span> <span class="kt">[]</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">go</span> <span class="kt">Leaf</span> <span class="n">acc</span> <span class="o">=</span> <span class="n">acc</span>
    <span class="n">go</span> <span class="p">(</span><span class="kt">Branch</span> <span class="n">l</span> <span class="n">x</span> <span class="n">r</span><span class="p">)</span> <span class="n">acc</span> <span class="o">=</span> <span class="n">go</span> <span class="n">l</span> <span class="p">(</span><span class="n">x</span> <span class="o">:</span> <span class="n">go</span> <span class="n">r</span> <span class="n">acc</span><span class="p">)</span></code></pre></figure>

<p>If we rearrange, and compare the worker, <code class="language-plaintext highlighter-rouge">go</code>, with the original, inefficient
version, we can see the same patterns we saw in the <code class="language-plaintext highlighter-rouge">reverse</code> function:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">flatten</span> <span class="o">::</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">flatten</span> <span class="n">t</span> <span class="o">=</span> <span class="n">go</span> <span class="n">t</span> <span class="kt">[]</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">go</span> <span class="kt">Leaf</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="kt">Branch</span> <span class="n">l</span> <span class="n">x</span> <span class="n">r</span><span class="p">)</span> <span class="o">=</span> <span class="n">go</span> <span class="n">l</span> <span class="o">.</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="p">)</span> <span class="o">.</span> <span class="n">go</span> <span class="n">r</span></code></pre></figure>

<h2 id="difference-lists">Difference lists</h2>

<p>Having identified the pattern, we can define the type of <em>difference lists</em>,
together with its basic operations:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="kr">type</span> <span class="kt">DList</span> <span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>

<span class="c1">-- O(1)</span>
<span class="n">empty</span> <span class="o">::</span> <span class="kt">DList</span> <span class="n">a</span>
<span class="n">empty</span> <span class="o">=</span> <span class="n">id</span>

<span class="c1">-- O(1)</span>
<span class="n">singleton</span> <span class="o">::</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">DList</span> <span class="n">a</span>
<span class="n">singleton</span> <span class="o">=</span> <span class="p">(</span><span class="o">:</span><span class="p">)</span>

<span class="c1">-- O(n)</span>
<span class="n">fromList</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="kt">DList</span> <span class="n">a</span>
<span class="n">fromList</span> <span class="o">=</span> <span class="p">(</span><span class="o">++</span><span class="p">)</span>

<span class="c1">-- O(1)</span>
<span class="n">append</span> <span class="o">::</span> <span class="kt">DList</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">DList</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">DList</span> <span class="n">a</span>
<span class="n">append</span> <span class="o">=</span> <span class="p">(</span><span class="o">.</span><span class="p">)</span>

<span class="c1">-- O(1)</span>
<span class="n">toList</span> <span class="o">::</span> <span class="kt">DList</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">toList</span> <span class="n">d</span> <span class="o">=</span> <span class="n">d</span> <span class="kt">[]</span></code></pre></figure>

<p>This means a difference list is a function which prepends some number of items
to its argument, without inspecting that argument. For example, this is a
difference list:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">myDList</span> <span class="o">::</span> <span class="kt">DList</span> <span class="kt">Int</span>
<span class="n">myDlist</span> <span class="n">r</span> <span class="o">=</span> <span class="mi">1</span><span class="o">:</span><span class="mi">2</span><span class="o">:</span><span class="mi">3</span><span class="o">:</span><span class="n">r</span></code></pre></figure>

<p>But the following is <em>not</em> a difference list, because the <code class="language-plaintext highlighter-rouge">reverse</code> function
inspects its argument, and because it does not incorporate the argument in its
result:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">notDList</span> <span class="o">::</span> <span class="kt">DList</span> <span class="n">a</span>
<span class="n">notDlist</span> <span class="o">=</span> <span class="n">reverse</span></code></pre></figure>

<p>Comparing the difference list operations with the corresponding ones on
ordinary lists, we see that that difference list <code class="language-plaintext highlighter-rouge">append</code> takes constant time,
whereas for ordinary lists, <code class="language-plaintext highlighter-rouge">(++)</code> takes time linear in the size of the left
argument. This means difference lists are good for building lists using
left-associated concatenation.</p>

<p>But there’s a catch!</p>

<p>The time complexities are <em>amortised</em>, and they are only valid when the
difference list is used <em>ephemerally</em>. If you attempt to use a difference list
<em>persistently</em>, <code class="language-plaintext highlighter-rouge">toList</code> may degrade to linear time.</p>

<p>The reason for this is that there are two costs associated with <code class="language-plaintext highlighter-rouge">append</code>. The
first is paid when <code class="language-plaintext highlighter-rouge">append</code> builds a closure for the function composition. The
second is paid every time the function composition is applied to an argument.
That is, whenever <code class="language-plaintext highlighter-rouge">toList</code> is evaluated.</p>

<p>This means that <code class="language-plaintext highlighter-rouge">toList</code> actually takes time that is linear in the number of
function compositions it has to apply. However, if we are only interested in
the overall time taken by a <em>sequence</em> of operations, we can assign the cost of
<em>evaluating</em> the function composition to <code class="language-plaintext highlighter-rouge">append</code>, even though the evaluation
occurs in <code class="language-plaintext highlighter-rouge">toList</code>. And so we can say that both <code class="language-plaintext highlighter-rouge">append</code> and <code class="language-plaintext highlighter-rouge">toList</code> take
<em>amortised constant time</em>.</p>

<p>Of course, that analysis assumes that <code class="language-plaintext highlighter-rouge">toList</code> is only evaluated once. This is
what it means to restrict ourselves to <em>ephemeral</em> usage.</p>

<h2 id="a-bad-example">A bad example</h2>

<p>To show that difference lists are not magical, let’s see how we might use them
inappropriately. Since difference lists are good for appending, perhaps they
could be used to implement a FIFO queue:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="kr">type</span> <span class="kt">Queue</span> <span class="n">a</span> <span class="o">=</span> <span class="kt">DList</span> <span class="n">a</span>

<span class="n">put</span> <span class="o">::</span> <span class="kt">Queue</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">Queue</span> <span class="n">a</span>
<span class="n">put</span> <span class="n">q</span> <span class="n">x</span> <span class="o">=</span> <span class="n">append</span> <span class="n">q</span> <span class="p">(</span><span class="n">singleton</span> <span class="n">x</span><span class="p">)</span>

<span class="c1">-- No!</span>
<span class="n">take</span> <span class="o">::</span> <span class="kt">Queue</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">Maybe</span> <span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="kt">Queue</span> <span class="n">a</span><span class="p">)</span>
<span class="n">take</span> <span class="n">q</span> <span class="o">=</span> <span class="kr">case</span> <span class="n">toList</span> <span class="n">q</span> <span class="kr">of</span>
  <span class="kt">[]</span> <span class="o">-&gt;</span> <span class="kt">Nothing</span>
  <span class="n">x</span><span class="o">:</span><span class="n">xs</span> <span class="o">-&gt;</span> <span class="kt">Just</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">fromList</span> <span class="n">xs</span><span class="p">)</span></code></pre></figure>

<p>The <code class="language-plaintext highlighter-rouge">put</code> operation seems fine, provided we don’t attempt to use the <code class="language-plaintext highlighter-rouge">Queue</code>
persistently. For <code class="language-plaintext highlighter-rouge">take</code>, we find that we need to use <code class="language-plaintext highlighter-rouge">toList</code> before we can
inspect the contents of the queue. Worst of all, we must use the linear-time
<code class="language-plaintext highlighter-rouge">fromList</code> to construct the new <code class="language-plaintext highlighter-rouge">Queue</code>.</p>

<p>Since switching back and forth between difference lists and ordinary lists is
inefficient, difference lists are primarily useful in build-then-consume
algorithms. We can use a difference list to efficiently build a list, before
converting to an ordinary list that is then consumed.</p>

<h2 id="some-fun-with-folds">Some fun with folds</h2>

<p>While it’s good to know when and how to use difference lists, it’s even nicer
to understand the connections to folds and monoids. Let’s reexamine our
difference-list-based <code class="language-plaintext highlighter-rouge">reverse</code>:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="kt">[]</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="o">.</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="p">)</span></code></pre></figure>

<p>The only places we actually construct any lists are the empty list, <code class="language-plaintext highlighter-rouge">[]</code>, at
the end of line 2, and the singleton difference list, <code class="language-plaintext highlighter-rouge">(x:)</code>, at the end of
line 6. Let’s abstract over those, calling them <code class="language-plaintext highlighter-rouge">z</code> and <code class="language-plaintext highlighter-rouge">f x</code> respectively:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="n">f</span> <span class="n">z</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="n">z</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="o">.</span> <span class="n">f</span> <span class="n">x</span></code></pre></figure>

<p>We can then generalise the type without touching the implementation, and arrive
at a familiar function:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldl</span> <span class="o">::</span> <span class="n">forall</span> <span class="n">a</span> <span class="n">b</span><span class="o">.</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span>
<span class="n">foldl</span> <span class="n">f</span> <span class="n">z</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="n">z</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="o">.</span> <span class="n">f</span> <span class="n">x</span></code></pre></figure>

<p>The type of argument <code class="language-plaintext highlighter-rouge">f</code> is flipped with respect to the Prelude version, but
the meaning is the same. So we can say that <code class="language-plaintext highlighter-rouge">foldl</code> is just <code class="language-plaintext highlighter-rouge">reverse</code> with the
constructors abstracted.</p>

<p>Similarly, we can say that <code class="language-plaintext highlighter-rouge">foldr</code> is just a list traversal with the
constructors abstracted. In fact, we can get the right-fold on <code class="language-plaintext highlighter-rouge">Tree</code> using the
same generalisation on <code class="language-plaintext highlighter-rouge">flatten</code>. For lists, we can get <code class="language-plaintext highlighter-rouge">foldr</code> by simply
flipping the function composition in line 6:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldr</span> <span class="o">::</span> <span class="n">forall</span> <span class="n">a</span> <span class="n">b</span><span class="o">.</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span>
<span class="n">foldr</span> <span class="n">f</span> <span class="n">z</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="n">z</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span> <span class="n">x</span> <span class="o">.</span> <span class="n">go</span> <span class="n">xs</span></code></pre></figure>

<h2 id="monoids">Monoids</h2>

<p>To make precise the comparison between the two versions of each of our
examples, we need to recognise that we are using the corresponding operations
of two different monoids, the list monoid and the <code class="language-plaintext highlighter-rouge">Endo</code> monoid:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="kr">instance</span> <span class="kt">Monoid</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="kr">where</span>
  <span class="n">mempty</span> <span class="o">=</span> <span class="kt">[]</span>
  <span class="p">(</span><span class="o">&lt;&gt;</span><span class="p">)</span> <span class="o">=</span> <span class="p">(</span><span class="o">++</span><span class="p">)</span>

<span class="kr">newtype</span> <span class="kt">Endo</span> <span class="n">b</span> <span class="o">=</span> <span class="kt">Endo</span> <span class="p">{</span> <span class="n">appEndo</span> <span class="o">::</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="p">}</span>

<span class="kr">instance</span> <span class="kt">Monoid</span> <span class="p">(</span><span class="kt">Endo</span> <span class="n">a</span><span class="p">)</span> <span class="kr">where</span>
  <span class="n">mempty</span> <span class="o">=</span> <span class="kt">Endo</span> <span class="n">id</span>
  <span class="kt">Endo</span> <span class="n">f</span> <span class="o">&lt;&gt;</span> <span class="kt">Endo</span> <span class="n">g</span> <span class="o">=</span> <span class="kt">Endo</span> <span class="p">(</span><span class="n">f</span> <span class="o">.</span> <span class="n">g</span><span class="p">)</span></code></pre></figure>

<p>Notice that in the <code class="language-plaintext highlighter-rouge">Endo</code> monoid, we’ve generalised from the type <code class="language-plaintext highlighter-rouge">[a] -&gt; [a]</code>
that we used for difference lists, to <code class="language-plaintext highlighter-rouge">b -&gt; b</code>, just as we did when we
generalised from <code class="language-plaintext highlighter-rouge">reverse</code> to <code class="language-plaintext highlighter-rouge">foldl</code>.</p>

<p>We also need a way to inject a single element into a monoid. We use the <code class="language-plaintext highlighter-rouge">unit</code>
method of the <code class="language-plaintext highlighter-rouge">Reducer</code> class, from the <a href="https://hackage.haskell.org/package/reducers">reducers</a> package. We can then
rewrite <code class="language-plaintext highlighter-rouge">reverse</code> and <code class="language-plaintext highlighter-rouge">flatten</code> like this:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse'</span> <span class="o">::</span> <span class="p">(</span><span class="kt">Monoid</span> <span class="n">m</span><span class="p">,</span> <span class="kt">Reducer</span> <span class="n">a</span> <span class="n">m</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">m</span>
<span class="n">reverse'</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">mempty</span>
<span class="n">reverse'</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">reverse'</span> <span class="n">xs</span> <span class="o">&lt;&gt;</span> <span class="n">unit</span> <span class="n">x</span>

<span class="n">flatten'</span> <span class="o">::</span> <span class="p">(</span><span class="kt">Monoid</span> <span class="n">m</span><span class="p">,</span> <span class="kt">Reducer</span> <span class="n">a</span> <span class="n">m</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="n">m</span>
<span class="n">flatten'</span> <span class="kt">Leaf</span> <span class="o">=</span> <span class="n">mempty</span>
<span class="n">flatten'</span> <span class="p">(</span><span class="kt">Branch</span> <span class="n">l</span> <span class="n">x</span> <span class="n">r</span><span class="p">)</span> <span class="o">=</span> <span class="n">flatten'</span> <span class="n">l</span> <span class="o">&lt;&gt;</span> <span class="n">unit</span> <span class="n">x</span> <span class="o">&lt;&gt;</span> <span class="n">flatten'</span> <span class="n">r</span></code></pre></figure>

<p>If we treat the result as a list, we get the inefficient versions:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="o">=</span> <span class="n">reverse'</span>

<span class="n">flatten</span> <span class="o">::</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">flatten</span> <span class="o">=</span> <span class="n">flatten'</span></code></pre></figure>

<p>But if we add an appropriate wrapper, we get the efficient versions:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">extract</span> <span class="o">::</span> <span class="kt">Endo</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">extract</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">appEndo</span> <span class="n">xs</span> <span class="kt">[]</span>

<span class="n">reverse</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="o">=</span> <span class="n">extract</span> <span class="o">.</span> <span class="n">reverse'</span>

<span class="n">flatten</span> <span class="o">::</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">flatten</span> <span class="o">=</span> <span class="n">extract</span> <span class="o">.</span> <span class="n">flatten'</span></code></pre></figure>

<h2 id="more-fun-with-folds">More fun with folds</h2>

<p>Now that we know about <code class="language-plaintext highlighter-rouge">Endo</code>, let’s reexamine <code class="language-plaintext highlighter-rouge">foldr</code>:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldr</span> <span class="o">::</span> <span class="n">forall</span> <span class="n">a</span> <span class="n">b</span><span class="o">.</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span>
<span class="n">foldr</span> <span class="n">f</span> <span class="n">z</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="n">z</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span> <span class="n">x</span> <span class="o">.</span> <span class="n">go</span> <span class="n">xs</span></code></pre></figure>

<p>First let’s rearrange the arguments a little, swapping <code class="language-plaintext highlighter-rouge">z</code> and <code class="language-plaintext highlighter-rouge">xs</code>:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldr</span> <span class="o">::</span> <span class="n">forall</span> <span class="n">a</span> <span class="n">b</span><span class="o">.</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span>
<span class="n">foldr</span> <span class="n">f</span> <span class="n">xs</span> <span class="n">z</span> <span class="o">=</span> <span class="n">go</span> <span class="n">xs</span> <span class="n">z</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">id</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span> <span class="n">x</span> <span class="o">.</span> <span class="n">go</span> <span class="n">xs</span></code></pre></figure>

<p>We can see the type <code class="language-plaintext highlighter-rouge">b -&gt; b</code> in lots of places, and we’re using the
function <code class="language-plaintext highlighter-rouge">id</code> and composition as well. That’s just the <code class="language-plaintext highlighter-rouge">Endo</code> monoid,
so let’s rewrite like this:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldr</span> <span class="o">::</span> <span class="n">forall</span> <span class="n">a</span> <span class="n">b</span><span class="o">.</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">Endo</span> <span class="n">b</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="kt">Endo</span> <span class="n">b</span>
<span class="n">foldr</span> <span class="n">f</span> <span class="o">=</span> <span class="n">go</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="kt">Endo</span> <span class="n">b</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">mempty</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span> <span class="n">x</span> <span class="o">&lt;&gt;</span> <span class="n">go</span> <span class="n">xs</span></code></pre></figure>

<p>Without touching the implementation, we can generalise the type to <em>any</em>
monoid, and rename:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldMap</span> <span class="o">::</span> <span class="n">forall</span> <span class="n">a</span> <span class="n">m</span><span class="o">.</span> <span class="kt">Monoid</span> <span class="n">m</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">m</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">m</span>
<span class="n">foldMap</span> <span class="n">f</span> <span class="o">=</span> <span class="n">go</span>
  <span class="kr">where</span>
    <span class="n">go</span> <span class="o">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">m</span>
    <span class="n">go</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">mempty</span>
    <span class="n">go</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span> <span class="n">x</span> <span class="o">&lt;&gt;</span> <span class="n">go</span> <span class="n">xs</span></code></pre></figure>

<p>The wrapper is no longer doing anything, so we have just this:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldMap</span> <span class="o">::</span> <span class="kt">Monoid</span> <span class="n">m</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">m</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">m</span>
<span class="n">foldMap</span> <span class="n">f</span> <span class="kt">[]</span> <span class="o">=</span> <span class="n">mempty</span>
<span class="n">foldMap</span> <span class="n">f</span> <span class="p">(</span><span class="n">x</span><span class="o">:</span><span class="n">xs</span><span class="p">)</span> <span class="o">=</span> <span class="n">f</span> <span class="n">x</span> <span class="o">&lt;&gt;</span> <span class="n">foldMap</span> <span class="n">f</span> <span class="n">xs</span></code></pre></figure>

<p>Notice how <code class="language-plaintext highlighter-rouge">foldMap</code> follows the structure of the list data type. We can
recover <code class="language-plaintext highlighter-rouge">foldr</code> by specialising to the <code class="language-plaintext highlighter-rouge">Endo</code> monoid, and extracting the
result by applying to the argument <code class="language-plaintext highlighter-rouge">z</code>:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldr</span> <span class="o">::</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span>
<span class="n">foldr</span> <span class="n">f</span> <span class="n">z</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">appEndo</span> <span class="p">(</span><span class="n">foldMap</span> <span class="p">(</span><span class="kt">Endo</span> <span class="o">.</span> <span class="n">f</span><span class="p">)</span> <span class="n">xs</span><span class="p">)</span> <span class="n">z</span></code></pre></figure>

<p>To get <code class="language-plaintext highlighter-rouge">foldl</code>, we would need a version of <code class="language-plaintext highlighter-rouge">Endo</code> in which the monoid append
(i.e. the function composition) is reversed. <code class="language-plaintext highlighter-rouge">Dual</code> is a monoid transformer
which just flips the monoid append operation, <code class="language-plaintext highlighter-rouge">&lt;&gt;</code>, with respect to the base
monoid:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldl</span> <span class="o">::</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="n">b</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">b</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="n">b</span>
<span class="n">foldl</span> <span class="n">f</span> <span class="n">z</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">appEndo</span> <span class="p">(</span><span class="n">getDual</span> <span class="o">$</span> <span class="n">foldMap</span> <span class="p">(</span><span class="kt">Dual</span> <span class="o">.</span> <span class="kt">Endo</span> <span class="o">.</span> <span class="n">f</span><span class="p">)</span> <span class="n">xs</span><span class="p">)</span> <span class="n">z</span></code></pre></figure>

<p>What about <code class="language-plaintext highlighter-rouge">Tree</code> flattening? Well, <code class="language-plaintext highlighter-rouge">Tree</code> has a <code class="language-plaintext highlighter-rouge">foldMap</code>, too:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">foldMap</span> <span class="o">::</span> <span class="kt">Monoid</span> <span class="n">m</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">m</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kt">Tree</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="n">m</span>
<span class="n">foldMap</span> <span class="n">f</span> <span class="kt">Leaf</span> <span class="o">=</span> <span class="n">mempty</span>
<span class="n">foldMap</span> <span class="n">f</span> <span class="p">(</span><span class="kt">Branch</span> <span class="n">l</span> <span class="n">x</span> <span class="n">r</span><span class="p">)</span> <span class="o">=</span> <span class="n">foldMap</span> <span class="n">f</span> <span class="n">l</span> <span class="o">&lt;&gt;</span> <span class="n">f</span> <span class="n">x</span> <span class="o">&lt;&gt;</span> <span class="n">foldMap</span> <span class="n">f</span> <span class="n">r</span></code></pre></figure>

<p>Again, notice how <code class="language-plaintext highlighter-rouge">foldMap</code> follows the structure of the <code class="language-plaintext highlighter-rouge">Tree</code> data type.
We could reuse the same definitions of <code class="language-plaintext highlighter-rouge">foldr</code> and <code class="language-plaintext highlighter-rouge">foldl</code> above, just by
changing the types.</p>

<p>In fact, we’ve just reinvented the <code class="language-plaintext highlighter-rouge">Foldable</code> type class from the <a href="https://hackage.haskell.org/package/base/docs/Data-Foldable.html">base</a>
package:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="kr">class</span> <span class="kt">Foldable</span> <span class="n">t</span> <span class="kr">where</span>
  <span class="n">foldMap</span> <span class="o">::</span> <span class="kt">Monoid</span> <span class="n">m</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">m</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">t</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="n">m</span></code></pre></figure>

<p>Just by implementing <code class="language-plaintext highlighter-rouge">foldMap</code> for your <code class="language-plaintext highlighter-rouge">Foldable</code> data types, you get <code class="language-plaintext highlighter-rouge">foldl</code>
and <code class="language-plaintext highlighter-rouge">foldr</code> for free. This means you can use whichever fold is most appropriate
for your situation. For example:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">reverse</span> <span class="o">::</span> <span class="kt">Foldable</span> <span class="n">t</span> <span class="o">=&gt;</span> <span class="n">t</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">reverse</span> <span class="o">=</span> <span class="n">foldl</span> <span class="p">(</span><span class="n">flip</span> <span class="p">(</span><span class="o">:</span><span class="p">))</span> <span class="kt">[]</span>

<span class="n">flatten</span> <span class="o">::</span> <span class="kt">Foldable</span> <span class="n">t</span> <span class="o">=&gt;</span> <span class="n">t</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">flatten</span> <span class="o">=</span> <span class="n">foldr</span> <span class="p">(</span><span class="o">:</span><span class="p">)</span> <span class="kt">[]</span>

<span class="n">first</span> <span class="o">::</span> <span class="kt">Foldable</span> <span class="n">t</span> <span class="o">=&gt;</span> <span class="n">t</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">Maybe</span> <span class="n">a</span>
<span class="n">first</span> <span class="o">=</span> <span class="n">foldr</span> <span class="p">(</span><span class="n">const</span> <span class="o">.</span> <span class="kt">Just</span><span class="p">)</span> <span class="kt">Nothing</span>

<span class="n">last</span> <span class="o">::</span> <span class="kt">Foldable</span> <span class="n">t</span> <span class="o">=&gt;</span> <span class="n">t</span> <span class="n">a</span> <span class="o">-&gt;</span> <span class="kt">Maybe</span> <span class="n">a</span>
<span class="n">last</span> <span class="o">=</span> <span class="n">foldl</span> <span class="p">(</span><span class="n">const</span> <span class="kt">Just</span><span class="p">)</span> <span class="kt">Nothing</span></code></pre></figure>

<p>What’s more, if your <code class="language-plaintext highlighter-rouge">foldMap</code> follows the structure of your data type, <code class="language-plaintext highlighter-rouge">foldl</code>
and <code class="language-plaintext highlighter-rouge">foldr</code> will both be maximally lazy and efficient. For example, <code class="language-plaintext highlighter-rouge">first</code> is
<em>O</em>(1) on lists, including infinite lists, and <em>O</em>(log <em>n</em>) on <code class="language-plaintext highlighter-rouge">Data.Set</code>, while
<code class="language-plaintext highlighter-rouge">last</code> is <em>O</em>(<em>n</em>) on lists, but still <em>O</em>(log <em>n</em>) on <code class="language-plaintext highlighter-rouge">Data.Set</code>.</p>

<h2 id="analogy-to-free-monads">Analogy to free monads</h2>

<p>When defining a term language and one or more interpreters, the <a href="https://hackage.haskell.org/package/free">free monad</a>
makes it easy to write computions in the term language without reference to any
specific interpretation.</p>

<p>Janis Voitgländer showed how to <a href="https://www.janis-voigtlaender.eu/Voi08d.html">improve the asymptotic complexity</a> of
computations over free monads. The method for free monad computations is
analogous to the difference-list transformation for list constructions, but
operating in a different category. Whereas list types are free monoid objects
in the category <em>Hask</em>, free monads are the corresponding objects in the
endofunctor category.</p>

<p>Following Voitgländer, we can write our <code class="language-plaintext highlighter-rouge">extract</code> function with a more
restrictive rank-2 type:</p>

<figure class="highlight"><pre><code class="language-haskell" data-lang="haskell"><span class="n">extract</span> <span class="o">::</span> <span class="n">forall</span> <span class="n">a</span><span class="o">.</span> <span class="p">(</span><span class="n">forall</span> <span class="n">m</span><span class="o">.</span> <span class="p">(</span><span class="kt">Monoid</span> <span class="n">m</span><span class="p">,</span> <span class="kt">Reducer</span> <span class="n">m</span> <span class="n">a</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="n">m</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span>
<span class="n">extract</span> <span class="n">xs</span> <span class="o">=</span> <span class="n">appEndo</span> <span class="n">xs</span> <span class="kt">[]</span></code></pre></figure>

<p>This ensures that the computed list is in fact a difference list, by
restricting the construction to <code class="language-plaintext highlighter-rouge">mempty</code>, <code class="language-plaintext highlighter-rouge">(&lt;&gt;)</code> and <code class="language-plaintext highlighter-rouge">unit</code>.</p>]]></content><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><category term="haskell" /><category term="data-structures" /><summary type="html"><![CDATA[This post is an extended version of a lightning talk I gave at the Brisbane Functional Programming Group. It introduces the difference list, a simple trick for improving the performance of certain kinds of list-building functions in Haskell, and goes on to explore the connections to monoids and folds. The first half is aimed at Haskell novices, while the latter parts might be interesting to intermediates.]]></summary></entry><entry><title type="html">C++11 universal reference pop-quiz</title><link href="https://matthew.brecknell.net/posts/c-plus-plus-11-universal-reference-pop-quiz/" rel="alternate" type="text/html" title="C++11 universal reference pop-quiz" /><published>2013-08-02T11:51:00+00:00</published><updated>2013-08-02T11:51:00+00:00</updated><id>https://matthew.brecknell.net/posts/c-plus-plus-11-universal-reference-pop-quiz</id><content type="html" xml:base="https://matthew.brecknell.net/posts/c-plus-plus-11-universal-reference-pop-quiz/"><![CDATA[<p>Here’s a little exercise for anyone who, like me, recently came across
<a href="https://scottmeyers.blogspot.com/">Scott</a> <a href="https://aristeia.com/">Meyers</a>’ <a href="https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers">work</a> on <a href="https://channel9.msdn.com/Shows/Going+Deep/Cpp-and-Beyond-2012-Scott-Meyers-Universal-References-in-Cpp11">universal</a> <a href="https://nwcpp.org/july-2013.html">references</a> in <a href="https://isocpp.org/std/the-standard">C++11</a>: Is
the following program well formed? Does it have well-defined behaviour? If not,
why not? If so, what is the value returned by <code class="language-plaintext highlighter-rouge">main()</code>? Why? <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf">References</a>,
please!</p>

<figure class="highlight"><pre><code class="language-c--" data-lang="c++"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">R</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">wat</span><span class="p">;</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">wat</span> <span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;&gt;</span> <span class="p">{</span>
  <span class="k">static</span> <span class="kt">int</span> <span class="n">value</span><span class="p">(</span><span class="n">T</span> <span class="o">&amp;</span> <span class="n">t</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">t</span> <span class="o">*</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span>
<span class="p">};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">wat</span> <span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;&amp;&gt;</span> <span class="p">{</span>
  <span class="k">static</span> <span class="kt">int</span> <span class="n">value</span><span class="p">(</span><span class="n">T</span> <span class="o">&amp;&amp;</span> <span class="n">t</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">t</span> <span class="o">*</span> <span class="mi">3</span><span class="p">;</span> <span class="p">}</span>
<span class="p">};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="k">struct</span> <span class="nc">ref</span> <span class="p">{</span>
  <span class="n">ref</span><span class="p">(</span><span class="n">T</span> <span class="o">&amp;&amp;</span> <span class="n">t</span><span class="p">)</span> <span class="o">:</span> <span class="n">t</span><span class="p">(</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;&amp;&gt;</span><span class="p">(</span><span class="n">t</span><span class="p">))</span> <span class="p">{}</span>
  <span class="kt">int</span> <span class="n">value</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">wat</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;&amp;&gt;::</span><span class="n">value</span><span class="p">(</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;&amp;&gt;</span><span class="p">(</span><span class="n">t</span><span class="p">));</span> <span class="p">}</span>
  <span class="n">T</span> <span class="o">&amp;&amp;</span> <span class="n">t</span><span class="p">;</span>
<span class="p">};</span>

<span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="nc">T</span><span class="p">&gt;</span>
<span class="n">ref</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">uni</span><span class="p">(</span><span class="n">T</span> <span class="o">&amp;&amp;</span> <span class="n">t</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="n">ref</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&amp;&amp;&gt;</span><span class="p">(</span><span class="n">t</span><span class="p">));</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
  <span class="kt">int</span> <span class="n">i</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
  <span class="k">return</span> <span class="n">uni</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="n">value</span><span class="p">()</span> <span class="o">+</span> <span class="n">uni</span><span class="p">(</span><span class="mi">13</span><span class="p">).</span><span class="n">value</span><span class="p">();</span>
<span class="p">}</span></code></pre></figure>

<p>I have written the program so that it needs no <code class="language-plaintext highlighter-rouge">#include</code> directives, and
therefore you can be sure there is not a single <code class="language-plaintext highlighter-rouge">typedef</code>, <code class="language-plaintext highlighter-rouge">decltype</code> or <code class="language-plaintext highlighter-rouge">auto</code>
specifier anywhere in or out of sight. That means there’s only one way that
so-called <em>universal</em> references can arise.</p>

<p>However, you might find one or two other little surprises. Oh, and <a href="https://clang.llvm.org/">Clang</a>
<a href="https://clang.llvm.org/cxx_status.html">3.3</a> and <a href="https://gcc.gnu.org/">GCC</a> <a href="https://gcc.gnu.org/projects/cxx0x.html">4.8.1</a> don’t even agree on this program, so there’s not
much point in cheating!</p>]]></content><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><category term="c-plus-plus" /><summary type="html"><![CDATA[Here’s a little exercise for anyone who, like me, recently came across Scott Meyers’ work on universal references in C++11: Is the following program well formed? Does it have well-defined behaviour? If not, why not? If so, what is the value returned by main()? Why? References, please! template &lt;typename R&gt; struct wat; template &lt;typename T&gt; struct wat &lt;T&amp;&gt; { static int value(T &amp; t) { return t * 1; } }; template &lt;typename T&gt; struct wat &lt;T&amp;&amp;&gt; { static int value(T &amp;&amp; t) { return t * 3; } }; template &lt;typename T&gt; struct ref { ref(T &amp;&amp; t) : t(static_cast&lt;T&amp;&amp;&gt;(t)) {} int value() { return wat&lt;T&amp;&amp;&gt;::value(static_cast&lt;T&amp;&amp;&gt;(t)); } T &amp;&amp; t; }; template &lt;typename T&gt; ref&lt;T&gt; uni(T &amp;&amp; t) { return ref&lt;T&gt;(static_cast&lt;T&amp;&amp;&gt;(t)); } int main() { int i(3); return uni(i).value() + uni(13).value(); } I have written the program so that it needs no #include directives, and therefore you can be sure there is not a single typedef, decltype or auto specifier anywhere in or out of sight. That means there’s only one way that so-called universal references can arise. However, you might find one or two other little surprises. Oh, and Clang 3.3 and GCC 4.8.1 don’t even agree on this program, so there’s not much point in cheating!]]></summary></entry><entry><title type="html">B-trees with GADTs</title><link href="https://matthew.brecknell.net/posts/btree-gadt/" rel="alternate" type="text/html" title="B-trees with GADTs" /><published>2013-05-15T23:15:00+00:00</published><updated>2013-05-15T23:15:00+00:00</updated><id>https://matthew.brecknell.net/posts/btree-gadt</id><content type="html" xml:base="https://matthew.brecknell.net/posts/btree-gadt/"><![CDATA[<p>I interactively build a simple B-tree data structure in Haskell, implementing
insertion and deletion, using a <a href="https://en.wikipedia.org/wiki/Generalized_algebraic_data_type">GADT</a> to enforce the structural invariant.
The GADT also guides us towards a correct implementation.</p>

<p class="vimeo-embed">
  <iframe src="https://player.vimeo.com/video/660405565?byline=0&amp;portrait=0&amp;title=0" allow="fullscreen" frameborder="0" title="Introduction to the seL4 proofs">
  </iframe>
</p>

<p>Also on <a href="https://youtu.be/VIeZW4TSSHg">YouTube</a>. MP4 downloads are available from <a href="https://vimeo.com/mbrcknl/btrees-with-gadts">Vimeo</a>. The
slides I used for my <a href="https://yowconference.com/lambdajam/2013">YLJ13</a> talk are available in <a href="/posts/btree-gadt/btree-gadt-ylj2013.pdf">PDF</a> or
<a href="/posts/btree-gadt/btree-gadt-ylj2013.keynote">Keynote</a>. There’s some code on <a href="https://github.com/mbrcknl/btree-gadt">GitHub</a>, and a <a href="/posts/btree-gadt/btree-gadt-script.pdf">script</a>.</p>]]></content><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><category term="haskell" /><category term="data-structures" /><category term="dependent-types" /><category term="screencast" /><summary type="html"><![CDATA[I interactively build a simple B-tree data structure in Haskell, implementing insertion and deletion, using a GADT to enforce the structural invariant. The GADT also guides us towards a correct implementation. Also on YouTube. MP4 downloads are available from Vimeo. The slides I used for my YLJ13 talk are available in PDF or Keynote. There’s some code on GitHub, and a script.]]></summary></entry><entry><title type="html">Hole-driven Haskell</title><link href="https://matthew.brecknell.net/posts/hole-driven-haskell/" rel="alternate" type="text/html" title="Hole-driven Haskell" /><published>2013-02-26T06:25:00+00:00</published><updated>2013-02-26T06:25:00+00:00</updated><id>https://matthew.brecknell.net/posts/hole-driven-haskell</id><content type="html" xml:base="https://matthew.brecknell.net/posts/hole-driven-haskell/"><![CDATA[<p>A demonstration of a technique for using types to guide the construction of
Haskell programs, based on natural deduction. Includes some tricks for getting
help from the compiler, <a href="https://www.haskell.org/ghc/">GHC</a>.</p>

<p class="vimeo-embed">
  <iframe src="https://player.vimeo.com/video/660402181?byline=0&amp;portrait=0&amp;title=0" allow="fullscreen" frameborder="0" title="Hole-driven Haskell">
  </iframe>
</p>

<p>Also on <a href="https://youtu.be/52VsgyexS8Q">YouTube</a>. MP4 downloads are available from <a href="https://vimeo.com/mbrcknl/hole-driven-haskell">Vimeo</a>. There are
<a href="/posts/hole-driven-haskell/hole-driven-haskell.srt">subtitles</a>.</p>]]></content><author><name>Matthew Brecknell</name><email>matthew@brecknell.net</email><uri>https://matthew.brecknell.net/</uri></author><category term="haskell" /><category term="screencast" /><summary type="html"><![CDATA[A demonstration of a technique for using types to guide the construction of Haskell programs, based on natural deduction. Includes some tricks for getting help from the compiler, GHC. Also on YouTube. MP4 downloads are available from Vimeo. There are subtitles.]]></summary></entry></feed>