<?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>The Life Monadic</title>
        <link>https://duplode.github.io</link>
        <description><![CDATA[Haskell amusements]]></description>
        <atom:link href="https://duplode.github.io/rss.xml" rel="self"
                   type="application/rss+xml" />
        <lastBuildDate>Mon, 07 Feb 2022 19:55:00 UT</lastBuildDate>
        <item>
    <title>Every Distributive is Representable</title>
    <link>https://duplode.github.io/posts/every-distributive-is-representable.html</link>
    <description><![CDATA[
<p>“Every <code>Distributive</code> <code>Functor</code> is actually <code>Representable</code>”, as the documentation for <a href="https://hackage.haskell.org/package/adjunctions-4.4/docs/Data-Functor-Rep.html"><code>Representable</code></a> tells us straight away, and yet it is far from obvious why that should be the case. At first glance, <a href="https://hackage.haskell.org/package/distributive-0.6.2.1/docs/Data-Distributive.html"><code>Distributive</code></a>, the dual to <code>Traversable</code>, appears to have little if anything to do with <code>Representable</code>, the class for functors isomorphic to functions. The goal of this post is making this connection explicit. In the process, we will tease out a fair amount of information about the two classes, and also contemplate what makes it tricky to fully bridge the gap to <code>Representable</code>.</p>
<div>

</div>
<!--more-->
<h2 id="the-basic-facts">The basic facts</h2>
<p>Over the course of this post, the focus will alternate between <code>Distributive</code> and <code>Representable</code>. In this first section, we will review the basic definitions and laws upon which we will build. Following that, we will work on both ends, aiming at making the classes meet in the middle.</p>
<h3 id="distributive">Distributive</h3>
<p>Let’s begin by jotting down a few basic facts about <code>Distributive</code>. Here is a minimalistic definition of the class:</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">Functor</span> g <span class="ot">=&gt;</span> <span class="dt">Distributive</span> g <span class="kw">where</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    distribute ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> f (g a) <span class="ot">-&gt;</span> g (f a)</span></code></pre></div>
<p>(In what follows, when used as a placeholder name for a functor, <code>g</code> will always stand for a distributive or representable functor, while <code>f</code> will typically stand for the other functor involved in <code>distribute</code>.)</p>
<p><code>distribute</code> is dual to <code>sequenceA</code>; accordingly, we will adopt the duals of <a href="https://hackage.haskell.org/package/base-4.16.0.0/docs/Data-Traversable.html#g:20">the <code>Traversable</code> laws</a>: <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<ul>
<li><p>Identity:</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> runIdentity <span class="op">.</span> distribute <span class="ot">=</span> runIdentity</span></code></pre></div></li>
<li><p>Composition:</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">fmap</span> getCompose <span class="op">.</span> distribute</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> distribute <span class="op">.</span> <span class="fu">fmap</span> distribute <span class="op">.</span> getCompose</span></code></pre></div></li>
<li><p>Naturality (ensured by parametricity):</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="co">-- For any natural transformation t</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- t :: (Functor f1, Functor f2) =&gt; forall x. f1 x -&gt; f2 x</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> t <span class="op">.</span> distribute <span class="ot">=</span> distribute <span class="op">.</span> t</span></code></pre></div>
<p>This naturality law is stronger than its <code>Traversable</code> counterpart. The <code>Applicative</code> constraint in <code>sequenceA</code> means only natural transformations between applicative functors that preserve <code>pure</code> and <code>(&lt;*&gt;)</code> are preserved by <code>distribute</code>. In contrast, <code>distribute</code> is oblivious to any specifics of <code>f1</code> and <code>f2</code> functor, and so any natural transformation will do.</p></li>
</ul>
<p>Homogeneous pairs are one example of a distributive functor:</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">Duo</span> a <span class="ot">=</span> <span class="dt">Duo</span> a a</span>
<span id="cb5-2"><a href="#cb5-2" 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>
<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>fstDuo,<span class="ot"> sndDuo ::</span> <span class="dt">Duo</span> a <span class="ot">-&gt;</span> a</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>fstDuo (<span class="dt">Duo</span> x _) <span class="ot">=</span> x</span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>sndDuo (<span class="dt">Duo</span> _ y) <span class="ot">=</span> y</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">instance</span> <span class="dt">Distributive</span> <span class="dt">Duo</span> <span class="kw">where</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    distribute m <span class="ot">=</span> <span class="dt">Duo</span> (fstDuo <span class="op">&lt;$&gt;</span> m) (sndDuo <span class="op">&lt;$&gt;</span> m)</span></code></pre></div>
<p><code>Duo</code> will be used in this post as a running example whenever a concrete illustration of <code>Distributive</code> and adjacent classes is called for. For the moment, here is a simple demonstration of <code>distribute @Duo</code> in action. It illustrates the zip-like flavour of <code>distribute</code>, which is shared by the closely related <code>collect</code> and <code>cotraverse</code> from <code>Data.Distributive</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="ot">names ::</span> [<span class="dt">Duo</span> <span class="dt">String</span>]</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>names <span class="ot">=</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>    [ <span class="dt">Duo</span> <span class="st">&quot;Alex&quot;</span> <span class="st">&quot;Lifeson&quot;</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>    , <span class="dt">Duo</span> <span class="st">&quot;Geddy&quot;</span> <span class="st">&quot;Lee&quot;</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    , <span class="dt">Duo</span> <span class="st">&quot;Neil&quot;</span> <span class="st">&quot;Peart&quot;</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    ]</span></code></pre></div>
<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>ghci<span class="op">&gt;</span> distribute names</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Duo</span> [<span class="st">&quot;Alex&quot;</span>,<span class="st">&quot;Geddy&quot;</span>,<span class="st">&quot;Neil&quot;</span>] [<span class="st">&quot;Lifeson&quot;</span>,<span class="st">&quot;Lee&quot;</span>,<span class="st">&quot;Peart&quot;</span>]</span></code></pre></div>
<p>The function functor is a very important example of <code>Distributive</code>. Consider the following combinator:</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">flap ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> f (r <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> r <span class="ot">-&gt;</span> f a</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>flap m <span class="ot">=</span> \r <span class="ot">-&gt;</span> (\f <span class="ot">-&gt;</span> f r) <span class="op">&lt;$&gt;</span> m</span></code></pre></div>
<p>It changes a <code>f (r -&gt; a)</code> functorial value into a <code>r -&gt; f a</code> function, which feeds its argument to all of the available <code>r -&gt; a</code> functions. <code>flap</code> is a lawful implementation of <code>distribute</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">Distributive</span> ((<span class="ot">-&gt;</span>) r) <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    distribute <span class="ot">=</span> flap</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>ghci<span class="op">&gt;</span> distribute [(<span class="op">*</span><span class="dv">3</span>), (<span class="op">+</span><span class="dv">7</span>), (<span class="op">^</span><span class="dv">2</span>)] <span class="dv">8</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>[<span class="dv">24</span>,<span class="dv">15</span>,<span class="dv">64</span>]</span></code></pre></div>
<p><code>flap</code> will be used in this post as a synonym for <code>distribute @((-&gt;) _)</code> whenever convenient, or necessary to avoid circularity. <a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a></p>
<h3 id="representable">Representable</h3>
<p>As for <code>Representable</code>, for our immediate purposes it suffices to characterise it as a class for functors isomorphic to functions:</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">class</span> <span class="dt">Functor</span> g <span class="ot">=&gt;</span> <span class="dt">Representable</span> g <span class="kw">where</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">Rep</span> g</span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="ot">    tabulate ::</span> (<span class="dt">Rep</span> g <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> g a</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="ot">    index ::</span> g a <span class="ot">-&gt;</span> <span class="dt">Rep</span> g <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>Here, <code>Rep g</code> is some concrete type such that <code>tabulate</code> and <code>index</code> witness an isomorphism between <code>Rep g -&gt; a</code> and <code>g a</code>. Accordingly, the laws are:</p>
<ul>
<li><p>Home direction (from <code>g a</code> and back):</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>tabulate <span class="op">.</span> <span class="fu">index</span> <span class="ot">=</span> <span class="fu">id</span></span></code></pre></div></li>
<li><p>Away direction (to <code>g a</code> and back):</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">index</span> <span class="op">.</span> tabulate <span class="ot">=</span> <span class="fu">id</span></span></code></pre></div></li>
</ul>
<p><code>Duo</code> can be given a <code>Representable</code> instance: pick <code>Bool</code> (or any other type with two inhabitants) as <code>Rep g</code>, and associate each possible value with a component of the pair:</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">instance</span> <span class="dt">Representable</span> <span class="dt">Duo</span> <span class="kw">where</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">type</span> <span class="dt">Rep</span> <span class="dt">Duo</span> <span class="ot">=</span> <span class="dt">Bool</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    tabulate f <span class="ot">=</span> <span class="dt">Duo</span> (f <span class="dt">False</span>) (f <span class="dt">True</span>)</span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">index</span> (<span class="dt">Duo</span> x y) <span class="ot">=</span> \<span class="kw">case</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>        <span class="dt">False</span> <span class="ot">-&gt;</span> x</span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">True</span> <span class="ot">-&gt;</span> y</span></code></pre></div>
<p>In order to treat the two classes in an even-handed way, I have opted to leave out the <code>Distributive g =&gt; Representable g</code> relationship that exists in the <code>Data.Functor.Rep</code> version of <code>Representable</code> . In any case, every representable is indeed distributive, with a default definition of <code>distribute</code> which uses the isomorphism to delegate to <code>flap</code> (that is, <code>distribute</code> for 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="ot">distributeRep ::</span> (<span class="dt">Representable</span> g, <span class="dt">Functor</span> f) <span class="ot">=&gt;</span> f (g a) <span class="ot">-&gt;</span> g (f a)</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>distributeRep <span class="ot">=</span> tabulate <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span></span></code></pre></div>
<p>The lawfulness of <code>distributeRep</code> follows from the lawfulness of <code>flap</code>. <a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></p>
<p>Our ultimate aim here is to go the other way around, from <code>Distributive</code> to <code>Representable</code>.</p>
<h2 id="no-need-to-choose">No need to choose</h2>
<p>If we are to start from <code>Distributive</code>, though, there is a pretty fundamental difficulty: setting up a <code>Representable g</code> instance requires picking a suitable <code>Rep g</code>, and there is nothing in <code>Distributive</code> that could possibly correspond to such a choice. That being so, we will spend some more time contemplating <code>Representable</code>, looking for a way to somehow obviate the need for specifying <code>Rep g</code>.</p>
<h3 id="askrep">askRep</h3>
<p>Let’s have another look at the type of <code>tabulate</code>:</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">tabulate ::</span> <span class="dt">Representable</span> g <span class="ot">=&gt;</span> (<span class="dt">Rep</span> g <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> g a</span></code></pre></div>
<p><code>tabulate</code> is a natural transformation from the function functor <code>((-&gt;) (Rep g)</code> to <code>g</code>. Now, all natural transformations from a function functor have the form: <a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></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="co">-- For some type R, functor G, and any</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="ot">t ::</span> <span class="kw">forall</span> x<span class="op">.</span> (<span class="dt">R</span> <span class="ot">-&gt;</span> x) <span class="ot">-&gt;</span> <span class="dt">G</span> x</span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- There is a</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a><span class="ot">w ::</span> <span class="dt">G</span> <span class="dt">R</span></span>
<span id="cb18-5"><a href="#cb18-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- Such that</span></span>
<span id="cb18-6"><a href="#cb18-6" aria-hidden="true" tabindex="-1"></a>t f <span class="ot">=</span> f <span class="op">&lt;$&gt;</span> w</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>w <span class="ot">=</span> t <span class="fu">id</span></span></code></pre></div>
<p>In words, the natural transformation must amount to mapping the function over some functorial value. In our case, <code>t</code> is <code>tabulate</code>; as for <code>w</code>, we will call it <code>askRep</code>, which is <a href="https://hackage.haskell.org/package/adjunctions-4.4/docs/src/Data-Functor-Rep.html#askRep">the name it goes by in <code>Data.Functor.Rep</code></a>. <a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a>. That being so, we have:</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">askRep ::</span> <span class="dt">Representable</span> g <span class="ot">=&gt;</span> g (<span class="dt">Rep</span> g)</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>askRep <span class="ot">=</span> tabulate <span class="fu">id</span></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>tabulate f <span class="ot">=</span> f <span class="op">&lt;$&gt;</span> askRep</span></code></pre></div>
<p>The <code>Representable</code> laws can be recast in terms of <code>askRep</code> and <code>index</code>. Here is the home direction of the isomorphism:</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>tabulate <span class="op">.</span> <span class="fu">index</span> <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb20-2"><a href="#cb20-2" aria-hidden="true" tabindex="-1"></a>tabulate (<span class="fu">index</span> u) <span class="ot">=</span> u</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="fu">index</span> u <span class="op">&lt;$&gt;</span> askRep <span class="ot">=</span> u</span></code></pre></div>
<p>That is, we can reconstruct any <code>u :: g a</code> by taking <code>askRep</code> and replacing every <code>Rep g</code> provided by it with the <code>a</code> value that applying <code>index u</code> on it gives us.</p>
<p>It is worth noting that <code>index u &lt;$&gt; askRep = u</code> also tells us that for any <code>u :: g a</code> there is a function (namely, <code>index u</code>) which will change <code>askRep</code> into <code>u</code> through <code>fmap</code>. That largely corresponds to the intuition that a representable functor must have a single shape.</p>
<p>The away direction of the isomorphism becomes:</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="fu">index</span> <span class="op">.</span> tabulate <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a><span class="fu">index</span> (f <span class="op">&lt;$&gt;</span> askRep) <span class="ot">=</span> f</span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- index is a natural transformation</span></span>
<span id="cb21-4"><a href="#cb21-4" aria-hidden="true" tabindex="-1"></a>f <span class="op">&lt;$&gt;</span> <span class="fu">index</span> askRep <span class="ot">=</span> f</span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- fmap @((-&gt;) _) = (.)</span></span>
<span id="cb21-6"><a href="#cb21-6" aria-hidden="true" tabindex="-1"></a>f <span class="op">.</span> <span class="fu">index</span> askRep <span class="ot">=</span> f</span>
<span id="cb21-7"><a href="#cb21-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- In particular, suppose f = id</span></span>
<span id="cb21-8"><a href="#cb21-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- (note that this step is reversible)</span></span>
<span id="cb21-9"><a href="#cb21-9" aria-hidden="true" tabindex="-1"></a><span class="fu">index</span> askRep <span class="ot">=</span> <span class="fu">id</span></span></code></pre></div>
<p>Intuitively, if we think of <code>Rep g</code> values as corresponding to positions in the <code>g</code> shape that can be queried through <code>index</code>, <code>index askRep = id</code> tells us that each and every <code>Rep g</code> will be found in <code>askRep</code> occupying the position it corresponds to. For example, with the <code>Representable</code> instance from the previous section, <code>askRep @Duo</code> looks 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>ghci<span class="op">&gt;</span> askRep <span class="op">@</span><span class="dt">Duo</span></span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Duo</span> <span class="dt">False</span> <span class="dt">True</span></span></code></pre></div>
<p>Lastly, we can also express <code>distributeRep</code> in terms of <code>askRep</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>distributeRep m</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>tabulate (flap (<span class="fu">index</span> <span class="op">&lt;$&gt;</span> m))</span>
<span id="cb23-3"><a href="#cb23-3" aria-hidden="true" tabindex="-1"></a>flap (<span class="fu">index</span> <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> askRep</span>
<span id="cb23-4"><a href="#cb23-4" aria-hidden="true" tabindex="-1"></a>(\r <span class="ot">-&gt;</span> (\f <span class="ot">-&gt;</span> f r) <span class="op">&lt;$&gt;</span> (<span class="fu">index</span> <span class="op">&lt;$&gt;</span> m)) <span class="op">&lt;$&gt;</span> askRep</span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>(\r <span class="ot">-&gt;</span> (\u <span class="ot">-&gt;</span> <span class="fu">index</span> u r) <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> askRep</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>distributeRep m <span class="ot">=</span> (\r <span class="ot">-&gt;</span> (\u <span class="ot">-&gt;</span> <span class="fu">index</span> u r) <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> askRep</span></code></pre></div>
<p>That is, replace every <code>Rep g</code> in <code>askRep</code> with the result of using it to <code>index</code> every <code>g a</code> in <code>m</code>.</p>
<h3 id="extracting-and-revealing">Extracting and revealing</h3>
<p>Now let’s direct our attention to <code>index</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="fu">index</span><span class="ot"> ::</span> <span class="dt">Representable</span> g <span class="ot">=&gt;</span> g a <span class="ot">-&gt;</span> <span class="dt">Rep</span> g <span class="ot">-&gt;</span> a</span></code></pre></div>
<p>Flipping <code>index</code> gives us:</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">fromRep ::</span> <span class="dt">Representable</span> g <span class="ot">=&gt;</span> <span class="dt">Rep</span> g <span class="ot">-&gt;</span> g a <span class="ot">-&gt;</span> a</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>fromRep r <span class="ot">=</span> \u <span class="ot">-&gt;</span> <span class="fu">index</span> u r</span></code></pre></div>
<p><code>fromRep</code> converts a <code>Rep g</code> into what I will call a <em>polymorphic extractor</em>, of type <code>forall a. g a -&gt; a</code>, which gives us <code>a</code> out of <code>g a</code>. The existence of <code>fromRep</code> is quite suggestive. Since <code>forall a. g a -&gt; a</code> doesn’t use <code>Rep g</code>, finding an inverse to <code>fromRep</code>, and thus showing those two types are isomorphic, might give us a way to work with <code>Representable</code> without relying on <code>Rep g</code>.</p>
<p>How might we go about converting a polymorphic extractor into a <code>Rep g</code> value? To do it in a non-trivial way , we will need a <code>g (Rep g)</code> source of <code>Rep g</code> on which we can use the extractor. Considering the discussion in the previous subsection, <code>askRep</code> looks like a reasonable option:</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">toRep ::</span> <span class="dt">Representable</span> g <span class="ot">=&gt;</span> (<span class="kw">forall</span> x<span class="op">.</span> g x <span class="ot">-&gt;</span> x) <span class="ot">-&gt;</span> <span class="dt">Rep</span> g</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>toRep p <span class="ot">=</span> p askRep</span></code></pre></div>
<p>Now let’s check if <code>fromRep</code> and <code>toRep</code> are indeed inverses, beginning with the <code>toRep . fromRep</code> direction:</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>toRep <span class="op">.</span> fromRep</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p askRep) <span class="op">.</span> (\r <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> <span class="fu">index</span> u r)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>\r <span class="ot">-&gt;</span> (\u <span class="ot">-&gt;</span> <span class="fu">index</span> u r) askRep</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>\r <span class="ot">-&gt;</span> <span class="fu">index</span> askRep r</span>
<span id="cb27-5"><a href="#cb27-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- index askRep = id</span></span>
<span id="cb27-6"><a href="#cb27-6" aria-hidden="true" tabindex="-1"></a><span class="fu">id</span></span></code></pre></div>
<p>We can proceed similarly with <code>fromRep . toRep</code>:</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>fromRep <span class="op">.</span> toRep</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>(\r <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> <span class="fu">index</span> u r) <span class="op">.</span> (\p <span class="ot">-&gt;</span> p askRep)</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>\p <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> <span class="fu">index</span> u (p askRep)</span></code></pre></div>
<p>To simplify this further, we can note that a polymorphic extractor <code>forall x. g x -&gt; x</code> amounts to natural transformation from <code>g</code> to <code>Identity</code>. That being so, we have, for any extractor <code>p</code> and any <code>f</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>f <span class="op">.</span> p <span class="ot">=</span> p <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>The above is the usual naturality property, <code>fmap f . p = p . fmap f</code>, except that, to account for the omission of the <code>Identity</code> newtype boilerplate, <code>fmap @Identity</code> has been replaced on the left-hand side by plain function application. We can now carry on:</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>\p <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> <span class="fu">index</span> u (p askRep)</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>\p <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> p (<span class="fu">index</span> u <span class="op">&lt;$&gt;</span> askRep)</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- index u &lt;$&gt; askRep = u</span></span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>\p <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> p u</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a><span class="fu">id</span></span></code></pre></div>
<p>And there it is: for any <code>Representable</code>, <code>Rep g</code> must be isomorphic to <code>forall x. g x -&gt; x</code>. That being so, we can use <code>forall x. g x -&gt; x</code> as a default <code>Rep g</code> that can be specified in terms of <code>g</code> alone. The change of perspective can be made clearer by setting up an alternative class:</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="dt">Pos</span> g <span class="ot">=</span> <span class="kw">forall</span> x<span class="op">.</span> g x <span class="ot">-&gt;</span> x</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a><span class="ot">elide ::</span> g a <span class="ot">-&gt;</span> <span class="dt">Pos</span> g <span class="ot">-&gt;</span> a</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>elide u <span class="ot">=</span> \p <span class="ot">-&gt;</span> p u</span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> <span class="dt">Functor</span> g <span class="ot">=&gt;</span> <span class="dt">Revealable</span> g <span class="kw">where</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a><span class="ot">    reveal ::</span> (<span class="dt">Pos</span> g <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> g a</span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a><span class="ot">    chart ::</span> g (<span class="dt">Pos</span> g)</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>    reveal e <span class="ot">=</span> e <span class="op">&lt;$&gt;</span> chart</span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a>    chart <span class="ot">=</span> reveal <span class="fu">id</span></span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a>    <span class="ot">{-# MINIMAL reveal | chart #-}</span></span></code></pre></div>
<p>Both the arrangement of those definitions and my idiosyncratic choice of names call for some explanation:</p>
<ul>
<li><p><code>Pos g</code> is a synonym for the type of polymorphic extractors. The name <code>Pos</code> is short for “position”, and is meant to allude to the intuition that an extractor picks a value from some specific position in a <code>g</code>-shaped structure.</p></li>
<li><p><code>elide</code> corresponds to <code>index</code>, defined in such a way that <code>fromRep =   id</code>. Since all it does is applying a <code>Pos g</code> extractor, on its own it doesn’t require any constraints on <code>g</code>. The choice of name is motivated by how <code>elide</code> hides the <code>g</code> shape, in that that the only information about <code>u :: g a</code> that can be recovered from <code>elide u</code> are the <code>a</code> values that a <code>Pos g</code> extractor can reach.</p></li>
<li><p><code>reveal</code>, in turn, corresponds to <code>tabulate</code>, and is the inverse of <code>elide</code>. If <code>g</code> is <code>Representable</code>, the <code>g</code> shape can be reconstituted with no additional information, and so it is possible to undo the hiding performed by <code>elide</code>.</p></li>
<li><p><code>chart</code> corresponds to <code>askRep</code>, with it and <code>reveal</code> being interdefinable. In particular, <code>chart</code> can be used to reveal the <code>g   a</code> that corresponds to a <code>Pos g -&gt; a</code> function by providing the means to reach every position in the <code>g</code> shape. <a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a></p></li>
</ul>
<p>Here is the <code>Duo</code> instance of <code>Revealable</code>. Note how each position in <code>chart</code> holds its own extractor:</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">Revealable</span> <span class="dt">Duo</span> <span class="kw">where</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>    reveal e <span class="ot">=</span> <span class="dt">Duo</span> (e fstDuo) (e sndDuo)</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>    chart <span class="ot">=</span> <span class="dt">Duo</span> fstDuo sndDuo</span></code></pre></div>
<p><code>distribute</code> can be implemented for <code>Revealable</code> in a way completely analogous to how it was done for <code>Representable</code>:</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">distributeRev ::</span> (<span class="dt">Revealable</span> g, <span class="dt">Functor</span> f) <span class="ot">=&gt;</span> f (g a) <span class="ot">-&gt;</span> g (f a)</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>distributeRev <span class="ot">=</span> reveal <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> elide</span></code></pre></div>
<p>Or, in terms of <code>chart</code>:</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>distributeRev m <span class="ot">=</span> (\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> chart</span></code></pre></div>
<p>That is, <code>distributeRev m</code> amounts to mapping every extractor in <code>chart</code> over <code>m</code>.</p>
<p>As for the laws, just like we were able to choose between expressing the <code>Representable</code> isomorphism directly, via <code>tabulate</code>, or indirectly via <code>askRep</code>, here we can use either <code>reveal</code> or <code>chart</code>:</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>reveal <span class="op">.</span> elide <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Or, equivalently</span></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a>elide u <span class="op">&lt;$&gt;</span> chart <span class="ot">=</span> u</span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a>elide <span class="op">.</span> reveal <span class="ot">=</span> <span class="fu">id</span></span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- Or, equivalently</span></span>
<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a>p chart <span class="ot">=</span> p</span></code></pre></div>
<p>With <code>Revealable</code>, though, we can streamline things by showing <code>p chart = p</code> follows from <code>elide u &lt;$&gt; chart = u</code>. The proof relies on the naturality of the polymorphic extractors:</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>elide u <span class="op">&lt;$&gt;</span> chart <span class="ot">=</span> u</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Apply some p :: Pos g to both sides</span></span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a>p (elide u <span class="op">&lt;$&gt;</span> chart) <span class="ot">=</span> p u</span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a><span class="co">-- p is natural</span></span>
<span id="cb36-5"><a href="#cb36-5" aria-hidden="true" tabindex="-1"></a>elide u (p chart) <span class="ot">=</span> p u</span>
<span id="cb36-6"><a href="#cb36-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- elide u p = p u</span></span>
<span id="cb36-7"><a href="#cb36-7" aria-hidden="true" tabindex="-1"></a>(p chart) u <span class="ot">=</span> p u</span>
<span id="cb36-8"><a href="#cb36-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- u is arbitrary</span></span>
<span id="cb36-9"><a href="#cb36-9" aria-hidden="true" tabindex="-1"></a>p chart <span class="ot">=</span> p</span></code></pre></div>
<p>That being so, <code>elide u &lt;$&gt; chart = u</code> is the only law we need to characterise <code>Revealable</code>. Since <code>elide</code> does not depend on the <code>Revealable</code> instance, we might as well inline its definition, which leaves us with:</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>(\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chart <span class="ot">=</span> u</span></code></pre></div>
<p>I suggest calling it the <em>law of extractors</em>: it tells us that the extractors provided by <code>chart</code> suffice to reconstitute an arbitrary <code>g a</code> value.</p>
<h2 id="revisiting-distributive">Revisiting Distributive</h2>
<p>In <code>Revealable</code>, we have a class equivalent to <code>Representable</code> which doesn’t rely on the <code>Rep</code> type family. That makes it feasible to continue our investigation by attempting to show that every <code>Distributive</code> functor is <code>Revealable</code>.</p>
<h3 id="natural-wonders">Natural wonders</h3>
<p>Naturality laws and parametricity properties not infrequently have interesting consequences that seem to us as hidden in plain sight. Considering the increased strength of <code>Distributive</code>’s naturality law relative to its <code>Traversable</code> counterpart and the important role naturality properties had in setting up <code>Revealable</code>, resuming our work on <code>Distributive</code> from the naturality law sounds like a reasonable bet:</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="co">-- For any natural transformation t</span></span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- t :: (Functor f1, Functor f2) =&gt; forall x. f1 x -&gt; f2 x</span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> t <span class="op">.</span> distribute <span class="ot">=</span> distribute <span class="op">.</span> t</span></code></pre></div>
<p>In particular, suppose <code>f1</code> is a function functor:</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="co">-- t :: Functor f =&gt; forall x. (r -&gt; x) -&gt; f x</span></span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a>t <span class="op">&lt;$&gt;</span> distribute f <span class="ot">=</span> distribute (t f)</span></code></pre></div>
<p>Now, by the same argument used back when we defined <code>askRep</code>, <code>t</code> must have the form:</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="co">-- m :: f r</span></span>
<span id="cb40-2"><a href="#cb40-2" aria-hidden="true" tabindex="-1"></a>t f <span class="ot">=</span> f <span class="op">&lt;$&gt;</span> m</span></code></pre></div>
<p>Therefore:</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>(\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> distribute f <span class="ot">=</span> distribute (f <span class="op">&lt;$&gt;</span> m)</span></code></pre></div>
<p>In particular, suppose <code>f = id</code>. We then end up with an specification of <code>distribute</code> in terms of <code>distribute id</code>:</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>(\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> distribute <span class="fu">id</span> <span class="ot">=</span> distribute m</span></code></pre></div>
<p><code>distribute id</code> has the following type:</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>ghci<span class="op">&gt;</span> <span class="op">:</span>t distribute <span class="fu">id</span></span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a>distribute<span class="ot"> id ::</span> <span class="dt">Distributive</span> g <span class="ot">=&gt;</span> g (g a <span class="ot">-&gt;</span> a)</span></code></pre></div>
<p>This looks a lot like something that holds extractors, and the specification itself mirrors the definition of <code>distributeRev</code> in terms of <code>chart</code>. As a preliminary check, <code>distribute @Duo id</code> holds <code>fstDuo</code> and <code>sndDuo</code> on their respective positions, exactly like <code>chart @Duo</code>:</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>distribute <span class="op">@</span><span class="dt">Duo</span> <span class="fu">id</span></span>
<span id="cb44-2"><a href="#cb44-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Duo</span> (<span class="fu">id</span> <span class="op">&lt;$&gt;</span> fstDuo) (<span class="fu">id</span> <span class="op">&lt;$&gt;</span> sndDuo)</span>
<span id="cb44-3"><a href="#cb44-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Duo</span> fstDuo sndDuo</span></code></pre></div>
<p>Given the clear resemblance, I will optimistically refer to <code>distribute id</code> as <code>chartDist</code>:</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="ot">chartDist ::</span> <span class="dt">Distributive</span> g <span class="ot">=&gt;</span> g (g a <span class="ot">-&gt;</span> a)</span>
<span id="cb45-2"><a href="#cb45-2" aria-hidden="true" tabindex="-1"></a>chartDist <span class="ot">=</span> distribute <span class="fu">id</span></span></code></pre></div>
<p>We therefore have:</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>distribute m <span class="ot">=</span> (\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> chartDist</span></code></pre></div>
<p>Now suppose <code>m = Identity u</code> for some <code>u :: g a</code>, and invoke the identity law:</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>distribute (<span class="dt">Identity</span> u) <span class="ot">=</span> (\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> <span class="dt">Identity</span> u) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb47-2"><a href="#cb47-2" aria-hidden="true" tabindex="-1"></a>distribute (<span class="dt">Identity</span> u) <span class="ot">=</span> (\p <span class="ot">-&gt;</span> <span class="dt">Identity</span> (p u)) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb47-3"><a href="#cb47-3" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">&lt;$&gt;</span> distribute (<span class="dt">Identity</span> u)</span>
<span id="cb47-4"><a href="#cb47-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> runIdentity <span class="op">&lt;$&gt;</span> ((\p <span class="ot">-&gt;</span><span class="dt">Identity</span> (p u)) <span class="op">&lt;$&gt;</span> chartDist)</span>
<span id="cb47-5"><a href="#cb47-5" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">&lt;$&gt;</span> distribute (<span class="dt">Identity</span> u)</span>
<span id="cb47-6"><a href="#cb47-6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> (\p <span class="ot">-&gt;</span> runIdentity (<span class="dt">Identity</span> (p u))) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb47-7"><a href="#cb47-7" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">&lt;$&gt;</span> distribute (<span class="dt">Identity</span> u)</span>
<span id="cb47-8"><a href="#cb47-8" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> (\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb47-9"><a href="#cb47-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- By the identity law</span></span>
<span id="cb47-10"><a href="#cb47-10" aria-hidden="true" tabindex="-1"></a>runIdentity (<span class="dt">Identity</span> u) <span class="ot">=</span> (\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb47-11"><a href="#cb47-11" aria-hidden="true" tabindex="-1"></a>u <span class="ot">=</span> (\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartDist</span></code></pre></div>
<p>We therefore have a <code>Distributive</code> version of the law of extractors, with <code>chartDist</code> playing the role of <code>chart</code>. It is also possible to turn things around and obtain the identity law from this law of extractors:</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>(\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartDist <span class="ot">=</span> u</span>
<span id="cb48-2"><a href="#cb48-2" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">.</span> <span class="dt">Identity</span> <span class="op">.</span> (\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartDist <span class="ot">=</span> u</span>
<span id="cb48-3"><a href="#cb48-3" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">.</span> (\p <span class="ot">-&gt;</span> <span class="dt">Identity</span> (p u)) <span class="op">&lt;$&gt;</span> chartDist <span class="ot">=</span> u</span>
<span id="cb48-4"><a href="#cb48-4" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">.</span> (\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> <span class="dt">Identity</span> u) <span class="op">&lt;$&gt;</span> chartDist <span class="ot">=</span> u</span>
<span id="cb48-5"><a href="#cb48-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- distribute m = (\p -&gt; p &lt;$&gt; m) &lt;$&gt; chartDist</span></span>
<span id="cb48-6"><a href="#cb48-6" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">&lt;$&gt;</span> distribute (<span class="dt">Identity</span> u) <span class="ot">=</span> u</span>
<span id="cb48-7"><a href="#cb48-7" aria-hidden="true" tabindex="-1"></a>runIdentity <span class="op">&lt;$&gt;</span> distribute (<span class="dt">Identity</span> u) <span class="ot">=</span> runIdentity (<span class="dt">Identity</span> u)</span>
<span id="cb48-8"><a href="#cb48-8" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> runIdentity <span class="op">.</span> distribute <span class="ot">=</span> runIdentity</span></code></pre></div>
<p>These are auspicious results. Given that the law of extractors is enough to establish an implementation of <code>chart</code> as lawful, and that there can’t be multiple distinct lawful implementations of <code>distribute</code> <a href="#fn7" class="footnote-ref" id="fnref7" role="doc-noteref"><sup>7</sup></a>, all we need to do is to identify <code>chartDist</code> with <code>chart</code>.</p>
<h3 id="the-roadblock-and-a-detour">The roadblock, and a detour</h3>
<p>Identifying <code>chartDist</code> with <code>chart</code>, however, is not trivial. As similar as <code>chart</code> and <code>chartDist</code> might feel like, their types differ in an insurmountable way:</p>
<div class="sourceCode" id="cb49"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a>chart <span class="op">@</span><span class="dt">G</span><span class="ot">     ::</span> <span class="dt">G</span> (<span class="kw">forall</span> a<span class="op">.</span> <span class="dt">G</span> a <span class="ot">-&gt;</span> a)  <span class="co">-- G (Pos G)</span></span>
<span id="cb49-2"><a href="#cb49-2" aria-hidden="true" tabindex="-1"></a>chartDist <span class="op">@</span><span class="dt">G</span><span class="ot"> ::</span> <span class="kw">forall</span> a<span class="op">.</span> <span class="dt">G</span> (<span class="dt">G</span> a <span class="ot">-&gt;</span> a)</span></code></pre></div>
<p>In particular:</p>
<ul>
<li><p>The <code>a</code> in <code>forall a. G (G a -&gt; a)</code> can be directly specialised to a concrete choice of <code>a</code>, and, as far as the specialised type <code>G (G A -&gt; A)</code> is concerned, it is conceivable that the involved <code>G A -&gt; A</code> functions might not be natural in <code>A</code>.</p></li>
<li><p>Accordingly, a rank-2 function that takes a <code>Pos G</code>, such as the argument to <code>reveal</code>, can be mapped over <code>chart</code>, but not <code>chartDist</code>.</p></li>
<li><p>There is no way to obtain the impredicative type of <code>chart</code>, or the rank-3 type of <code>reveal</code>, through <code>distribute</code>.</p></li>
</ul>
<p>To put it in another way, <code>chartDist</code> doesn’t have a type strong enough to, on its own, ensure that it provides natural, polymorphic extractors, and <code>Distributive</code> is not enough to implement a <code>chart</code> which provides such guarantees.</p>
<p>Still, not all is lost. If there is a way to use the laws of <code>Distributive</code> to show that the extractors of <code>chartDist</code> are natural, we should be able to claim <code>chart</code> and <code>chartDist</code> are morally the same, providing the same extractors with subtly different types.</p>
<p>(Meta note: while I believe the following argument suffices for the task at hand, it is not as crystalline as the derivations elsewhere in this post. Upgrading it to a proper proof will probably require some tricky parametricity maneuver which I haven’t managed to fully figure out yet.)</p>
<p>Let’s turn to the composition law, the one we haven’t touched so far:</p>
<div class="sourceCode" id="cb50"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> getCompose <span class="op">.</span> distribute <span class="ot">=</span> distribute <span class="op">.</span> <span class="fu">fmap</span> distribute <span class="op">.</span> getCompose</span></code></pre></div>
<p>That is, given some <code>m :: Compose fo fi (g a)</code> (“o” is for outer, and “i” for inner):</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>getCompose <span class="op">&lt;$&gt;</span> distribute m <span class="ot">=</span> distribute (distribute <span class="op">&lt;$&gt;</span> getCompose m)</span></code></pre></div>
<p>Let’s use <code>distribute m = (\p -&gt; p &lt;$&gt; m) &lt;$&gt; chartDist</code> on the left-hand side, and on the outer <code>distribute</code> on the right-hand side:</p>
<div class="sourceCode" id="cb52"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a>getCompose <span class="op">&lt;$&gt;</span> ((\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> chartDist)</span>
<span id="cb52-2"><a href="#cb52-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> (\q <span class="ot">-&gt;</span> q <span class="op">&lt;$&gt;</span> (distribute <span class="op">&lt;$&gt;</span> getCompose m)) <span class="op">&lt;$&gt;</span> chartDist</span></code></pre></div>
<p>Note that the left-hand side <code>chartDist</code> has type <code>g (g a -&gt; a)</code>, while the right-hand side one has type <code>g (g (fi a) -&gt; fi a)</code>. Since we can’t take for granted that the extractors provided by them (which are bound to <code>p</code> and <code>q</code>, respectively) are natural, it is important to keep track of this difference.</p>
<p>Tidying the equation a little further, we get:</p>
<div class="sourceCode" id="cb53"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb53-1"><a href="#cb53-1" aria-hidden="true" tabindex="-1"></a>getCompose <span class="op">&lt;$&gt;</span> ((\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> chartDist)</span>
<span id="cb53-2"><a href="#cb53-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> (\q <span class="ot">-&gt;</span> q <span class="op">&lt;$&gt;</span> (distribute <span class="op">&lt;$&gt;</span> getCompose m)) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb53-3"><a href="#cb53-3" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> getCompose (p <span class="op">&lt;$&gt;</span> m)) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb53-4"><a href="#cb53-4" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> (\q <span class="ot">-&gt;</span> q <span class="op">.</span> distribute <span class="op">&lt;$&gt;</span> getCompose m) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb53-5"><a href="#cb53-5" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> <span class="fu">fmap</span> p <span class="op">&lt;$&gt;</span> getCompose m) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb53-6"><a href="#cb53-6" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> (\q <span class="ot">-&gt;</span> q <span class="op">.</span> distribute <span class="op">&lt;$&gt;</span> getCompose m) <span class="op">&lt;$&gt;</span> chartDist</span></code></pre></div>
<p>On either side of the equation, we have <code>fmap</code> being used to obtain a <code>g (fo (fi a))</code> result. That being so, any <code>fo (fi a)</code> value that, thanks to <code>fmap</code>, shows up in the left-hand side must also show up in the right-hand side. More precisely, given any <code>p :: g a -&gt; a</code> drawn from <code>chartDist</code> on the left-hand side, there must be some <code>q :: g (fi a) -&gt; fi a</code> drawn from the <code>chartDist</code> on the right hand side such that…</p>
<div class="sourceCode" id="cb54"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb54-1"><a href="#cb54-1" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> p <span class="op">&lt;$&gt;</span> getCompose m <span class="ot">=</span> q <span class="op">.</span> distribute <span class="op">&lt;$&gt;</span> getCompose m</span></code></pre></div>
<p>… and vice versa. That allows us to reason about <code>p</code> and <code>q</code>, which amount to the extractors drawn from <code>chartDist</code> we are interested in.</p>
<p>As neither <code>p</code> nor <code>q</code> involve <code>fo</code>, and the equation must hold for all choices of <code>fo</code>, we can freely consider the case in which it is <code>Identity</code>, or anything else that has an injective <code>fmap</code>. If <code>fmap</code> is injective, the equation further simplifies to:</p>
<div class="sourceCode" id="cb55"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb55-1"><a href="#cb55-1" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> p <span class="ot">=</span> q <span class="op">.</span> distribute</span></code></pre></div>
<p>Now, <code>fmap p :: fi (g a) -&gt; fi a</code> cannot affect the <code>fi</code> shape; therefore, the same holds for <code>q . distribute :: fi (g a) -&gt;  fi a</code>. <code>distribute :: fi (g a) -&gt; g (fi a)</code> is natural in <code>fi</code>, and so it, too, can’t affect the <code>fi</code> shape. It follows that <code>q :: g (fi a) -&gt; fi a</code> is also unable to affect the <code>fi</code> shape.</p>
<p>Zooming back out, we have just established that, if the composition law holds, <code>chartDist :: g (g (fi a) -&gt; fi a)</code> only provides extractors that preserve the <code>fi</code> shape. <code>chartDist</code>, however, is defined as <code>distribute id :: forall b. g (g b -&gt; b)</code>, which is fully polymorphic on the element type <code>b</code>. That being so, if there is a way for <code>distribute id</code> to somehow produce non-natural extractors, it cannot possibly rely in any way about the specifics of <code>b</code>. That, in particular, rules out any means of, given <code>b ~ fi a</code> for some functor <code>fi</code>, producing just non-natural extractors that preserve the <code>fi</code> shape: such a distinction cannot be expressed. We must conclude, therefore, that if the composition law holds <code>chartDist</code> can only provide natural extractors, as we hoped to show.</p>
<p>The converse of this conclusion, by the way, also holds: assuming the identity law holds, if all <code>q</code> drawn from <code>chartDist</code> are natural, the composition law must hold. To show that, we can use the fact that, for a natural <code>q :: forall x. g x -&gt; x</code>, <code>q chartDist = q</code> holds, just like it does for <code>chart</code>:</p>
<div class="sourceCode" id="cb56"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb56-1"><a href="#cb56-1" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartDist <span class="ot">=</span> u</span>
<span id="cb56-2"><a href="#cb56-2" aria-hidden="true" tabindex="-1"></a>q ((\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartDist)) <span class="ot">=</span> q u</span>
<span id="cb56-3"><a href="#cb56-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- Since q is natural, q . fmap f = f . q</span></span>
<span id="cb56-4"><a href="#cb56-4" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p u) (q chartDist) <span class="ot">=</span> q u</span>
<span id="cb56-5"><a href="#cb56-5" aria-hidden="true" tabindex="-1"></a>(q chartDist) u <span class="ot">=</span> q u</span>
<span id="cb56-6"><a href="#cb56-6" aria-hidden="true" tabindex="-1"></a>q chartDist <span class="ot">=</span> q</span></code></pre></div>
<p>As a consequence, <code>q . distribute = fmap q</code>:</p>
<div class="sourceCode" id="cb57"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb57-1"><a href="#cb57-1" aria-hidden="true" tabindex="-1"></a>q (distribute m)</span>
<span id="cb57-2"><a href="#cb57-2" aria-hidden="true" tabindex="-1"></a>q ((\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) <span class="op">&lt;$&gt;</span> chartDist)</span>
<span id="cb57-3"><a href="#cb57-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- q is natural</span></span>
<span id="cb57-4"><a href="#cb57-4" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) (q chartDist)</span>
<span id="cb57-5"><a href="#cb57-5" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p <span class="op">&lt;$&gt;</span> m) q</span>
<span id="cb57-6"><a href="#cb57-6" aria-hidden="true" tabindex="-1"></a>q <span class="op">&lt;$&gt;</span> m</span></code></pre></div>
<p>We can now return to the rearranged version of the composition law we were dealing with in the preceding argument, this time without taking it for granted:</p>
<div class="sourceCode" id="cb58"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb58-1"><a href="#cb58-1" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> <span class="fu">fmap</span> p <span class="op">&lt;$&gt;</span> getCompose m) <span class="op">&lt;$&gt;</span> chartDist</span>
<span id="cb58-2"><a href="#cb58-2" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> (\q <span class="ot">-&gt;</span> q <span class="op">.</span> distribute <span class="op">&lt;$&gt;</span> getCompose m) <span class="op">&lt;$&gt;</span> chartDist</span></code></pre></div>
<p>By the above, however, if <code>q</code> is natural the right-hand side amounts to…</p>
<div class="sourceCode" id="cb59"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb59-1"><a href="#cb59-1" aria-hidden="true" tabindex="-1"></a>(\q <span class="ot">-&gt;</span> <span class="fu">fmap</span> q <span class="op">&lt;$&gt;</span> getCompose m) <span class="op">&lt;$&gt;</span> chartDist</span></code></pre></div>
<p>… which is the same as the left-hand side.</p>
<h3 id="in-summary">In summary</h3>
<p>After quite a long ride, we have managed to shed some light on the connection between <code>Distributive</code> and <code>Representable</code>:</p>
<ul>
<li><p>Every <code>Distributive</code> is indeed <code>Representable</code>, even though, as expected, <code>Representable</code> cannot be implemented in terms of <code>distribute</code>.</p></li>
<li><p>The connection is mediated by choosing <code>forall x. g x -&gt; x</code>, the type of polymorphic extractors, as a default representation, encoded here as the <code>Revealable</code> class. It can then be shown that this representation is mirrored in <code>Distributive</code> by <code>chartDist =   distribute id :: Distributive g =&gt; g (g a -&gt; a)</code>, which gives a corresponding characterisation of <code>Distributive</code> in terms of extractors.</p></li>
<li><p>The single-shapedness characteristic of both distributive and representable functors follows from the identity law of <code>Distributive</code>.</p></li>
<li><p>The composition law plays an important, if unobvious, role in the connection, as it ensures the naturality of the extractors provided by <code>chartDist</code>, a property that can’t be established on the basis of the involved types.</p></li>
</ul>
<h2 id="the-select-loophole">The Select loophole</h2>
<p>There is one aspect of our investigation that is worth a closer look. All the concern with establishing that <code>chartDist</code> can only provide natural extractors, which kept us busy for a good chunk of the previous section, might have felt surprising. <code>chartDist</code>, after all…</p>
<div class="sourceCode" id="cb60"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb60-1"><a href="#cb60-1" aria-hidden="true" tabindex="-1"></a><span class="ot">chartDist ::</span> <span class="kw">forall</span> g a<span class="op">.</span> <span class="dt">Distributive</span> g <span class="ot">=&gt;</span> g (g a <span class="ot">-&gt;</span> a)</span></code></pre></div>
<p>… is fully polymorphic in <code>a</code>, and therefore its definition cannot rely on anything specific about <code>a</code>. That being so, it may seem outlandish to suppose that specialising <code>chartDist</code> to, say, <code>g (g Integer -&gt; Integer)</code> might somehow bring forth non-natural <code>g Integer -&gt; Integer</code> extractors that perform <code>Integer</code>-specific operations.</p>
<p>To illustrate why the naturality of extractors is, in fact, a relevant issue, let’s consider the curious case of <a href="https://hackage.haskell.org/package/transformers-0.6.0.2/docs/Control-Monad-Trans-Select.html"><code>Select</code></a>:</p>
<div class="sourceCode" id="cb61"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb61-1"><a href="#cb61-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- A paraphrased, non-transformer version of Select.</span></span>
<span id="cb61-2"><a href="#cb61-2" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Select</span> r a <span class="ot">=</span> <span class="dt">Select</span> {<span class="ot"> runSelect ::</span> (a <span class="ot">-&gt;</span> r) <span class="ot">-&gt;</span> a }</span>
<span id="cb61-3"><a href="#cb61-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb61-4"><a href="#cb61-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">Select</span> r) <span class="kw">where</span></span>
<span id="cb61-5"><a href="#cb61-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f u <span class="ot">=</span> <span class="dt">Select</span> <span class="op">$</span> \k <span class="ot">-&gt;</span> f (u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k (f a))</span></code></pre></div>
<p>(A <code>Select r a</code> value can be thought of as a way to choose an <code>a</code> value based on some user-specified criterion, expressed as an <code>a -&gt; r</code> function.)</p>
<p>Corner cases such as <code>r ~ ()</code> aside, <code>Select r</code> cannot be <code>Representable</code>, as that would require it to be isomorphic to a function functor; that being so, it should be similarly ill-suited for <code>Distributive</code>. In spite of that, there is a nontrivial implementation of a <code>Select r</code> combinator with the type <code>chartDist</code> would have: <a href="#fn8" class="footnote-ref" id="fnref8" role="doc-noteref"><sup>8</sup></a></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="ot">chartSelect ::</span> <span class="dt">Select</span> r (<span class="dt">Select</span> r a <span class="ot">-&gt;</span> a)</span>
<span id="cb62-2"><a href="#cb62-2" aria-hidden="true" tabindex="-1"></a>chartSelect <span class="ot">=</span> <span class="dt">Select</span> <span class="op">$</span> \k <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k (<span class="fu">const</span> a)</span></code></pre></div>
<p>What’s more, <code>chartSelect</code> follows the law of extractors:</p>
<div class="sourceCode" id="cb63"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb63-1"><a href="#cb63-1" aria-hidden="true" tabindex="-1"></a><span class="co">-- Goal:</span></span>
<span id="cb63-2"><a href="#cb63-2" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartSelect <span class="ot">=</span> u</span>
<span id="cb63-3"><a href="#cb63-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- LHS</span></span>
<span id="cb63-4"><a href="#cb63-4" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> chartSelect</span>
<span id="cb63-5"><a href="#cb63-5" aria-hidden="true" tabindex="-1"></a>(\p <span class="ot">-&gt;</span> p u) <span class="op">&lt;$&gt;</span> <span class="dt">Select</span> <span class="op">$</span> \k <span class="ot">-&gt;</span> \u <span class="ot">-&gt;</span> u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k (<span class="fu">const</span> a)</span>
<span id="cb63-6"><a href="#cb63-6" aria-hidden="true" tabindex="-1"></a><span class="dt">Select</span> <span class="op">$</span> \k' <span class="ot">-&gt;</span></span>
<span id="cb63-7"><a href="#cb63-7" aria-hidden="true" tabindex="-1"></a>    (\p <span class="ot">-&gt;</span> p u) (\u <span class="ot">-&gt;</span> u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k' ((\p <span class="ot">-&gt;</span> p u) (<span class="fu">const</span> a)))</span>
<span id="cb63-8"><a href="#cb63-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Select</span> <span class="op">$</span> \k' <span class="ot">-&gt;</span> u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k' ((\p <span class="ot">-&gt;</span> p u) (<span class="fu">const</span> a))</span>
<span id="cb63-9"><a href="#cb63-9" aria-hidden="true" tabindex="-1"></a><span class="dt">Select</span> <span class="op">$</span> \k' <span class="ot">-&gt;</span> u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k' (<span class="fu">const</span> a u)</span>
<span id="cb63-10"><a href="#cb63-10" aria-hidden="true" tabindex="-1"></a><span class="dt">Select</span> <span class="op">$</span> \k' <span class="ot">-&gt;</span> u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k' a</span>
<span id="cb63-11"><a href="#cb63-11" aria-hidden="true" tabindex="-1"></a>u  <span class="co">-- LHS = RHS</span></span></code></pre></div>
<p>That means the <code>distribute</code> candidate we get out of <code>chartSelect</code>…</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="ot">nonDistribute ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> f (<span class="dt">Select</span> r a) <span class="ot">-&gt;</span> <span class="dt">Select</span> r (f a)</span>
<span id="cb64-2"><a href="#cb64-2" aria-hidden="true" tabindex="-1"></a>nonDistribute m <span class="ot">=</span> <span class="dt">Select</span> <span class="op">$</span></span>
<span id="cb64-3"><a href="#cb64-3" aria-hidden="true" tabindex="-1"></a>    \k <span class="ot">-&gt;</span> (\u <span class="ot">-&gt;</span> u <span class="ot">`runSelect`</span> \a <span class="ot">-&gt;</span> k (a <span class="op">&lt;$</span> m)) <span class="op">&lt;$&gt;</span> m</span></code></pre></div>
<p>… follows the identity law. As <code>Select r</code> is not supposed to be <code>Distributive</code>, we expect <code>nonDistribute</code> to break the composition law, and that is indeed what happens. <a href="#fn9" class="footnote-ref" id="fnref9" role="doc-noteref"><sup>9</sup></a></p>
<p>Now, by the earlier arguments about the naturality of extractors, if a candidate implementation of <code>chartDist</code> follows the extractors law and only provides natural extractors, the corresponding <code>distribute</code> must follow the composition law. Since <code>chartSelect</code> follows the extractors law but doesn’t give rise to a lawful <code>distribute</code>, we must conclude that it provides non-natural extractors. How does that come to pass?</p>
<p>Every criterion function <code>k :: a -&gt; r</code> gives rise to a non-natural extractor for <code>Select r a</code>, namely <code>\u -&gt; u `runSelect` k :: Select a r -&gt; a</code>. <code>chartSelect</code> indirectly makes all these non-natural extractors available through its own criterion argument, the <code>k</code> that shows up in its definition. (How the encoding works can be seen in the verification above of the law of extractors: note how performing the <code>fmap</code> between the third and fourth lines of the proof requires replacing <code>k :: (Select r a -&gt; a) -&gt; r</code> with <code>k' :: a -&gt; r</code>.)</p>
<p>Non-naturality sneaking into <code>chartSelect</code> has to do with <code>Select r</code> not being a strictly positive functor; that is, it has an occurrence of the element type variable, <code>a</code>, to the left of a function arrow. <a href="#fn10" class="footnote-ref" id="fnref10" role="doc-noteref"><sup>10</sup></a> The lack of strict positivity creates a loophole, through which things can be incorporated to a <code>Select r a</code> value without being specified. It is a plausible conjecture that the composition law of <code>Distributive</code> is a way of ruling out functors that aren’t strictly positive, with lack of strict positivity being the only possible source of non-naturality in <code>chartDist</code>, and any non-trivial lack of strict positivity leading to non-naturality and the composition law being broken. <a href="#fn11" class="footnote-ref" id="fnref11" role="doc-noteref"><sup>11</sup></a></p>
<h2 id="further-reading">Further reading</h2>
<p>There are other interesting ways of approaching <code>Distributive</code> and <code>Representable</code> that I haven’t covered here to avoid making this post longer than it already is. Here are a few suggestions for further reading:</p>
<ul>
<li><p>Chris Penner’s <a href="https://chrispenner.ca/posts/adjunction-battleship"><em>Adjunctions and Battleship</em></a> post is a fine introduction to <a href="https://hackage.haskell.org/package/adjunctions-4.4/docs/Data-Functor-Adjunction.html"><code>Adjunction</code></a>, the class for <strong>Hask</strong>-<strong>Hask</strong> adjunctions, which provides an alternative encoding of <code>Representable</code>.</p></li>
<li><p>The following Stack Overflow answers by Conor McBride on <em>Naperian functors</em>, “Naperian” here being an alternative name for <code>Representable</code>:</p>
<ul>
<li><p><a href="https://stackoverflow.com/a/46502280/2751851"><em>Which Haskell Functors are equivalent to the Reader functor</em></a>, which introduces Naperian functors in a style reminiscent of the <code>askRep</code>-centric formuation of <code>Representable</code> discussed here.</p></li>
<li><p><a href="https://stackoverflow.com/a/13100857/2751851"><em>Writing cojoin or cobind for n-dimensional grid type</em></a>, which includes an outline of how Naperian functors are handled by container theory.</p></li>
</ul></li>
</ul>
<p>On a final note, there is a <a href="https://github.com/ekmett/distributive/blob/117377d7ba38efc5b115169b565dfb80de8ad407/src/Data/Rep/Internal.hs">reworking of <code>Representable</code></a> being developed as part of a potential future release of the <em>distributive</em> package. It aims at unifying the presentations of distributive into a single class that fits equally well the various use cases. An overview of how this new formulation could be a nice topic for a future, follow-up post.</p>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>The <code>Data.Distributive</code> documentation, as of the version 0.6.2.1 of the <em>distributive</em> package, mentions a different set of properties in lieu of these laws, the crucial one being <code>distribute . distribute = id</code>. Though that is a viable approach, I feel that in the context of what this post aims at such a formulation raises more questions than they answer. (For instance, regarding <code>distribute .  distribute = id</code>: Are there two <code>Distributive</code> instances involved? If so, how are we supposed to check that an individual instance is lawful? Does that law correspond to anything from <code>Traversable</code>?) That being so, I have chosen to take a step back and regard the “dual to <code>Traversable</code>” formulation as the starting point.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>The name <code>flap</code>, which I have borrowed from <a href="https://hackage.haskell.org/package/relude-1.0.0.1/docs/Relude-Functor-Fmap.html#v:flap"><em>relude</em></a>, is a play on how <code>distribute @((-&gt;) _) @((-&gt;) _)</code> turns out to be <code>flip</code>.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p>Here is a proof of its lawfulness:</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="co">-- Goal (identity law):</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> runIdentity <span class="op">.</span> distributeRep <span class="ot">=</span> runIdentity</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> runIdentity <span class="op">.</span> distributeRep  <span class="co">-- LHS</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> runIdentity <span class="op">.</span> tabulate <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- tabulate is natural</span></span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a>tabulate <span class="op">.</span> <span class="fu">fmap</span> runIdentity <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- flap follows the identity law</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a>tabulate <span class="op">.</span> runIdentity <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a>tabulate <span class="op">.</span> <span class="fu">index</span> <span class="op">.</span> runIdentity</span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- tabulate . index = id</span></span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true" tabindex="-1"></a>runIdentity  <span class="co">-- LHS = RHS</span></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true" tabindex="-1"></a><span class="co">-- Goal (composition law):</span></span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> getCompose <span class="op">.</span> distributeRep</span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a>    <span class="ot">=</span> distributeRep <span class="op">.</span> <span class="fu">fmap</span> distributeRep <span class="op">.</span> getCompose</span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a>distributeRep <span class="op">.</span> <span class="fu">fmap</span> distributeRep <span class="op">.</span> getCompose   <span class="co">-- RHS</span></span>
<span id="cb16-17"><a href="#cb16-17" aria-hidden="true" tabindex="-1"></a>tabulate <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span> <span class="op">.</span> <span class="fu">fmap</span> tabulate</span>
<span id="cb16-18"><a href="#cb16-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">.</span> <span class="fu">fmap</span> flap <span class="op">.</span> <span class="fu">fmap</span> (<span class="fu">fmap</span> <span class="fu">index</span>) <span class="op">.</span> getCompose</span>
<span id="cb16-19"><a href="#cb16-19" aria-hidden="true" tabindex="-1"></a><span class="co">-- index . tabulate = id</span></span>
<span id="cb16-20"><a href="#cb16-20" aria-hidden="true" tabindex="-1"></a>tabulate <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> flap <span class="op">.</span> <span class="fu">fmap</span> (<span class="fu">fmap</span> <span class="fu">index</span>) <span class="op">.</span> getCompose</span>
<span id="cb16-21"><a href="#cb16-21" aria-hidden="true" tabindex="-1"></a>tabulate <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> flap <span class="op">.</span> getCompose <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span></span>
<span id="cb16-22"><a href="#cb16-22" aria-hidden="true" tabindex="-1"></a><span class="co">-- flap follows the composition law</span></span>
<span id="cb16-23"><a href="#cb16-23" aria-hidden="true" tabindex="-1"></a>tabulate <span class="op">.</span> <span class="fu">fmap</span> getCompose <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span></span>
<span id="cb16-24"><a href="#cb16-24" aria-hidden="true" tabindex="-1"></a><span class="co">-- tabulate is natural</span></span>
<span id="cb16-25"><a href="#cb16-25" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> getCompose <span class="op">.</span> tabulate <span class="op">.</span> flap <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">index</span></span>
<span id="cb16-26"><a href="#cb16-26" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> getCompose <span class="op">.</span> distributeRep  <span class="co">-- RHS = LHS</span></span></code></pre></div>
<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></li>
<li id="fn4" role="doc-endnote"><p>That is a manifestation of the Yoneda lemma. For a Haskell-oriented introduction to it, see Dan Piponi’s <a href="http://blog.sigfpe.com/2006/11/yoneda-lemma.html"><em>Reverse Engineering Machines with the Yoneda Lemma</em></a>.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p><code>askRep</code> is indeed <code>ask</code> for <code>MonadReader (Rep g) g</code>; accordingly, <code>tabulate</code> is <code>asks</code>/<code>reader</code>.<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6" role="doc-endnote"><p>On a technical note, given that the type of <code>chart</code> amounts to <code>g (forall x. g x -&gt; x)</code> using these definitions as written requires the <code>ImpredicativeTypes</code> extension and, ideally, GHC 9.2 or above. Doing it without <code>ImpredicativeTypes</code> would require making <code>Pos g</code> a <code>newtype</code> instead of a mere synonym.<a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn7" role="doc-endnote"><p>In brief: two implementations of <code>distribute :: f (g a) -&gt; g (f a)</code> might differ by what they do to the <code>a</code> values, <code>f</code> shapes, or <code>g</code> shapes. Naturality means <code>a</code> and <code>f</code> can’t be affected by <code>distribute</code>, and so any difference would have to arise from what is done to <code>g</code>. However, the identity law means the <code>g</code> shape can’t be affected either. Therefore, implementations which follow the identity law can’t differ.<a href="#fnref7" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn8" role="doc-endnote"><p>I originally realised it is possible through <a href="https://stackoverflow.com/a/39736535/2751851">a Stack Overflow answer by Sergei Winitzki</a>. I thank him for helping to drive this post to completion, as thinking about <code>Select</code> was instrumental in putting the pieces together.<a href="#fnref8" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn9" role="doc-endnote"><p>Sparing the very messy full proof, the gist of it has to do with the <code>(&lt;$)</code> trick <code>nonDistribute</code> uses to borrow the shape of <code>m</code> in order to have something to feed the <code>k :: f a -&gt;   r</code> criterion. In the left-hand side of the composition law, <code>fmap   getCompose . distribute</code>, the trick is applied once, at the outermost level, while in the right-hand side, <code>distribute . fmap distribute.   getCompose</code>, thanks to the <code>fmap distribute</code> it is also done inside of the outer layer. That being so, there is no way the two sides might be equal.<a href="#fnref9" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn10" role="doc-endnote"><p>Though it doesn’t explicitly mention strict positivity, Michael Snoyman’s <a href="https://www.fpcomplete.com/blog/2016/11/covariance-contravariance/"><em>Covariance and Contravariance</em></a> is an useful primer on polarity, production and consumption in functors. In particular, the <code>CallbackRunner</code> example in the “Positive and negative position” section towards the end is a <code>Functor</code> that isn’t strictly positive.<a href="#fnref10" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn11" role="doc-endnote"><p>On a tangential note, the lack of strict positivity also breaks down the intuitive notion of the shape, as something that can be distinguished from the <code>a</code> values contained or produced by some functorial value <code>f a</code>. While <code>chartSelect</code> abiding by the law of extractors suggests that we should think of <code>Select r</code> as single-shaped, it is hard to even tell what a shape is supposed to be in this case. If <code>Select r a</code> were a garden-variety function type, we might say that there is one <code>a</code> result for every possible <code>a -&gt; r</code> criterion. However, the number of possible <code>a -&gt; r</code> functions also depends on the choice of <code>a</code>. As a result, the number of inhabitants (that is, distinct possible values) of <code>Select r a</code> grows much faster than linearly with the number of inhabitants of <code>a</code>. Were we to say <code>Select r</code> is a single-shaped functor, we would have to concede the shape is <a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/BiggerOnTheInside">is bigger on the inside</a>.<a href="#fnref11" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>


<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/17">Comment on GitHub</a>

    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
      <a id="discourse-button" class="pure-button" href="https://discourse.haskell.org/t/4043">Discourse topic</a>

    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2022-02-07T16:55:00-03:00</pubDate>
    <guid>https://duplode.github.io/posts/every-distributive-is-representable.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Divisible and the Monoidal Quartet</title>
    <link>https://duplode.github.io/posts/divisible-and-the-monoidal-quartet.html</link>
    <description><![CDATA[
<p>A recent blog post by Gabriella Gonzalez, <a href="https://www.haskellforall.com/2021/10/co-applicative-programming-style.html"><em>Co-Applicative programming style</em></a>, has sparked discussion on ergonomic ways to make use of <a href="https://hackage.haskell.org/package/contravariant-1.5.5">the <code>Divisible</code> type class</a>. The conversation pointed to an interesting rabbit hole, and jumping into it resulted in these notes, in which I attempt to get a clearer view of picture of the constellation of monoidal functor classes that <code>Divisible</code> belongs to. The gist of it is that “<code>Divisible</code> is a contravariant <code>Applicative</code>, and <code>Decidable</code> is a contravariant <code>Alternative</code>” is not a full picture of the relationships between the classes, as there are a few extra connections that aren’t obvious to the naked eye.</p>
<div>

</div>
<!--more-->
<p>Besides Gabriella’s post, which is an excellent introduction to <code>Divisible</code>, I recommend as background reading Tom Ellis’ <a href="http://h2.jaguarpaw.co.uk/posts/alternatives-convert-products-to-sums/"><em><code>Alternatives</code> convert products to sums</em></a>, which conveys the core intuition about monoidal functor classes in an accessible manner. There is a second post by Tom, <a href="http://h2.jaguarpaw.co.uk/posts/mysterious-incomposability-of-decidable/"><em>The Mysterious Incomposability of <code>Decidable</code></em></a>, that this article will be in constant dialogue with, in particular as a source of examples. From now on I will refer to it as “the <em>Decidable</em> post”. Thanks to Gabriella and Tom for inspiring the writing of this article.</p>
<p>For those of you reading with GHCi on the side, the key general definitions in this post are available from <a href="../demos/Quartet/Combinators.hs">this <code>.hs</code> file</a>.</p>
<h2 id="applicative">Applicative</h2>
<p>As I hinted at the introduction, this post is not solely about <code>Divisible</code>, but more broadly about monoidal functor classes. To start from familiar ground and set up a reference point, I will first look at the best known of those classes, <code>Applicative</code>. We won’t, however, stick with the usual presentation of <code>Applicative</code> in terms of <code>(&lt;*&gt;)</code>, as it doesn’t generalise to the other classes we’re interested in. Instead, we will switch to the monoidal presentation: <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></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">zipped ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f (a, b)</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>zipped <span class="ot">=</span> liftA2 (,)</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="co">-- An operator spelling, for convenience.</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ot">(&amp;*&amp;) ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f (a, b)</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>(<span class="op">&amp;*&amp;</span>) <span class="ot">=</span> zipped</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">&amp;*&amp;</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">unit ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> f ()</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>unit <span class="ot">=</span> <span class="fu">pure</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="co">-- Laws:</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="co">-- unit &amp;*&amp; v ~ v</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- u &amp;*&amp; unit ~ u</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- (u &amp;*&amp; v) &amp;*&amp; w ~ u &amp;*&amp; (v &amp;*&amp; w)</span></span></code></pre></div>
<p>(Purely for the sake of consistency, I will try to stick to the <code>Data.Functor.Contravariant.Divisible</code> naming conventions for functions like <code>zipped</code>.)</p>
<p>The matter with <code>(&lt;*&gt;)</code> (and also <code>liftA2</code>) that stops it from being generalised for our purposes is that it leans heavily on the fact that <strong>Hask</strong> is a <em>Cartesian closed category</em>, with pairs as the relevant product. Without that, the currying and the partial application we rely on when writing in applicative style become unfeasible.</p>
<p>While keeping ourselves away from <code>(&lt;*&gt;)</code> and <code>liftA2</code>, we can recover, if not the full flexibility, the power of applicative style with a variant of <code>liftA2</code> that takes an uncurried 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">lizip ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> ((a, 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="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>lizip f u v <span class="ot">=</span> <span class="fu">fmap</span> f (zipped u v)</span></code></pre></div>
<p>(That is admittedly a weird name; all the clashing naming conventions around this topic has left me with few good options.)</p>
<p>On a closing note for this section, my choice of operator for <code>zipped</code> is motivated by the similarity with <code>(&amp;&amp;&amp;)</code> from <code>Control.Arrow</code>:</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">(&amp;&amp;&amp;) ::</span> <span class="dt">Arrow</span> p <span class="ot">=&gt;</span> p a b <span class="ot">-&gt;</span> p a c <span class="ot">-&gt;</span> p a (b, c)</span></code></pre></div>
<p>In particular, <code>(&amp;*&amp;)</code> for the function <code>Applicative</code> coincides with <code>(&amp;&amp;&amp;)</code> for the function <code>Arrow</code>.</p>
<p>Leaning on connections like this one, I will use <code>Control.Arrow</code> combinators liberally, beginning with the definition of the following two convenience functions that will show up shortly:</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">dup ::</span> a <span class="ot">-&gt;</span> (a, a)</span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>dup <span class="ot">=</span> <span class="fu">id</span> <span class="op">&amp;&amp;&amp;</span> <span class="fu">id</span></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">forget ::</span> <span class="dt">Either</span> a a <span class="ot">-&gt;</span> a</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>forget <span class="ot">=</span> <span class="fu">id</span> <span class="op">|||</span> <span class="fu">id</span></span></code></pre></div>
<h2 id="divisible">Divisible</h2>
<p>As summarised at the beginning of the <em>Decidable</em> post, while <code>Applicative</code> converts products to products covariantly, <code>Divisible</code> converts products to products contravariantly. From that point of view, I will take <code>divided</code>, the counterpart to <code>zipped</code>, as the fundamental combinator of the class:</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="co">-- This is the divided operator featured on Gabriella's post, soon to</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- become available from Data.Functor.Contravariant.Divisible</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="ot">(&gt;*&lt;) ::</span> <span class="dt">Divisible</span> k <span class="ot">=&gt;</span> k a <span class="ot">-&gt;</span> k b <span class="ot">-&gt;</span> k (a, b)</span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>(<span class="op">&gt;*&lt;</span>) <span class="ot">=</span> divided</span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">&gt;*&lt;</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="co">-- Laws:</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="co">-- conquered &gt;*&lt; v ~ v</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- u &gt;*&lt; conquered ~ u</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a><span class="co">-- (u &gt;*&lt; v) &gt;*&lt; w ~ u &gt;*&lt; (v &gt;*&lt; w)</span></span></code></pre></div>
<p>Recovering <code>divide</code> from <code>divided</code> is straightforward, and entirely analogous to how <code>lizip</code> can be obtained from <code>zipped</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="ot">divide ::</span> <span class="dt">Divisible</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> (b, c)) <span class="ot">-&gt;</span> k b <span class="ot">-&gt;</span> k c <span class="ot">-&gt;</span> k a</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>divide f <span class="ot">=</span> contramap f (divided u v)</span></code></pre></div>
<p>Lessened currying aside, we might say that <code>divide</code> plays the role of <code>liftA2</code> in <code>Divisible</code>.</p>
<p>It’s about time for an example. For that, I will borrow the one from Gabriella’s post:</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">Point</span> <span class="ot">=</span> <span class="dt">Point</span> {<span class="ot"> x ::</span> <span class="dt">Double</span>,<span class="ot"> y ::</span> <span class="dt">Double</span>,<span class="ot"> z ::</span> <span class="dt">Double</span> }</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> <span class="dt">Show</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><span class="ot">nonNegative ::</span> <span class="dt">Predicate</span> <span class="dt">Double</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>nonNegative <span class="ot">=</span> <span class="dt">Predicate</span> (<span class="dv">0</span> <span class="op">&lt;=</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="co">-- (&gt;$&lt;) = contramap</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="ot">nonNegativeOctant ::</span> <span class="dt">Predicate</span> <span class="dt">Point</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a>nonNegativeOctant <span class="ot">=</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a>    adapt <span class="op">&gt;$&lt;</span> nonNegative <span class="op">&gt;*&lt;</span> nonNegative <span class="op">&gt;*&lt;</span> nonNegative</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>    adapt <span class="ot">=</span> x <span class="op">&amp;&amp;&amp;</span> y <span class="op">&amp;&amp;&amp;</span> z</span></code></pre></div>
<p>The slight distortion to Gabriella’s style in using <code>(&amp;&amp;&amp;)</code> to write <code>adapt</code> pointfree is meant to emphasise how that deconstructor can be cleanly assembled out of the component projection functions <code>x</code>, <code>y</code> and <code>z</code>. Importantly, that holds in general: pair-producing functions <code>a -&gt; (b, c)</code> are isomorphic <code>(a -&gt; b, a -&gt; c)</code> pairs of projections. That gives us a variant of <code>divide</code> that takes the projections separately:</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">tdivide ::</span> <span class="dt">Divisible</span> k <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 class="ot">-&gt;</span> k b <span class="ot">-&gt;</span> k c <span class="ot">-&gt;</span> k a</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>tdivide f g u v <span class="ot">=</span> divide (f <span class="op">&amp;&amp;&amp;</span> g) u v</span></code></pre></div>
<p>Besides offering an extra option with respect to ergonomics, <code>tdivide</code> hints at extra structure available from the <code>Divisible</code> class. Let’s play with the definitions a little:</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>tdivide f g u v</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>divide (f <span class="op">&amp;&amp;&amp;</span> g) u v</span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>contramap (f <span class="op">&amp;&amp;&amp;</span> g) (divided u v)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>contramap ((f <span class="op">***</span> g) <span class="op">.</span> dup) (divided u v)</span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>(contramap dup <span class="op">.</span> contramap (f <span class="op">***</span> g)) (divided u v)</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a>contramap dup (divided (contramap f u) (contramap g v))</span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true" tabindex="-1"></a>divide dup (contramap f u) (contramap g v)</span></code></pre></div>
<p><code>divide dup</code>, which duplicates input in order to feed each of its arguments, is a combinator worthy of a name, or even two:</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">dplus ::</span> <span class="dt">Divisible</span> k <span class="ot">=&gt;</span> k a <span class="ot">-&gt;</span> k a <span class="ot">-&gt;</span> k a</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>dplus <span class="ot">=</span> divide dup</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">(&gt;+&lt;) ::</span> <span class="dt">Divisible</span> k <span class="ot">=&gt;</span> k a <span class="ot">-&gt;</span> k a <span class="ot">-&gt;</span> k a</span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>(<span class="op">&gt;+&lt;</span>) <span class="ot">=</span> dplus</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">&gt;+&lt;</span></span></code></pre></div>
<p>So we have:</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>tdivide f g u v <span class="ot">=</span> dplus (contramap f u) (contramap g v)</span></code></pre></div>
<p>Or, using the operators:</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>tdivide f g u v <span class="ot">=</span> f <span class="op">&gt;$&lt;</span> u <span class="op">&gt;+&lt;</span> g <span class="op">&gt;$&lt;</span> v</span></code></pre></div>
<p>An alternative to using the projections to set up a deconstructor to be used with <code>divide</code> is to contramap each projection to its corresponding divisible value and combine the pieces with <code>(&gt;+&lt;)</code>. That is the style favoured by Tom Ellis, <a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> which is why I have added a “t” prefix to <code>tdivide</code> comes from. For instance, Gabriella Gonzalez’s example would be spelled as follows in this style:</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">nonNegativeOctantT ::</span> <span class="dt">Predicate</span> <span class="dt">Point</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>nonNegativeOctantT <span class="ot">=</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    x <span class="op">&gt;$&lt;</span> nonNegative <span class="op">&gt;+&lt;</span> y <span class="op">&gt;$&lt;</span> nonNegative <span class="op">&gt;+&lt;</span> z <span class="op">&gt;$&lt;</span> nonNegative</span></code></pre></div>
<h2 id="alternative">Alternative</h2>
<p>The <code>(&gt;+&lt;)</code> combinator defined above is strikingly similar to <code>(&lt;|&gt;)</code> from <code>Alternative</code>, down to its implied monoidal nature: <a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></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">(&gt;+&lt;) ::</span> <span class="dt">Divisible</span> k <span class="ot">=&gt;</span> k a <span class="ot">-&gt;</span> k a <span class="ot">-&gt;</span> k 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">(&lt;|&gt;) ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> f a <span class="ot">-&gt;</span> f a</span></code></pre></div>
<p>It is surprising that <code>(&gt;+&lt;)</code> springs forth in <code>Divisible</code> rather than <code>Decidable</code>, which might look like the more obvious candidate to be <code>Alternative</code>’s contravariant counterpart. To understand what is going on, it helps to look at <code>Alternative</code> from the same perspective we have used here for <code>Applicative</code> and <code>Divisible</code>. For that, first of all we need an analogue to <code>divided</code>. Let’s borrow the definition from <em>Applicatives convert products to sums</em>:</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">combined ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f (<span class="dt">Either</span> a b)</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>combined u v <span class="ot">=</span> <span class="dt">Left</span> <span class="op">&lt;$&gt;</span> u <span class="op">&lt;|&gt;</span> <span class="dt">Right</span> <span class="op">&lt;$&gt;</span> v</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">(-|-) ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</span> f b <span class="ot">-&gt;</span> f (<span class="dt">Either</span> a b)</span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a>(<span class="op">-|-</span>) <span class="ot">=</span> combined</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">-|-</span></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="co">-- We also need a suitable identity:</span></span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true" tabindex="-1"></a><span class="ot">zero ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> f <span class="dt">Void</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true" tabindex="-1"></a>zero <span class="ot">=</span> empty</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="co">-- Laws:</span></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><span class="co">-- zero -|- v ~ v</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- u -|- zero ~ u</span></span>
<span id="cb16-16"><a href="#cb16-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- (u -|- v) -|- w ~ u -|- (v -|- w)</span></span></code></pre></div>
<p>(I won’t entertain the various controversies about the <code>Alternative</code> laws here, nor any interaction laws involving <code>Applicative</code>. Those might be interesting matters to think about from this vantage point, though.)</p>
<p>A <code>divide</code> analogue follows:</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">combine ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> (<span class="dt">Either</span> a 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-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>combine f u v <span class="ot">=</span> <span class="fu">fmap</span> f (combined u v)</span></code></pre></div>
<p>Crucially, <code>Either a b -&gt; c</code> can be split in a way dual to what we have seen earlier with <code>a -&gt; (b, c)</code>: an <code>Either</code>-consuming function amounts to a pair of functions, one to deal with each component. That being so, we can use the alternative style trick done for <code>Divisible</code> by dualising things:</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">tcombine ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> c) <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="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>tcombine f g <span class="ot">=</span> combine (f <span class="op">|||</span> g)</span></code></pre></div>
<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>tcombine f g u v</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a>combine (f <span class="op">|||</span> g) u v</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> (f <span class="op">|||</span> g) (combined u v)</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> (forget <span class="op">.</span> (f <span class="op">+++</span> g)) (combined u v)</span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> forget (combined (<span class="fu">fmap</span> f u) (<span class="fu">fmap</span> g v))</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a>combine forget (<span class="fu">fmap</span> f u) (<span class="fu">fmap</span> g v)</span></code></pre></div>
<p>To keep things symmetrical, let’s define:</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">aplus ::</span> <span class="dt">Alternative</span> f <span class="ot">=&gt;</span> f a <span class="ot">-&gt;</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>aplus <span class="ot">=</span> combine forget</span>
<span id="cb20-3"><a href="#cb20-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- (&lt;|&gt;) = aplus</span></span></code></pre></div>
<p>So that we end up with:</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>tcombine f g u v <span class="ot">=</span> aplus (<span class="fu">fmap</span> f u) (<span class="fu">fmap</span> g v)</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>tcombine f g u v <span class="ot">=</span> f <span class="op">&lt;$&gt;</span> u <span class="op">&lt;|&gt;</span> g <span class="op">&lt;$&gt;</span> v</span></code></pre></div>
<p>For instance, here is the <code>Alternative</code> composition example from the <em>Decidable</em> post…</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">alternativeCompose ::</span> [<span class="dt">String</span>]</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>alternativeCompose <span class="ot">=</span> <span class="fu">show</span> <span class="op">&lt;$&gt;</span> [<span class="dv">1</span>,<span class="dv">2</span>] <span class="op">&lt;|&gt;</span> <span class="fu">reverse</span> <span class="op">&lt;$&gt;</span> [<span class="st">&quot;hello&quot;</span>, <span class="st">&quot;world&quot;</span>]</span></code></pre></div>
<p>… and how it might be rendered using <code>combine</code>/<code>(-|-)</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">alternativeComposeG ::</span> [<span class="dt">String</span>]</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>alternativeComposeG <span class="ot">=</span> merge <span class="op">&lt;$&gt;</span> [<span class="dv">1</span>,<span class="dv">2</span>] <span class="op">-|-</span> [<span class="st">&quot;hello&quot;</span>, <span class="st">&quot;world&quot;</span>]</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>    merge <span class="ot">=</span> <span class="fu">show</span> <span class="op">|||</span> <span class="fu">reverse</span></span></code></pre></div>
<p>There is, therefore, something of a subterranean connection between <code>Alternative</code> and <code>Divisible</code>. The function arguments to both <code>combine</code> and <code>divide</code>, whose types are dual to each other, can be split in a way that not only reveals an underlying monoidal operation, <code>(&lt;|&gt;)</code> and <code>(&gt;+&lt;)</code> respectively, but also allows for a certain flexibility in using the class combinators.</p>
<h2 id="decidable">Decidable</h2>
<p>Last, but not least, there is <code>Decidable</code> to deal with. <code>Data.Functor.Contravariant.Divisible</code> already provides <code>chosen</code> as the <code>divided</code> analogue, so let’s just supply the and operator variant: <a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a></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">(|-|) ::</span> <span class="dt">Decidable</span> k <span class="ot">=&gt;</span> k a <span class="ot">-&gt;</span> k b <span class="ot">-&gt;</span> k (<span class="dt">Either</span> a b)</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>(<span class="op">|-|</span>) <span class="ot">=</span> chosen</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="kw">infixr</span> <span class="dv">5</span> <span class="op">|-|</span></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="co">-- Laws:</span></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="co">-- lost |-| v ~ v</span></span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- u |-| lost ~ u</span></span>
<span id="cb24-9"><a href="#cb24-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- (u |-| v) |-| w ~ u |-| (v |-| w)</span></span></code></pre></div>
<p><code>choose</code> can be recovered from <code>chosen</code> in the usual way:</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">choose ::</span> <span class="dt">Decidable</span> k <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Either</span> b c) <span class="ot">-&gt;</span> k b <span class="ot">-&gt;</span> k c <span class="ot">-&gt;</span> k a</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>choose f u v <span class="ot">=</span> contamap f (chosen u v)</span></code></pre></div>
<p>The <code>a -&gt; Either b c</code> argument of <code>choose</code>, however, is not amenable to the function splitting trick we have used for <code>divide</code> and <code>combine</code>. <code>Either</code>-producing functions cannot be decomposed in that manner, as the case analysis to decide whether to return <code>Left</code> or <code>Right</code> cannot be disentangled. This is ultimately what Tom’s complaint about the “mysterious incomposability” of <code>Decidable</code> is about. Below is a paraphrased version of the <code>Decidable</code> example from the <em>Decidable</em> post:</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">Foo</span> <span class="ot">=</span> <span class="dt">Bar</span> <span class="dt">String</span> <span class="op">|</span> <span class="dt">Baz</span> <span class="dt">Bool</span> <span class="op">|</span> <span class="dt">Quux</span> <span class="dt">Int</span></span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> <span class="dt">Show</span></span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a><span class="ot">pString ::</span> <span class="dt">Predicate</span> <span class="dt">String</span></span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>pString <span class="ot">=</span> <span class="dt">Predicate</span> (<span class="fu">const</span> <span class="dt">False</span>)</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">pBool ::</span> <span class="dt">Predicate</span> <span class="dt">Bool</span></span>
<span id="cb26-8"><a href="#cb26-8" aria-hidden="true" tabindex="-1"></a>pBool <span class="ot">=</span> <span class="dt">Predicate</span> <span class="fu">id</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><span class="ot">pInt ::</span> <span class="dt">Predicate</span> <span class="dt">Int</span></span>
<span id="cb26-11"><a href="#cb26-11" aria-hidden="true" tabindex="-1"></a>pInt <span class="ot">=</span> <span class="dt">Predicate</span> (<span class="op">&gt;=</span> <span class="dv">0</span>)</span>
<span id="cb26-12"><a href="#cb26-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-13"><a href="#cb26-13" aria-hidden="true" tabindex="-1"></a><span class="ot">decidableCompose ::</span> <span class="dt">Predicate</span> <span class="dt">Foo</span></span>
<span id="cb26-14"><a href="#cb26-14" aria-hidden="true" tabindex="-1"></a>decidableCompose <span class="ot">=</span> analyse <span class="op">&gt;$&lt;</span> pString <span class="op">|-|</span> pBool <span class="op">|-|</span> pInt</span>
<span id="cb26-15"><a href="#cb26-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb26-16"><a href="#cb26-16" aria-hidden="true" tabindex="-1"></a>    analyse <span class="ot">=</span> \<span class="kw">case</span></span>
<span id="cb26-17"><a href="#cb26-17" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Bar</span> s <span class="ot">-&gt;</span> <span class="dt">Left</span> s</span>
<span id="cb26-18"><a href="#cb26-18" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Baz</span> b <span class="ot">-&gt;</span> <span class="dt">Right</span> (<span class="dt">Left</span> b)</span>
<span id="cb26-19"><a href="#cb26-19" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Quux</span> n <span class="ot">-&gt;</span> <span class="dt">Right</span> (<span class="dt">Right</span> n)</span></code></pre></div>
<p>The problem identified in the post is that there is no straightfoward way around having to write “the explicit unpacking into an <code>Either</code>” performed by <code>analyse</code>. In the <code>Divisible</code> and <code>Alternative</code> examples, it was possible to avoid tuple or <code>Either</code> shuffling by decomposing the counterparts to <code>analyse</code>, but that is not possible here. <a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a></p>
<p>In the last few paragraphs, we have mentioned <code>Divisible</code>, <code>Alternative</code> and <code>Decidable</code>. What about <code>Applicative</code>, though? The <code>Applicative</code> example from the <em>Decidable</em> post is written in the usual applicative style:</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">applicativeCompose ::</span> [[<span class="dt">String</span>]]</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>applicativeCompose <span class="ot">=</span></span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>    f <span class="op">&lt;$&gt;</span> [<span class="dv">1</span>, <span class="dv">2</span>] <span class="op">&lt;*&gt;</span> [<span class="dt">True</span>, <span class="dt">False</span>] <span class="op">&lt;*&gt;</span> [<span class="st">&quot;hello&quot;</span>, <span class="st">&quot;world&quot;</span>]</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>    f <span class="ot">=</span> (\a b c <span class="ot">-&gt;</span> <span class="fu">replicate</span> a (<span class="kw">if</span> b <span class="kw">then</span> c <span class="kw">else</span> <span class="st">&quot;False&quot;</span>))</span></code></pre></div>
<p>As noted earlier, though, applicative style is a fortunate consequence of <strong>Hask</strong> being Cartesian closed, which makes it possible to turn <code>(a, b) -&gt; c</code> into <code>a -&gt; b -&gt; c</code>. If we leave out <code>(&lt;*&gt;)</code> and restrict ourselves to <code>(&amp;*&amp;)</code>, we end up having to deal explicitly with tuples, which is a dual version of the <code>Decidable</code> issue:</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">monoidalCompose ::</span> [[<span class="dt">String</span>]]</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>monoidalCompose <span class="ot">=</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a>    consume <span class="op">&lt;$&gt;</span> [<span class="dv">1</span>, <span class="dv">2</span>] <span class="op">&amp;*&amp;</span> [<span class="dt">True</span>, <span class="dt">False</span>] <span class="op">&amp;*&amp;</span> [<span class="st">&quot;hello&quot;</span>, <span class="st">&quot;world&quot;</span>]</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>    consume (a, (b, c)) <span class="ot">=</span> <span class="fu">replicate</span> a (<span class="kw">if</span> b <span class="kw">then</span> c <span class="kw">else</span> <span class="st">&quot;False&quot;</span>)</span></code></pre></div>
<p>Just like <code>a -&gt; Either b c</code> functions, <code>(a, b) -&gt; c</code> functions cannot be decomposed: the <code>c</code> value can be produced by using the <code>a</code> and <code>b</code> components in arbitrary ways, and there is no easy way to disentangle that.</p>
<p><code>Decidable</code>, then, relates to <code>Applicative</code> in an analogous way to how <code>Divisible</code> does to <code>Alternative</code>. There are a few other similarities between them that are worth pointing out:</p>
<ul>
<li><p>Neither <code>Applicative</code> nor <code>Decidable</code> offer a monoidal <code>f a -&gt; f a -&gt;   f a</code> operation like the ones of <code>Alternative</code> and <code>Decidable</code>. A related observation is that, for example, <code>Op</code>’s <code>Decidable</code> instance inherits a <code>Monoid</code> constraint from <code>Divisible</code> but doesn’t actually use it in the method implementations.</p></li>
<li><p><code>choose Left</code> and <code>choose Right</code> can be used to combine consumers so that one of them doesn’t actually receive input. That is analogous to how <code>(&lt;*) = lizip fst</code> and <code>(*&gt;) = lizip snd</code> combine applicative values while discarding the output from one of them.</p></li>
<li><p>Dually to how <code>zipped</code>/<code>&amp;*&amp;</code> for the function functor is <code>(&amp;&amp;&amp;)</code>, <code>chosen</code> for decidables such as <code>Op</code> and <code>Predicate</code> amounts to <code>(|||)</code>. My choice of <code>|-|</code> as the corresponding operator hints at that.</p></li>
</ul>
<h2 id="in-summary">In summary</h2>
<p>To wrap things up, here is a visual summary of the parallels between the four classes:</p>
<figure>
<img src="../images/posts/divisible-and-the-monoidal-quartet/monoidal-quartet-diagram.png" alt="Diagram of the four monoidal functor classes under consideration, with Applicative and Decidable in one diagonal, and Alternative and Divisible in the other." /><figcaption aria-hidden="true"><em>Diagram of the four monoidal functor classes under consideration, with <code>Applicative</code> and <code>Decidable</code> in one diagonal, and <code>Alternative</code> and <code>Divisible</code> in the other.</em></figcaption>
</figure>
<p>To my eyes, the main takeaway of our figure of eight trip around this diagram has to do with its diagonals. Thanks to a peculiar kind of duality, classes in opposite corners of it are similar to each other in quite a few ways. In particular, the orange diagonal classes, <code>Alternative</code> and <code>Divisible</code>, have monoidal operations of <code>f a -&gt; f a -&gt; f a</code> signature that emerge from their monoidal functor structure.</p>
<p>That <code>Divisible</code>, from this perspective, appears to have more to do with <code>Alternative</code> than with <code>Applicative</code> leaves us a question to ponder: what does that mean for the relationship between <code>Divisible</code> and <code>Decidable</code>? The current class hierarchy, with <code>Decidable</code> being a subclass of <code>Divisible</code>, mirrors the <code>Alternative</code>-<code>Applicative</code> relationship on the other side of the covariant-contravariant divide. That, however, is not the only reasonable arrangement, and possibly not even the most natural one. <a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a></p>
<h2 id="appendixes">Appendixes</h2>
<h3 id="dplus-is-a-monoidal-operation">dplus is a monoidal operation</h3>
<p>If we are to show that <code>(&gt;+&lt;)</code> is a monoidal operation, first of all we need an identity for it. <code>conquer :: f a</code> sounds like a reasonable candidate. It can be expressed in terms of <code>conquered</code>, the unit for <code>divided</code>, 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="co">-- conquer discards input.</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a>conquer <span class="ot">=</span> <span class="fu">const</span> () <span class="op">&gt;$&lt;</span> conquered</span></code></pre></div>
<p>The identity laws do come out all right:</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>conquer <span class="op">&gt;+&lt;</span> v <span class="ot">=</span> v  <span class="co">-- Goal</span></span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>conquer <span class="op">&gt;+&lt;</span> v  <span class="co">-- LHS</span></span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (conquer <span class="op">&gt;*&lt;</span> v)</span>
<span id="cb30-4"><a href="#cb30-4" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> ((<span class="fu">const</span> () <span class="op">&gt;$&lt;</span> conquered) <span class="op">&gt;*&lt;</span> v)</span>
<span id="cb30-5"><a href="#cb30-5" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (first (<span class="fu">const</span> ()) <span class="op">&gt;$&lt;</span> (conquered <span class="op">&gt;*&lt;</span> v))</span>
<span id="cb30-6"><a href="#cb30-6" aria-hidden="true" tabindex="-1"></a>first (<span class="fu">const</span> ()) <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> (conquered <span class="op">&gt;*&lt;</span> v)</span>
<span id="cb30-7"><a href="#cb30-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- conquered &gt;*&lt; v ~ v</span></span>
<span id="cb30-8"><a href="#cb30-8" aria-hidden="true" tabindex="-1"></a>first (<span class="fu">const</span> ()) <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> (<span class="fu">snd</span> <span class="op">&gt;$&lt;</span> v)</span>
<span id="cb30-9"><a href="#cb30-9" aria-hidden="true" tabindex="-1"></a><span class="fu">snd</span> <span class="op">.</span> first (<span class="fu">const</span> ()) <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> v</span>
<span id="cb30-10"><a href="#cb30-10" aria-hidden="true" tabindex="-1"></a>v  <span class="co">-- LHS = RHS</span></span>
<span id="cb30-11"><a href="#cb30-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb30-12"><a href="#cb30-12" aria-hidden="true" tabindex="-1"></a>u <span class="op">&gt;+&lt;</span> conquer <span class="ot">=</span> u  <span class="co">-- Goal</span></span>
<span id="cb30-13"><a href="#cb30-13" aria-hidden="true" tabindex="-1"></a>u <span class="op">&gt;+&lt;</span> conquer  <span class="co">-- LHS</span></span>
<span id="cb30-14"><a href="#cb30-14" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> discard)</span>
<span id="cb30-15"><a href="#cb30-15" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> (<span class="fu">const</span> () <span class="op">&gt;$&lt;</span> conquered))</span>
<span id="cb30-16"><a href="#cb30-16" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (second (<span class="fu">const</span> ()) <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> conquered))</span>
<span id="cb30-17"><a href="#cb30-17" aria-hidden="true" tabindex="-1"></a>second (<span class="fu">const</span> ()) <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> conquered)</span>
<span id="cb30-18"><a href="#cb30-18" aria-hidden="true" tabindex="-1"></a><span class="co">-- u &gt;*&lt; conquered ~ u</span></span>
<span id="cb30-19"><a href="#cb30-19" aria-hidden="true" tabindex="-1"></a>second (<span class="fu">const</span> ()) <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> (<span class="fu">fst</span> <span class="op">&gt;$&lt;</span> u)</span>
<span id="cb30-20"><a href="#cb30-20" aria-hidden="true" tabindex="-1"></a><span class="fu">fst</span> <span class="op">.</span> second (<span class="fu">const</span> ()) <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> u</span>
<span id="cb30-21"><a href="#cb30-21" aria-hidden="true" tabindex="-1"></a>u  <span class="co">-- LHS = RHS</span></span></code></pre></div>
<p>And so does the associativity one:</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>(u <span class="op">&gt;+&lt;</span> v) <span class="op">&gt;+&lt;</span> w <span class="ot">=</span> u <span class="op">&gt;+&lt;</span> (v <span class="op">&gt;+&lt;</span> w)  <span class="co">-- Goal</span></span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>(u <span class="op">&gt;+&lt;</span> v) <span class="op">&gt;+&lt;</span> w  <span class="co">-- LHS</span></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> ((dup <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> v)) <span class="op">&gt;*&lt;</span> w)</span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (first dup <span class="op">&gt;$&lt;</span> ((u <span class="op">&gt;*&lt;</span> v) <span class="op">&gt;*&lt;</span> w))</span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>first dup <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> ((u <span class="op">&gt;*&lt;</span> v) <span class="op">&gt;*&lt;</span> w)</span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>u <span class="op">&gt;+&lt;</span> (v <span class="op">&gt;+&lt;</span> w)  <span class="co">-- RHS</span></span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> (dup <span class="op">&gt;$&lt;</span> (v <span class="op">&gt;*&lt;</span> w)))</span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>dup <span class="op">&gt;$&lt;</span> (second dup <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> (v <span class="op">&gt;*&lt;</span> w)))</span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>second dup <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> (v <span class="op">&gt;*&lt;</span> w))</span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- (u &gt;*&lt; v) &gt;*&lt; w ~ u &gt;*&lt; (v &gt;*&lt; w)</span></span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a><span class="co">-- assoc ((x, y), z) = (x, (y, z))</span></span>
<span id="cb31-12"><a href="#cb31-12" aria-hidden="true" tabindex="-1"></a>second dup <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> (assoc <span class="op">&gt;$&lt;</span> ((u <span class="op">&gt;*&lt;</span> v) <span class="op">&gt;*&lt;</span> w))</span>
<span id="cb31-13"><a href="#cb31-13" aria-hidden="true" tabindex="-1"></a>assoc <span class="op">.</span> second dup <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> ((u <span class="op">&gt;*&lt;</span> v) <span class="op">&gt;*&lt;</span> w)</span>
<span id="cb31-14"><a href="#cb31-14" aria-hidden="true" tabindex="-1"></a>first dup <span class="op">.</span> dup <span class="op">&gt;$&lt;</span> ((u <span class="op">&gt;*&lt;</span> v) <span class="op">&gt;*&lt;</span> w)  <span class="co">-- LHS = RHS</span></span></code></pre></div>
<h3 id="handling-nested-either">Handling nested Either</h3>
<p><em>The examples in this appendix are available as <a href="../demos/Quartet/Appendix.hs">a separate <code>.hs</code> file</a>.</em></p>
<p>There is a certain awkwardness in dealing with nested <code>Either</code> as anonymous sums that is hard to get rid of completely. Prisms are a tool worth looking into in this context, as they are largely about expressing pattern matching in a composable way. Let’s bring <em>lens</em> into Tom’s <code>Decidable</code> example, then:</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">Foo</span> <span class="ot">=</span> <span class="dt">Bar</span> <span class="dt">String</span> <span class="op">|</span> <span class="dt">Baz</span> <span class="dt">Bool</span> <span class="op">|</span> <span class="dt">Quux</span> <span class="dt">Int</span></span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Show</span>)</span>
<span id="cb32-3"><a href="#cb32-3" aria-hidden="true" tabindex="-1"></a>makePrisms '<span class="dt">'Foo</span></span></code></pre></div>
<p>A cute trick with prisms is using <a href="https://hackage.haskell.org/package/lens-5.0.1/docs/Control-Lens-Prism.html#v:outside"><code>outside</code></a> to fill in the missing cases of a partial function (in this case, <code>(^?! _Quux)</code>:</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">anonSum ::</span> <span class="dt">APrism'</span> s a <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Either</span> a b</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>anonSum p cases <span class="ot">=</span> set (outside p) <span class="dt">Left</span> (<span class="dt">Right</span> <span class="op">.</span> cases)</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">decidableOutside ::</span> <span class="dt">Predicate</span> <span class="dt">Foo</span></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a>decidableOutside <span class="ot">=</span> analyse <span class="op">&gt;$&lt;</span> pString <span class="op">|-|</span> pBool <span class="op">|-|</span> pInt</span>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span>
<span id="cb33-7"><a href="#cb33-7" aria-hidden="true" tabindex="-1"></a>    analyse <span class="ot">=</span> _Bar <span class="ot">`anonSum`</span> (_Baz <span class="ot">`anonSum`</span> (<span class="op">^?!</span> _Quux))</span></code></pre></div>
<p>An alternative is using <a href="https://hackage.haskell.org/package/lens-5.0.1/docs/Control-Lens-Prism.html#v:matching"><code>matching</code></a> to write it in a more self-explanatory way:</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="ot">matchingL ::</span> <span class="dt">APrism'</span> s a <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Either</span> a s</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>matchingL p <span class="ot">=</span> view swapped <span class="op">.</span> matching p</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a><span class="ot">decidableMatching ::</span> <span class="dt">Predicate</span> <span class="dt">Foo</span></span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a>decidableMatching <span class="ot">=</span></span>
<span id="cb34-6"><a href="#cb34-6" aria-hidden="true" tabindex="-1"></a>    choose (matchingL _Bar) pString <span class="op">$</span></span>
<span id="cb34-7"><a href="#cb34-7" aria-hidden="true" tabindex="-1"></a>    choose (matchingL _Baz) pBool <span class="op">$</span></span>
<span id="cb34-8"><a href="#cb34-8" aria-hidden="true" tabindex="-1"></a>    choose (matchingL _Quux) pInt <span class="op">$</span></span>
<span id="cb34-9"><a href="#cb34-9" aria-hidden="true" tabindex="-1"></a>    <span class="fu">error</span> <span class="st">&quot;Missing case in decidableMatching&quot;</span></span></code></pre></div>
<p>These implementations have a few inconveniences of their own, the main one perhaps being that there is noting to stop us from forgetting one of the prisms. The combinators from <a href="https://hackage.haskell.org/package/total-1.0.6">the <em>total</em> package</a> improve on that by incorporating exhaustiveness checking for prisms, at the cost of requiring the sum type to be defined in a particular way.</p>
<p>There presumably also is the option of brining in heavy machinery, and setting up an anonymous sum wrangler with Template Haskell or generics. In fact, it appears <a href="https://hackage.haskell.org/package/shapely-data">the <em>shapely-data</em> package</a> used to offer precisely that. It might be worth it to take a moment to make it build with recent GHCs.</p>
<p>All in all, these approaches feel like attempts to approximate extra language support for juggling sum types. As it happens, though, there is a corner of the language which does provide extra support: <a href="https://downloads.haskell.org/ghc/9.2.1/docs/html/users_guide/exts/arrows.html#conditional-commands">arrow notation</a>. Converting the example to arrows provides a glimpse of what might be:</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="co">-- I'm going to play nice, rather than making b phantom and writing a</span></span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- blatantly unlawful Arrow instance just for the sake of the notation.</span></span>
<span id="cb35-3"><a href="#cb35-3" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Pipecate</span> a b <span class="ot">=</span> <span class="dt">Pipecate</span> {<span class="ot"> getPipecate ::</span> a <span class="ot">-&gt;</span> (<span class="dt">Bool</span>, b) }</span>
<span id="cb35-4"><a href="#cb35-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-5"><a href="#cb35-5" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Category</span> <span class="dt">Pipecate</span> <span class="kw">where</span></span>
<span id="cb35-6"><a href="#cb35-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">id</span> <span class="ot">=</span> <span class="dt">Pipecate</span> (<span class="dt">True</span>,)</span>
<span id="cb35-7"><a href="#cb35-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Pipecate</span> q <span class="op">.</span> <span class="dt">Pipecate</span> p <span class="ot">=</span> <span class="dt">Pipecate</span> <span class="op">$</span> \x <span class="ot">-&gt;</span></span>
<span id="cb35-8"><a href="#cb35-8" aria-hidden="true" tabindex="-1"></a>        <span class="kw">let</span> (bx, y) <span class="ot">=</span> p x</span>
<span id="cb35-9"><a href="#cb35-9" aria-hidden="true" tabindex="-1"></a>            (by, z) <span class="ot">=</span> q y</span>
<span id="cb35-10"><a href="#cb35-10" aria-hidden="true" tabindex="-1"></a>        <span class="kw">in</span> (bx <span class="op">&amp;&amp;</span> by, z)</span>
<span id="cb35-11"><a href="#cb35-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-12"><a href="#cb35-12" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Arrow</span> <span class="dt">Pipecate</span> <span class="kw">where</span></span>
<span id="cb35-13"><a href="#cb35-13" aria-hidden="true" tabindex="-1"></a>    arr f <span class="ot">=</span> <span class="dt">Pipecate</span> (<span class="fu">const</span> <span class="dt">True</span> <span class="op">&amp;&amp;&amp;</span> f)</span>
<span id="cb35-14"><a href="#cb35-14" aria-hidden="true" tabindex="-1"></a>    first (<span class="dt">Pipecate</span> p) <span class="ot">=</span> <span class="dt">Pipecate</span> <span class="op">$</span> \(x, o) <span class="ot">-&gt;</span></span>
<span id="cb35-15"><a href="#cb35-15" aria-hidden="true" tabindex="-1"></a>         <span class="kw">let</span> (bx, y) <span class="ot">=</span> p x</span>
<span id="cb35-16"><a href="#cb35-16" aria-hidden="true" tabindex="-1"></a>         <span class="kw">in</span> (bx, (y, o))</span>
<span id="cb35-17"><a href="#cb35-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-18"><a href="#cb35-18" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">ArrowChoice</span> <span class="dt">Pipecate</span> <span class="kw">where</span></span>
<span id="cb35-19"><a href="#cb35-19" aria-hidden="true" tabindex="-1"></a>    left (<span class="dt">Pipecate</span> p) <span class="ot">=</span> <span class="dt">Pipecate</span> <span class="op">$</span> \<span class="kw">case</span></span>
<span id="cb35-20"><a href="#cb35-20" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Left</span> x <span class="ot">-&gt;</span></span>
<span id="cb35-21"><a href="#cb35-21" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> (bx, y) <span class="ot">=</span> p x</span>
<span id="cb35-22"><a href="#cb35-22" aria-hidden="true" tabindex="-1"></a>            <span class="kw">in</span> (bx, <span class="dt">Left</span> y)</span>
<span id="cb35-23"><a href="#cb35-23" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Right</span> o <span class="ot">-&gt;</span> (<span class="dt">True</span>, <span class="dt">Right</span> o)</span>
<span id="cb35-24"><a href="#cb35-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-25"><a href="#cb35-25" aria-hidden="true" tabindex="-1"></a><span class="ot">fromPred ::</span> <span class="dt">Predicate</span> a <span class="ot">-&gt;</span> <span class="dt">Pipecate</span> a ()</span>
<span id="cb35-26"><a href="#cb35-26" aria-hidden="true" tabindex="-1"></a>fromPred (<span class="dt">Predicate</span> p) <span class="ot">=</span> <span class="dt">Pipecate</span> (p <span class="op">&amp;&amp;&amp;</span> <span class="fu">const</span> ())</span>
<span id="cb35-27"><a href="#cb35-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-28"><a href="#cb35-28" aria-hidden="true" tabindex="-1"></a><span class="ot">toPred ::</span> <span class="dt">Pipecate</span> a x <span class="ot">-&gt;</span> <span class="dt">Predicate</span> a</span>
<span id="cb35-29"><a href="#cb35-29" aria-hidden="true" tabindex="-1"></a>toPred (<span class="dt">Pipecate</span> p) <span class="ot">=</span> <span class="dt">Predicate</span> (<span class="fu">fst</span> <span class="op">.</span> p)</span>
<span id="cb35-30"><a href="#cb35-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb35-31"><a href="#cb35-31" aria-hidden="true" tabindex="-1"></a><span class="ot">decidableArrowised ::</span> <span class="dt">Predicate</span> <span class="dt">Foo</span></span>
<span id="cb35-32"><a href="#cb35-32" aria-hidden="true" tabindex="-1"></a>decidableArrowised <span class="ot">=</span> toPred <span class="op">$</span> proc foo <span class="ot">-&gt;</span> <span class="kw">case</span> foo <span class="kw">of</span></span>
<span id="cb35-33"><a href="#cb35-33" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Bar</span> s <span class="ot">-&gt;</span> fromPred pString <span class="op">-&lt;</span> s</span>
<span id="cb35-34"><a href="#cb35-34" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Baz</span> b <span class="ot">-&gt;</span> fromPred pBool <span class="op">-&lt;</span> b</span>
<span id="cb35-35"><a href="#cb35-35" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Quux</span> n <span class="ot">-&gt;</span> fromPred pInt <span class="op">-&lt;</span> n</span></code></pre></div>
<p><code>decidableArrowised</code> corresponds quite closely to the various <code>Decidable</code>-powered implementations. Behind the scenes, <code>case</code> commands in arrow notation give rise to nested eithers. Said eithers are dealt with by the arrows, which are combined in an appropriate way with <code>(|||)</code>. <code>(|||)</code>, in turn, can be seen as an arrow counterpart to <code>chosen</code>/<code>(|-|)</code>. Even the <code>-&lt;</code> “feed” syntax, which the example above doesn’t really take advantage of, amounts to slots for contramapping. If someone ever feels like arranging a do-esque noation for <code>Decidable</code> to go with Gabriella’s <code>DivisibleFrom</code>, it seems <code>case</code> commands would be a nice starting point.</p>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>See <a href="https://wiki.haskell.org/Typeclassopedia#Alternative_formulation">the relevant section of the <em>Typeclassopedia</em></a> for a brief explanation of it.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>See, for instance, <a href="https://twitter.com/tomjaguarpaw/status/1451235378363609096">this Twitter conversation</a>, or the <code>Divisible</code> example in the <em>Decidable</em> post. Note that, though I’m using <code>(&gt;$&lt;)</code> here for ease of comparison, the examples in this style arguably look tidier when spelled with <code>contramap</code>.</p>
<p>Speaking of operator usage, it is not straightforward to decide on the right fixities for all those operators, and it is entirely possible that I have overlooked something. I have picked them aiming to have both styles work without parentheses, and to have the pairs associated to the right, that is:</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>adapt <span class="op">&gt;$&lt;</span> u <span class="op">&gt;*&lt;</span> v <span class="op">&gt;*&lt;</span> w</span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> adapt <span class="op">&gt;$&lt;</span> (u <span class="op">&gt;*&lt;</span> (v <span class="op">&gt;*&lt;</span> w))</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>f <span class="op">&gt;$&lt;</span> u <span class="op">&gt;+&lt;</span> g <span class="op">&gt;$&lt;</span> v <span class="op">&gt;+&lt;</span> h <span class="op">&gt;$&lt;</span> v</span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  <span class="ot">=</span> (f <span class="op">&gt;$&lt;</span> u) <span class="op">&gt;+&lt;</span> (g <span class="op">&gt;$&lt;</span> v) <span class="op">&gt;+&lt;</span> (h <span class="op">&gt;$&lt;</span> w)</span></code></pre></div>
<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></li>
<li id="fn3" role="doc-endnote"><p>A proof that <code>(&gt;+&lt;)</code> is indeed monoidal is in <a href="#dplus-is-a-monoidal-operation">an end note</a> to this post.</p>
<p>On a related note, my choice of <code>&gt;+&lt;</code> as the <code>dplus</code> operator is, in part, a pun on <a href="https://hackage.haskell.org/package/base-4.16.0.0/docs/Control-Arrow.html#t:ArrowPlus"><code>(&lt;+&gt;)</code> from <code>ArrowPlus</code></a>. <code>(&gt;+&lt;)</code> for many instances works very much like <code>(&lt;+&gt;)</code>, monoidally combining outputs, even if there probably isn’t a sensible way to actually make the types underlying the various <code>Divisible</code> functors instances of <code>ArrowPlus</code>.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p>Both <a href="https://hackage.haskell.org/package/dhall-1.40.1/docs/Dhall-Marshal-Encode.html#v:-62--124--60-"><em>dhall</em></a> and <a href="https://hackage.haskell.org/package/co-log-core-0.3.0.0/docs/Colog-Core-Action.html#v:-62--124--60-"><em>co-log-core</em></a> define <code>(&gt;|&lt;)</code> as <code>chosen</code>-like operators. To my eyes, though, <code>&gt;|&lt;</code> fits <code>dplus</code> better. As a compromise, I opted to not use <code>&gt;|&lt;</code> for neither of them here.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>I will play with a couple of approaches to nested <code>Either</code> ergonomics at the end of the post, in an appendix.<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6" role="doc-endnote"><p>See also <a href="https://github.com/ekmett/contravariant/issues/64"><em>contravariant</em> issue #64</a>, which suggests no longer making <code>Decidable</code> a subclass of <code>Divisible</code>. Though the argument made by Zemyla is a different one, there are resonances with the observations made here. On a related development, <em>semigroupoids</em> has recently introduced <a href="https://hackage.haskell.org/package/semigroupoids-5.3.6/docs/Data-Functor-Contravariant-Conclude.html">a <code>Conclude</code> class</a>, which amounts to “<code>Decidable</code> without a superclass constraint on <code>Divisible</code>”.<a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>


<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/16">Comment on GitHub</a>

    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
      <a id="discourse-button" class="pure-button" href="https://discourse.haskell.org/t/3666">Discourse topic</a>

    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2021-11-11T23:50:00-03:00</pubDate>
    <guid>https://duplode.github.io/posts/divisible-and-the-monoidal-quartet.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Idempotent Applicatives, Parametricity, and a Puzzle</title>
    <link>https://duplode.github.io/posts/idempotent-applicatives-parametricity-and-a-puzzle.html</link>
    <description><![CDATA[
<p>Some applicative functors are idempotent, in the sense that repeating an effect is the same as having it just once. An example and a counterexample are <code>Maybe</code> and <code>IO</code>, respectively (contrast <code>Just 3 *&gt; Just 3</code> with <code>print 3 *&gt; print 3</code>). More precisely, idempotency means that <code>f &lt;$&gt; u &lt;*&gt; u = (\x -&gt; f x x) &lt;$&gt; u</code>. Given the informal description I began with, though, one might wonder whether the simpler property <code>u *&gt; u = u</code>, which seems to capture the intuition about repeated effects, is equivalent to the usual idempotency property. In this post, I will tell how I went about exploring this conjecture, as well as a few things I learnt about parametricity along the way.</p>
<div>

</div>
<!--more-->
<p>Before I begin, a few remarks about this notion of idempotency. The earliest mention of it that I know of is in <em>Combining Monads</em>, a paper by King and Wadler <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>. There, idempotent monads are presented alongside the most widely known concept of commutative monads (<code>f &lt;$&gt; u &lt;*&gt; v = flip f &lt;$&gt; v &lt;*&gt; u</code>). Both properties generalise straightforwardly to applicative functors, which has the neat side-effect of allowing myself to skirt the ambiguity of the phrase “idempotent monad” (in category theory, that usually means a monad that, in Haskell parlance, has a <code>join</code> that is an isomorphism – a meaning that mostly doesn’t show up in Haskell). Lastly, I knew of the conjecture about idempotency amounting to <code>u *&gt; u = u</code> through a Stack Overflow comment by David Feuer, and so I thank him for inspiring this post.</p>
<h2 id="prolegomena">Prolegomena</h2>
<p>Given we are looking into a general claim about applicatives, our first port of call are the applicative laws. Since the laws written in terms of <code>(&lt;*&gt;)</code> can be rather clunky to wield, I will switch to <a href="http://blog.ezyang.com/2012/08/applicative-functors">the monoidal presentation of <code>Applicative</code></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">-- fzip and unit correspond to (&lt;*&gt;) and pure, respectively.</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ot">fzip ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> (f a, f b) <span class="ot">-&gt;</span> f (a, b)</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>fzip (u, v) <span class="ot">=</span> (,) <span class="op">&lt;$&gt;</span> u <span class="op">&lt;*&gt;</span> v</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="ot">unit ::</span> <span class="dt">Applicative</span> f <span class="ot">=&gt;</span> f ()</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>unit <span class="ot">=</span> <span class="fu">pure</span> ()</span></code></pre></div>
<p>Note I am using an uncurried version of <code>fzip</code>, as I feel it makes what follows slightly easier to explain. I will also introduce a couple teensy little combinators so that the required tuple shuffling becomes easier on the eye:</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">app ::</span> (a <span class="ot">-&gt;</span> b, a) <span class="ot">-&gt;</span> b</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>app (f, x) <span class="ot">=</span> f x</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="ot">dup ::</span> a <span class="ot">-&gt;</span> (a, a)</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>dup x <span class="ot">=</span> (x, x)</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="co">{-</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="co">I will also use the Bifunctor methods for pairs, which amount to:</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="co">bimap f g (x, y) = (f x, g y)</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="co">first f = bimap f id</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="co">second g = bimap id g</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="co">-}</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="co">--</span></span></code></pre></div>
<p>The converse definitions of <code>pure</code> and <code>(&lt;*&gt;)</code> in terms of <code>unit</code> and <code>fzip</code> would be:</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>u <span class="op">&lt;*&gt;</span> v <span class="ot">=</span> app <span class="op">&lt;$&gt;</span> fzip (u, v)</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="fu">pure</span> x <span class="ot">=</span> <span class="fu">const</span> x <span class="op">&lt;$&gt;</span> unit</span></code></pre></div>
<p>Using that vocabulary, the applicative laws become:</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="co">-- &quot;~&quot; here means &quot;the same up to a relevant isomorphism&quot;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>fzip (u, unit) <span class="op">~</span> u <span class="co">-- up to pairing with ()</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>fzip (unit, u) <span class="op">~</span> u <span class="co">-- up to pairing with ()</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>fzip (fzip (u, v), w) <span class="op">~</span> fzip (u, fzip (v, w)) <span class="co">-- up to reassociating pairs</span></span></code></pre></div>
<p>As for the idempotency property, it can be expressed as:</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>fzip (u, u) <span class="ot">=</span> dup <span class="op">&lt;$&gt;</span> u <span class="co">-- fzip . dup = fmap dup</span></span></code></pre></div>
<p><code>(*&gt;)</code> and its sibling <code>(&lt;*)</code> become:</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>u <span class="op">&lt;*</span> v <span class="ot">=</span> <span class="fu">fst</span> <span class="op">&lt;$&gt;</span> fzip (u, v)</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">*&gt;</span> v <span class="ot">=</span> <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (u, v)</span></code></pre></div>
<p>(Proofs of the claims just above can be found at the appendix at the end of this post.)</p>
<p>Finally, the conjecture amounts to:</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">snd</span> <span class="op">&lt;$&gt;</span> fzip (u, u) <span class="ot">=</span> u <span class="co">-- u *&gt; u = u</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Is equivalent to...</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>fzip (u, u) <span class="ot">=</span> dup <span class="op">&lt;$&gt;</span> u <span class="co">-- idempotency</span></span></code></pre></div>
<p>That <code>fzip (u, u) = dup &lt;$&gt; u</code> implies <code>snd &lt;$&gt; fzip (u, u)</code> is immediate, as <code>snd . dup = id</code>. Our goal, then, is getting <code>fzip (u, u) = dup &lt;$&gt; u</code> out of <code>snd &lt;$&gt; fzip (u, u) = u</code>.</p>
<h2 id="drawing-relations">Drawing relations</h2>
<p>How might we get from <code>snd &lt;$&gt; fzip (u, u) = u</code> to <code>fzip (u, u) = dup &lt;$&gt; u</code>? It appears we have to take a fact about the second components of the pairs in <code>fzip (u, u)</code> (note that mapping <code>snd</code> discards the first components) and squeeze something about the first components out of it (namely, that they are equal to the second components everywhere). At first glance, it doesn’t appear the applicative laws connect the components in any obviously exploitable way. The one glimmer of hope lies in how, in the associativity law…</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>fzip (fzip (u, v), w) <span class="op">~</span> fzip (u, fzip (v, w)) <span class="co">-- up to reassociating pairs</span></span></code></pre></div>
<p>… whatever values originally belonging to <code>v</code> must show up as second components of pairs on the left hand side, and as first components on the right hand side. While that, on its own, is too vague to be actionable, there is a seemingly innocuous observation we can make use of: <code>snd &lt;$&gt; fzip (u, u) = u</code> tells us we can turn <code>fzip (u, u)</code> into <code>u</code> using <code>fmap</code> (informally, we can say that they have the same shape), and that they can be <em>related</em> using <code>snd</code> while making use of a free theorem <a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>. For our current purposes, that means we can borrow the types involved in the left side of the associativity law and use them to draw the following diagram…</p>
<pre><code>                  fzip
(F (a, b), F c) --------&gt; F ((a, b), c)
     |      |                  |     |
     |      |                  |     |
  snd|      |id             snd|     |id 
     |      |                  |     |
     v      v                  v     v
(F   b, F   c ) --------&gt; F (  b,    c)
                  fzip</code></pre>
<p>… such that we get the same result by following either path from the top left corner to the bottom right one. Omitting the occurrences of <code>id</code>, we can state that through this equation:</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="fu">fmap</span> (first <span class="fu">snd</span>) <span class="op">.</span> fzip <span class="ot">=</span> fzip <span class="op">.</span> first (<span class="fu">fmap</span> <span class="fu">snd</span>)</span></code></pre></div>
<p>In words, it doesn’t matter whether we use <code>snd</code> after or before using <code>fzip</code>. <code>fmap</code> and <code>first</code>, left implicit in the diagram, are used to lift <code>snd</code> across the applicative layer and the pairs, respectively. This is just one specific instance of the free theorem; instead of <code>snd</code> and <code>id</code>, we could have any functions – or, more generally, any relations <a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>– between the involved types. Free theorems tell us about relations being preserved; in this case, <code>snd</code> sets up a relation on the left side of the diagram, and <code>fzip</code> preserves it.</p>
<p>We can get back to our problem by slipping in suitable concrete values in the equation. For an arbitrary <code>u :: F A</code>, we have…</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>first <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (fzip (u, u), u) <span class="ot">=</span> fzip (<span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (u, u), u)</span></code></pre></div>
<p>… and, thanks to our <code>snd &lt;$&gt; fzip (u, u) = u</code> premise:</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>first <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (fzip (u, u), u) <span class="ot">=</span> fzip (u, u)</span></code></pre></div>
<p>Now, why should we restrict ourselves to the left side of the associativity law? We can get a very similar diagram to work with from the right side:</p>
<pre><code>                  fzip
(F a, F (b, c)) --------&gt; F (a, (b, c))
   |      |                  |    |
   |      |                  |    |
 id|      |snd             id|    |snd
   |      |                  |    |
   v      v                  v    v
(F a, F   c   ) --------&gt; F (a,   c   )
                  fzip</code></pre>
<p>Or, as an equation:</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">fmap</span> (second <span class="fu">snd</span>) <span class="op">.</span> fzip <span class="ot">=</span> fzip <span class="op">.</span> second (<span class="fu">fmap</span> <span class="fu">snd</span>)</span></code></pre></div>
<p>Proceeding just like before, we get:</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>second <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (u, fzip (u, u)) <span class="ot">=</span> fzip (u, <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (u, u))</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>second <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (u, fzip (u, u)) <span class="ot">=</span> fzip (u, u)</span></code></pre></div>
<p>Since <code>fzip (u, fzip (u, u)) ~ fzip (fzip (u, u), u)</code> (associativity), we can shuffle that into:</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="co">-- Both first fst and second snd get rid of the value in the middle.</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>first <span class="fu">fst</span> <span class="op">&lt;$&gt;</span> fzip (fzip (u, u), u) <span class="ot">=</span> fzip (u, u)</span></code></pre></div>
<p>The equations we squeezed out of the diagrams…</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>first <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (fzip (u, u), u) <span class="ot">=</span> fzip (u, u)</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>first <span class="fu">fst</span> <span class="op">&lt;$&gt;</span> fzip (fzip (u, u), u) <span class="ot">=</span> fzip (u, u)</span></code></pre></div>
<p>… can be combined into:</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>fzip (fzip (u, u), u) <span class="ot">=</span> first dup <span class="op">&lt;$&gt;</span> fzip (u, u)</span></code></pre></div>
<p>This kind of looks like idempotency, except for the extra occurrence of <code>u</code> tagging along for the ride. We might have a go at getting rid of it by sketching a diagram of a slightly different nature, which shows how the relations play out across the specific values that appear in the equation above:</p>
<pre><code>                                        fzip 
          (u, u) :: (F   a   , F a) -----------&gt; F (  a   , a)
                         |       |                    |     |
                         |       |                    |     |
                        R|      S|               {dup}| {id}|
                         |       |                    |     |
                         |       |      fzip          |     |
(fzip (u, u), u) :: (F (a, a), F a) -----------&gt; F ((a, a), a)</code></pre>
<p><code>dup</code> can be used to relate <code>fzip (u, u)</code> and <code>fzip (fzip (u, u), u)</code> on the right of the diagram. That this diagram involves specific values leads to a subtle yet crucial difference from the previous ones: the relation on the right side is not necessarily the function <code>dup</code>, but some relation that happens to agree with <code>dup</code> <em>for the specific values we happen to be using here</em> (that is what I have attempted to suggest by adding the curly brackets as ad hoc notation and dropping the arrow tips from the vertical connectors). This is important because, given how <code>fzip</code> preserves relations, we might be tempted to work backwards and identify <code>R</code> on the left side with <code>dup</code>, giving us a proof – <code>dup &lt;$&gt; u = fzip (u, u)</code> would be an immediate consequence. We can’t do that, though, as <code>R</code> only must agree with <code>dup</code> for those values which show up in a relevant way on the right side. More explicitly, consider some element <code>x :: a</code> of <code>u</code>. If <code>x</code> shows up as a first component anywhere in <code>fzip (u, u)</code>, then the corresponding element of <code>fzip (u, u)</code> must have its first and second components equal to each other (because <code>dup</code> agrees with <code>R</code> on <code>x</code>, and <code>R</code> in turn relates <code>u</code> and <code>fzip (u, u)</code>), and to <code>x</code> (since <code>snd &lt;$&gt; fzip (u, u) = u</code>). If that held for all elements of <code>u</code>, we would have <code>fzip (u, u) = dup &lt;$&gt; u</code>. However if <code>x</code> <em>doesn’t</em> show up as a first component in <code>fzip (u, u)</code>, there are no guarantees (as the right side offers no evidence on what <code>x</code> is related to through <code>R</code>), and so we don’t have grounds for the ultimate claim.</p>
<p>Close, but no cigar.</p>
<h2 id="something-twisted">Something twisted</h2>
<p>While those parametricity tricks gave us no proof, we did learn something interesting: the conjecture holds as long as all elements from <code>u</code> show up as first components in <code>fzip (u, u)</code>. That sounds like a decent lead for a counterexample, so let’s switch course and look for one instead. To begin with, here is an inoffensive length-two vector/homogeneous pair 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="ot">{-# LANGUAGE DeriveFunctor #-}</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">Good</span> a <span class="ot">=</span> <span class="dt">Good</span> a a</span>
<span id="cb20-4"><a href="#cb20-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Show</span>, <span class="dt">Ord</span>, <span class="dt">Functor</span>)</span></code></pre></div>
<p>Here is its <code>Applicative</code> instance, specified in terms of the monoidal presentation:</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>unit <span class="ot">=</span> <span class="dt">Good</span> () ()</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb21-3"><a href="#cb21-3" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> <span class="dt">Good</span> (x1, y1) (x2, y2)</span></code></pre></div>
<p><code>Good</code>, like any other applicative with a single shape, is idempotent – as there is just one shape, it can’t help but be preserved <a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a>. That means we need a second constructor:</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">Twisted</span> a <span class="ot">=</span> <span class="dt">Evil</span> a a <span class="op">|</span> <span class="dt">Good</span> a a</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">deriving</span> (<span class="dt">Eq</span>, <span class="dt">Show</span>, <span class="dt">Ord</span>, <span class="dt">Functor</span>)</span></code></pre></div>
<p><code>unit</code> can remain the same…</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>unit <span class="ot">=</span> <span class="dt">Good</span> () ()</span></code></pre></div>
<p>… which means the <code>Good</code>-and-<code>Good</code> case <em>must</em> remain the same: the identity effect has to be idempotent <a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a>:</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>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> <span class="dt">Good</span> (x1, y1) (x2, y2)</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> _</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> _</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> _</span></code></pre></div>
<p>The twist comes in the <code>Evil</code>-and-<code>Evil</code> case: we repeat our pick of a first element of the vector, and thus discard one of the first elements. (We can’t do the same with the second element, as we want <code>snd &lt;$&gt; fzip (u, u) = u</code> to hold.)</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>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> <span class="dt">Good</span> (x1, y1) (x2, y2)</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> <span class="dt">Evil</span> (x1, y1) (x1, y2)</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> _</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> _</span></code></pre></div>
<p>The <code>Evil</code>-and-<code>Good</code> case is determined by the right identity law…</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>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> <span class="dt">Good</span> (x1, y1) (x2, y2)</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> <span class="dt">Evil</span> (x1, y2) (x2, y2)</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> <span class="dt">Evil</span> (x1, y1) (x2, y2)</span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> _</span></code></pre></div>
<p>… while associativity forces our hand in the <code>Good</code>-and-<code>Evil</code> case (consider what would happen in a <code>Good</code>-<code>Evil</code>-<code>Evil</code> chain <a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a>):</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>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> <span class="dt">Good</span> (x1, y1) (x2, y2)</span>
<span id="cb27-2"><a href="#cb27-2" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> <span class="dt">Evil</span> (x1, y1) (x1, y2)</span>
<span id="cb27-3"><a href="#cb27-3" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> y1 y2) <span class="ot">=</span> <span class="dt">Evil</span> (x1, y1) (x2, y2)</span>
<span id="cb27-4"><a href="#cb27-4" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> y1 y2) <span class="ot">=</span> <span class="dt">Evil</span> (x1, y1) (x1, y2)</span></code></pre></div>
<p><code>Evil</code> spreads, leaving a trail of repeated picks of first elements to the left of its rightmost occurrence in an applicative chain.</p>
<p>Getting an actual <code>Applicative</code> instance from those definitions is easy: fill <code>unit</code> with something, and take away the commas from <code>fzip</code>:</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">Applicative</span> <span class="dt">Twisted</span> <span class="kw">where</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">pure</span> x <span class="ot">=</span> <span class="dt">Good</span> x x</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="dt">Good</span> x1 x2 <span class="op">&lt;*&gt;</span> <span class="dt">Good</span> y1 y2 <span class="ot">=</span> <span class="dt">Good</span> (x1 y1) (x2 y2)</span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Evil</span> x1 x2 <span class="op">&lt;*&gt;</span> <span class="dt">Evil</span> y1 y2 <span class="ot">=</span> <span class="dt">Evil</span> (x1 y1) (x1 y2)</span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Evil</span> x1 x2 <span class="op">&lt;*&gt;</span> <span class="dt">Good</span> y1 y2 <span class="ot">=</span> <span class="dt">Evil</span> (x1 y1) (x2 y2)</span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Good</span> x1 x2 <span class="op">&lt;*&gt;</span> <span class="dt">Evil</span> y1 y2 <span class="ot">=</span> <span class="dt">Evil</span> (x1 y1) (x1 y2) </span></code></pre></div>
<p>And there it is:</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="dt">GHCi</span><span class="op">&gt;</span> test <span class="ot">=</span> <span class="dt">Evil</span> <span class="dv">1</span> <span class="dv">2</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> test <span class="op">*&gt;</span> test</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> <span class="dv">1</span> <span class="dv">2</span></span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> dup <span class="op">&lt;$&gt;</span> test</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (<span class="dv">1</span>,<span class="dv">1</span>) (<span class="dv">2</span>,<span class="dv">2</span>)</span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> fzip (test, test)</span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (<span class="dv">1</span>,<span class="dv">1</span>) (<span class="dv">1</span>,<span class="dv">2</span>)</span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> (\x <span class="ot">-&gt;</span> x <span class="op">+</span> x) <span class="op">&lt;$&gt;</span> test</span>
<span id="cb29-9"><a href="#cb29-9" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> <span class="dv">2</span> <span class="dv">4</span></span>
<span id="cb29-10"><a href="#cb29-10" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> (<span class="op">+</span>) <span class="op">&lt;$&gt;</span> test <span class="op">&lt;*&gt;</span> test</span>
<span id="cb29-11"><a href="#cb29-11" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> <span class="dv">2</span> <span class="dv">3</span></span></code></pre></div>
<p>The conjecture is thus refuted. While parametricity isn’t truly necessary to bring out this counterexample, I am far from sure I would have thought of it without having explored it under the light of parametricity. On another note, it is rather interesting that there are biased applicatives like <code>Twisted</code>. I wonder whether less contrived cases can be found out there in the wild.</p>
<h2 id="appendix">Appendix</h2>
<p>Below are some derivations that might distract from the main thrust of the post.</p>
<h3 id="alternative-presentation-of-the-idempotency-property">Alternative presentation of the idempotency property</h3>
<p>One direction of the equivalency between the two formulations of the idempotency property follows from a straightforward substitution…</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>f <span class="op">&lt;$&gt;</span> u <span class="op">&lt;*&gt;</span> u <span class="ot">=</span> (\x <span class="ot">-&gt;</span> f x x) <span class="op">&lt;$&gt;</span> u</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>(,) <span class="op">&lt;$&gt;</span> u <span class="op">&lt;*&gt;</span> u <span class="ot">=</span> (\x <span class="ot">-&gt;</span> (,) x x) <span class="op">&lt;$&gt;</span> u</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>fzip (u, u) <span class="ot">=</span> dup <span class="op">&lt;$&gt;</span> u</span></code></pre></div>
<p>… while the other one calls for a small dose of parametricity:</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>fzip (u, u) <span class="ot">=</span> dup <span class="op">&lt;$&gt;</span> u</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a>first f <span class="op">&lt;$&gt;</span> fzip (u, u) <span class="ot">=</span> first f <span class="op">&lt;$&gt;</span> dup <span class="op">&lt;$&gt;</span> u</span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- g &lt;$&gt; f &lt;$&gt; u = g . f &lt;$&gt; u</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>first f <span class="op">&lt;$&gt;</span> fzip (u, u) <span class="ot">=</span> (\x <span class="ot">-&gt;</span> (f x, x)) <span class="op">&lt;$&gt;</span> u</span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- Parametricity: first f &lt;$&gt; fzip (u, v) = fzip (f &lt;$&gt; u, v)</span></span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>fzip (f <span class="op">&lt;$&gt;</span> u, u) <span class="ot">=</span> (\x <span class="ot">-&gt;</span> (f x, x)) <span class="op">&lt;$&gt;</span> u</span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>app <span class="op">&lt;$&gt;</span> fzip (f <span class="op">&lt;$&gt;</span> u, u) <span class="ot">=</span> app <span class="op">&lt;$&gt;</span> (\x <span class="ot">-&gt;</span> (f x, x)) <span class="op">&lt;$&gt;</span> u</span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>f <span class="op">&lt;$&gt;</span> u <span class="op">&lt;*&gt;</span> u <span class="ot">=</span> (\x <span class="ot">-&gt;</span> f x x) <span class="op">&lt;$&gt;</span> u</span></code></pre></div>
<h3 id="alternative-definitions-of-and">Alternative definitions of <code>(&lt;*)</code> and <code>(*&gt;)</code></h3>
<p>Starting from…</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>u <span class="op">&lt;*</span> v <span class="ot">=</span> <span class="fu">const</span> <span class="op">&lt;$&gt;</span> u <span class="op">&lt;*&gt;</span> v</span>
<span id="cb32-2"><a href="#cb32-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">*&gt;</span> v <span class="ot">=</span> <span class="fu">flip</span> <span class="fu">const</span> <span class="op">&lt;$&gt;</span> u <span class="op">&lt;*&gt;</span> v</span></code></pre></div>
<p>… we can switch to the monoidal presentation:</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>u <span class="op">&lt;*</span> v <span class="ot">=</span> app <span class="op">&lt;$&gt;</span> fzip (<span class="fu">const</span> <span class="op">&lt;$&gt;</span> u, v)</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">*&gt;</span> v <span class="ot">=</span> app <span class="op">&lt;$&gt;</span> fzip (<span class="fu">flip</span> <span class="fu">const</span> <span class="op">&lt;$&gt;</span> u, v)</span></code></pre></div>
<p>It follows from parametricity that…</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="co">-- Parametricity: first f &lt;$&gt; fzip (u, v) = fzip (f &lt;$&gt; u, v)</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">&lt;*</span> v <span class="ot">=</span> app <span class="op">.</span> first <span class="fu">const</span> <span class="op">&lt;$&gt;</span> fzip (u, v)</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a>u <span class="op">*&gt;</span> v <span class="ot">=</span> app <span class="op">.</span> first (<span class="fu">flip</span> <span class="fu">const</span>) <span class="op">&lt;$&gt;</span> fzip (u, v)</span></code></pre></div>
<p>… which amount to…</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>u <span class="op">&lt;*</span> v <span class="ot">=</span> (\(x, y) <span class="ot">-&gt;</span> <span class="fu">const</span> x y) <span class="op">&lt;$&gt;</span> fzip (u, v)</span>
<span id="cb35-2"><a href="#cb35-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">*&gt;</span> v <span class="ot">=</span> (\(x, y) <span class="ot">-&gt;</span> <span class="fu">flip</span> <span class="fu">const</span> x y) <span class="op">&lt;$&gt;</span> fzip (u, v)</span></code></pre></div>
<p>… or simply:</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>u <span class="op">&lt;*</span> v <span class="ot">=</span> <span class="fu">fst</span> <span class="op">&lt;$&gt;</span> fzip (u, v)</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">*&gt;</span> v <span class="ot">=</span> <span class="fu">snd</span> <span class="op">&lt;$&gt;</span> fzip (u, v)</span></code></pre></div>
<h3 id="lawfulness-of-twisted-as-an-applicative-functor">Lawfulness of <code>Twisted</code> as an applicative functor</h3>
<p>Right identity:</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>fzip (u, unit) <span class="op">~</span> u</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Case: u = Good x1 x2 </span></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> () ()) <span class="co">-- LHS</span></span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a><span class="dt">Good</span> (x1, ()) (x2, ()) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- Note that Twisted behaves like an ordinary length-two vector as</span></span>
<span id="cb37-6"><a href="#cb37-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- long as only Good is involved. That being so, it would have been</span></span>
<span id="cb37-7"><a href="#cb37-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- fine to skip the Good-only cases here and elsewhere.</span></span>
<span id="cb37-8"><a href="#cb37-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- Case: u = Evil x1 x2</span></span>
<span id="cb37-9"><a href="#cb37-9" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> () ()) <span class="co">-- LHS</span></span>
<span id="cb37-10"><a href="#cb37-10" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, ()) (x2, ()) <span class="co">-- LHS ~ RHS</span></span></code></pre></div>
<p>Left identity:</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>fzip (unit, u) <span class="op">~</span> u</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Case: u = Good x1 x2 </span></span>
<span id="cb38-3"><a href="#cb38-3" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> () (), <span class="dt">Good</span> y1 y2)</span>
<span id="cb38-4"><a href="#cb38-4" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((), y1) ((), y2) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb38-5"><a href="#cb38-5" aria-hidden="true" tabindex="-1"></a><span class="co">-- Case: u = Evil x1 x2 </span></span>
<span id="cb38-6"><a href="#cb38-6" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> () (), <span class="dt">Evil</span> y1 y2)</span>
<span id="cb38-7"><a href="#cb38-7" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((), y1) ((), y2) <span class="co">-- LHS ~ RHS</span></span></code></pre></div>
<p>Associativity:</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>fzip (fzip (u, v), w) <span class="op">~</span> fzip (u, fzip (v, w))</span>
<span id="cb39-2"><a href="#cb39-2" aria-hidden="true" tabindex="-1"></a><span class="co">-- Good/Good/Good case: holds.</span></span>
<span id="cb39-3"><a href="#cb39-3" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> y1 y2), <span class="dt">Good</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-4"><a href="#cb39-4" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> (x1, y1) (x2, y2), <span class="dt">Good</span> z1, z2)</span>
<span id="cb39-5"><a href="#cb39-5" aria-hidden="true" tabindex="-1"></a><span class="dt">Good</span> ((x1, y1), z1) ((x2, y2), z2)</span>
<span id="cb39-6"><a href="#cb39-6" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, fzip (<span class="dt">Good</span> y1 y2, <span class="dt">Good</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-7"><a href="#cb39-7" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> (y1, z1) (y2, z2))</span>
<span id="cb39-8"><a href="#cb39-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Good</span> (x1, (y1, z1)) (x2, (y2, z2)) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb39-9"><a href="#cb39-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- Evil/Evil/Evil case:</span></span>
<span id="cb39-10"><a href="#cb39-10" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> y1 y2), <span class="dt">Evil</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-11"><a href="#cb39-11" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> (x1, y1) (x1, y2), <span class="dt">Evil</span> z1, z2)</span>
<span id="cb39-12"><a href="#cb39-12" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((x1, y1), z1) ((x1, y1), z2)</span>
<span id="cb39-13"><a href="#cb39-13" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, fzip (<span class="dt">Evil</span> y1 y2, <span class="dt">Evil</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-14"><a href="#cb39-14" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> (y1, z1) (y1, z2))</span>
<span id="cb39-15"><a href="#cb39-15" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, (y1, z1)) (x1, (y1, z2)) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb39-16"><a href="#cb39-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- Good/Evil/Evil case:</span></span>
<span id="cb39-17"><a href="#cb39-17" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> y1 y2), <span class="dt">Evil</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-18"><a href="#cb39-18" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> (x1, y1) (x2, y2), <span class="dt">Evil</span> z1, z2)</span>
<span id="cb39-19"><a href="#cb39-19" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((x1, y1), z1) ((x1, y1), z2)</span>
<span id="cb39-20"><a href="#cb39-20" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, fzip (<span class="dt">Evil</span> y1 y2, <span class="dt">Evil</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-21"><a href="#cb39-21" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> (y1, z1) (y1, z2))</span>
<span id="cb39-22"><a href="#cb39-22" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, (y1, z1)) (x1, (y1, z2)) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb39-23"><a href="#cb39-23" aria-hidden="true" tabindex="-1"></a><span class="co">-- Evil/Good/Evil case:</span></span>
<span id="cb39-24"><a href="#cb39-24" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> y1 y2), <span class="dt">Evil</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-25"><a href="#cb39-25" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> (x1, y1) (x2, y2), <span class="dt">Evil</span> z1, z2)</span>
<span id="cb39-26"><a href="#cb39-26" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((x1, y1), z1) ((x1, y1), z2)</span>
<span id="cb39-27"><a href="#cb39-27" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, fzip (<span class="dt">Good</span> y1 y2, <span class="dt">Evil</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-28"><a href="#cb39-28" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> (y1, z1) (y1, z2))</span>
<span id="cb39-29"><a href="#cb39-29" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, (y1, z1)) (x1, (y1, z2)) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb39-30"><a href="#cb39-30" aria-hidden="true" tabindex="-1"></a><span class="co">-- Evil/Evil/Good case:</span></span>
<span id="cb39-31"><a href="#cb39-31" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> y1 y2), <span class="dt">Good</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-32"><a href="#cb39-32" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> (x1, y1) (x1, y2), <span class="dt">Good</span> z1, z2)</span>
<span id="cb39-33"><a href="#cb39-33" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((x1, y1), z1) ((x1, y2), z2)</span>
<span id="cb39-34"><a href="#cb39-34" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, fzip (<span class="dt">Evil</span> y1 y2, <span class="dt">Good</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-35"><a href="#cb39-35" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Evil</span> (y1, z1) (y2, z2))</span>
<span id="cb39-36"><a href="#cb39-36" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, (y1, z1)) (x1, (y2, z2)) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb39-37"><a href="#cb39-37" aria-hidden="true" tabindex="-1"></a><span class="co">-- Evil/Good/Good case:</span></span>
<span id="cb39-38"><a href="#cb39-38" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> y1 y2), <span class="dt">Good</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-39"><a href="#cb39-39" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> (x1, y1) (x2, y2), <span class="dt">Good</span> z1, z2)</span>
<span id="cb39-40"><a href="#cb39-40" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((x1, y1), z1) ((x2, y2), z2)</span>
<span id="cb39-41"><a href="#cb39-41" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, fzip (<span class="dt">Good</span> y1 y2, <span class="dt">Good</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-42"><a href="#cb39-42" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> x1 x2, <span class="dt">Good</span> (y1, z1) (y2, z2))</span>
<span id="cb39-43"><a href="#cb39-43" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, (y1, z1)) (x2, (y2, z2)) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb39-44"><a href="#cb39-44" aria-hidden="true" tabindex="-1"></a><span class="co">-- Good/Evil/Good case:</span></span>
<span id="cb39-45"><a href="#cb39-45" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> y1 y2), <span class="dt">Good</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-46"><a href="#cb39-46" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Evil</span> (x1, y1) (x1, y2), <span class="dt">Good</span> z1, z2)</span>
<span id="cb39-47"><a href="#cb39-47" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((x1, y1), z1) ((x1, y2), z2)</span>
<span id="cb39-48"><a href="#cb39-48" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, fzip (<span class="dt">Evil</span> y1 y2, <span class="dt">Good</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-49"><a href="#cb39-49" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> (y1, z1) (y2, z2))</span>
<span id="cb39-50"><a href="#cb39-50" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, (y1, z1)) (x1, (y2, z2)) <span class="co">-- LHS ~ RHS</span></span>
<span id="cb39-51"><a href="#cb39-51" aria-hidden="true" tabindex="-1"></a><span class="co">-- Good/Good/Evil case:</span></span>
<span id="cb39-52"><a href="#cb39-52" aria-hidden="true" tabindex="-1"></a>fzip (fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Good</span> y1 y2), <span class="dt">Evil</span> z1, z2) <span class="co">-- LHS</span></span>
<span id="cb39-53"><a href="#cb39-53" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> (x1, y1) (x2, y2), <span class="dt">Evil</span> z1, z2)</span>
<span id="cb39-54"><a href="#cb39-54" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> ((x1, y1), z1) ((x1, y1), z2)</span>
<span id="cb39-55"><a href="#cb39-55" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, fzip (<span class="dt">Good</span> y1 y2, <span class="dt">Evil</span> z1 z2)) <span class="co">-- RHS</span></span>
<span id="cb39-56"><a href="#cb39-56" aria-hidden="true" tabindex="-1"></a>fzip (<span class="dt">Good</span> x1 x2, <span class="dt">Evil</span> (y1, z1) (y1, z2))</span>
<span id="cb39-57"><a href="#cb39-57" aria-hidden="true" tabindex="-1"></a><span class="dt">Evil</span> (x1, (y1, z1)) (x1, (y1, z2)) <span class="co">-- LHS ~ RHS</span></span></code></pre></div>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>One of <a href="http://homepages.inf.ed.ac.uk/wadler/topics/monads.html">Philip Wadler’s papers about monads</a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>For a gentle initial illustration of the underlying theme of parametricity, see <a href="../posts/what-does-fmap-preserve.html"><em>What Does fmap Preserve?</em></a>. For a more thorough introduction, see <a href="https://bartoszmilewski.com/2014/09/22/parametricity-money-for-nothing-and-theorems-for-free"><em>Parametricity: Money for Nothing and Theorems for Free</em></a>, by Bartosz Milewski.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p>A relation is a set of pairs; or, if you will, of associations between values. As an arbitrary example, we can have a less-than relation on integers which includes all pairs of integers <code>(x, y)</code> such that <code>x &lt; y</code>. In particular, functions are relations: seen as a relation, a function <code>f</code> seen in this way includes all pairs <code>(x, f x)</code>, there being exactly one pair for each possible value of the first component.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p>One way to prove that is by using parametricity in tandem with the identity laws, analogously to how we used associativity in the previous section, while exploiting how there being only one shape means any applicative value can be related to <code>unit</code>.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>See the previous note about relating things to <code>unit</code>.<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6" role="doc-endnote"><p>The appendix includes a proof of the lawfulness of <code>Twisted</code>.<a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>


<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/14">Comment on GitHub</a>

    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2019-04-01T02:30:00-03:00</pubDate>
    <guid>https://duplode.github.io/posts/idempotent-applicatives-parametricity-and-a-puzzle.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Traversable: A Remix</title>
    <link>https://duplode.github.io/posts/traversable-a-remix.html</link>
    <description><![CDATA[
<p><code>Traversable</code> is a fun type class. It lies at a crossroad, where many basic Haskell concepts meet, and it can be presented in multiple ways that provide complementary intuitions. In this post, <code>Traversable</code> will be described from a slightly unusual point of view, or at least one that is not put into foreground all that often. We will suspend for a moment the picture of walking across a container while using an effectful function, and instead start by considering what can be done with effectful functions.</p>
<div>

</div>
<!--more-->
<h2 id="weird-fishes">Weird fishes</h2>
<p>Let’s begin with a familiar sight:</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>a <span class="ot">-&gt;</span> <span class="dt">F</span> b</span></code></pre></div>
<p>There are quite a few overlapping ways of talking about functions with such a type. If <code>F</code> is a <code>Functor</code>, we can say the function produces a functorial context; if it is an <code>Applicative</code>, we (also) say it produces an effect; and if it is a <code>Monad</code> we (also) call it a Kleisli arrow. Kleisli arrows are the functions we use with <code>(&gt;&gt;=)</code>. Kleisli arrows for a specific <code>Monad</code> form a category, with <code>return</code> as identity and the fish operator, <code>(&lt;=&lt;)</code>, as composition. If we pick <code>join</code> as the fundamental <code>Monad</code> operation, <code>(&lt;=&lt;)</code> can be defined in terms of it as:</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;=&lt;) ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> m c) <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 c)</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>g <span class="op">&lt;=&lt;</span> f <span class="ot">=</span> join <span class="op">.</span> <span class="fu">fmap</span> g <span class="op">.</span> f</span></code></pre></div>
<p>The category laws, then, become an alternative presentation of the monad 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><span class="fu">return</span> <span class="op">&lt;=&lt;</span> f <span class="ot">=</span> f</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>f <span class="op">&lt;=&lt;</span> <span class="fu">return</span> <span class="ot">=</span> f</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>(h <span class="op">&lt;=&lt;</span> g) <span class="op">&lt;=&lt;</span> f <span class="ot">=</span> h <span class="op">&lt;=&lt;</span> (g <span class="op">&lt;=&lt;</span> f)</span></code></pre></div>
<p>All of that is very well-known. Something less often noted, though, is that there is an interesting category for <code>a -&gt; F b</code> functions even if <code>F</code> is not a <code>Monad</code>. Getting to it is amusingly easy: we just have to take the Kleisli category operators and erase the monad-specific parts from their definitions. In the case of <code>(&lt;=&lt;)</code>, that means removing the <code>join</code> (and, for type bookkeeping purposes, slipping in a <a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Compose.html"><code>Compose</code></a> in its place):</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">(&lt;%&lt;) ::</span> (<span class="dt">Functor</span> f, <span class="dt">Functor</span> g) <span class="ot">=&gt;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    (b <span class="ot">-&gt;</span> g c) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Compose</span> f g c)</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>g <span class="op">&lt;%&lt;</span> f <span class="ot">=</span> <span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> g <span class="op">.</span> f</span></code></pre></div>
<p>While <code>(&lt;=&lt;)</code> creates two monadic layers and merges them, <code>(&lt;%&lt;)</code> creates two functorial layers and leaves both in place. Note that doing away with <code>join</code> means the <code>Functor</code>s introduced by the functions being composed can differ, and so the category we are setting up has <em>all</em> functions that fit <code>Functor f =&gt; a -&gt; f b</code> as arrows. That is unlike what we have with <code>(&lt;=&lt;)</code> and the corresponding Kleisli categories, which only concern a single specific monad.</p>
<p>As for <code>return</code>, not relying on <code>Monad</code> means we need a different identity. Given the freedom to pick any <code>Functor</code> mentioned just above, it makes perfect sense to replace bringing a value into a <code>Monad</code> in a boring way by bringing a value into the boring <code>Functor</code> <em>par excellence</em>, <a href="http://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Identity.html"><code>Identity</code></a>:</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">Identity</span><span class="ot"> ::</span> a <span class="ot">-&gt;</span> <span class="dt">Identity</span> a</span></code></pre></div>
<p>With <code>(&lt;%&lt;)</code> as composition and <code>Identity</code> as identity, we can state the following category laws:</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="dt">Identity</span> <span class="op">&lt;%&lt;</span> f <span class="op">~</span> f</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>f <span class="op">&lt;%&lt;</span> <span class="dt">Identity</span> <span class="op">~</span> f</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>(h <span class="op">&lt;%&lt;</span> g) <span class="op">&lt;%&lt;</span> f <span class="op">~</span> h <span class="op">&lt;%&lt;</span> (g <span class="op">&lt;%&lt;</span> f)</span></code></pre></div>
<p>Why didn’t I write them as equalities? Once the definition of <code>(&lt;%&lt;)</code> is substituted, it becomes clear that they do not hold literally as equalities: the left hand sides of the identity laws will have a stray <code>Identity</code>, and the uses of <code>Compose</code> on either side of the associativity law will be associated differently. Since <code>Identity</code> and <code>Compose</code> are essentially bookkeeping boilerplate, however, it would be entirely reasonable to ignore such differences. If we do that, it becomes clear that the laws do hold. All in all, we have a category, even though we can’t go all the way and shape it into a <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Control-Category.html"><code>Category</code></a> instance, not only due to the trivialities we chose to overlook, but also because of how each <code>a -&gt; F b</code> function introduces a functorial layer <code>F</code> in a way that is not reflected in the target object <code>b</code>.</p>
<p>The first thing to do once after figuring out we have a category in our hands is looking for functors involving it.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> One of the simplest paths towards one is considering a way to, given some <code>Functor</code> <code>T</code>, change the source and target objects in an <code>a -&gt; F b</code> function to <code>T a</code> and <code>T b</code> (that is precisely what <code>fmap</code> does with regular functions). This would give an endofunctor, whose arrow mapping would have a signature shaped 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>(a <span class="ot">-&gt;</span> <span class="dt">F</span> b) <span class="ot">-&gt;</span> <span class="dt">T</span> a <span class="ot">-&gt;</span> <span class="dt">F</span> (<span class="dt">T</span> b)</span></code></pre></div>
<p>This signature shape, however, <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Traversable.html">should ring a bell</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="kw">class</span> (<span class="dt">Functor</span> t, <span class="dt">Foldable</span> t) <span class="ot">=&gt;</span> <span class="dt">Traversable</span> t <span class="kw">where</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    traverse ::</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> t a <span class="ot">-&gt;</span> f (t b)</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- etc.</span></span></code></pre></div>
<p>If <code>traverse</code> were the arrow mapping of our endofunctor, the relevant functor laws would be:</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">traverse</span> <span class="dt">Identity</span> <span class="ot">=</span> <span class="dt">Identity</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="fu">traverse</span> (g <span class="op">&lt;%&lt;</span> f) <span class="ot">=</span> <span class="fu">traverse</span> g <span class="op">&lt;%&lt;</span> <span class="fu">traverse</span> f</span></code></pre></div>
<p>Substituting the definition of <code>(&lt;%&lt;)</code> reveals these are the identity and composition laws of <code>Traversable</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="fu">traverse</span> <span class="dt">Identity</span> <span class="ot">=</span> <span class="dt">Identity</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="fu">traverse</span> (<span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> g <span class="op">.</span> f) <span class="ot">=</span> <span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> (<span class="fu">traverse</span> g) <span class="op">.</span> <span class="fu">traverse</span> f</span></code></pre></div>
<p>There it is: a <code>Traversable</code> instance is an endofunctor for a category made of arbitrary context-producing functions.<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a></p>
<p>Is it really, though? You may have noticed I have glossed over something quite glaring: if <code>(&lt;%&lt;)</code> only involved <code>Functor</code> constraints, where does the <code>Applicative</code> in <code>traverse</code> comes from?</p>
<h2 id="arpeggi">Arpeggi</h2>
<p>Let’s pretend we have just invented the <code>Traversable</code> class by building it around the aforementioned endofunctor. At this point, there is no reason for using anything more restrictive than <code>Functor</code> in the signature of its arrow mapping:</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="co">-- Tentative signature:</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="fu">traverse</span><span class="ot"> ::</span> (<span class="dt">Functor</span> f, <span class="dt">Traversable</span> t) <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></code></pre></div>
<p>The natural thing to do now is trying to write <code>traverse</code> for various choices of <code>t</code>. Let’s try it for one of the simplest <code>Functor</code>s around: the pair functor, <code>(,) e</code> – values with something extra attached:</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">Traversable</span> ((,) e) <span class="kw">where</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- traverse :: Functor f =&gt; (a -&gt; f b) -&gt; (e, a) -&gt; f (e, b)</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">traverse</span> f (e, x) <span class="ot">=</span> ((,) e) <span class="op">&lt;$&gt;</span> f x</span></code></pre></div>
<p>Simple enough: apply the function to the contained value, and then shift the extra stuff into the functorial context with <code>fmap</code>. The resulting <code>traverse</code> follows the functor laws just fine.</p>
<p>If we try to do it for different functors, though, we quickly run into trouble. <code>Maybe</code> looks simple enough…</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">Traversable</span> <span class="dt">Maybe</span> <span class="kw">where</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- traverse :: Functor f =&gt; (a -&gt; f b) -&gt; Maybe a -&gt; f (Maybe b)</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">traverse</span> f (<span class="dt">Just</span> x) <span class="ot">=</span> <span class="dt">Just</span> <span class="op">&lt;$&gt;</span> f x</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">traverse</span> f <span class="dt">Nothing</span>  <span class="ot">=</span> <span class="co">-- ex nihilo</span></span></code></pre></div>
<p>… but the <code>Nothing</code> case stumps us: there is no value that can be supplied to <code>f</code>, which means the functorial context would have to be created out of nothing.</p>
<p>For another example, consider what we might do with an homogeneous pair type (or, if you will, a vector of length two):</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">Duo</span> a <span class="ot">=</span> <span class="dt">Duo</span> a 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="kw">instance</span> <span class="dt">Functor</span> <span class="dt">Duo</span> <span class="kw">where</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (<span class="dt">Duo</span> x y) <span class="ot">=</span> <span class="dt">Duo</span> (f x) (f y)</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="kw">instance</span> <span class="dt">Traversable</span> <span class="dt">Duo</span> <span class="kw">where</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- traverse :: Functor f =&gt; (a -&gt; f b) -&gt; Duo a -&gt; f (Duo b)</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">traverse</span> f (<span class="dt">Duo</span> x y) <span class="ot">=</span> <span class="co">-- dilemma</span></span></code></pre></div>
<p>Here, we seemingly have to choose between applying <code>f</code> to <code>x</code> or to <code>y</code>, and then using <code>fmap (\z -&gt; Duo z z)</code> on the result. No matter the choice, though, discarding one of the values means the functor laws will be broken. A lawful implementation would require somehow combining the functorial values <code>f x</code> and <code>f y</code>.</p>
<p>As luck would have it, though, there is a type class which provides ways to both create a functorial context out of nothing and to combine functorial values: <code>Applicative</code>. <code>pure</code> solves the first problem; <code>(&lt;*&gt;)</code>, the second:</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">instance</span> <span class="dt">Traversable</span> <span class="dt">Maybe</span> <span class="kw">where</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- traverse :: Applicative f =&gt; (a -&gt; f b) -&gt; Maybe a -&gt; f (Maybe b)</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    <span class="fu">traverse</span> f (<span class="dt">Just</span> x) <span class="ot">=</span> <span class="dt">Just</span> <span class="op">&lt;$&gt;</span> f x</span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">traverse</span> f <span class="dt">Nothing</span>  <span class="ot">=</span> <span class="fu">pure</span> <span class="dt">Nothing</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><span class="kw">instance</span> <span class="dt">Traversable</span> <span class="dt">Duo</span> <span class="kw">where</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">-- traverse :: Applicative f =&gt; (a -&gt; f b) -&gt; Duo a -&gt; f (Duo b)</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">traverse</span> f (<span class="dt">Duo</span> x y) <span class="ot">=</span> <span class="dt">Duo</span> <span class="op">&lt;$&gt;</span> f x <span class="op">&lt;*&gt;</span> f y</span></code></pre></div>
<p>Shifting to the terminology of containers for a moment, we can describe the matter by saying the version of <code>traverse</code> with the <code>Functor</code> constraint can only handle containers that hold exactly one value. Once the constraint is strengthened to <code>Applicative</code>, however, we have the means to deal with containers that may hold zero or many values. This is a very general solution: there are instances of <code>Traversable</code> for the <code>Identity</code>, <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Const.html"><code>Const</code></a>, <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Sum.html"><code>Sum</code></a>, and <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Product.html"><code>Product</code></a> functors, which suffice to encode any algebraic data type.<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a> That explains why the <code>DeriveTraversable</code> GHC extension exists. (Note, though, that <code>Traversable</code> instances in general aren’t unique.)</p>
<p>It must be noted that our reconstruction does not reflect how <code>Traversable</code> was discovered, as the idea of using it to walk across containers holding an arbitrary number of values was there from the start. That being so, <code>Applicative</code> plays an essential role in the usual presentations of <code>Traversable</code>. To illustrate that, I will now paraphrase Definition 3.3 in Jaskelioff and Rypacek’s <a href="https://arxiv.org/abs/1202.2919"><em>An Investigation of the Laws of Traversals</em></a>. It is formulated not in terms of <code>traverse</code>, but of <code>sequenceA</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><span class="fu">sequenceA</span><span class="ot"> ::</span> (<span class="dt">Applicative</span> f, <span class="dt">Traversable</span> t) <span class="ot">=&gt;</span> t (f a) <span class="ot">-&gt;</span> f (t a)</span></code></pre></div>
<p><code>sequenceA</code> is characterised as a natural transformation in the category of applicative functors which “respects the monoidal structure of applicative functor composition”. It is worth it to take a few moments to unpack that:</p>
<ul>
<li><p>The category of applicative functors has what the <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Traversable.html"><code>Data.Traversable</code> documentation</a> calls “applicative transformations” as arrows – functions of general type <code>(Applicative f, Applicative g) =&gt; f a -&gt; g a</code> which preserve <code>pure</code> and <code>(&lt;*&gt;)</code>.</p></li>
<li><p><code>sequenceA</code> is a natural transformation in the aforementioned category of applicative functors. The two functors it maps between amount to the two ways of composing an applicative functor with the relevant traversable functor. The naturality law of <code>Traversable</code>…</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">-- t is an applicative transformation</span></span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a>t <span class="op">.</span> <span class="fu">sequenceA</span> <span class="ot">=</span> <span class="fu">sequenceA</span> <span class="op">.</span> <span class="fu">fmap</span> t</span></code></pre></div>
<p>… captures that fact (which, thanks to parametricity, is a given in Haskell).</p></li>
<li><p>Applicative functors form a monoid, with <code>Identity</code> as unit and functor composition as multiplication. <code>sequenceA</code> preserves these monoidal operations, and the identity and composition laws of <code>Traversable</code> express that:</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="fu">sequenceA</span> <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Identity</span> <span class="ot">=</span> <span class="dt">Identity</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a><span class="fu">sequenceA</span> <span class="op">.</span> <span class="fu">fmap</span> <span class="dt">Compose</span> <span class="ot">=</span> <span class="dt">Compose</span> <span class="op">.</span> <span class="fu">fmap</span> <span class="fu">sequenceA</span> <span class="op">.</span> <span class="fu">sequenceA</span></span></code></pre></div></li>
</ul>
<p>All of that seems only accidentally related to what we have done up to this point. However, if <code>sequenceA</code> is taken as the starting point, <code>traverse</code> can be defined in terms of 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="fu">traverse</span> f <span class="ot">=</span> <span class="fu">sequenceA</span> <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>Crucially, the opposite path is also possible. It follows from parametricity<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a> 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="fu">traverse</span> f <span class="ot">=</span> <span class="fu">traverse</span> <span class="fu">id</span> <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>… which allows us to start from <code>traverse</code>, define…</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="fu">sequenceA</span> <span class="ot">=</span> <span class="fu">traverse</span> <span class="fu">id</span></span></code></pre></div>
<p>… and continue as before. At this point, our narrative merges with the traditional account of <code>Traversable</code>.</p>
<h2 id="a-note-about-lenses">A note about lenses</h2>
<p>In the previous section, we saw how using <code>Applicative</code> rather than <code>Functor</code> in the type of <code>traverse</code> made it possible to handle containers which don’t necessarily hold just one value. It is not a coincidence that, in <em>lens</em>, this is precisely the difference between <code>Traversal</code> and <code>Lens</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">type</span> <span class="dt">Traversal</span> s t a b <span class="ot">=</span> <span class="kw">forall</span> f<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> s <span class="ot">-&gt;</span> f t</span>
<span id="cb22-2"><a href="#cb22-2" aria-hidden="true" tabindex="-1"></a><span class="kw">type</span> <span class="dt">Lens</span> s t a b <span class="ot">=</span> <span class="kw">forall</span> f<span class="op">.</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> f t</span></code></pre></div>
<p>A <code>Lens</code> targets exactly one value. A <code>Traversal</code> might reach zero, one or many targets, which requires a strengthening of the constraint. Van Laarhoven (i.e. <em>lens</em>-style) <code>Traversal</code>s and <code>Lens</code>es can be seen as a straightforward generalisation of the <code>traverse</code>-as-arrow-mapping view we have been discussing here, in which the, so to say, functoriality of the container isn’t necessarily reflected at type level in a direct way.</p>
<h2 id="a-note-about-profunctors">A note about profunctors</h2>
<p>Early on, we noted that <code>(&lt;%&lt;)</code> gave us a category that cannot be expressed as a Haskell <code>Category</code> because its composition is too quirky. We have a general-purpose class that is often a good fit for things that look like functions, arrows and/or <code>Category</code> instances but don’t compose in conventional ways: <code>Profunctor</code>. And sure enough: <em>profunctors</em> defines a profunctor called <a href="https://hackage.haskell.org/package/profunctors-5.2/docs/Data-Profunctor.html#t:Star"><code>Star</code></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="co">-- | Lift a 'Functor' into a 'Profunctor' (forwards).</span></span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a><span class="kw">newtype</span> <span class="dt">Star</span> f d c <span class="ot">=</span> <span class="dt">Star</span> {<span class="ot"> runStar ::</span> d <span class="ot">-&gt;</span> f c }</span></code></pre></div>
<p>… which corresponds to the arrows of the category we presented in the first section. It should come as no surprise that <code>Star</code> is an instance of a class called <code>Traversing</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="co">-- Abridged definition.</span></span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="kw">class</span> (<span class="dt">Choice</span> p, <span class="dt">Strong</span> p) <span class="ot">=&gt;</span> <span class="dt">Traversing</span> p <span class="kw">where</span></span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a><span class="ot">  traverse' ::</span> <span class="dt">Traversable</span> f <span class="ot">=&gt;</span> p a b <span class="ot">-&gt;</span> p (f a) (f b)</span>
<span id="cb24-4"><a href="#cb24-4" aria-hidden="true" tabindex="-1"></a><span class="ot">  wander ::</span> (<span class="kw">forall</span> f<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> s <span class="ot">-&gt;</span> f t) <span class="ot">-&gt;</span> p a b <span class="ot">-&gt;</span> p s t</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">Applicative</span> m <span class="ot">=&gt;</span> <span class="dt">Traversing</span> (<span class="dt">Star</span> m) <span class="kw">where</span></span>
<span id="cb24-7"><a href="#cb24-7" aria-hidden="true" tabindex="-1"></a>  traverse' (<span class="dt">Star</span> m) <span class="ot">=</span> <span class="dt">Star</span> (<span class="fu">traverse</span> m)</span>
<span id="cb24-8"><a href="#cb24-8" aria-hidden="true" tabindex="-1"></a>  wander f (<span class="dt">Star</span> amb) <span class="ot">=</span> <span class="dt">Star</span> (f amb)</span></code></pre></div>
<p>… which is a profunctor-oriented generalisation of <code>Traversable</code>.</p>
<p>Amusingly, it turns out there is a baroque way of expressing <code>(&lt;%&lt;)</code> composition with the <em>profunctors</em> vocabulary. <a href="https://hackage.haskell.org/package/profunctors-5.2/docs/Data-Profunctor-Composition.html"><code>Data.Profunctor.Composition</code></a> gives us a notion of profunctor composition:</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">data</span> <span class="dt">Procompose</span> p q d c <span class="kw">where</span></span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">Procompose</span><span class="ot"> ::</span> p x c <span class="ot">-&gt;</span> q d x <span class="ot">-&gt;</span> <span class="dt">Procompose</span> p q d c</span></code></pre></div>
<p><code>Procompose</code> simply pairs two profunctorial values with matching extremities. That is unlike <code>Category</code> composition, which welds two arrows<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a> into one:</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">(.) ::</span> <span class="dt">Category</span> cat <span class="ot">=&gt;</span> cat b c <span class="ot">-&gt;</span> cat a b <span class="ot">-&gt;</span> cat a c</span></code></pre></div>
<p>The difference is rather like that between combining functorial layers at type level with <code>Compose</code> and fusing monadic layers with <code>join</code><a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a>.</p>
<p>Among a handful of other interesting things, <code>Data.Functor.Procompose</code> offers <a href="https://hackage.haskell.org/package/profunctors-5.2/docs/Data-Profunctor-Composition.html#v:stars">a <em>lens</em>-style isomorphism</a>…</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">stars ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> <span class="dt">Iso'</span> (<span class="dt">Procompose</span> (<span class="dt">Star</span> f) (<span class="dt">Star</span> g) d c) (<span class="dt">Star</span> (<span class="dt">Compose</span> f g) d c)</span></code></pre></div>
<p>… which gives us a rather lyrical encoding of <code>(&lt;%&lt;)</code>:</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="dt">GHCi</span><span class="op">&gt;</span> <span class="kw">import</span> <span class="dt">Data.Profunctor</span></span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="kw">import</span> <span class="dt">Data.Profunctor.Composition</span></span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="kw">import</span> <span class="dt">Data.Profunctor.Traversing</span></span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="kw">import</span> <span class="dt">Data.Functor.Compose</span></span>
<span id="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="kw">import</span> <span class="dt">Control.Lens</span></span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> f <span class="ot">=</span> <span class="dt">Star</span> <span class="op">$</span> \x <span class="ot">-&gt;</span> <span class="fu">print</span> x <span class="op">*&gt;</span> <span class="fu">pure</span> x</span>
<span id="cb28-7"><a href="#cb28-7" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> g <span class="ot">=</span> <span class="dt">Star</span> <span class="op">$</span> \x <span class="ot">-&gt;</span> [<span class="dv">0</span><span class="op">..</span>x]</span>
<span id="cb28-8"><a href="#cb28-8" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> getCompose <span class="op">$</span> runStar (traverse' (view stars (g <span class="ot">`Procompose`</span> f))) [<span class="dv">0</span><span class="op">..</span><span class="dv">2</span>]</span>
<span id="cb28-9"><a href="#cb28-9" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span></span>
<span id="cb28-10"><a href="#cb28-10" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb28-11"><a href="#cb28-11" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span>
<span id="cb28-12"><a href="#cb28-12" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">0</span>],[<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">1</span>],[<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">2</span>],[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">0</span>],[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">1</span>],[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>]]</span></code></pre></div>
<p>If you feel like playing with that, note that <a href="https://hackage.haskell.org/package/profunctors-5.2/docs/Data-Profunctor-Sieve.html"><code>Data.Profunctor.Sieve</code></a> offers a more compact (though prosaic) spelling:</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="dt">GHCi</span><span class="op">&gt;</span> <span class="kw">import</span> <span class="dt">Data.Profunctor.Sieve</span></span>
<span id="cb29-2"><a href="#cb29-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="op">:</span>t sieve</span>
<span id="cb29-3"><a href="#cb29-3" aria-hidden="true" tabindex="-1"></a><span class="ot">sieve ::</span> <span class="dt">Sieve</span> p f <span class="ot">=&gt;</span> p a b <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> f b</span>
<span id="cb29-4"><a href="#cb29-4" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> getCompose <span class="op">$</span> <span class="fu">traverse</span> (sieve (g <span class="ot">`Procompose`</span> f)) [<span class="dv">0</span><span class="op">..</span><span class="dv">2</span>]</span>
<span id="cb29-5"><a href="#cb29-5" aria-hidden="true" tabindex="-1"></a><span class="dv">0</span></span>
<span id="cb29-6"><a href="#cb29-6" aria-hidden="true" tabindex="-1"></a><span class="dv">1</span></span>
<span id="cb29-7"><a href="#cb29-7" aria-hidden="true" tabindex="-1"></a><span class="dv">2</span></span>
<span id="cb29-8"><a href="#cb29-8" aria-hidden="true" tabindex="-1"></a>[[<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">0</span>],[<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">1</span>],[<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">2</span>],[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">0</span>],[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">1</span>],[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>]]</span></code></pre></div>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><p>The already mentioned <a href="https://arxiv.org/abs/1202.2919"><em>An Investigation of the Laws of Traversals</em></a>, by Mauro Jaskelioff and Ondrej Rypacek, is a fine entry point to the ways of formulating <code>Traversable</code>. It also touches upon some important matters I didn’t explore here, such as how the notion of container <code>Traversable</code> mobilises can be made precise, or the implications of the <code>Traversable</code> laws. I plan to discuss some aspects of these issues in a follow-up post.</p></li>
<li><p>Will Fancher’s <a href="http://elvishjerricco.github.io/2017/03/10/profunctors-arrows-and-static-analysis.html"><em>Profunctors, Arrows, &amp; Static Analysis</em></a> is a good applied introduction to profunctors. In its final sections, it demonstrates some use cases for the <code>Traversing</code> class mentioned here.</p></li>
<li><p>The explanation of profunctor composition in this post is intentionally cursory. If you want to dig deeper, Dan Piponi’s <a href="http://blog.sigfpe.com/2011/07/profunctors-in-haskell.html"><em>Profunctors in Haskell</em></a> can be a starting point. (N.B.: Wherever you see “cofunctor” there, read “contravariant functor” instead). Another option is going to <a href="https://bartoszmilewski.com">Bartosz Milewski’s blog</a> and searching for “profunctor” (most of the results will be relevant).</p></li>
</ul>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>For why that is a good idea, see Gabriella Gonzalez’s <a href="http://www.haskellforall.com/2012/09/the-functor-design-pattern.html"><em>The functor design pattern</em></a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>A more proper derivation for the results in this section can be found <a href="http://stackoverflow.com/a/39955475/2751851">in this Stack Overflow answer</a>, which I didn’t transcribe here to avoid boring you.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p>Suffice, that is, with the help of the trivial data types, <code>()</code> (unit) and <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Void.html"><code>Void</code></a>. As an arbitrary example, <code>Maybe</code> can be encoded using this functor toolkit as <code>Sum (Const ()) Identity</code>.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p>The property is an immediate consequence of the free theorem for <code>traverse</code>. Cf. <a href="http://stackoverflow.com/a/32813063/2751851">this Stack Overflow answer by Rein Heinrichs</a>.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>I mean “arrows” in the general sense, and not necessarily <code>Arrow</code>s as in <a href="https://hackage.haskell.org/package/base-4.9.1.0/docs/Control-Arrows.html"><code>Control.Arrow</code></a>!<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6" role="doc-endnote"><p>This is not merely a loose analogy. For details, see Bartosz Milewski’s <a href="https://bartoszmilewski.com/2017/02/09/monoids-on-steroids/"><em>Monoids on Steroids</em></a>, and and in particular its section about <code>Arrow</code>s.<a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>


<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/13">Comment on GitHub</a>

    
      
        (see <a href="posts/traversable-a-remix.html#comment-nav">the full post</a> for a reddit link)
      
    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2017-05-19T07:30:00Z</pubDate>
    <guid>https://duplode.github.io/posts/traversable-a-remix.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>What's in a Fold: The Basic Catamorphism in recursion-schemes</title>
    <link>https://duplode.github.io/posts/whats-in-a-fold.html</link>
    <description><![CDATA[
<p>This article is meant as an accessible introduction to the most basic recursion scheme, the catamorphism. It won’t engage in deep dives into theory, or survey practical motives for using recursion schemes – that will be covered by the further reading suggestions at the end. Rather, its main goal is simply offering a concrete presentation of how folds can be generalised. This presentation will be done in terms of the types and combinators used by the <a href="https://hackage.haskell.org/package/recursion-schemes-5.0.1"><em>recursion-schemes</em></a> library, so that the article doubles as an introduction to some of its key conventions.</p>
<div>

</div>
<!--more-->
<h2 id="foldr">foldr</h2>
<p>The primeval example of a fold in Haskell is the right fold of a 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="fu">foldr</span><span class="ot"> ::</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></code></pre></div>
<p>One way of picturing what the first two arguments of <code>foldr</code> are for is seeing them as replacements for the list constructors: the <code>b</code> argument is an initial value corresponding to the empty list, while the binary function incorporates each element prepended through <code>(:)</code> into the result of the fold.</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> [a] <span class="ot">=</span> [] <span class="op">|</span> a <span class="op">:</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="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="cb2-4"><a href="#cb2-4" 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="op">:</span> (<span class="dv">2</span> <span class="op">:</span> (<span class="dv">3</span> <span class="op">:</span> [])) )</span>
<span id="cb2-5"><a href="#cb2-5" 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>By applying this strategy to other data structures, we can get analogous folds for them.</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">-- This is foldr; I have flipped the arguments for cosmetic reasons.</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> [a] <span class="ot">=</span> [] <span class="op">|</span> (<span class="op">:</span>) a [a]</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ot">foldList ::</span> b <span class="ot">-&gt;</span> (a <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="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="co">-- Does this one look familiar?</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">Maybe</span> a <span class="ot">=</span> <span class="dt">Nothing</span> <span class="op">|</span> <span class="dt">Just</span> a</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="ot">foldMaybe ::</span> b <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a <span class="ot">-&gt;</span> b</span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="co">-- This is not the definition in Data.List.NonEmpty; the differences</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a><span class="co">-- between them, however, are superficial.</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">NEList</span><span class="ot"> ::</span> <span class="dt">NEList</span> a (<span class="dt">Maybe</span> (<span class="dt">NEList</span> a))</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a><span class="ot">foldNEList ::</span> (a <span class="ot">-&gt;</span> <span class="dt">Maybe</span> b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">NEList</span> a <span class="ot">-&gt;</span> b</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a><span class="co">-- A binary tree like the one in Diagrams.TwoD.Layout.Tree (and in</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- many other places).</span></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">BTree</span> a <span class="ot">=</span> <span class="dt">Empty</span> <span class="op">|</span> <span class="dt">BNode</span> a (<span class="dt">BTree</span> a) (<span class="dt">BTree</span> a)</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a><span class="ot">foldBTree ::</span> b <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> <span class="dt">BTree</span> a <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>It would make sense to capture this pattern into an abstraction. At first glance, however, it is not obvious how to do so. Though we know intuitively what the folds above have in common, their type signatures have lots of superficial differences between them. Our immediate goal, then, will be simplifying things by getting rid of these differences.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<h2 id="listf">ListF</h2>
<p>We will sketch the simplification using the tangible and familiar example of lists. Let’s return to the type of <code>foldr</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>(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></code></pre></div>
<p>With the cosmetic flip I had applied previously, it becomes:</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>b <span class="ot">-&gt;</span> (a <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></code></pre></div>
<p>The annoying irregularities among the types of the folds in the previous section had to do with the number of arguments other than the data structure (one per constructor) and the types of said arguments (dependent on the shape of each constructor). Though we cannot entirely suppress these differences, we have a few tricks that make it possible to disguise them rather well. The number of extra arguments, for instance, can be always be reduced to just one with sufficient uncurrying:</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>(b, a <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></code></pre></div>
<p>The first argument is now a pair. We continue by making its two halves more like each other by converting them into unary functions: the first component acquires a dummy <code>()</code> argument, while the second one gets some more uncurrying:</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> b, (a, b) <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>We now have a pair of unary functions with result type <code>b</code>. A pair of functions with the same result type, however, is equivalent to a single function from <code>Either</code> one of the argument types (if you are sceptical about that, you might want to work out the isomorphism – that is, the pair of conversion functions – that witnesses this fact):</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="dt">Either</span> () (a, b) <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>At this point, the only extra argument of the fold is an unary function with result type <code>b</code>. We have condensed the peculiarities of the original arguments at a single place (the argument of said function), which makes the overall shape of the signature a lot simpler. Since it can be awkward to work with anonymous nestings of <code>Either</code> and pairs, we will replace <code>Either () (a, b)</code> with an equivalent type equipped with suggestive names:</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">ListF</span> a b <span class="ot">=</span>  <span class="dt">Nil</span> <span class="op">|</span> <span class="dt">Cons</span> a b</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="co">--            Left () | Right (a,b)</span></span></code></pre></div>
<p>That leaves us with:</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="dt">ListF</span> a b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>The most important fact about <code>ListF</code> is that it mirrors the shape of the list type except for one crucial difference…</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> []    a   <span class="ot">=</span> []  <span class="op">|</span> (<span class="op">:</span>)  a [a]</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="kw">data</span> <span class="dt">ListF</span> a b <span class="ot">=</span> <span class="dt">Nil</span> <span class="op">|</span> <span class="dt">Cons</span> a b</span></code></pre></div>
<p>… namely, <em>it is not recursive</em>. An <code>[a]</code> value built with <code>(:)</code> has another <code>[a]</code> in itself, but a <code>ListF a b</code> built with <code>Cons</code> does not contain another <code>ListF a b</code>. To put it in another way, <code>ListF</code> is the outcome of taking away the recursive nesting in the list data type and filling the resulting hole with a placeholder type, the <code>b</code> in our signatures, that corresponds to the result of the fold. This strategy can be used to obtain a <code>ListF</code> analogue for any other data structure. You might, for instance, try it with the <code>BTree a</code> type shown in the first section.</p>
<h2 id="cata">cata</h2>
<p>We have just learned that the list <code>foldr</code> can be expressed using this signature:</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="dt">ListF</span> a b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>We might figure out a <code>foldr</code> implementation with this signature in a mechanical way, by throwing all of the tricks from the previous section at <code>Data.List.foldr</code> until we squeeze out something with the right type. It is far more illuminating, however, to start from scratch. If we go down that route, the first question that arises is how to apply a <code>ListF a b -&gt; b</code> function to an <code>[a]</code>. It is clear that the list must somehow be converted to a <code>ListF a b</code>, so that the function can be applied to it.</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">foldList ::</span> (<span class="dt">ListF</span> a b <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>foldList f <span class="ot">=</span> f <span class="op">.</span> something</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- foldList f xs = f (something xs)</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="co">-- something :: [a] -&gt; ListF a b</span></span></code></pre></div>
<p>We can get part of the way there by recalling how <code>ListF</code> mirrors the shape of the list type. That being so, going from <code>[a]</code> to <code>ListF a [a]</code> is just a question of matching the corresponding constructors.<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a></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">project ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">ListF</span> a [a]</span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a>project <span class="ot">=</span> \<span class="kw">case</span></span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a>    [] <span class="ot">-&gt;</span> <span class="dt">Nil</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    x<span class="op">:</span>xs <span class="ot">-&gt;</span> <span class="dt">Cons</span> x xs</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 class="ot">foldList ::</span> (<span class="dt">ListF</span> a b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b</span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a>foldList f <span class="ot">=</span> f <span class="op">.</span> something <span class="op">.</span> project</span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true" tabindex="-1"></a><span class="co">-- something :: ListF a [a] -&gt; ListF a b</span></span></code></pre></div>
<p><code>project</code> witnesses the simple fact that, given that <code>ListF a b</code> is the <code>[a]</code> except with a <code>b</code> placeholder in the tail position, where there would be a nested <code>[a]</code>, if we plug the placeholder with <code>[a]</code> we get something equivalent to the <code>[a]</code> list type we began with.</p>
<p>We now need to go from <code>ListF a [a]</code> to <code>ListF a b</code>; in other words, we have to change the <code>[a]</code> inside <code>ListF</code> into a <code>b</code>. And sure enough, we do have a function from <code>[a]</code> to <code>b</code>…</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">foldList ::</span> (<span class="dt">ListF</span> a b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> ([a] <span class="ot">-&gt;</span> b)</span>
<span id="cb17-2"><a href="#cb17-2" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">ListF</span> a b <span class="ot">-&gt;</span> b</span>
<span id="cb17-3"><a href="#cb17-3" aria-hidden="true" tabindex="-1"></a>foldList<span class="ot"> f ::</span> [a] <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>… the fold itself! To conveniently reach inside <code>ListF a b</code>, we set up a <code>Functor</code> 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="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">ListF</span> a) <span class="kw">where</span></span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f <span class="ot">=</span> \<span class="kw">case</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Nil</span> <span class="ot">-&gt;</span> <span class="dt">Nil</span></span>
<span id="cb18-4"><a href="#cb18-4" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Cons</span> x y <span class="ot">-&gt;</span> <span class="dt">Cons</span> x (f y)</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><span class="ot">foldList ::</span> (<span class="dt">ListF</span> a b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> b</span>
<span id="cb18-7"><a href="#cb18-7" aria-hidden="true" tabindex="-1"></a>foldList f <span class="ot">=</span> f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">.</span> project</span></code></pre></div>
<p>And there it is, the list fold. First, <code>project</code> exposes the list (or, more precisely, its first constructor) to our machinery; then, the tail of the list (if there is one – what happens if there isn’t?) is recursively folded through the <code>Functor</code> instance of <code>ListF</code>; finally, the overall result is obtained by applying <code>f</code> to the resulting <code>ListF a b</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="co">-- A simple demonstration of foldList in action.</span></span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a><span class="ot">f ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">ListF</span> a a <span class="ot">-&gt;</span> a</span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a>f <span class="ot">=</span> \<span class="kw">case</span> { <span class="dt">Nil</span> <span class="ot">-&gt;</span> <span class="dv">0</span>; <span class="dt">Cons</span> x y <span class="ot">-&gt;</span> x <span class="op">+</span> y }</span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-5"><a href="#cb19-5" aria-hidden="true" tabindex="-1"></a>foldList f [<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>]</span>
<span id="cb19-6"><a href="#cb19-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- Let's try and evaluate this by hand.</span></span>
<span id="cb19-7"><a href="#cb19-7" aria-hidden="true" tabindex="-1"></a>foldList f (<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="cb19-8"><a href="#cb19-8" aria-hidden="true" tabindex="-1"></a>f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">.</span> project <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="cb19-9"><a href="#cb19-9" aria-hidden="true" tabindex="-1"></a>f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (<span class="dv">2</span> <span class="op">:</span> <span class="dv">3</span> <span class="op">:</span> [])</span>
<span id="cb19-10"><a href="#cb19-10" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (foldList f (<span class="dv">2</span> <span class="op">:</span> <span class="dv">3</span> <span class="op">:</span> []))</span>
<span id="cb19-11"><a href="#cb19-11" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">$</span> project (<span class="dv">2</span> <span class="op">:</span> <span class="dv">3</span> <span class="op">:</span> []))</span>
<span id="cb19-12"><a href="#cb19-12" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (<span class="dv">3</span> <span class="op">:</span> []))</span>
<span id="cb19-13"><a href="#cb19-13" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (foldList f (<span class="dv">3</span> <span class="op">:</span> [])))</span>
<span id="cb19-14"><a href="#cb19-14" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">.</span> project <span class="op">$</span> (<span class="dv">3</span> <span class="op">:</span> [])))</span>
<span id="cb19-15"><a href="#cb19-15" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">3</span> []))</span>
<span id="cb19-16"><a href="#cb19-16" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">3</span> (foldList f [])))</span>
<span id="cb19-17"><a href="#cb19-17" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">3</span> (f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">.</span> project <span class="op">$</span> [])))</span>
<span id="cb19-18"><a href="#cb19-18" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">3</span> (f <span class="op">.</span> <span class="fu">fmap</span> (foldList f) <span class="op">$</span> <span class="dt">Nil</span>)))</span>
<span id="cb19-19"><a href="#cb19-19" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">3</span> (f <span class="op">$</span> <span class="dt">Nil</span>)))</span>
<span id="cb19-20"><a href="#cb19-20" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">3</span> <span class="dv">0</span>))</span>
<span id="cb19-21"><a href="#cb19-21" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> (f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">2</span> <span class="dv">3</span>)</span>
<span id="cb19-22"><a href="#cb19-22" aria-hidden="true" tabindex="-1"></a>f <span class="op">$</span> <span class="dt">Cons</span> <span class="dv">1</span> <span class="dv">5</span></span>
<span id="cb19-23"><a href="#cb19-23" aria-hidden="true" tabindex="-1"></a><span class="dv">6</span></span></code></pre></div>
<p>One interesting thing about our definition of <code>foldList</code> is that all the list-specific details are tucked within the implementations of <code>project</code>, <code>fmap</code> for <code>ListF</code> and <code>f</code> (whatever it is). That being so, if we look only at the implementation and not at the signature, we find no outward signs of anything related to lists. No outward signs, that is, except for the name we gave the function. That’s easy enough to solve, though: it is just a question of inventing a new one:</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>cata f <span class="ot">=</span> f <span class="op">.</span> <span class="fu">fmap</span> (cata f) <span class="op">.</span> project</span></code></pre></div>
<p><code>cata</code> is short for <em>catamorphism</em>, the fancy name given to ordinary folds in the relevant theory. There is a function called <code>cata</code> in <em>recursion-schemes</em>. <a href="https://hackage.haskell.org/package/recursion-schemes-5.0.1/docs/Data-Functor-Foldable.html#t:Recursive">Its implementation</a>…</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>cata f <span class="ot">=</span> c <span class="kw">where</span> c <span class="ot">=</span> f <span class="op">.</span> <span class="fu">fmap</span> c <span class="op">.</span> project</span></code></pre></div>
<p>… is the same as ours, almost down to the last character. Its type signature, however, is much more general:</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">cata ::</span> <span class="dt">Recursive</span> t <span class="ot">=&gt;</span> (<span class="dt">Base</span> t b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> t <span class="ot">-&gt;</span> b</span></code></pre></div>
<p>It involves, in no particular order:</p>
<ul>
<li><p><code>b</code>, the type of the result of the fold;</p></li>
<li><p><code>t</code>, the type of the data structure being folded. In our example, <code>t</code> would be <code>[a]</code>; or, as GHC would put it, <code>t ~ [a]</code>.</p></li>
<li><p><code>Base</code>, a type family that generalises what we did with <code>[a]</code> and <code>ListF</code> by assigning <em>base functors</em> to data types. We can read <code>Base t</code> as “the base functor of <code>t</code>”; in our example, we have <code>Base   [a] ~ ListF a</code>.</p></li>
<li><p><code>Recursive</code>, a type class whose minimal definition consists of <code>project</code>, with the type of <code>project</code> now being <code>t -&gt; Base t t</code>.</p></li>
</ul>
<p>The base functor is supposed to be a <code>Functor</code>, so that we can use <code>fmap</code> on it. That is enforced through a <code>Functor (Base t)</code> constraint in the definition of the <code>Recursive</code> class. Note, however, that there is no such restriction on <code>t</code> itself: it doesn’t need to be a polymorphic type, or even to involve a type constructor.</p>
<p>In summary, once we managed to concentrate the surface complexity in the signature of <code>foldr</code> at a single place, the <code>ListF a b -&gt; b</code> function, an opportunity to generalise it revealed itself. Incidentally, that function, and more generally any <code>Base t b -&gt; b</code> function that can be given to <code>cata</code>, is referred to as an <em>algebra</em>. In this context, the term “algebra” is meant in a precise technical sense; still, we can motivate it with a legitimate recourse to intuition. In basic school algebra, we use certain rules to get simpler expressions out of more complicated ones, such as <span class="math inline"><em>a</em><em>x</em> + <em>b</em><em>x</em> = (<em>a</em>+<em>b</em>)<em>x</em></span>. Similarly, a <code>Base t b -&gt; b</code> algebra boils down to a set of rules that tell us what to do to get a <code>b</code> result out of the <code>Base t b</code> we are given at each step of the fold.</p>
<h2 id="fix">Fix</h2>
<p>The <code>cata</code> function we ended up with in the previous section…</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">cata ::</span> <span class="dt">Recursive</span> t <span class="ot">=&gt;</span> (<span class="dt">Base</span> t b <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> t <span class="ot">-&gt;</span> b</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>cata f <span class="ot">=</span> c <span class="kw">where</span> c <span class="ot">=</span> f <span class="op">.</span> <span class="fu">fmap</span> c <span class="op">.</span> project</span></code></pre></div>
<p>… is perfectly good for practical purposes: it allows us to fold anything that we can give a <code>Base</code> functor and a corresponding <code>project</code>. Not only that, the implementation of <code>cata</code> is very elegant. And yet, a second look at its signature suggests that there might be an even simpler way of expressing <code>cata</code>. The signature uses both <code>t</code> and <code>Base t b</code>. As we have seen for the <code>ListF</code> example, these two types are very similar (their shapes match except for recursiveness), and so using both in the same signature amounts to encoding the same information in two different ways – perhaps unnecessarily so.</p>
<p>In the implementation of <code>cata</code>, it is specifically <code>project</code> that links <code>t</code> and <code>Base t b</code>, as it translates the constructors from one type to the other.</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>project (<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="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Cons</span> <span class="dv">1</span> (<span class="dv">2</span> <span class="op">:</span> <span class="dv">3</span> <span class="op">:</span> [])</span></code></pre></div>
<p>Now, let’s look at what happens once we repeatedly expand the definition of <code>cata</code>:</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>c <span class="ot">=</span> cata f</span>
<span id="cb25-2"><a href="#cb25-2" aria-hidden="true" tabindex="-1"></a>p <span class="ot">=</span> project</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>                                c</span>
<span id="cb25-4"><a href="#cb25-4" aria-hidden="true" tabindex="-1"></a>                         f <span class="op">.</span> <span class="fu">fmap</span> c <span class="op">.</span> p</span>
<span id="cb25-5"><a href="#cb25-5" aria-hidden="true" tabindex="-1"></a>               f <span class="op">.</span> <span class="fu">fmap</span> (f <span class="op">.</span> <span class="fu">fmap</span> c <span class="op">.</span> p) <span class="op">.</span> p</span>
<span id="cb25-6"><a href="#cb25-6" aria-hidden="true" tabindex="-1"></a>     f <span class="op">.</span> <span class="fu">fmap</span> (f <span class="op">.</span> <span class="fu">fmap</span> (f <span class="op">.</span> <span class="fu">fmap</span> c <span class="op">.</span> p) <span class="op">.</span> p) <span class="op">.</span> p</span>
<span id="cb25-7"><a href="#cb25-7" aria-hidden="true" tabindex="-1"></a>f <span class="op">.</span> <span class="fu">fmap</span> (   <span class="op">.</span>   <span class="op">.</span>   <span class="op">.</span>   f <span class="op">.</span> <span class="fu">fmap</span> c <span class="op">.</span> p   <span class="op">.</span>   <span class="op">.</span>   <span class="op">.</span>   ) <span class="op">.</span> p</span></code></pre></div>
<p>This continues indefinitely. The fold terminates when, at some point, <code>fmap c</code> does nothing (in the case of <code>ListF</code>, that happens when we get to a <code>Nil</code>). Note, however, that even at that point we can carry on expanding the definition, merrily introducing do-nothing operations for as long as we want.</p>
<p>At the right side of the expanded expression, we have a chain of increasingly deep <code>fmap</code>-ped applications of <code>project</code>:<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></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="op">.</span>   <span class="op">.</span>   <span class="op">.</span>   <span class="fu">fmap</span> (<span class="fu">fmap</span> project) <span class="op">.</span> <span class="fu">fmap</span> project <span class="op">.</span> project</span></code></pre></div>
<p>If we could factor that out into a separate function, it would change a <code>t</code> data structure into something equivalent to it, but built with the <code>Base t</code> constructors:</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="dt">GHCi</span><span class="op">&gt;</span> <span class="op">:</span>{</span>
<span id="cb28-2"><a href="#cb28-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">|</span> <span class="fu">fmap</span> (<span class="fu">fmap</span> (<span class="fu">fmap</span> project))</span>
<span id="cb28-3"><a href="#cb28-3" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">|</span>     <span class="op">.</span> <span class="fu">fmap</span> (<span class="fu">fmap</span> project) <span class="op">.</span> <span class="fu">fmap</span> project <span class="op">.</span> project</span>
<span id="cb28-4"><a href="#cb28-4" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</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="cb28-5"><a href="#cb28-5" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">|</span> <span class="op">:</span>}</span>
<span id="cb28-6"><a href="#cb28-6" aria-hidden="true" tabindex="-1"></a><span class="dt">Cons</span> <span class="dv">1</span> (<span class="dt">Cons</span> <span class="dv">2</span> (<span class="dt">Cons</span> <span class="dv">3</span> <span class="dt">Nil</span>))</span></code></pre></div>
<p>We would then be able to regard this conversion as a preliminary, relatively uninteresting step that precedes the application of a slimmed down <code>cata</code>, that doesn’t use neither <code>project</code> nor the <code>t</code> type.<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a></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>cata f <span class="ot">=</span> leanCata f <span class="op">.</span> omniProject</span></code></pre></div>
<p>Defining <code>omniProject</code> seems simple once we notice the self-similarity in the chain of <code>project</code>:</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>omniProject <span class="ot">=</span> <span class="op">.</span>   <span class="op">.</span>   <span class="op">.</span>   <span class="fu">fmap</span> (<span class="fu">fmap</span> project) <span class="op">.</span> <span class="fu">fmap</span> project <span class="op">.</span> project</span>
<span id="cb30-2"><a href="#cb30-2" aria-hidden="true" tabindex="-1"></a>omniProject <span class="ot">=</span> <span class="fu">fmap</span> (<span class="fu">fmap</span> (   <span class="op">.</span>   <span class="op">.</span>   <span class="op">.</span>   project) <span class="op">.</span> project) <span class="op">.</span> project</span>
<span id="cb30-3"><a href="#cb30-3" aria-hidden="true" tabindex="-1"></a>omniProject <span class="ot">=</span> <span class="fu">fmap</span> omniProject <span class="op">.</span> project</span></code></pre></div>
<p>Guess what happens next:</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="dt">GHCi</span><span class="op">&gt;</span> omniProject <span class="ot">=</span> <span class="fu">fmap</span> omniProject <span class="op">.</span> project</span>
<span id="cb31-2"><a href="#cb31-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb31-3"><a href="#cb31-3" aria-hidden="true" tabindex="-1"></a><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">502</span><span class="op">:</span><span class="dv">16</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></span>
<span id="cb31-4"><a href="#cb31-4" aria-hidden="true" tabindex="-1"></a>    • <span class="dt">Occurs</span> check<span class="op">:</span> cannot construct the infinite <span class="kw">type</span><span class="op">:</span> b <span class="op">~</span> <span class="dt">Base</span> t b</span>
<span id="cb31-5"><a href="#cb31-5" aria-hidden="true" tabindex="-1"></a>      <span class="dt">Expected</span> <span class="kw">type</span><span class="op">:</span> t <span class="ot">-&gt;</span> b</span>
<span id="cb31-6"><a href="#cb31-6" aria-hidden="true" tabindex="-1"></a>        <span class="dt">Actual</span> <span class="kw">type</span><span class="op">:</span> t <span class="ot">-&gt;</span> <span class="dt">Base</span> t b</span>
<span id="cb31-7"><a href="#cb31-7" aria-hidden="true" tabindex="-1"></a>    • <span class="dt">In</span> the expression<span class="op">:</span> <span class="fu">fmap</span> omniProject <span class="op">.</span> project</span>
<span id="cb31-8"><a href="#cb31-8" aria-hidden="true" tabindex="-1"></a>      <span class="dt">In</span> an equation for ‘omniProject’<span class="op">:</span></span>
<span id="cb31-9"><a href="#cb31-9" aria-hidden="true" tabindex="-1"></a>          omniProject <span class="ot">=</span> <span class="fu">fmap</span> omniProject <span class="op">.</span> project</span>
<span id="cb31-10"><a href="#cb31-10" aria-hidden="true" tabindex="-1"></a>    • <span class="dt">Relevant</span> bindings include</span>
<span id="cb31-11"><a href="#cb31-11" aria-hidden="true" tabindex="-1"></a><span class="ot">        omniProject ::</span> t <span class="ot">-&gt;</span> b (bound at <span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">502</span><span class="op">:</span><span class="dv">1</span>)</span></code></pre></div>
<p>GHCi complains about an “infinite type”, and that is entirely appropriate. Every <code>fmap</code>-ped <code>project</code> changes the type of the result by introducing a new layer of <code>Base t</code>. That being so, the type of <code>omniProject</code> would be…</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">omniProject ::</span> <span class="dt">Recursive</span> t <span class="ot">=&gt;</span> t <span class="ot">-&gt;</span> <span class="dt">Base</span> t (<span class="dt">Base</span> t (<span class="dt">Base</span> t (  <span class="op">.</span>  <span class="op">.</span>  <span class="op">.</span></span></code></pre></div>
<p>… which is clearly a problem, as we don’t have a type that encodes an infinite nesting of type constructors. There is a simple way of solving that, though: we <em>make up</em> the type we want!</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">newtype</span> <span class="dt">Fix</span> f <span class="ot">=</span> <span class="dt">Fix</span> (f (<span class="dt">Fix</span> f))</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a><span class="ot">unfix ::</span> <span class="dt">Fix</span> f <span class="ot">-&gt;</span> f (<span class="dt">Fix</span> f)</span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a>unfix (<span class="dt">Fix</span> f) <span class="ot">=</span> f</span></code></pre></div>
<p>If we read <code>Fix f</code> as “infinite nesting of <code>f</code>”, the right-hand side of the <code>newtype</code> definition just above reads “an infinite nesting of <code>f</code> contains an <code>f</code> of infinite nestings of <code>f</code>”, which is an entirely reasonable encoding of such a thing.<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a></p>
<p>All we need to make our tentative definition of <code>omniProject</code> legal Haskell is wrapping the whole thing in a <code>Fix</code>. The recursive <code>fmap</code>-ping will ensure <code>Fix</code> is applied at all levels:</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="ot">omniProject ::</span> <span class="dt">Recursive</span> t <span class="ot">=&gt;</span> t <span class="ot">-&gt;</span> <span class="dt">Fix</span> (<span class="dt">Base</span> t)</span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a>omniProject <span class="ot">=</span> <span class="dt">Fix</span> <span class="op">.</span> <span class="fu">fmap</span> omniProject <span class="op">.</span> project</span></code></pre></div>
<p>Another glance at the definition of <code>cata</code> shows that this is just <code>cata</code> using <code>Fix</code> as the algebra:</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>omniProject <span class="ot">=</span> cata <span class="dt">Fix</span></span></code></pre></div>
<p>That being so, <code>cata Fix</code> will change anything with a <code>Recursive</code> instance into its <code>Fix</code>-wearing form:</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="dt">GHCi</span><span class="op">&gt;</span> cata <span class="dt">Fix</span> [<span class="dv">0</span><span class="op">..</span><span class="dv">9</span>]</span>
<span id="cb36-2"><a href="#cb36-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">0</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">1</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">2</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">3</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">4</span> (</span>
<span id="cb36-3"><a href="#cb36-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">5</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">6</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">7</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">8</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">9</span> (</span>
<span id="cb36-4"><a href="#cb36-4" aria-hidden="true" tabindex="-1"></a><span class="dt">Fix</span> <span class="dt">Nil</span>))))))))))))))))))))</span></code></pre></div>
<p>Defining a <code>Fix</code>-style structure from scratch, without relying on a <code>Recursive</code> instance, is just a question of introducing <code>Fix</code> in the appropriate places. For extra convenience, you might want to define “smart constructors” like these two:<a href="#fn6" class="footnote-ref" id="fnref6" role="doc-noteref"><sup>6</sup></a></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">nil ::</span> <span class="dt">Fix</span> (<span class="dt">ListF</span> a)</span>
<span id="cb37-2"><a href="#cb37-2" aria-hidden="true" tabindex="-1"></a>nil <span class="ot">=</span> <span class="dt">Fix</span> <span class="dt">Nil</span></span>
<span id="cb37-3"><a href="#cb37-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb37-4"><a href="#cb37-4" aria-hidden="true" tabindex="-1"></a><span class="ot">cons ::</span> a <span class="ot">-&gt;</span> <span class="dt">Fix</span> (<span class="dt">ListF</span> a) <span class="ot">-&gt;</span> <span class="dt">Fix</span> (<span class="dt">ListF</span> a)</span>
<span id="cb37-5"><a href="#cb37-5" aria-hidden="true" tabindex="-1"></a>cons x xs <span class="ot">=</span> <span class="dt">Fix</span> (<span class="dt">Cons</span> x xs)</span></code></pre></div>
<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">GHCi</span><span class="op">&gt;</span> <span class="dv">1</span> <span class="ot">`cons`</span> (<span class="dv">2</span> <span class="ot">`cons`</span> (<span class="dv">3</span> <span class="ot">`cons`</span> nil))</span>
<span id="cb38-2"><a href="#cb38-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">1</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">2</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">3</span> (<span class="dt">Fix</span> <span class="dt">Nil</span>))))))</span></code></pre></div>
<p>Before we jumped into this <code>Fix</code> rabbit hole, we were trying to find a <code>leanCata</code> function such that:</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>cata f <span class="ot">=</span> leanCata f <span class="op">.</span> omniProject</span></code></pre></div>
<p>We can now easily define <code>leanCata</code> by mirroring what we have done for <code>omniProject</code>: first, we get rid of the <code>Fix</code> wrapper; then, we fill in the other half of the definition of <code>cata</code> that we left behind when we extracted <code>omniProject</code> – that is, the repeated application of <code>f</code>:</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>leanCata f <span class="ot">=</span> f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f) <span class="op">.</span> unfix</span></code></pre></div>
<p>(It is possible to prove that this <em>must</em> be the definition of <code>leanCata</code> using the definitions of <code>cata</code> and <code>omniProject</code> and the <code>cata f = leanCata f . omniProject</code> specification. You might want to work it out yourself; alternatively, you can find the derivation in an appendix at the end of this article.)</p>
<p>What should be the type of <code>leanCata</code>? <code>unfix</code> calls for a <code>Fix f</code>, and <code>fmap</code> demands this <code>f</code> to be a <code>Functor</code>. As the definition doesn’t use <code>cata</code> or <code>project</code>, there is no need to involve <code>Base</code> or <code>Recursive</code>. That being so, we get:</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="ot">leanCata ::</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> <span class="dt">Fix</span> f <span class="ot">-&gt;</span> b</span>
<span id="cb41-2"><a href="#cb41-2" aria-hidden="true" tabindex="-1"></a>leanCata f <span class="ot">=</span> f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f) <span class="op">.</span> unfix</span></code></pre></div>
<p>This is how you will usually see <code>cata</code> being defined in other texts about the subject.<a href="#fn7" class="footnote-ref" id="fnref7" role="doc-noteref"><sup>7</sup></a></p>
<p>Similarly to what we have seen for <code>omniProject</code>, the implementation of <code>leanCata</code> looks a lot like the <code>cata</code> we began with, except that it has <code>unfix</code> where <code>project</code> used to be. And sure enough, <em>recursion-schemes</em> defines…</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">type</span> <span class="kw">instance</span> <span class="dt">Base</span> (<span class="dt">Fix</span> f) <span class="ot">=</span> f</span>
<span id="cb42-2"><a href="#cb42-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb42-3"><a href="#cb42-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">Recursive</span> (<span class="dt">Fix</span> f) <span class="kw">where</span></span>
<span id="cb42-4"><a href="#cb42-4" aria-hidden="true" tabindex="-1"></a>  project (<span class="dt">Fix</span> a) <span class="ot">=</span> a</span></code></pre></div>
<p>… so that its <code>cata</code> also works as <code>leanCata</code>:</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">GHCi</span><span class="op">&gt;</span> foo <span class="ot">=</span> <span class="dv">1</span> <span class="ot">`cons`</span> (<span class="dv">2</span> <span class="ot">`cons`</span> (<span class="dv">3</span> <span class="ot">`cons`</span> nil))</span>
<span id="cb43-2"><a href="#cb43-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> foo</span>
<span id="cb43-3"><a href="#cb43-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">1</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">2</span> (<span class="dt">Fix</span> (<span class="dt">Cons</span> <span class="dv">3</span> (<span class="dt">Fix</span> <span class="dt">Nil</span>))))))</span>
<span id="cb43-4"><a href="#cb43-4" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> cata (\<span class="kw">case</span> {<span class="dt">Nil</span> <span class="ot">-&gt;</span> <span class="dv">1</span>; <span class="dt">Cons</span> x y <span class="ot">-&gt;</span> x <span class="op">*</span> y}) foo</span>
<span id="cb43-5"><a href="#cb43-5" aria-hidden="true" tabindex="-1"></a><span class="dv">6</span></span></code></pre></div>
<p>In the end, we did manage to get a tidier <code>cata</code>. Crucially, we now also have a clear picture of folding, the fundamental way of consuming a data structure recursively. On the one hand, any fold can be expressed in terms of an algebra for the base functor of the structure being folded by the means of a simple function, <code>cata</code>. On the other hand, the relationship between data structures and their base functors is made precise through <code>Fix</code>, which introduces recursion into functors in a way that captures the essence of recursiveness of data types.</p>
<p>To wrap things up, here a few more questions for you to ponder:</p>
<ul>
<li><p>Does the data structure that we get by using <code>Maybe</code> as a base functor correspond to anything familiar? Use <code>cata</code> to write a fold that does something interesting with it.</p></li>
<li><p>What could possibly be the base functor of a non-recursive data structure?</p></li>
<li><p>Find <em>two</em> base functors that give rise to non-empty lists. One of them corresponds directly to the <code>NEList</code> definition given at the beginning of this article.</p></li>
<li><p>As we have discussed, <code>omniProject</code>/<code>cata Fix</code> can be used to losslessly convert a data structure to the corresponding <code>Fix</code>-encoded form. Write the other half of the isomorphism for lists; that is, the function that changes a <code>Fix (ListF a)</code> back into an <code>[a]</code>.</p></li>
</ul>
<h2 id="closing-remarks">Closing remarks</h2>
<p>When it comes to recursion schemes, there is a lot more to play with than just the fundamental catamorphism that we discussed here. In particular, <em>recursion-schemes</em> offers all sorts of specialised folds (and <em>un</em>folds), often with richly decorated type signatures meant to express more directly some particular kind of recursive (or <em>co</em>recursive) algorithm. But that’s a story for another time. For now, I will just make a final observation about unfolds.</p>
<p>Intuitively, an unfold is the opposite of a fold – while a fold consumes a data structure to produce a result, an unfold generates a data structure from a seed. In recursion schemes parlance, the intuition is made precise by the notion of <em>anamorphism</em>, a counterpart (technically, a <em>dual</em>) to the catamorphism. Still, if we have a look at <code>unfoldr</code> in <code>Data.List</code>, the exact manner in which it is opposite to <code>foldr</code> is not immediately obvious from its signature.</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">unfoldr ::</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></code></pre></div>
<p>One way of clarifying that is considering the first argument of <code>unfoldr</code> from the same perspective that we used to uncover <code>ListF</code> early in this article.</p>
<h2 id="further-reading">Further reading</h2>
<ul>
<li><p><a href="https://www.schoolofhaskell.com/user/bartosz/understanding-algebras"><em>Understanding F-Algebras</em></a>, by Bartosz Milewski, covers similar ground to this article from an explicitly categorical perspective. A good follow-up read for sharpening your picture of the key concepts we have discussed here.</p></li>
<li><p><a href="http://blog.sumtypeofway.com/an-introduction-to-recursion-schemes/"><em>An Introduction to Recursion Schemes</em></a>, by Patrick Thompson, is the first in a series of three articles that present some common recursion schemes at a gentle pace. You will note that examples involving syntax trees and simplifying expressions are a running theme across these articles. That is in line with what we said about the word “algebra” at the end of the section about <code>cata</code>.</p></li>
<li><p><a href="https://jtobin.io/practical-recursion-schemes"><em>Practical Recursion Schemes</em></a>, by Jared Tobin, offers a faster-paced demonstration of basic recursion schemes. Unlike the other articles in this list, it explores the machinery of the <em>recursion-schemes</em> library that we have dealt with here.</p></li>
<li><p><a href="http://maartenfokkinga.github.io/utwente/#detail_0000003415">*Functional Programming With Bananas, Lenses, Envelopes and Barbed Wire</a>, by Erik Meijer, Maarten Fokkinga and Ross Paterson, is a classic paper about recursion schemes, the one which popularised concepts such as catamorphism and anamorphism. If you plan to go through it, you may find <a href="http://blog.ezyang.com/2010/05/bananas-lenses-envelopes-and-barbed-wire-a-translation-guide/">this key to its notation</a> by Edward Z. Yang useful.</p></li>
</ul>
<h2 id="appendix-leancata">Appendix: leanCata</h2>
<p>This is the derivation mentioned in the middle of the section about <code>Fix</code>. We begin from our specification for <code>leanCata</code>:</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>cata f <span class="ot">=</span> leanCata f <span class="op">.</span> omniProject</span></code></pre></div>
<p>Take the left-hand side and substitute the definition of <code>cata</code>:</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>f <span class="op">.</span> <span class="fu">fmap</span> (cata f) <span class="op">.</span> project</span></code></pre></div>
<p>Substitute the right-hand side of the <code>leanCata</code> specification:</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>f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f <span class="op">.</span> omniProject) <span class="op">.</span> project</span></code></pre></div>
<p>By the second functor law:</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>f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f) <span class="op">.</span> <span class="fu">fmap</span> omniProject <span class="op">.</span> project</span></code></pre></div>
<p><code>unfix . Fix = id</code>, so we can slip it in like this:</p>
<div class="sourceCode" id="cb49"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb49-1"><a href="#cb49-1" aria-hidden="true" tabindex="-1"></a>f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f) <span class="op">.</span> unfix <span class="op">.</span> <span class="dt">Fix</span> <span class="op">.</span> <span class="fu">fmap</span> omniProject <span class="op">.</span> project</span></code></pre></div>
<p>Substituting the definition of <code>omniProject</code>:</p>
<div class="sourceCode" id="cb50"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb50-1"><a href="#cb50-1" aria-hidden="true" tabindex="-1"></a>f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f) <span class="op">.</span> unfix <span class="op">.</span> omniProject</span></code></pre></div>
<p>Substituting this back into the specification:</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>f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f) <span class="op">.</span> unfix <span class="op">.</span> omniProject <span class="ot">=</span> leanCata f <span class="op">.</span> omniProject</span></code></pre></div>
<p>Assuming a sensible <code>Recursive</code> and <code>Base</code> instances for <code>t</code>, <code>t</code> and <code>Fix (Base t)</code> should be isomorphic (that is, losslessly interconvertible) types, with <code>omniProject</code> performing one of the two relevant conversions. As a consequence, <code>omniProject</code> is surjective (that is, it is possible to obtain every <code>Fix (Base t)</code> value through it). That being so, we can “cancel out” the <code>omniProject</code>s at the right end of both sides of the equation above. The definition of <code>leanCata</code> follows immediately.</p>
<div class="sourceCode" id="cb52"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb52-1"><a href="#cb52-1" aria-hidden="true" tabindex="-1"></a>f <span class="op">.</span> <span class="fu">fmap</span> (leanCata f) <span class="op">.</span> unfix <span class="ot">=</span> leanCata f</span></code></pre></div>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>By the way, it is worth emphasising that the <code>Foldable</code> class from <em>base</em> is not the abstraction we are looking for. One way of seeing why is placing the signature of <code>foldBTree</code> side by side with the one of <code>Foldable.foldr</code>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>In what follows, I will use the <code>LambdaCase</code> extension liberally, so that I have fewer boring variable names to make up. If you haven’t seen it yet, all you need to know is that…</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">case</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>    [] <span class="ot">-&gt;</span> foo</span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    x<span class="op">:</span>xs <span class="ot">-&gt;</span> bar</span></code></pre></div>
<p>… is the same as:</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>\list <span class="ot">-&gt;</span> <span class="kw">case</span> list <span class="kw">of</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>    [] <span class="ot">-&gt;</span> foo</span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    x<span class="op">:</span>xs <span class="ot">-&gt;</span> bar</span></code></pre></div>
<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></li>
<li id="fn3" role="doc-endnote"><p>While that is clear to the naked eye, it can be shown more rigorously by applying the second functor law, that is:</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="fu">fmap</span> (g <span class="op">.</span> f) <span class="ot">=</span> <span class="fu">fmap</span> g <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></li>
<li id="fn4" role="doc-endnote"><p>This is in some ways similar to how <code>(&gt;&gt;= f) = join . fmap f</code> can be read as a factoring of <code>(&gt;&gt;=)</code> into a preliminary step (<code>fmap f</code>) followed by the quintessential monadic operation (<code>join</code>).<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>The name <code>Fix</code> comes from “fixed point”, the mathematical term used to describe a value which is left unchanged by some function. In this case, if we have an infinite nesting of the <code>f</code> type constructor, it doesn’t make any difference if we apply <code>f</code> to it one more time.<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn6" role="doc-endnote"><p>As suggested by Jared Tobin’s <em>Practical Recursion Schemes</em> article, which is in the further reading list at the end of this post.<a href="#fnref6" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn7" role="doc-endnote"><p>The names in said texts tend to be different, though. Common picks include <code>μ</code> for the <code>Fix</code> type constructor, <code>In</code> for the <code>Fix</code> value constructor, <code>out</code> for <code>unfix</code>, and <code>⦇f⦈</code> for <code>leanCata f</code> (using the famed banana brackets).<a href="#fnref7" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>


<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/12">Comment on GitHub</a>

    
      
        (see <a href="posts/whats-in-a-fold.html#comment-nav">the full post</a> for a reddit link)
      
    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2017-03-10T06:00:00Z</pubDate>
    <guid>https://duplode.github.io/posts/whats-in-a-fold.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Casual Hacking With stack, Reloaded</title>
    <link>https://duplode.github.io/posts/casual-hacking-with-stack-reloaded.html</link>
    <description><![CDATA[<p>It has been quite a while since I <a href="../posts/casual-hacking-with-stack.html">wrote</a> about how to use stack for casual play outside of the context of a conventional Haskell project. In the meantime, stack has gained a feature called the <em>global project</em> which in many cases makes it possible to do quick experiments with essentially no setup, while still taking advantage of the infrastructure provided through stack.</p>
<div>

</div>
<!--more-->
<p>The global project consists of a <code>stack.yaml</code> file and an associated <code>.stack-work</code> directory, which are kept in <code>~/.stack/global-project</code> and are used by stack whenever there is no other <code>stack.yaml</code> lying around. The <code>stack.yaml</code> of the global project specifies a resolver, just like any other <code>stack.yaml</code>. If said resolver is a snapshot you use elsewhere, you get access to all packages you have installed from that snapshot with zero configuration.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> pwd</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">/home/duplode</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> ls <span class="at">-lrt</span> <span class="kw">|</span> <span class="fu">grep</span> stack.yaml</span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> stack ghci</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a><span class="ex">Configuring</span> GHCi with the following packages: </span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi,</span> version 8.0.1: http://www.haskell.org/ghc/  :<span class="pp">?</span> for help</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /home/duplode/.ghci</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /tmp/ghci22741/ghci-script</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> import Control.Lens</span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> <span class="er">(</span><span class="ex">1,2</span><span class="kw">)</span> <span class="ex">^.</span> _1</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a><span class="ex">1</span></span></code></pre></div>
<p>By the way, this also holds for the stack-powered <a href="http://commercialhaskell.github.io/intero/">Intero</a> Emacs mode, which makes it possible to simply open a new <code>*.hs</code> file anywhere and immediately start hacking away.</p>
<p>What about packages you didn’t install beforehand? They are no problem, thanks to the <code>--package</code> option of <code>stack ghci</code>, which allows installing snapshot packages at a whim.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> stack ghci <span class="at">--package</span> fmlist</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ex">fmlist-0.9:</span> download</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ex">fmlist-0.9:</span> configure</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="ex">fmlist-0.9:</span> build</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a><span class="ex">fmlist-0.9:</span> copy/register</span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a><span class="ex">Configuring</span> GHCi with the following packages: </span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi,</span> version 8.0.1: http://www.haskell.org/ghc/  :<span class="pp">?</span> for help</span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /home/duplode/.ghci</span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /tmp/ghci22828/ghci-script</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> import qualified Data.FMList as FM</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> FM.foldMapA <span class="er">(</span><span class="ex">\x</span> <span class="at">-</span><span class="op">&gt;</span> show <span class="op">&lt;</span>$<span class="op">&gt;</span> [0..x]<span class="kw">)</span> <span class="ex">[0..3]</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a><span class="ex">[</span><span class="st">&quot;0000&quot;</span><span class="ex">,</span><span class="st">&quot;0001&quot;</span><span class="ex">,</span><span class="st">&quot;0002&quot;</span><span class="ex">,</span><span class="st">&quot;0003&quot;</span><span class="ex">,</span><span class="st">&quot;0010&quot;</span><span class="ex">,</span><span class="st">&quot;0011&quot;</span><span class="ex">,</span><span class="st">&quot;0012&quot;</span><span class="ex">,</span><span class="st">&quot;0013&quot;</span><span class="ex">,</span><span class="st">&quot;0020&quot;</span><span class="ex">,</span><span class="st">&quot;0021&quot;</span><span class="ex">,</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;0022&quot;</span><span class="ex">,</span><span class="st">&quot;0023&quot;</span><span class="ex">,</span><span class="st">&quot;0100&quot;</span><span class="ex">,</span><span class="st">&quot;0101&quot;</span><span class="ex">,</span><span class="st">&quot;0102&quot;</span><span class="ex">,</span><span class="st">&quot;0103&quot;</span><span class="ex">,</span><span class="st">&quot;0110&quot;</span><span class="ex">,</span><span class="st">&quot;0111&quot;</span><span class="ex">,</span><span class="st">&quot;0112&quot;</span><span class="ex">,</span><span class="st">&quot;0113&quot;</span><span class="ex">,</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a><span class="st">&quot;0120&quot;</span><span class="ex">,</span><span class="st">&quot;0121&quot;</span><span class="ex">,</span><span class="st">&quot;0122&quot;</span><span class="ex">,</span><span class="st">&quot;0123&quot;</span><span class="ex">]</span></span></code></pre></div>
<p>One caveat is that <code>--package</code> won’t install packages outside of the snapshot on its own, so you have to add them to the <code>extra-deps</code> field of the global project’s <code>stack.yaml</code> beforehand, just like you would do for an actual project. If you need several non-Stackage packages, you may find it convenient to create a throwaway project for the sole purpose of letting <code>stack solver</code> figure out the necessary <code>extra-deps</code> for you.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> mkdir throwaway</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> stack new throwaway <span class="at">--resolver</span> lts-7.14 <span class="co"># Same resolver of the global project.</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="co"># ...</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="ex">Writing</span> configuration to file: throwaway/stack.yaml</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="ex">All</span> done.</span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> cd throwaway</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> vi throwaway.cabal <span class="co"># Let's add reactive-banana to the dependencies.</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> stack solver</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a><span class="co"># ...</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a><span class="ex">Successfully</span> determined a build plan with 2 external dependencies.</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="ex">The</span> following changes will be made to stack.yaml:</span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a><span class="ex">*</span> Dependencies to be added</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    <span class="ex">extra-deps:</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a>    <span class="ex">-</span> pqueue-1.3.2</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>    <span class="ex">-</span> reactive-banana-1.1.0.1</span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a><span class="ex">To</span> automatically update stack.yaml, rerun with <span class="st">'--update-config'</span></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> vi ~/.stack/global-project/stack.yaml <span class="co"># Add the packages to the extra-deps.</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> cd ..</span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> rm <span class="at">-rf</span> throwaway/</span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> stack ghci <span class="at">--package</span> reactive-banana</span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a><span class="ex">pqueue-1.3.2:</span> configure</span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a><span class="ex">pqueue-1.3.2:</span> build</span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a><span class="ex">pqueue-1.3.2:</span> copy/register</span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a><span class="ex">reactive-banana-1.1.0.1:</span> configure</span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a><span class="ex">reactive-banana-1.1.0.1:</span> build</span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a><span class="ex">reactive-banana-1.1.0.1:</span> copy/register</span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a><span class="ex">Completed</span> 2 action<span class="er">(</span><span class="ex">s</span><span class="kw">)</span><span class="bu">.</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a><span class="ex">Configuring</span> GHCi with the following packages: </span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi,</span> version 8.0.1: http://www.haskell.org/ghc/  :<span class="pp">?</span> for help</span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /home/duplode/.ghci</span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /tmp/ghci23103/ghci-script</span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> import Reactive.Banana</span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> :t stepper</span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a><span class="ex">stepper</span> :: MonadMoment m =<span class="op">&gt;</span> a <span class="at">-</span><span class="op">&gt;</span> Event a <span class="at">-</span><span class="op">&gt;</span> m <span class="er">(</span><span class="ex">Behavior</span> a<span class="kw">)</span></span></code></pre></div>
<p>Support for running <code>stack solver</code> directly with the global project <a href="https://github.com/commercialhaskell/stack/issues/2656">is on the horizon</a>.</p>
<p>There are also interesting possibilities if you need to compile your throwaway code. That might be useful, for instance, if you ever feel like testing a hypothesis with a <a href="http://www.serpentine.com/criterion/tutorial.html">criterion</a> benchmark). While there is a <code>stack ghc</code> command, if you don’t need GHC profiles then taking advantage of <code>--ghci-options</code> to enable <code>-fobject-code</code> for <code>stack ghci</code> can be a more pleasant alternative.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> stack ghci <span class="at">--ghci-options</span> <span class="st">&quot;-O2 -fobject-code&quot;</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a><span class="ex">Configuring</span> GHCi with the following packages: </span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi,</span> version 8.0.1: http://www.haskell.org/ghc/  :<span class="pp">?</span> for help</span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /home/duplode/.ghci</span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="ex">Loaded</span> GHCi configuration from /tmp/ghci23628/ghci-script</span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> :l Foo.hs </span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="ex">[1</span> of 1] Compiling Foo              <span class="er">(</span> <span class="ex">Foo.hs,</span> /home/duplode/.stack/global-project/.stack-work/odir/Foo.o <span class="kw">)</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="ex">Ok,</span> modules loaded: Foo <span class="er">(</span><span class="ex">/home/duplode/.stack/global-project/.stack-work/odir/Foo.o</span><span class="kw">)</span><span class="bu">.</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="ex">GHCi</span><span class="op">&gt;</span> :main</span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="ex">A</span> random number for you: 2045528912275320075</span></code></pre></div>
<p>A nice little thing about this approach is that the build artifacts are kept in the global project’s <code>.stack-work</code>, which means they won’t pollute whichever other directory you happen to be at. <code>-fobject-code</code> means you can’t write definitions directly on the GHCi prompt; however, that is not much of a nuisance, given that you are compiling the code anyway, and that the source file is just a <code>:!vim Foo.hs</code> away.</p>
<p>While in these notes I have focused on seat-of-the-pants experimentation, stack also provides tools for running Haskell code with minimal configuration in a more controlled manner. I specially recommend having a look at the <a href="https://docs.haskellstack.org/en/stable/GUIDE/#script-interpreter"><em>script interpreter</em> section of the stack User Guide</a>.</p>

<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/9">Comment on GitHub</a>

    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2017-02-26T10:00:00Z</pubDate>
    <guid>https://duplode.github.io/posts/casual-hacking-with-stack-reloaded.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Migrating a Project to stack</title>
    <link>https://duplode.github.io/posts/migrating-a-project-to-stack.html</link>
    <description><![CDATA[<p>This post consists of notes on how I converted one of my Haskell projects to stack. It provides a small illustration of how flexible stack can be in accomodating project organisation quirks on the way towards predictable builds.<!--more--> If you want to see the complete results, here are links to the <a href="https://bitbucket.org/duplode/stunts-cartography">Bitbucket repository</a> of Stunts Cartography, the example project I am using, and specifically to the <a href="https://bitbucket.org/duplode/stunts-cartography/src/3eb07c44f6e2eed19591f765b14fc5fbe2b8f946">source tree immediately after the migration</a>.</p>
<p>The first decision to make when migrating a project is which Stackage snapshot to pick. It had been a while since I last updated my project, and building it with the latest versions of all its dependencies would require a few adjustments. That being so, I chose to migrate to stack before any further patches. Since one of the main dependencies was <code>diagrams</code> 1.2, I went for <a href="https://www.stackage.org/lts-2.19"><code>lts-2.19</code></a>, the most recent LTS snapshot with that version of <code>diagrams</code> <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>.</p>
<pre><code>$ stack init --resolver lts-2.19</code></pre>
<p><code>stack init</code> creates a <code>stack.yaml</code> file based on an existing cabal file in the current directory. The <code>--resolver</code> option can be used to pick a specific snapshot.</p>
<p>One complicating factor in the conversion to stack was that two of the extra dependencies, <code>threepenny-gui-0.5.0.0</code> (one major version behind the current one) and <code>zip-conduit</code>, wouldn’t build with the LTS snapshot plus current Hackage without version bumps in their cabal files. Fortunately, stack deals very well with situations like this, in which minor changes to some dependency are needed. I simply forked the dependencies on GitHub, pushed the version bumps to my forks and referenced the commits in the <em>remote</em> GitHub repository in <code>stack.yaml</code>. A typical entry for a Git commit in the <code>packages</code> section looks like this:</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="kw">-</span><span class="at"> </span><span class="fu">location</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">git</span><span class="kw">:</span><span class="at"> https://github.com/duplode/zip-conduit</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">commit</span><span class="kw">:</span><span class="at"> 1eefc8bd91d5f38b760bce1fb8dd16d6e05a671d</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="at">  </span><span class="fu">extra-dep</span><span class="kw">:</span><span class="at"> </span><span class="ch">true</span></span></code></pre></div>
<p>Keeping customised dependencies in public remote repositories is an excellent solution. It enables users to build the package without further intervention without requiring developers to clumsily bundle the source tree of the dependencies with the project, or waiting for a pull request to be accepted upstream and reach Hackage.</p>
<p>With the two tricky extra dependencies being offloaded to Git repositories, the next step was using <code>stack solver</code> to figure out the rest of them:</p>
<pre><code>$ stack solver --modify-stack-yaml
This command is not guaranteed to give you a perfect build plan
It's possible that even with the changes generated below, you will still
need to do some manual tweaking
Asking cabal to calculate a build plan, please wait
extra-deps:
- parsec-permutation-0.1.2.0
- websockets-snap-0.9.2.0
Updated /home/duplode/Development/stunts/diagrams/stack.yaml</code></pre>
<p>Here is the final <code>stack.yaml</code>:</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="fu">flags</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">stunts-cartography</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">repldump2carto</span><span class="kw">:</span><span class="at"> </span><span class="ch">true</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="fu">packages</span><span class="kw">:</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="st">'.'</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="fu">location</span><span class="kw">:</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">git</span><span class="kw">:</span><span class="at"> https://github.com/duplode/zip-conduit</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">commit</span><span class="kw">:</span><span class="at"> 1eefc8bd91d5f38b760bce1fb8dd16d6e05a671d</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a><span class="at">  </span><span class="fu">extra-dep</span><span class="kw">:</span><span class="at"> </span><span class="ch">true</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="fu">location</span><span class="kw">:</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">git</span><span class="kw">:</span><span class="at"> https://github.com/duplode/threepenny-gui</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="at">    </span><span class="fu">commit</span><span class="kw">:</span><span class="at"> 2dd88e893f09e8e31378f542a9cd253cc009a2c5</span></span>
<span id="cb4-13"><a href="#cb4-13" aria-hidden="true" tabindex="-1"></a><span class="at">  </span><span class="fu">extra-dep</span><span class="kw">:</span><span class="at"> </span><span class="ch">true</span></span>
<span id="cb4-14"><a href="#cb4-14" aria-hidden="true" tabindex="-1"></a><span class="fu">extra-deps</span><span class="kw">:</span></span>
<span id="cb4-15"><a href="#cb4-15" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> parsec-permutation-0.1.2.0</span></span>
<span id="cb4-16"><a href="#cb4-16" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> websockets-snap-0.9.2.0</span></span>
<span id="cb4-17"><a href="#cb4-17" aria-hidden="true" tabindex="-1"></a><span class="fu">resolver</span><span class="kw">:</span><span class="at"> lts-2.19</span></span></code></pre></div>
<p><code>repldump2carto</code> is a flag defined in the cabal file. It is used to build a secondary executable. Beyond demonstrating how the <code>flags</code> section of <code>stack.yaml</code> works, I added it because <code>stack ghci</code> expects all possible build targets to have been built <a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>.</p>
<p>As I have GHC 7.10.1 from my Linux distribution and the LTS 2.19 snapshot is made for GHC 7.8.4, I needed <code>stack setup</code> as an additional step. That command locally installs (in <code>~/.stack</code>) the GHC version required by the chosen snapshot.</p>
<p>That pretty much concludes the migration. All that is left is demonstrating: <code>stack build</code> to compile the project…</p>
<pre><code>$ stack build
JuicyPixels-3.2.5.2: configure
Boolean-0.2.3: download
# etc. (Note how deps from Git are handled seamlessly.)
threepenny-gui-0.5.0.0: configure
threepenny-gui-0.5.0.0: build
threepenny-gui-0.5.0.0: install
zip-conduit-0.2.2.2: configure
zip-conduit-0.2.2.2: build
zip-conduit-0.2.2.2: install
# etc.
stunts-cartography-0.4.0.3: configure
stunts-cartography-0.4.0.3: build
stunts-cartography-0.4.0.3: install
Completed all 64 actions.</code></pre>
<p>… <code>stack ghci</code> to play with it in GHCi…</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">$</span> stack ghci</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Configuring</span> <span class="dt">GHCi</span> with the following packages<span class="op">:</span> stunts<span class="op">-</span>cartography</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span>, version <span class="fl">7.8</span><span class="op">.</span><span class="dv">4</span><span class="op">:</span> http<span class="op">://</span>www<span class="op">.</span>haskell<span class="op">.</span>org<span class="op">/</span>ghc<span class="op">/</span>  <span class="op">:?</span> for help</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a><span class="dt">Loading</span> package ghc<span class="op">-</span>prim <span class="op">...</span> linking <span class="op">...</span> done<span class="op">.</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a><span class="dt">Loading</span> package integer<span class="op">-</span>gmp <span class="op">...</span> linking <span class="op">...</span> done<span class="op">.</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a><span class="dt">Loading</span> package base <span class="op">...</span> linking <span class="op">...</span> done<span class="op">.</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- etc.</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Ok</span>, modules loaded<span class="op">:</span> <span class="dt">GameState</span>, <span class="dt">Annotation</span>, <span class="dt">Types.Diagrams</span>, <span class="dt">Pics</span>,</span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true" tabindex="-1"></a><span class="dt">Pics.MM</span>, <span class="dt">Annotation.Flipbook</span>, <span class="dt">Annotation.LapTrace</span>,</span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true" tabindex="-1"></a><span class="dt">Annotation.LapTrace.Vec</span>, <span class="dt">Annotation.LapTrace.Parser.Simple</span>,</span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true" tabindex="-1"></a><span class="dt">Annotation.Parser</span>, <span class="dt">Types.CartoM</span>, <span class="dt">Parameters</span>, <span class="dt">Composition</span>, <span class="dt">Track</span>,</span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true" tabindex="-1"></a><span class="dt">Util.Misc</span>, <span class="dt">Pics.Palette</span>, <span class="dt">Output</span>, <span class="dt">Util.ByteString</span>, <span class="dt">Util.ZipConduit</span>,</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true" tabindex="-1"></a><span class="dt">Replay</span>, <span class="dt">Paths</span>, <span class="dt">Util.Reactive.Threepenny</span>, <span class="dt">Util.Threepenny.Alertify</span>,</span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true" tabindex="-1"></a><span class="dt">Widgets.BoundedInput</span><span class="op">.</span></span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true" tabindex="-1"></a><span class="op">*</span><span class="dt">GameState</span><span class="op">&gt;</span> <span class="op">:</span>l src<span class="op">/</span>Viewer.hs <span class="co">-- The Main module.</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true" tabindex="-1"></a><span class="co">-- etc.</span></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true" tabindex="-1"></a><span class="op">*</span><span class="dt">Main</span><span class="op">&gt;</span> <span class="op">:</span>main</span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true" tabindex="-1"></a><span class="dt">Welcome</span> to <span class="dt">Stunts</span> <span class="dt">Cartography</span><span class="op">.</span></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true" tabindex="-1"></a><span class="dt">Open</span> your web browser <span class="fu">and</span> navigate to localhost<span class="op">:</span><span class="dv">10000</span> to begin<span class="op">.</span></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="dt">Listening</span> on http<span class="op">://</span><span class="fl">127.0</span><span class="op">.</span><span class="fl">0.1</span><span class="op">:</span><span class="dv">10000</span><span class="op">/</span></span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true" tabindex="-1"></a>[<span class="dv">27</span><span class="op">/</span><span class="dt">Jul</span><span class="op">/</span><span class="dv">2015</span><span class="op">:</span><span class="dv">00</span><span class="op">:</span><span class="dv">55</span><span class="op">:</span><span class="dv">11</span> <span class="op">-</span><span class="dv">0300</span>] Server.httpServe<span class="op">:</span> <span class="dt">START</span>, binding to</span>
<span id="cb6-23"><a href="#cb6-23" aria-hidden="true" tabindex="-1"></a>[http<span class="op">://</span><span class="fl">127.0</span><span class="op">.</span><span class="fl">0.1</span><span class="op">:</span><span class="dv">10000</span><span class="op">/</span>]</span></code></pre></div>
<p>… and looking at the build output in the depths of <code>.stack-work</code>:</p>
<pre><code>$ .stack-work/dist/x86_64-linux/Cabal-1.18.1.5/build/sc-trk-viewer/sc-trk-viewer
Welcome to Stunts Cartography 0.4.0.3.
Open your web browser and navigate to localhost:10000 to begin.

Listening on http://127.0.0.1:10000/
[26/Jul/2015:20:02:54 -0300] Server.httpServe: START, binding to
[http://127.0.0.1:10000/]</code></pre>
<p>With the upcoming stack 0.2 it will be possible to use <code>stack build --copy-bins --local-bin-path &lt;path&gt;</code> to copy any executables built as part of the project to a path. If the <code>--local-bin-path</code> option is omitted, the default is <code>~/.local/bin</code>. (In fact, you can already copy executables to <code>~/.local/bin</code> with stack 0.1.2 through <code>stack install</code>. However, I don’t want to overemphasise that command, as <code>stack install</code> not being equivalent to <code>cabal install</code> can cause some confusion.)</p>
<p>Hopefully this report will give you an idea of what to expect when migrating your projects to stack. Some details may appear a little strange, given how familiar cabal-install workflows are, and some features are still being shaped. All in all, however, stack works very well already: it definitely makes setting up reliable builds easier. The <a href="https://github.com/commercialhaskell/stack">stack repository at GitHub</a>, and specially <a href="https://github.com/commercialhaskell/stack/wiki">the wiki therein</a>, offers lots of helpful information, in case you need further details and usage tips.</p>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>As a broader point, it just seems polite to, when possible, pick a LTS snapshot over than a nightly for a public project. It is more likely that those interested in building your project already have a specific LTS rather than an arbitrary nightly.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>That being so, a more natural arrangement would be treating <code>repldump2carto</code> as a full-blown subproject by giving it its own cabal file and adding it to the <code>packages</code> section. I would then be able to load only the main project in GHCi with <code>stack ghci stunts-cartography</code>.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>

<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/7">Comment on GitHub</a>

    
      
        (see <a href="posts/migrating-a-project-to-stack.html#comment-nav">the full post</a> for a reddit link)
      
    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2015-07-27T03:00:00-03:00</pubDate>
    <guid>https://duplode.github.io/posts/migrating-a-project-to-stack.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Casual Hacking With stack</title>
    <link>https://duplode.github.io/posts/casual-hacking-with-stack.html</link>
    <description><![CDATA[<p><em>2017 update: This post was written shortly after the initial release of stack. While the workflow suggested here remains potentially useful, later versions of stack offer more immediate support for working outside the boundaries of a conventional Haskell project. For more on that, see <a href="../posts/casual-hacking-with-stack-reloaded.html">Casual Hacking With stack, Reloaded</a>.</em></p>
<p>Sandboxes are exceptionally helpful not just for working in long-term Haskell projects, but also for casual experiments. While playing around, we tend to install all sorts of packages in a carefree way, which increases a lot the risk of entering cabal hell. While vanilla cabal-install sandboxes prevent such a disaster, using them systematically for experiments mean that, unless you are meticulous, you will end up either with dozens of .hs files in a single sandbox or with dozens of copies of the libraries strewn across your home directory. And no one likes to be meticulous while playing around. In that context, stack, the recently released alternative to cabal-install, can prevent trouble with installing packages in a way more manageable than through ad-hoc sandboxes. In this post, I will suggest a few ways of using stack that may be convenient for experiments. I have been using stack for only a few days, therefore suggestions are most welcome!</p>
<div>

</div>
<!--more-->
<p>I won’t dwell on the motivation and philosophy behind stack <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a>. Suffice it to say that, at least in the less exotic workflows, there is a centralised package database somewhere in <code>~/.stack</code> with packages pulled from a <a href="https://www.stackage.org/">Stackage</a> snapshot (and therefore known to be compatible with each other), which is supplemented by a per-project database (that is, just like cabal sandboxes) for packages not in Stackage (from Hackage or anywhere else). As that sounds like a great way to avoid headaches, we will stick to this arrangement, with only minor adjustments.</p>
<p>Once you have installed stack <a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>, you can create a new environment for experiments with <code>stack new</code>:</p>
<pre><code>$ mkdir -p Development/haskell/playground
$ cd Development/haskell/playground
$ stack new --prefer-nightly</code></pre>
<p>The <code>--prefer-nightly</code> option makes stack use a nightly snapshot of Stackage, as opposed to a long term support one. As we are just playing around, it makes sense to pick as recent as possible packages from the nightly instead of the LTS. (Moreover, I use Arch Linux, which already has GHC 7.10 and <code>base</code> 4.8, while the current LTS snapshot assumes <code>base</code> 4.7.) If this is the first time you use stack, it will pick the latest nightly; otherwise it will default to whatever nightly you already have in <code>~/.stack</code>.</p>
<p><code>stack new</code> creates a neat default project structure for you <a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a>:</p>
<pre><code>$ ls -R
.:
app  LICENSE  new-template.cabal  Setup.hs  src  stack.yaml  test

./app:
Main.hs

./src:
Lib.hs

./test:
Spec.hs</code></pre>
<p>Of particular interest is the <code>stack.yaml</code> file, which holds the settings for the local stack environment. We will talk more about it soon.</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="fu">flags</span><span class="kw">:</span><span class="at"> </span><span class="kw">{}</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="fu">packages</span><span class="kw">:</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="st">'.'</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a><span class="fu">extra-deps</span><span class="kw">:</span><span class="at"> </span><span class="kw">[]</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="fu">resolver</span><span class="kw">:</span><span class="at"> nightly-2015-07-19</span></span></code></pre></div>
<p>As for the default <code>new-template.cabal</code> file, you can use its <code>build-depends</code> section to keep track of what you are installing. That will make <code>stack build</code> (the command which builds the current project without installing it) to download and install any dependencies you add to the cabal file automatically. Besides that, having the installed packages noted down may prove useful in case you need to reproduce your configuration elsewhere <a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a>. If your experiments become a real project, you can clean up the <code>build-depends</code> without losing track of the packages you installed for testing purposes by moving their entries to a second cabal file, kept in a subdirectory:</p>
<pre><code>$ mkdir xp
$ cp new-template.cabal xp/xp.cabal
$ cp LICENSE xp # Too lazy to delete the lines from the cabal file.
$ cd xp
$ vi Dummy.hs # module Dummy where &lt;END OF FILE&gt;
$ vi xp.cabal # Adjust accordingly, and list your extra deps.</code></pre>
<p>You also need to tell stack about this fake subproject. All it takes is adding an entry for the subdirectory in <code>stack.yaml</code>:</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="fu">packages</span><span class="kw">:</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="st">'.'</span><span class="co"> # The default entry.</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="st">'xp'</span></span></code></pre></div>
<p>With the initial setup done, we use <code>stack build</code> to compile the projects:</p>
<pre><code>$ stack build
new-template-0.1.0.0: configure
new-template-0.1.0.0: build
fmlist-0.9: download
fmlist-0.9: configure
fmlist-0.9: build
new-template-0.1.0.0: install
fmlist-0.9: install
xp-0.1.0.0: configure
xp-0.1.0.0: build
xp-0.1.0.0: install
Completed all 3 actions.</code></pre>
<p>In this test run, I added <code>fmlist</code> as a dependency of the fake package <code>xp</code>, and so it was automatically installed by stack. The output of <code>stack build</code> goes to a <code>.stack-work</code> subdirectory.</p>
<p>With the packages built, we can use GHCi in the stack environment with <code>stack ghci</code>. It loads the library source files of the current project by default:</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">$</span> stack ghci</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Configuring</span> <span class="dt">GHCi</span> with the following packages<span class="op">:</span> new<span class="op">-</span>template, xp</span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span>, version <span class="fl">7.10</span><span class="op">.</span><span class="dv">1</span><span class="op">:</span> http<span class="op">://</span>www<span class="op">.</span>haskell<span class="op">.</span>org<span class="op">/</span>ghc<span class="op">/</span>  <span class="op">:?</span> for help</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span> <span class="kw">of</span> <span class="dv">2</span>] <span class="dt">Compiling</span> <span class="dt">Lib</span>              (</span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a><span class="op">/</span>home<span class="op">/</span>duplode<span class="op">/</span><span class="dt">Development</span><span class="op">/</span>haskell<span class="op">/</span>playground<span class="op">/</span>src<span class="op">/</span>Lib.hs, interpreted )</span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span> <span class="kw">of</span> <span class="dv">2</span>] <span class="dt">Compiling</span> <span class="dt">Dummy</span>            (</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a><span class="op">/</span>home<span class="op">/</span>duplode<span class="op">/</span><span class="dt">Development</span><span class="op">/</span>haskell<span class="op">/</span>playground<span class="op">/</span>xp<span class="op">/</span>Dummy.hs, interpreted )</span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Ok</span>, modules loaded<span class="op">:</span> <span class="dt">Dummy</span>, <span class="dt">Lib</span><span class="op">.</span></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true" tabindex="-1"></a><span class="op">*</span><span class="dt">Lib</span><span class="op">&gt;</span> <span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.FMList</span> <span class="kw">as</span> <span class="dt">F</span> <span class="co">-- Which we have just installed.</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true" tabindex="-1"></a><span class="op">*</span><span class="dt">Lib</span> <span class="dt">F</span><span class="op">&gt;</span> <span class="co">-- We can also load executables specified in the cabal file.</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true" tabindex="-1"></a><span class="op">*</span><span class="dt">Lib</span> <span class="dt">F</span><span class="op">&gt;</span> <span class="op">:</span>l <span class="dt">Main</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true" tabindex="-1"></a>[<span class="dv">1</span> <span class="kw">of</span> <span class="dv">2</span>] <span class="dt">Compiling</span> <span class="dt">Lib</span>              (</span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true" tabindex="-1"></a><span class="op">/</span>home<span class="op">/</span>duplode<span class="op">/</span><span class="dt">Development</span><span class="op">/</span>haskell<span class="op">/</span>playground<span class="op">/</span>src<span class="op">/</span>Lib.hs, interpreted )</span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true" tabindex="-1"></a>[<span class="dv">2</span> <span class="kw">of</span> <span class="dv">2</span>] <span class="dt">Compiling</span> <span class="dt">Main</span>             (</span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true" tabindex="-1"></a><span class="op">/</span>home<span class="op">/</span>duplode<span class="op">/</span><span class="dt">Development</span><span class="op">/</span>haskell<span class="op">/</span>playground<span class="op">/</span>app<span class="op">/</span>Main.hs, interpreted )</span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true" tabindex="-1"></a><span class="dt">Ok</span>, modules loaded<span class="op">:</span> <span class="dt">Lib</span>, <span class="dt">Main</span><span class="op">.</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true" tabindex="-1"></a><span class="op">*</span><span class="dt">Main</span> <span class="dt">F</span><span class="op">&gt;</span></span></code></pre></div>
<p>Dependencies not in Stackage have to be specified in <code>stack.yaml</code> as well as in the cabal files, so that stack can manage them too. Alternative sources of packages include source trees in subdirectories of the project, Hackage and remote Git repositories <a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a>:</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="fu">flags</span><span class="kw">:</span><span class="at"> </span><span class="kw">{}</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="fu">packages</span><span class="kw">:</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="st">'.'</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="st">'xp'</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> </span><span class="fu">location</span><span class="kw">:</span><span class="at"> deps/acme-missiles-0.3</span><span class="co"> # Sources in a subdirectory.</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="at">  </span><span class="fu">extra-dep</span><span class="kw">:</span><span class="at"> </span><span class="ch">true</span><span class="co"> # Mark as dep, i.e. not part of the project proper.</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="fu">extra-deps</span><span class="kw">:</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> acme-safe-0.1.0.0</span><span class="co"> # From Hackage.</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="kw">-</span><span class="at"> acme-dont-1.1</span><span class="co"> # Also from Hackage, dependency of acme-safe.</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="fu">resolver</span><span class="kw">:</span><span class="at"> nightly-2015-07-19</span></span></code></pre></div>
<p><code>stack build</code> will then install the extra dependencies to <code>.stack-work/install</code>. You can use <code>stack solver</code> to chase the indirect dependencies introduced by them. For instance, this is its output after commenting the <code>acme-dont</code> line in the <code>stack.yaml</code> just above:</p>
<pre><code>$ stack solver --no-modify-stack-yaml
This command is not guaranteed to give you a perfect build plan
It's possible that even with the changes generated below, you will still
need to do some manual tweaking
Asking cabal to calculate a build plan, please wait
extra-deps:
- acme-dont-1.1</code></pre>
<p>To conclude this tour, once you get bored of the initial Stackage snapshot all it takes to switch it is changing the <code>resolver</code> field in <code>stack.yaml</code> (with nightlies, that amounts to changing the date at the end of the snapshot name). That will cause all dependencies to be downloaded and built from the chosen snapshot when <code>stack build</code> is next ran. As of now, the previous snapshot will remain in <code>~/.stack</code> unless you go there and delete it manually; however, a command for removing unused snapshots <a href="https://github.com/commercialhaskell/stack/issues/133">is in the plans</a>.</p>
<p>I have not tested the sketch of a workflow presented here extensively, yet what I have seen was enough to convince me stack can provide a pleasant experience for casual experiments as well as full-fledged projects. Happy hacking!</p>
<p><strong>Update:</strong> There is now a follow-up post about the other side of the coin, <a href="../posts/migrating-a-project-to-stack.html">Migrating a Project to stack</a>.</p>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>For that, see <a href="https://www.fpcomplete.com/blog/2015/06/why-is-stack-not-cabal">Why is stack not cabal?</a>, written by a member of its development team.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>For installation guidance, see the <a href="https://github.com/commercialhaskell/stack/wiki/Downloads">GitHub project wiki</a>. Installing stack is easy, and there are many ways to do it (I simply got it from Hackage with <code>cabal install stack</code>).<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p>To create an environment for an existing project, with its own structure and cabal file, you would use <code>stack init</code> instead.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p>In any case, you can also use <code>stack exec -- ghc-pkg list</code> to see all packages installed from the snapshot you are currently using. That, however, will be far messier than the <code>build-depends</code> list, as it will include indirect dependencies as well.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>For the latter, see <a href="https://github.com/commercialhaskell/stack/wiki/Nonstandard-project-initialization">the project wiki</a>.<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>

<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/6">Comment on GitHub</a>

    
      
        (see <a href="posts/casual-hacking-with-stack.html#comment-nav">the full post</a> for a reddit link)
      
    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2015-07-22T23:30:00-03:00</pubDate>
    <guid>https://duplode.github.io/posts/casual-hacking-with-stack.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Applicative Archery</title>
    <link>https://duplode.github.io/posts/applicative-archery.html</link>
    <description><![CDATA[<p>It is widely agreed that the laws of the <code>Applicative</code> class are not pretty to look at.</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">pure</span> <span class="fu">id</span> <span class="op">&lt;*&gt;</span> v <span class="ot">=</span> v                            <span class="co">-- identity</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">pure</span> f <span class="op">&lt;*&gt;</span> <span class="fu">pure</span> x <span class="ot">=</span> <span class="fu">pure</span> (f x)               <span class="co">-- homomorphism</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>u <span class="op">&lt;*&gt;</span> <span class="fu">pure</span> y <span class="ot">=</span> <span class="fu">pure</span> (<span class="op">$</span> y) <span class="op">&lt;*&gt;</span> u              <span class="co">-- interchange</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="fu">pure</span> (<span class="op">.</span>) <span class="op">&lt;*&gt;</span> u <span class="op">&lt;*&gt;</span> v <span class="op">&lt;*&gt;</span> w <span class="ot">=</span> u <span class="op">&lt;*&gt;</span> (v <span class="op">&lt;*&gt;</span> w) <span class="co">-- composition</span></span></code></pre></div>
<p>Monad laws, in comparison, not only look less odd to begin with but can also be stated in a much more elegant way in terms of Kleisli composition <code>(&lt;=&lt;)</code>. Shouldn’t there be an analogous nice presentation for <code>Applicative</code> as well? That became a static question in my mind while I was studying applicative functors many moons ago. After finding surprisingly little commentary on this issue, I decided to try figuring it out by myself. <!--more--> <a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<p>Let’s cast our eye over <code>Applicative</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="kw">class</span> <span class="dt">Functor</span> t <span class="ot">=&gt;</span> <span class="dt">Applicative</span> t <span class="kw">where</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    pure  ::</span> a <span class="ot">-&gt;</span> t a</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="ot">    (&lt;*&gt;) ::</span> t (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> t b</span></code></pre></div>
<p>If our inspiration for reformulating <code>Applicative</code> is Kleisli composition, the only sensible plan is to look for a category in which the <code>t (a -&gt; b)</code> functions-in-a-context from the type of <code>(&lt;*&gt;)</code> are the arrows, just like <code>a -&gt; t b</code> functions are arrows in a Kleisli category. Here is one way to state that plan in Haskell terms:</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">class</span> <span class="dt">Applicative</span> t <span class="ot">=&gt;</span> <span class="dt">Starry</span> t <span class="kw">where</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ot">    idA  ::</span> t (a <span class="ot">-&gt;</span> a)</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ot">    (.*) ::</span> t (b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> t (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> t (a <span class="ot">-&gt;</span> c)</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="kw">infixl</span> <span class="dv">4</span> <span class="op">.*</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="co">-- The Applicative constraint is wishful thinking:</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- When you wish upon a star...</span></span></code></pre></div>
<p>The laws of <code>Starry</code> are the category laws for the <code>t (a -&gt; b)</code> arrows:</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>idA <span class="op">.*</span> v <span class="ot">=</span> v                <span class="co">-- left identity</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">.*</span> idA <span class="ot">=</span> u                <span class="co">-- right identity</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>u <span class="op">.*</span> v <span class="op">.*</span> w <span class="ot">=</span> u <span class="op">.*</span> (v <span class="op">.*</span> w) <span class="co">-- associativity</span></span></code></pre></div>
<p>The question, then, is whether it is possible to reconstruct <code>Applicative</code> and its laws from <code>Starry</code>. The answer is a resounding yes! The proof is in <a href="../extras/applicative-archery-manuscript.pdf">this manuscript</a>, which I have not transcribed here as it is a little too long for a leisurely post like this one <a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a>. The argument is set in motion by establishing that <code>pure</code> is an arrow mapping of a functor from <strong>Hask</strong> to a <code>Starry</code> category, and that both <code>(&lt;*&gt;)</code> and <code>(.*)</code> are arrow mappings of functors in the opposite direction. That leads to several naturality properties of those functors, from which the <code>Applicative</code> laws can be obtained. Along the way, we also get definitions for the <code>Starry</code> methods in terms of the <code>Applicative</code> ones…</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>    idA <span class="ot">=</span> <span class="fu">pure</span> <span class="fu">id</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    u <span class="op">.*</span> v <span class="ot">=</span> <span class="fu">fmap</span> (<span class="op">.</span>) u <span class="op">&lt;*&gt;</span> v</span></code></pre></div>
<p>… and vice-versa:</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">pure</span> x <span class="ot">=</span> <span class="fu">fmap</span> (<span class="fu">const</span> x) idA</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>u <span class="op">&lt;*&gt;</span> v <span class="ot">=</span> <span class="fu">fmap</span> (<span class="op">$</span> ()) (u <span class="op">.*</span> <span class="fu">fmap</span> <span class="fu">const</span> v)</span></code></pre></div>
<p>Also interesting is how the property relating <code>fmap</code> and <code>(&lt;*&gt;)</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">fmap</span> f u <span class="ot">=</span> <span class="fu">pure</span> f <span class="op">&lt;*&gt;</span> u</span></code></pre></div>
<p>… now tells us that a <code>Functor</code> results from composing the <code>pure</code> functor with the <code>(&lt;*&gt;)</code> functor. That becomes more transparent if we write it point-free:</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="op">&lt;*&gt;</span>) <span class="op">.</span> <span class="fu">pure</span></span></code></pre></div>
<p>In order to ensure <code>Starry</code> is equivalent to <code>Applicative</code> we still need to prove the converse, that is, obtain the <code>Starry</code> laws from the <code>Applicative</code> laws plus the definitions of <code>idA</code> and <code>(.*)</code> just above. That is not difficult; all it takes is substituting the definitions in the <code>Starry</code> laws and:</p>
<ul>
<li><p>For left identity, noticing that <code>(id .) = id</code>.</p></li>
<li><p>For right identity, applying the interchange law and noticing that <code>($ id) . (.)</code> is <code>id</code> in a better disguise.</p></li>
<li><p>For associativity, using the laws to move all <code>(.)</code> to the left of the <code>(&lt;*&gt;)</code> and then verifying that the resulting messes of dots in both sides are equivalent.</p></li>
</ul>
<p>As a tiny example, here is the <code>Starry</code> instance of <code>Maybe</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">Starry</span> <span class="dt">Maybe</span> <span class="kw">where</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>    idA              <span class="ot">=</span> <span class="dt">Just</span> <span class="fu">id</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">Just</span> g <span class="op">.*</span> <span class="dt">Just</span> f <span class="ot">=</span> <span class="dt">Just</span> (g <span class="op">.</span> f)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>    _      <span class="op">.*</span> _      <span class="ot">=</span> <span class="dt">Nothing</span></span></code></pre></div>
<p>… and the verification of the laws for it:</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="co">-- Left identity:</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>idA <span class="op">.*</span> u <span class="ot">=</span> u</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> <span class="fu">id</span> <span class="op">.*</span> u <span class="ot">=</span> u</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="co">-- u = Nothing</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> <span class="fu">id</span> <span class="op">.*</span> <span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a><span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="co">-- u = Just f</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> <span class="fu">id</span> <span class="op">.*</span> <span class="dt">Just</span> f <span class="ot">=</span> <span class="dt">Just</span> f</span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> (<span class="fu">id</span> <span class="op">.</span> f) <span class="ot">=</span> <span class="dt">Just</span> f</span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> f <span class="ot">=</span> <span class="dt">Just</span> f</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="co">-- Right identity:</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>u <span class="op">.*</span> idA <span class="ot">=</span> u</span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true" tabindex="-1"></a>u <span class="op">.*</span> <span class="dt">Just</span> <span class="fu">id</span> <span class="ot">=</span> u</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true" tabindex="-1"></a><span class="co">-- u = Nothing</span></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true" tabindex="-1"></a><span class="dt">Nothing</span> <span class="op">.*</span> <span class="dt">Just</span> <span class="fu">id</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true" tabindex="-1"></a><span class="dt">Nothing</span> <span class="ot">=</span> <span class="dt">Nothing</span></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true" tabindex="-1"></a><span class="co">-- u = Just g</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> g <span class="op">.*</span> <span class="dt">Just</span> <span class="fu">id</span> <span class="ot">=</span> <span class="dt">Just</span> g</span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> (g <span class="op">.*</span> <span class="fu">id</span>) <span class="ot">=</span> <span class="dt">Just</span> g</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> g <span class="ot">=</span> <span class="dt">Just</span> g</span>
<span id="cb10-22"><a href="#cb10-22" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-23"><a href="#cb10-23" aria-hidden="true" tabindex="-1"></a><span class="co">-- Associativity:</span></span>
<span id="cb10-24"><a href="#cb10-24" aria-hidden="true" tabindex="-1"></a>u <span class="op">.*</span> v <span class="op">.*</span> w <span class="ot">=</span> u <span class="op">.*</span> (v <span class="op">.*</span> w)</span>
<span id="cb10-25"><a href="#cb10-25" aria-hidden="true" tabindex="-1"></a><span class="co">-- If any of u, v and w are Nothing, both sides will be Nothing.</span></span>
<span id="cb10-26"><a href="#cb10-26" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> h <span class="op">.*</span> <span class="dt">Just</span> g <span class="op">.*</span> <span class="dt">Just</span> f <span class="ot">=</span> <span class="dt">Just</span> h <span class="op">.*</span> (<span class="dt">Just</span> g <span class="op">.*</span> <span class="dt">Just</span> f)</span>
<span id="cb10-27"><a href="#cb10-27" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> (h <span class="op">.</span> g) <span class="op">.*</span> <span class="dt">Just</span> f <span class="ot">=</span> <span class="dt">Just</span> h <span class="op">.*</span> (<span class="dt">Just</span> (g <span class="op">.</span> f))</span>
<span id="cb10-28"><a href="#cb10-28" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> (h <span class="op">.</span> g <span class="op">.</span> f) <span class="ot">=</span> <span class="dt">Just</span> (h <span class="op">.</span> (g <span class="op">.</span> f))</span>
<span id="cb10-29"><a href="#cb10-29" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> (h <span class="op">.</span> g <span class="op">.</span> f) <span class="ot">=</span> <span class="dt">Just</span> (h <span class="op">.</span> g <span class="op">.</span> f)</span></code></pre></div>
<p>It works just as intended:</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="dt">GHCi</span><span class="op">&gt;</span> <span class="dt">Just</span> (<span class="dv">2</span><span class="op">*</span>) <span class="op">.*</span> <span class="dt">Just</span> (<span class="fu">subtract</span> <span class="dv">3</span>) <span class="op">.*</span> <span class="dt">Just</span> (<span class="op">*</span><span class="dv">4</span>) <span class="op">&lt;*&gt;</span> <span class="dt">Just</span> <span class="dv">5</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Just</span> <span class="dv">34</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="dt">Just</span> (<span class="dv">2</span><span class="op">*</span>) <span class="op">.*</span> <span class="dt">Nothing</span> <span class="op">.*</span> <span class="dt">Just</span> (<span class="op">*</span><span class="dv">4</span>) <span class="op">&lt;*&gt;</span> <span class="dt">Just</span> <span class="dv">5</span></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a><span class="dt">Nothing</span></span></code></pre></div>
<p>I do not think there will be many opportunities to use the <code>Starry</code> methods in practice. We are comfortable enough with applicative style, through which we see most <code>t (a -&gt; b)</code> arrows as intermediates generated on demand, rather than truly meaningful values. Furthermore, the <code>Starry</code> laws are not really easier to prove (though they are certainly easier to remember!). Still, it was an interesting exercise to do, and it eases my mind to know that there is a neat presentation of the <code>Applicative</code> laws that I can relate to.</p>
<p>This post is Literate Haskell, in case you wish to play with <code>Starry</code> in GHCi (here is <a href="https://raw.githubusercontent.com/duplode/duplode.github.io/sources/src/posts/applicative-archery.lhs">the raw .lhs file</a> ).</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">instance</span> <span class="dt">Starry</span> <span class="dt">Maybe</span> <span class="kw">where</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Starry</span> [] <span class="kw">where</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Starry</span> ((<span class="ot">-&gt;</span>) a) <span class="kw">where</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Starry</span> <span class="dt">IO</span> <span class="kw">where</span></span></code></pre></div>
<p>As for proper implementations in libraries, the closest I found was <a href="https://hackage.haskell.org/package/semigroupoids-5.0.0.2/docs/Data-Semigroupoid-Static.html"><code>Data.Semigroupoid.Static</code></a>, which lives in Edward Kmett’s <a href="https://hackage.haskell.org/package/semigroupoids-5.0.0.2"><code>semigroupoids</code></a> package. <em>“Static arrows”</em> is the actual technical term for the <code>t (a -&gt; b)</code> arrows. The module provides…</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">Static</span> f a b <span class="ot">=</span> <span class="dt">Static</span> {<span class="ot"> runStatic ::</span> f (a <span class="ot">-&gt;</span> b) }</span></code></pre></div>
<p>… which uses the definitions shown here for <code>idA</code> and <code>(.*)</code> as <code>id</code> and <code>(.)</code> of its <code>Category</code> instance.</p>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>There is a reasonably well-known alternative formulation of <code>Applicative</code>: the <code>Monoidal</code> class as featured in <a href="http://blog.ezyang.com/2012/08/applicative-functors">this post by Edward Z. Yang</a>. It is quite handy to work with when it comes to checking whether an instance follows the laws.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn2" role="doc-endnote"><p>Please excuse some oddities in the manuscript, such as off-kilter terminology and weird conventions (e.g. consistently naming arguments in applicative style as <code>w &lt;*&gt; v &lt;*&gt; u</code> rather than <code>u &lt;*&gt; v &lt;*&gt; w</code> in applicative style). The most baffling choice was using <code>id</code> rather than <code>()</code> as the throwaway argument to <code>const</code>. I guess I did that because <code>($ ())</code> looks bad in handwriting.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>

<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/5">Comment on GitHub</a>

    
      
        (see <a href="posts/applicative-archery.html#comment-nav">the full post</a> for a reddit link)
      
    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2015-07-06T17:00:00-03:00</pubDate>
    <guid>https://duplode.github.io/posts/applicative-archery.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>What Does fmap Preserve?</title>
    <link>https://duplode.github.io/posts/what-does-fmap-preserve.html</link>
    <description><![CDATA[
<p>A common way of introducing <code>fmap</code> is saying that it only changes the values in a container, and not its structure. Leaving behind the the functors-as-containers metaphor, we can convey the same idea by saying that <code>fmap</code> leaves the context of the values in a <code>Functor</code> unchanged. But what, exactly, is the “context” or “structure” being preserved? “It depends on the functor”, though correct, is not an entirely satisfactory answer. The functor laws, after all, are highly abstract, and make no mention of anything a programmer would be inclined to call “structure” (say, the skeleton of a list); and yet the preservation we alluded to follows from them. After struggling a bit with this question, I realised that the incompatibility is only apparent. This post shows how the tension can be resolved through the mediation of <em>parametricity</em> and <em>naturality</em>, two concepts from different domains that are intertwined in Haskell.</p>
<div>

</div>
<!--more-->
<h2 id="categorical-cautionary-comment">Categorical Cautionary Comment</h2>
<p>A correct, if rather cruel, answer to “Why does <code>fmap</code> preserve structure?” would be “By definition, you silly!” To see what would be meant by that, let’s have a look at the functor laws.</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">fmap</span> <span class="fu">id</span> <span class="ot">=</span> <span class="fu">id</span>                   <span class="co">-- 1st functor law</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> (g <span class="op">.</span> f) <span class="ot">=</span> <span class="fu">fmap</span> g <span class="op">.</span> <span class="fu">fmap</span> f <span class="co">-- 2nd functor law</span></span></code></pre></div>
<p><code>fmap</code> is a mapping of functions that takes identity to identity, and composed functions to the corresponding composed functions. Identity and composition make up the structure, in the mathematical sense, of a category. In category theory, a functor is a mapping between categories that preserves category structure. Therefore, the functor laws ensure that Haskell <code>Functor</code>s are indeed functors; more precisely, functors from <strong>Hask</strong> to <strong>Hask</strong>, <strong>Hask</strong> being the category with Haskell types as objects and Haskell functions as arrows.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a></p>
<p>That functors preserve category structure is evident. However, our question is not directly about “structure” in the mathematical sense, but with the looser acception it has in programmer parlance. In what follows, our goal will be clarifying this casual meaning.</p>
<h2 id="what-can-you-do-with-a-function">What Can You Do With a Function?</h2>
<p>As an intial, fuzzy characterisation, we can say that, given a functorial value, the <code>Functor</code> context is everything in it other than the wrapped values. Starting from that, a straightforward way of showing why <code>fmap</code> preserves context involves <em>parametric polymorphism</em>; more specifically, the preservation is ensured by the wild generality of the types in the signature of <code>fmap</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="fu">fmap</span><span class="ot"> ::</span> (<span class="dt">Functor</span> t) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> (t a <span class="ot">-&gt;</span> t b)</span></code></pre></div>
<p>We will look at <code>fmap</code> as a function of one argument which converts a plain <code>a -&gt; b</code> function into a function which operates on functorial values. The key fact is that there is very little we can do with the <code>a -&gt; b</code> function when defining <code>fmap</code>. Composition is not an option, as choosing a function other than <code>id</code> to compose it with would require knowledge about the <code>a</code> and <code>b</code> types. The only thing that can be done is applying the function to any <code>a</code> values we can retrieve from the <code>t a</code> functorial value. Since the context of a <code>t a</code> value, whatever it is, does not include the <code>a</code> values, it follows that changes to the context cannot depend on the <code>a -&gt; b</code> function. Given that <code>fmap</code> takes no other arguments, any changes in the context must happen for any <code>a -&gt; b</code> arguments uniformly. The first functor law, however, says that <code>fmap id = id</code>, and so there is one argument, <code>id</code>, which leads to no changes in the context. Therefore, <code>fmap</code> never changes the context.</p>
<p>The informal argument above can be made precise through a proper type theory treatment of parametricity. Philip Wadler’s <em><a href="http://homepages.inf.ed.ac.uk/wadler/topics/parametricity.html#free">Theorems for free!</a></em> is a well-known example of such work. However, a type theory approach, while entirely appropriate, would have us taking concrete Haksell types for granted and only incidentally concluding they are functors; in contrast, our problem begins with functors. For that reason, we will follow a different path and look at the issue from a primarily categorical point of view.</p>
<h2 id="what-is-a-context-after-all">What Is a Context, After All?</h2>
<p>In the spirit of category theory, we will now focus not on the types but on the functions between them. After all, given functional purity any interesting properties of a Haskell value can be verified with suitable functions. Let’s start with a few concrete examples of how the context of a <code>Functor</code> can be probed with functions.</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">length</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Int</span></span></code></pre></div>
<p>The length of a list is perhaps the most obvious example of a structural property. It depends only on the list skeleton, and not at all on the values in it. The type of <code>length</code>, with a fully polymorphic element type which is not mentioned by the result type, reflects such an independence. An obvious consequence is that <code>fmap</code>, which only affects the list elements, cannot change the length of a list. We can state that 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">length</span> xs <span class="ot">=</span> <span class="fu">length</span> (<span class="fu">fmap</span> f xs)</span></code></pre></div>
<p>Or, in a more categorical fashion:</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">length</span> <span class="ot">=</span> <span class="fu">length</span> <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>Our second example of a structure-probing function will be <code>reverse</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="fu">reverse</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [a]</span></code></pre></div>
<p>While the result value of <code>reverse</code> obviously depends on the list elements, <code>reverse</code> cannot actually modify the elements, given that the function is fully polymorphic on the element type. <code>fmap</code> applied to a list after reversing it will thus affect the same element values there were before the reversal; they will only have been rearranged. In other words, <code>fmap</code> <em>commutes</em> with <code>reverse</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">fmap</span> f <span class="op">.</span> <span class="fu">reverse</span> <span class="ot">=</span> <span class="fu">reverse</span> <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>Our final example will be <code>listToMaybe</code> from <code>Data.Maybe</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">listToMaybe ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> a</span></code></pre></div>
<p>Operationally, <code>listToMaybe</code> is a safe version of <code>head</code>, which returns <code>Nothing</code> when given an empty list. Again, the function is fully polymorphic in the element type, and so the value of the first element cannot be affected by it. The scenario is very similar to what we have seen for <code>reverse</code>, and an analogous property holds, with the only difference being that <code>fmap</code> is instantiated at a different <code>Functor</code> at each side of the equation:</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="co">-- Maybe-fmap on the left, []-fmap on the right.</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> f <span class="op">.</span> listToMaybe <span class="ot">=</span> listToMaybe <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>Earlier we said that the <code>Functor</code> context consists of everything but the wrapped values. Our examples illustrate how parametric polymorphism makes it possible to keep that general idea while putting functions rather than values under the spotlight. The context is all that can be probed with functions fully polymorphic on the type parameter of the <code>Functor</code>; or, taking the abstraction further, the context <em>is</em> the collection of functions fully polymorphic on the type parameter of the <code>Functor</code>. We now have done away with the fuzziness of our preliminary, valure-centric definition. The next step is clarifying how that definition relates to <code>fmap</code>.</p>
<h2 id="your-freedom-comes-naturally">Your Freedom Comes Naturally</h2>
<p>By identifying the <code>Functor</code> context with polymorphic functions, we can also state the context-preserving trait of <code>fmap</code> through commutativity equations like those shown in the above examples. For an arbitrary context-probing function <code>r</code>, the equation 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="co">-- f is arbitrary, and so are the involved functors.</span></span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> f <span class="op">.</span> r <span class="ot">=</span> r <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>The equations for <code>reverse</code> and <code>listToMaybe</code> clearly have that shape. <code>length</code> does not seem to fit at first sight, but that can be easily solved by lifting it to a constant functor such as the one provided by <code>Control.Applicative</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">lengthC ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Const</span> <span class="dt">Int</span> a</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>lengthC <span class="ot">=</span> <span class="dt">Const</span> <span class="op">.</span> <span class="fu">length</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a><span class="co">-- length = getConst . lengthC</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="co">-- For constant functors, fmap f = id regardless of f.</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> f <span class="op">.</span> lengthC <span class="ot">=</span> lengthC <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>A similar trick can be done with the <code>Identity</code> functor to make functions in which the type parameter of the <code>Functor</code> appears bare, such as <code>Just :: a -&gt; Maybe a</code>, fit our scheme.</p>
<p>It turns out that there is a category theory concept that captures the commutativity property we are interested in. A <em>natural transformation</em> is a translation between functors which preserves arrows being mapped through them. For Haskell <code>Functor</code>s, that amounts to preserving functions being mapped via <code>fmap</code>. We can display the relation through a diagram:</p>
<figure>
<img src="../images/posts/what-does-fmap-preserve/naturality-diagram.png" alt="Naturality for Haskell Functors. Example instantation: T = []; U = Maybe; r = listToMaybe." /><figcaption aria-hidden="true"><em>Naturality for Haskell <code>Functor</code>s. Example instantation: <code>T = []; U = Maybe; r = listToMaybe</code>.</em></figcaption>
</figure>
<p>The naturality condition matches our commuativity property. Indeed, <em>polymorphic functions are natural transformations between Haskell <code>Functors</code></em>. The proof of this appealing result is not trivial, and requires some theoretical work, just like in the case of the closely related results about parametricity we alluded to earlier. In any case, all it takes to go from “natural transformations preserve <code>fmap</code>” to “<code>fmap</code> preserves natural transformations” is tilting our heads while looking at the diagram above!</p>
<p>Given how we identified <code>Functor</code> contexts, polymorphic functions and natural transformations, we can finally give a precise answer to our question. The context consists of natural transformations between functors, and therefore <code>fmap</code> preserves it.</p>
<h2 id="structures-and-structures">Structures and Structures</h2>
<p>Earlier on, we have said that we would not be directly concerned with structure in the sense mathematicians use the word, but only with the fuzzy Haskell concept that sometimes goes by the same name. To wrap things up, we will now illustrate the fact that both acceptions are not worlds apart. Let’s have another look at the second functor law, which states that <code>fmap</code> preserves composition:</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">fmap</span> (g <span class="op">.</span> f) <span class="ot">=</span> <span class="fu">fmap</span> g <span class="op">.</span> <span class="fu">fmap</span> f</span></code></pre></div>
<p>Structure, in the mathematical sense, refers to some collection of interesting operations and distinguished elements. In this example, the relevant operation is function composition, which is part of the structure of the <strong>Hask</strong> category. Besides that, however, we are now able to note the uncanny resemblance between the shapes of the law, which says that it does not matter whether we compose <code>f</code> and <code>g</code> before applying <code>fmap</code>, and of the commutativity properties we used to characterise functorial contexts. The upshot is that by identifying context and structure of a <code>Functor</code> with polymorphic functions, we retain much of the spirit of the mathematical usage of structure. The interesting operations, in our case, are the polymorphic functions with which the context is probed. Perhaps it even makes sense to keep talking of structure of a <code>Functor</code> even after dropping the container metaphor.</p>
<h2 id="fmap-preserves-fmap">fmap Preserves fmap</h2>
<p>Speaking of the second law, we will, just for kicks, use it to show how to turn things around and look at <code>fmap</code> as a natural transformation between <code>Functor</code>s. In order to do so, we have to recall that <code>(.)</code> is <code>fmap</code> for the function functor:</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">-- First, we rewrite the second law in a more suggestive form:</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> (g <span class="op">.</span> f) <span class="ot">=</span> <span class="fu">fmap</span> g <span class="op">.</span> <span class="fu">fmap</span> f</span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> (((<span class="op">.</span>) g) f) <span class="ot">=</span> (<span class="op">.</span>) (<span class="fu">fmap</span> g) (<span class="fu">fmap</span> f)</span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> <span class="op">.</span> (<span class="op">.</span>) g <span class="ot">=</span> ((<span class="op">.</span>) <span class="op">.</span> <span class="fu">fmap</span>) g <span class="op">.</span> <span class="fu">fmap</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><span class="co">-- Next, some synonyms to indicate the Functors fmap leads to.</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="co">-- fmap from identity to t</span></span>
<span id="cb13-9"><a href="#cb13-9" aria-hidden="true" tabindex="-1"></a><span class="ot">fmap_t ::</span> (<span class="dt">Functor</span> t) <span class="ot">=&gt;</span> (<span class="ot">-&gt;</span>) a b <span class="ot">-&gt;</span> (<span class="ot">-&gt;</span>) (t a) (t b)</span>
<span id="cb13-10"><a href="#cb13-10" aria-hidden="true" tabindex="-1"></a>fmap_t <span class="ot">=</span> <span class="fu">fmap</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="co">-- fmap from identity to ((-&gt;) a)</span></span>
<span id="cb13-13"><a href="#cb13-13" aria-hidden="true" tabindex="-1"></a><span class="ot">fmap_fun ::</span> (b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> ((<span class="ot">-&gt;</span>) a b <span class="ot">-&gt;</span> (<span class="ot">-&gt;</span>) a c)</span>
<span id="cb13-14"><a href="#cb13-14" aria-hidden="true" tabindex="-1"></a>fmap_fun <span class="ot">=</span> (<span class="op">.</span>)</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="co">-- fmap from identity to the composite functor ((-&gt;) (t a)) . t</span></span>
<span id="cb13-17"><a href="#cb13-17" aria-hidden="true" tabindex="-1"></a><span class="ot">fmap_fun_t ::</span> (<span class="dt">Functor</span> t)</span>
<span id="cb13-18"><a href="#cb13-18" aria-hidden="true" tabindex="-1"></a>           <span class="ot">=&gt;</span> (b <span class="ot">-&gt;</span> c) <span class="ot">-&gt;</span> ((<span class="ot">-&gt;</span>) (t a) (t b) <span class="ot">-&gt;</span> (<span class="ot">-&gt;</span>) (t a) (t c))</span>
<span id="cb13-19"><a href="#cb13-19" aria-hidden="true" tabindex="-1"></a>fmap_fun_t <span class="ot">=</span> fmap_fun <span class="op">.</span> fmap_t</span>
<span id="cb13-20"><a href="#cb13-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb13-21"><a href="#cb13-21" aria-hidden="true" tabindex="-1"></a><span class="co">-- The second law then becomes:</span></span>
<span id="cb13-22"><a href="#cb13-22" aria-hidden="true" tabindex="-1"></a>fmap_t <span class="op">.</span> fmap_fun g <span class="ot">=</span> fmap_fun_t g <span class="op">.</span> fmap_t</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><span class="co">-- That, however, shows fmap_t is a natural transformation:</span></span>
<span id="cb13-25"><a href="#cb13-25" aria-hidden="true" tabindex="-1"></a><span class="fu">fmap</span> <span class="op">.</span> <span class="fu">fmap</span> g <span class="ot">=</span> <span class="fu">fmap</span> g <span class="op">.</span> <span class="fu">fmap</span></span></code></pre></div>
<p>By fixing <code>t</code> and <code>a</code> in the signature of <code>fmap_t</code> above, we get one functor on either side of the outer function arrow: <code>((-&gt;) a)</code> on the left and <code>((-&gt;) (t a)) . t</code> on the right. <code>fmap</code> is a natural transformation between these two functors.</p>
<h2 id="further-reading">Further Reading</h2>
<ul>
<li><p>In <em><a href="http://existentialtype.wordpress.com/2011/03/27/the-holy-trinity/">The Holy Trinity</a></em>, Robert Harper comments on the deep connection between logic, type theory and category theory that allows us to shift seamlessly between the categorical and the type theoretical perspectives, as we have done here.</p></li>
<li><p><em><a href="http://blog.sigfpe.com/2008/05/you-could-have-defined-natural.html">You Could Have Defined Natural Transformations</a></em> by Dan Piponi is a very clear introduction to natural transformations in a Haskell context.</p></li>
<li><p>We have already mentioned Philip Wadler’s <em><a href="http://homepages.inf.ed.ac.uk/wadler/topics/parametricity.html#free">Theorems for free!</a></em>, which is a reasonably accessible introduction to the <em>free theorems</em>. <em>Free theorems</em> are results about functions that, thanks to parametric polymorphism, can be deduced from the type of the function alone. Given suitable generalisations, free theorems and naturality conditions provide two parallel ways of reaching the same results about Haskell functions.</p></li>
<li><p><em><a href="http://www.janis-voigtlaender.eu/Voi09b.html">Free Theorems Involving Type Constructor Classes</a></em>, a functional pearl by Janis Voigtländer that illustrates how free theorem generation can be generalised to types parametric on type constructors and type classes.</p></li>
<li><p>For an explicitly categorical perspective on parametricity, a good place to start if you are willing to dig into theory is the section on parametricity in <em><a href="http://www.site.uottawa.ca/~phil/papers/">Some Aspects of Categories in Computer Science</a></em> by Philip J. Scott.</p></li>
</ul>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>A category theory primer would be too big a detour for this post. If the category theory concepts I just mentioned are new to you, I suggest the following gentle introductions for Haskellers, which have very different approaches: <a href="https://en.wikibooks.org/wiki/Haskell/Category_theory">Haskell Wikibook chapter on category theory</a>, and Gabriella Gonzalez’s posts <a href="http://www.haskellforall.com/2012/08/the-category-design-pattern.html">The category design pattern</a> and <a href="http://www.haskellforall.com/2012/09/the-functor-design-pattern.html">The functor design pattern</a>.<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>


<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/2">Comment on GitHub</a>

    
      
        (see <a href="posts/what-does-fmap-preserve.html#comment-nav">the full post</a> for a reddit link)
      
    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2014-06-02T06:00:00Z</pubDate>
    <guid>https://duplode.github.io/posts/what-does-fmap-preserve.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>
<item>
    <title>Lenses You Can Make at Home</title>
    <link>https://duplode.github.io/posts/lenses-you-can-make-at-home.html</link>
    <description><![CDATA[
<p>The most striking traits of the <code>lens</code> library are its astonishing breadth and generality. And yet, the whole edifice is built around van Laarhoven lenses, which are a simple and elegant concept. In this hands-on exposition, I will show how the <code>Lens</code> type can be understood without prerequisites other than a passing acquaintance with Haskell functors. Encouraging sound intuition in an accessible manner can go a long way towards making <code>lens</code> and lenses less intimidating.</p>
<div>

</div>
<!--more-->
<h2 id="humble-beginnings">Humble Beginnings</h2>
<p>Dramatis personæ:</p>
<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="kw">import</span> <span class="dt">Data.Functor.Identity</span> (<span class="dt">Identity</span>(..))</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Applicative</span> (<span class="dt">Const</span>(..))</span></code></pre></div>
<p>I will define a toy data type so that we have something concrete to play with, as well as a starting point for working out generalisations.</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">Foo</span> <span class="ot">=</span> <span class="dt">Foo</span> {<span class="ot"> bar ::</span> <span class="dt">Int</span> } <span class="kw">deriving</span> (<span class="dt">Show</span>)</span></code></pre></div>
<p>The record definition gets us a function for accessing the <code>bar</code> field.</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="dt">GHCi</span><span class="op">&gt;</span> <span class="op">:</span>t bar</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ot">bar ::</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span></code></pre></div>
<p>As for the setter, we have to define it ourselves, unless we feel like mucking around with record update syntax.</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">setBar ::</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Foo</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>setBar x y <span class="ot">=</span> x { bar <span class="ot">=</span> y }</span></code></pre></div>
<p>Armed with a proper getter and setter pair, we can easily flip the sign of the <code>bar</code> inside a <code>Foo</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="dt">GHCi</span><span class="op">&gt;</span> <span class="kw">let</span> x <span class="ot">=</span> <span class="dt">Foo</span> <span class="dv">3</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> setBar x (<span class="fu">negate</span> <span class="op">$</span> bar x)</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="dt">Foo</span> {bar <span class="ot">=</span> <span class="op">-</span><span class="dv">3</span>}</span></code></pre></div>
<p>We can make it even easier by defining a modifier function for <code>bar</code>.</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">modifyBar ::</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Foo</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>modifyBar k x <span class="ot">=</span> setBar x <span class="op">.</span> k <span class="op">.</span> bar <span class="op">$</span> x</span></code></pre></div>
<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="dt">GHCi</span><span class="op">&gt;</span> modifyBar <span class="fu">negate</span> x</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="dt">Foo</span> {bar <span class="ot">=</span> <span class="op">-</span><span class="dv">3</span>}</span></code></pre></div>
<p><code>setBar</code> can be recovered from <code>modifyBar</code> by using <code>const</code> to discard the original value and put the new one in its place.</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">const</span> y <span class="ot">=</span> \_ <span class="ot">-&gt;</span> y</span></code></pre></div>
<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">setBar' ::</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Foo</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>setBar' x y <span class="ot">=</span> modifyBar (<span class="fu">const</span> y) x</span></code></pre></div>
<p>If our data type had several fields, defining a modifier for each of them would amount to quite a lot of boilerplate. We could minimise it by, starting from our <code>modifyBar</code> definition, abstracting from the specific getter and setter for <code>bar</code>. Here, things begin to pick up steam. I will define a general <code>modify</code> function, which, given an appropriate getter-setter pair, can deal with any field of any data type.</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">modify ::</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> s</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>modify getter setter k x <span class="ot">=</span> setter x <span class="op">.</span> k <span class="op">.</span> getter <span class="op">$</span> x</span></code></pre></div>
<p>It is trivial to recover <code>modifyBar</code>; when we do so, <code>s</code> becomes <code>Foo</code> and <code>a</code> becomes <code>Int</code>.</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">modifyBar' ::</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Foo</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>modifyBar' <span class="ot">=</span> modify bar setBar</span></code></pre></div>
<h2 id="functors-galore">Functors Galore</h2>
<p>The next step of generalisation is the one leap of faith I will ask of you in the way towards lenses. I will introduce a variant of <code>modify</code> in which the modifying function, rather than being a plain <code>a -&gt; a</code> function, returns a functorial value. Defining it only takes an extra <code>fmap</code>.</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">modifyF ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s)</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>                     <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> f a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> f s</span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>modifyF getter setter k x <span class="ot">=</span> <span class="fu">fmap</span> (setter x) <span class="op">.</span> k <span class="op">.</span> getter <span class="op">$</span> x</span></code></pre></div>
<p>And here is its specialisation for <code>bar</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">modifyBarF ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> f <span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> f <span class="dt">Foo</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>modifyBarF <span class="ot">=</span> modifyF bar setBar</span></code></pre></div>
<p>Why on Earth we would want to do that? For one, it allows for some nifty tricks depending on the functor we choose. Let’s try it with lists. Specialising the <code>modifyF</code> type would give:</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">modifyL ::</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> [a]) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> [s]</span></code></pre></div>
<p>Providing the getter and the setter would result in a <code>(a -&gt; [a]) -&gt; s -&gt; [s]</code> function. Can you guess what it would do?</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="dt">GHCi</span><span class="op">&gt;</span> modifyBarF (\y <span class="ot">-&gt;</span> [<span class="dv">0</span><span class="op">..</span>y]) x</span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>[<span class="dt">Foo</span> {bar <span class="ot">=</span> <span class="dv">0</span>},<span class="dt">Foo</span> {bar <span class="ot">=</span> <span class="dv">1</span>},<span class="dt">Foo</span> {bar <span class="ot">=</span> <span class="dv">2</span>},<span class="dt">Foo</span> {bar <span class="ot">=</span> <span class="dv">3</span>}]</span></code></pre></div>
<p>As the types suggest, we get a function which modifies the field in multiple ways and collects the results.</p>
<p>I claimed that moving from <code>modify</code> to <code>modifyF</code> was a generalisation. Indeed, we can recover <code>modify</code> by bringing <code>Identity</code>, the dummy functor, into play.</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">Identity</span> a <span class="ot">=</span> <span class="dt">Identity</span> {<span class="ot"> runIdentity ::</span> 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">instance</span> <span class="dt">Functor</span> <span class="dt">Identity</span> <span class="kw">where</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> f (<span class="dt">Identity</span> x) <span class="ot">=</span> <span class="dt">Identity</span> (f x)</span></code></pre></div>
<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">modifyI ::</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Identity</span> a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Identity</span> s</span></code></pre></div>
<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="ot">modify' ::</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> s</span>
<span id="cb18-2"><a href="#cb18-2" aria-hidden="true" tabindex="-1"></a>modify' getter setter k <span class="ot">=</span></span>
<span id="cb18-3"><a href="#cb18-3" aria-hidden="true" tabindex="-1"></a>    runIdentity <span class="op">.</span> modifyF getter setter (<span class="dt">Identity</span> <span class="op">.</span> k)</span></code></pre></div>
<p>We wrap the field value with <code>Identity</code> value after applying <code>k</code> and unwrap the final result after applying the setter. Since <code>Identity</code> does nothing interesting to the wrapped values, the overall result boils down to our original <code>modify</code>. If you have found this definition confusing, I suggest that you, as an exercise, rewrite it in pointful style and substitute the definition of <code>modifyF</code>.</p>
<p>We managed to get <code>modify</code> back with little trouble, which is rather interesting. However, what is truly surprising is that we can reconstruct not only the modifier but also the getter! To pull that off, we will use <code>Const</code>, which is a very quaint functor.</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">Const</span> a b <span class="ot">=</span> <span class="dt">Const</span> {<span class="ot"> getConst ::</span> a }</span>
<span id="cb19-2"><a href="#cb19-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb19-3"><a href="#cb19-3" aria-hidden="true" tabindex="-1"></a><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">Const</span> a) <span class="kw">where</span></span>
<span id="cb19-4"><a href="#cb19-4" aria-hidden="true" tabindex="-1"></a>    <span class="fu">fmap</span> _ (<span class="dt">Const</span> y) <span class="ot">=</span> <span class="dt">Const</span> y</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">modifyC ::</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> <span class="dt">Const</span> r a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Const</span> r s</span></code></pre></div>
<p>If functors were really containers, <code>Const</code> would be an Acme product. A <code>Const a b</code> value does not contain anything of type <code>b</code>; what it does contain is an <code>a</code> value that we cannot even modify, given that <code>fmap f</code> is <code>id</code> regardless of what <code>f</code> is. As a consequence, if, given a field of type <code>a</code>, we pick <code>Const a</code> as the functor to use with <code>modifyF</code> and use the modifying function to wrap the field value with <code>Const</code>, then the value will not be affected by the setter, and we will be able to recover it later. That suffices for recovering the getter.</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">get ::</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> a</span>
<span id="cb21-2"><a href="#cb21-2" aria-hidden="true" tabindex="-1"></a>get getter setter <span class="ot">=</span> getConst <span class="op">.</span> modifyF getter setter <span class="dt">Const</span></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="ot">getBar ::</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb21-5"><a href="#cb21-5" aria-hidden="true" tabindex="-1"></a>getBar <span class="ot">=</span> get bar setBar</span></code></pre></div>
<h2 id="the-grand-unification">The Grand Unification</h2>
<p>Given a getter and a setter, <code>modifyF</code> gets us a corresponding functorial modifier. From it, by choosing the appropriate functors, we can recover the getter and a plain modifier; the latter, in turn, allows us to recover the setter. We can highlight the correspondence by redefining once more the recovered getters and modifiers, this time in terms of the functorial modifier.</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">modifyF ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s)</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 a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> f s)</span></code></pre></div>
<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">modify'' ::</span> ((a <span class="ot">-&gt;</span> <span class="dt">Identity</span> a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Identity</span> s) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> s</span>
<span id="cb23-2"><a href="#cb23-2" aria-hidden="true" tabindex="-1"></a>modify'' modifier k <span class="ot">=</span> runIdentity <span class="op">.</span> modifier (<span class="dt">Identity</span> <span class="op">.</span> k)</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">modifyBar'' ::</span> (<span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span>) <span class="ot">-&gt;</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Foo</span></span>
<span id="cb23-5"><a href="#cb23-5" aria-hidden="true" tabindex="-1"></a>modifyBar'' <span class="ot">=</span> modify'' modifyBarF</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="ot">set ::</span> ((a <span class="ot">-&gt;</span> <span class="dt">Identity</span> a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Identity</span> s) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s</span>
<span id="cb23-8"><a href="#cb23-8" aria-hidden="true" tabindex="-1"></a>set modifier x y <span class="ot">=</span> modify'' modifier (<span class="fu">const</span> y) x</span>
<span id="cb23-9"><a href="#cb23-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-10"><a href="#cb23-10" aria-hidden="true" tabindex="-1"></a><span class="ot">setBar'' ::</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Foo</span></span>
<span id="cb23-11"><a href="#cb23-11" aria-hidden="true" tabindex="-1"></a>setBar'' <span class="ot">=</span> set modifyBarF</span>
<span id="cb23-12"><a href="#cb23-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-13"><a href="#cb23-13" aria-hidden="true" tabindex="-1"></a><span class="ot">get' ::</span> ((a <span class="ot">-&gt;</span> <span class="dt">Const</span> a a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Const</span> a s) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a)</span>
<span id="cb23-14"><a href="#cb23-14" aria-hidden="true" tabindex="-1"></a>get' modifier <span class="ot">=</span> getConst <span class="op">.</span> modifier <span class="dt">Const</span></span>
<span id="cb23-15"><a href="#cb23-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb23-16"><a href="#cb23-16" aria-hidden="true" tabindex="-1"></a><span class="ot">getBar' ::</span> <span class="dt">Foo</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></span>
<span id="cb23-17"><a href="#cb23-17" aria-hidden="true" tabindex="-1"></a>getBar' <span class="ot">=</span> get' modifyBarF</span></code></pre></div>
<p>The bottom line is that given <code>modifyBarF</code> we can get by without <code>modifyBar</code>, <code>setBar</code> and <code>bar</code>, as <code>modify''</code>, <code>set</code> and <code>get'</code> allow us to reconstruct them whenever necessary. While our first version of <code>get</code> was, in effect, just a specialised <code>const</code> with a wacky implementation, <code>get'</code> is genuinely useful because it cuts the number of separate field manipulation functions we have to deal with by a third.</p>
<h2 id="expanding-horizons">Expanding Horizons</h2>
<p>Even after all of the work so far we can still generalise further! Let’s have a second look at <code>modifyF</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">modifyF ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> s)</span>
<span id="cb24-2"><a href="#cb24-2" aria-hidden="true" tabindex="-1"></a>                     <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> f a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> f s</span>
<span id="cb24-3"><a href="#cb24-3" aria-hidden="true" tabindex="-1"></a>modifyF getter setter k x <span class="ot">=</span> <span class="fu">fmap</span> (setter x) <span class="op">.</span> k <span class="op">.</span> getter <span class="op">$</span> x</span></code></pre></div>
<p>The type of <code>setter</code> is <code>(s -&gt; a -&gt; s)</code>; however, nothing in the implementation forces the first argument and the result to have the same type. Furthermore, with a different signature <code>k</code> could have a more general type, <code>(a -&gt; f b)</code>, as long as the type of <code>setter</code> was adjusted accordingly. We can thus give <code>modifyF</code> a more general type.</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">modifyGenF ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (s <span class="ot">-&gt;</span> a) <span class="ot">-&gt;</span> (s <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> t)</span>
<span id="cb25-2"><a href="#cb25-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> s <span class="ot">-&gt;</span> f t</span>
<span id="cb25-3"><a href="#cb25-3" aria-hidden="true" tabindex="-1"></a>modifyGenF getter setter k x <span class="ot">=</span> <span class="fu">fmap</span> (setter x) <span class="op">.</span> k <span class="op">.</span> getter <span class="op">$</span> x</span></code></pre></div>
<p>For the sake of completeness, here are the generalised recovery functions. <code>get</code> is not included because the generalisation does not affect it.</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">modifyGen ::</span> ((a <span class="ot">-&gt;</span> <span class="dt">Identity</span> b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Identity</span> t) <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> t</span>
<span id="cb26-2"><a href="#cb26-2" aria-hidden="true" tabindex="-1"></a>modifyGen modifier k <span class="ot">=</span> runIdentity <span class="op">.</span> modifier (<span class="dt">Identity</span> <span class="op">.</span> k)</span>
<span id="cb26-3"><a href="#cb26-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb26-4"><a href="#cb26-4" aria-hidden="true" tabindex="-1"></a><span class="ot">setGen ::</span> ((a <span class="ot">-&gt;</span> <span class="dt">Identity</span> b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Identity</span> t) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> t</span>
<span id="cb26-5"><a href="#cb26-5" aria-hidden="true" tabindex="-1"></a>setGen modifier x y <span class="ot">=</span> modifyGen modifier (<span class="fu">const</span> y) x</span></code></pre></div>
<p>By now, it is clear that our getters and setters need not be ways to manipulate fields in a record. In a broader sense, a getter is anything that produces a value from another; in other words, any function can be a getter. By the same token, any binary function can be a setter, as all that is required is that it combines one value with another producing a third; the initial and final values do not even need to have the same type.<a href="#fn1" class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> That is a long way from the toy data type we started with!</p>
<h2 id="the-reveal">The Reveal</h2>
<p>If we look at <code>modifyGenF</code> as a function of two arguments, its result type becomes:</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="dt">Functor</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> f t</span></code></pre></div>
<p>Now, let’s take a peek at <a href="http://hackage.haskell.org/package/lens-4.1.2/docs/Control-Lens-Lens.html#t:Lens">Control.Lens.Lens</a>:</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">type</span> <span class="dt">Lens</span> s t a b <span class="ot">=</span> <span class="kw">forall</span> f<span class="op">.</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> f t</span></code></pre></div>
<p>It is the same type! We have reached our destination.<a href="#fn2" class="footnote-ref" id="fnref2" role="doc-noteref"><sup>2</sup></a> A lens is what we might have called a generalised functorial modifier; furthermore, sans implementation details we have that:</p>
<ul>
<li>The <code>lens</code> function is <code>modifyGenF</code>;</li>
<li><code>modifyF</code> is <code>lens</code> specialised to produce simple lenses;<a href="#fn3" class="footnote-ref" id="fnref3" role="doc-noteref"><sup>3</sup></a></li>
<li><code>modifyBarF</code> is a lens with type <code>Lens Foo Foo Int Int</code>;</li>
<li><code>(^.)</code> is flipped <code>get'</code>;</li>
<li><code>set</code> is <code>setGen</code>;</li>
<li><code>over</code> is <code>modifyGen</code> further generalised.<a href="#fn4" class="footnote-ref" id="fnref4" role="doc-noteref"><sup>4</sup></a></li>
</ul>
<p><code>lens</code> uses type synonyms liberally, so those correspondences are not immediately obvious form the signatures in the documentation. Digging a little deeper, however, shows that in</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">set ::</span> <span class="dt">ASetter</span> s t a b <span class="ot">-&gt;</span> b <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> t</span></code></pre></div>
<p><code>ASetter</code> is merely</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="dt">ASetter</span> s t a b <span class="ot">=</span> (a <span class="ot">-&gt;</span> <span class="dt">Identity</span> b) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Identity</span> t</span></code></pre></div>
<p>Analogously, we have</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">(^.) ::</span> s <span class="ot">-&gt;</span> <span class="dt">Getting</span> a s a <span class="ot">-&gt;</span> a</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">type</span> <span class="dt">Getting</span> r s a <span class="ot">=</span> (a <span class="ot">-&gt;</span> <span class="dt">Const</span> r a) <span class="ot">-&gt;</span> s <span class="ot">-&gt;</span> <span class="dt">Const</span> r s</span></code></pre></div>
<p>Behind the plethora of type synonyms - <code>ASetter</code>, <code>Getting</code>, <code>Fold</code>, <code>Traversal</code>, <code>Prism</code>, <code>Iso</code> and so forth - there are different choices of functors,<a href="#fn5" class="footnote-ref" id="fnref5" role="doc-noteref"><sup>5</sup></a> which make it possible to capture many different concepts as variations on lenses. The variations may be more general or less general than lenses; occasionally they are neither, as the overlap is just partial. The fact that we can express so much through parametrization of functors is key to the extraordinary breadth of <code>lens</code>.</p>
<h2 id="going-forward">Going Forward</h2>
<p>This exposition is primarily concerned with building lenses, and so very little was said about how to use them. In any case, we have seen enough to understand why lenses are also known as functional references. By unifying getters and setters, lenses provide a completely general vocabulary to point at parts of a whole.</p>
<p>Finally, a few words about composition of lenses are unavoidable. One of the great things about lenses is that they are just functions; even better, they are functions with signatures tidy enough for them to compose cleanly with <code>(.)</code>. That makes it possible to compose lenses independently of whether you intend to get, set or modify their targets. Here is a quick demonstration using the tuple lenses from <code>lens</code>.</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">GHCi</span><span class="op">&gt;</span> <span class="op">:</span>m</span>
<span id="cb33-2"><a href="#cb33-2" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="op">:</span>m <span class="op">+</span><span class="dt">Control.Lens</span></span>
<span id="cb33-3"><a href="#cb33-3" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> ((<span class="dv">1</span>,<span class="dv">2</span>),(<span class="dv">3</span>,<span class="dv">4</span>)) <span class="op">^.</span> _1 <span class="op">.</span> _2</span>
<span id="cb33-4"><a href="#cb33-4" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="dv">2</span></span>
<span id="cb33-5"><a href="#cb33-5" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> set (_1 <span class="op">.</span> _2) <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>
<span id="cb33-6"><a href="#cb33-6" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> ((<span class="dv">1</span>,<span class="dv">0</span>),(<span class="dv">3</span>,<span class="dv">4</span>))</span></code></pre></div>
<p>A perennial topic in discussions about <code>lens</code> is the order of composition of lenses. They are often said to compose backwards; that is, backwards with respect to composition of record accessors and similar getters. For instance, the getter corresponding to the <code>_1 . _2</code> lens is <code>snd . fst</code>. The claim that lenses compose backwards, or in the “wrong order”, however, are only defensible when talking about style, and not about semantics. That becomes clear after placing the signatures of a getter and its corresponding lens side by side.</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">GHCi</span><span class="op">&gt;</span> <span class="op">:</span>t <span class="fu">fst</span></span>
<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a><span class="fu">fst</span><span class="ot"> ::</span> (a, b) <span class="ot">-&gt;</span> a</span>
<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a><span class="dt">GHCi</span><span class="op">&gt;</span> <span class="op">:</span>t<span class="ot"> _1 ::</span> <span class="dt">Lens'</span> (a, b) a</span>
<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a><span class="ot">_1 ::</span> <span class="dt">Lens'</span> (a, b) a</span>
<span id="cb34-5"><a href="#cb34-5" aria-hidden="true" tabindex="-1"></a><span class="ot"> ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> f a) <span class="ot">-&gt;</span> (a, b) <span class="ot">-&gt;</span> f (a, b)</span></code></pre></div>
<p>The getter takes a value of the source type and produces a value of the target type. The lens, however, takes a function from the target type and produces a function from the source type. Therefore, it is no surprise that the order of composition differs, and the order for lenses is entirely natural. That ties in closely to what we have seen while implementing lenses. While we can squeeze lenses until they give back getters, it is much easier to think of them as generalised modifiers.</p>
<section class="footnotes footnotes-end-of-document" role="doc-endnotes">
<hr />
<ol>
<li id="fn1" role="doc-endnote"><p>We are not quite as free when it comes to pairing getters and setters. Beyond the obvious need for getter and setter to start from values of the same type, they should behave sanely when composed. In particular, the following should hold:</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>get' modifier (setGen modifier y x) ≡ y</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>setGen modifier (get' modifier x) x ≡ x</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>setGen modifier z (setGen modifier y x) ≡ setGen modifier z x</span></code></pre></div>
<a href="#fnref1" class="footnote-back" role="doc-backlink">↩︎</a></li>
<li id="fn2" role="doc-endnote"><p>“What about the <code>forall</code>?” you might ask. Are we cheating? Not quite. The <code>forall</code> is there to control how <code>f</code> is specialised when lens combinators are used. The underlying issue does not affect our reasoning here. If you are into type system subtleties, there were a few interesting comments about it in the <a href="http://www.reddit.com/r/haskell/comments/241aec/lenses_you_can_make_at_home/ch2rbgp">reddit thread</a> for this post.<a href="#fnref2" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn3" role="doc-endnote"><p><code>Lens' s a</code> or <code>Lens s s a a</code>, as opposed to <code>Lens s t a b</code>.<a href="#fnref3" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn4" role="doc-endnote"><p>Yes, even further; from taking modifying functions to taking modifying <a href="https://www.fpcomplete.com/user/liyang/profunctors">profunctors</a>. The difference need not worry us now.<a href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
<li id="fn5" role="doc-endnote"><p>And in some cases of profunctors to replace the function type constructor.<a href="#fnref5" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
</ol>
</section>


<div id="comment-nav" class="pure-g-r no-print">
  <div class="pure-u-1-4">
    <a id="gh-comments-button" class="pure-button" href="https://github.com/duplode/duplode.github.io/issues/1">Comment on GitHub</a>

    
      
        (see <a href="posts/lenses-you-can-make-at-home.html#comment-nav">the full post</a> for a reddit link)
      
    
  </div>
  <div class="pure-u-1-4">
    
    
  </div>
  <div class="pure-u-1-4">
    
  </div>
  <div class="pure-u-1-4">
  </div>
</div>

<div><div class="license">
  <p>
    <span class="inline-centered">
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">
        <img alt="Creative Commons License" style="border-width:0" src="//i.creativecommons.org/l/by-sa/4.0/80x15.png" /></a>
    </span>
    <span class="inline-centered">
      Post licensed under a
      <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
    </span>
  </p>
</div>

</div>
]]></description>
    <pubDate>2014-04-26T12:00:00Z</pubDate>
    <guid>https://duplode.github.io/posts/lenses-you-can-make-at-home.html</guid>
    <dc:creator>Daniel Mlot</dc:creator>
</item>

    </channel>
</rss>
