<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Sylvain Henry (Blog)</title>
    <link href="http://www.hsyl20.fr/home/atom.xml" rel="self" />
    <link href="http://www.hsyl20.fr/home" />
    <id>http://www.hsyl20.fr/home/atom.xml</id>
    <author>
        <name>Sylvain HENRY</name>
        <email>sylvain@haskus.fr</email>
    </author>
    <updated>2024-09-12T00:00:00Z</updated>
    <entry>
    <title>Variant and recursion schemes</title>
    <link href="http://www.hsyl20.fr/home/posts/2024-09-12-variant-recursion-schemes.html" />
    <id>http://www.hsyl20.fr/home/posts/2024-09-12-variant-recursion-schemes.html</id>
    <published>2024-09-12T00:00:00Z</published>
    <updated>2024-09-12T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Variant and recursion schemes</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">September 12, 2024</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>Yesterday on Reddit, <a href="https://www.reddit.com/r/haskell/comments/1fe29ib/what_exactly_is_the_point_of_recursion_schemes/">someone asked</a> the following question:</p>
<blockquote>
<p>What exactly is the point of recursion schemes?</p>
<p>[..]</p>
<p>I understand it’s usefulness from an academic perspective, understanding the similarities between different types of recursive algorithms and their common patterns, but in practice, it just seems kind of… pointless?</p>
<p>[..]</p>
<p>I’m not not ripping on this particular library or it’s author at all, I think it’s worthwhile to explore topics like this, but as anything other than a mental exercise I struggle to see what the benefit is in practice. Personally I don’t understand what the aversion is to explicit recursion when the algorithm you’re writing calls for it. For other complicated ideas born out of Haskell like lenses I can immediately see the utility that outweighs any added complexity. Am I missing something here?</p>
</blockquote>
<p>I thought the same before working on <a href="https://hackage.haskell.org/package/variant">variants</a> and in particular on <a href="https://hackage.haskell.org/package/variant/docs/Data-Variant-EADT.html">EADTs</a>. This post is my answer to the question for the posterity and so that I can easily find it back. It’s a revision of <a href="https://www.reddit.com/r/haskell/comments/1fe29ib/comment/lmldtc8/">my answer</a> on Reddit.</p>
<hr />
<p>I’ve found a particularly compelling use case for them in my <a href="https://hackage.haskell.org/package/variant">variant</a> package. I’ll try to explain but it’s a bit long to setup…</p>
<p>The idea of variant is to compose a sum type from other types like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">type</span> <span class="dt">MyMaybe</span> a <span class="ot">=</span> <span class="dt">V</span> [(), a]</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw">type</span> <span class="dt">MyEither</span> a b <span class="ot">=</span> <span class="dt">V</span> [a,b]</a></code></pre></div>
<p>At some point we may want to use variants to encode ASTs that can get or lose constructors. E.g.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="kw">data</span> <span class="dt">Let</span> b e <span class="ot">=</span> <span class="dt">Let</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="kw">data</span> <span class="dt">Abs</span> b e <span class="ot">=</span> <span class="dt">Abs</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="kw">data</span> <span class="dt">App</span>   e <span class="ot">=</span> <span class="dt">App</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-4" title="4"><span class="kw">data</span> <span class="dt">Var</span> b   <span class="ot">=</span> <span class="dt">Var</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-5" title="5"></a>
<a class="sourceLine" id="cb2-6" title="6"><span class="kw">type</span> <span class="dt">LC</span>        b e <span class="ot">=</span> <span class="dt">V</span> [<span class="dt">Abs</span> b e, <span class="dt">App</span> e, <span class="dt">Var</span> b]</a>
<a class="sourceLine" id="cb2-7" title="7"><span class="kw">type</span> <span class="dt">LCWithLet</span> b e <span class="ot">=</span> <span class="dt">V</span> [<span class="dt">Abs</span> b e, <span class="dt">App</span> e, <span class="dt">Var</span> b, <span class="dt">Let</span> b e]</a></code></pre></div>
<p>However <code>e</code> in <code>LC b e</code>/<code>LCWithLet b e</code> should really be <code>LC b e</code>/<code>LCWithLet b e</code> (respectively): <code>e</code> is the type of an expression in our AST. But we can’t encode a recursive type like this with simple type synonyms: we need to introduce a <a href="https://hackage.haskell.org/package/data-fix-0.3.4/docs/Data-Fix.html#t:Fix">fixpoint data type</a>.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><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))</a>
<a class="sourceLine" id="cb3-2" title="2"></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="kw">type</span> <span class="dt">LCF</span>        b e <span class="ot">=</span> <span class="dt">V</span> [<span class="dt">Abs</span> b e, <span class="dt">App</span> e, <span class="dt">Var</span> b]</a>
<a class="sourceLine" id="cb3-4" title="4"><span class="kw">type</span> <span class="dt">LCWithLetF</span> b e <span class="ot">=</span> <span class="dt">V</span> [<span class="dt">Abs</span> b e, <span class="dt">App</span> e, <span class="dt">Var</span> b, <span class="dt">Let</span> b e]</a>
<a class="sourceLine" id="cb3-5" title="5"></a>
<a class="sourceLine" id="cb3-6" title="6"><span class="co">-- our recursive variant-based ASTs</span></a>
<a class="sourceLine" id="cb3-7" title="7"><span class="kw">type</span> <span class="dt">LC</span>        b <span class="ot">=</span> <span class="dt">Fix</span> (<span class="dt">LCF</span> b)</a>
<a class="sourceLine" id="cb3-8" title="8"><span class="kw">type</span> <span class="dt">LCWithLet</span> b <span class="ot">=</span> <span class="dt">Fix</span> (<span class="dt">LCWithLetF</span> b)</a></code></pre></div>
<p>Now to avoid this boilerplate, in my package there is:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="co">-- same as (V xs) but takes an additional argument</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="co">-- 'e' applied to every types in the list</span></a>
<a class="sourceLine" id="cb4-3" title="3"><span class="kw">newtype</span> <span class="dt">VariantF</span> (<span class="ot">xs ::</span> [t <span class="ot">-&gt;</span> <span class="dt">Type</span>]) (<span class="ot">e ::</span> t)</a>
<a class="sourceLine" id="cb4-4" title="4">   <span class="ot">=</span> <span class="dt">VariantF</span> (<span class="dt">V</span> (<span class="dt">ApplyAll</span> e xs))</a>
<a class="sourceLine" id="cb4-5" title="5"></a>
<a class="sourceLine" id="cb4-6" title="6"><span class="co">-- fixpoint datatype specialized for variants</span></a>
<a class="sourceLine" id="cb4-7" title="7"><span class="kw">newtype</span> <span class="dt">EADT</span> fs</a>
<a class="sourceLine" id="cb4-8" title="8">   <span class="ot">=</span> <span class="dt">EADT</span> (<span class="dt">VariantF</span> fs (<span class="dt">EADT</span> fs))</a></code></pre></div>
<p>It means that we can define a recursive ADT based on variants (i.e. an EADT, for Extensible ADT) like this:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="co">-- every type embedded in an EADT requires the `e`</span></a>
<a class="sourceLine" id="cb5-2" title="2"><span class="co">-- argument (ADT type), even if it doesn't use it.</span></a>
<a class="sourceLine" id="cb5-3" title="3"><span class="co">-- So rewrite &quot;data Var b = Var ...&quot; into:</span></a>
<a class="sourceLine" id="cb5-4" title="4"><span class="kw">data</span> <span class="dt">Var</span> b e <span class="ot">=</span> <span class="dt">Var</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb5-5" title="5"></a>
<a class="sourceLine" id="cb5-6" title="6"><span class="kw">type</span> <span class="dt">LC</span>        b <span class="ot">=</span> <span class="dt">EADT</span> [<span class="dt">Abs</span> b, <span class="dt">App</span>, <span class="dt">Var</span> b]</a>
<a class="sourceLine" id="cb5-7" title="7"><span class="kw">type</span> <span class="dt">LCWithLet</span> b <span class="ot">=</span> <span class="dt">EADT</span> [<span class="dt">Abs</span> b, <span class="dt">App</span>, <span class="dt">Var</span> b, <span class="dt">Let</span> b]</a></code></pre></div>
<p>Now suppose we want to write some code to collect the free variables. We can use explicit recursion and write two functions for the two ASTs. But it would be duplicating a lot of code (especially if we have even more ASTs). This is (finally!) where recursion schemes are useful!</p>
<p>It’s easy to add functor instances to the datatypes embedded in the EADTs: just derive them:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">data</span> <span class="dt">Let</span> b e <span class="ot">=</span> <span class="dt">Let</span> <span class="op">...</span> <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb6-2" title="2"><span class="kw">data</span> <span class="dt">Abs</span> b e <span class="ot">=</span> <span class="dt">Abs</span> <span class="op">...</span> <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb6-3" title="3"><span class="kw">data</span> <span class="dt">App</span>   e <span class="ot">=</span> <span class="dt">App</span> <span class="op">...</span> <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb6-4" title="4"><span class="kw">data</span> <span class="dt">Var</span> b e <span class="ot">=</span> <span class="dt">Var</span> <span class="op">...</span> <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a></code></pre></div>
<p><code>VariantF</code> also has a <code>Functor</code> instance. It’s Functors all the way down!</p>
<p>So we can define a generic function for all those functors using a typeclass like this:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">class</span> <span class="dt">FreeVars</span> b f <span class="kw">where</span></a>
<a class="sourceLine" id="cb7-2" title="2">  <span class="co">-- return free variables. Use this with a bottom-up traversal (catamorphism)</span></a>
<a class="sourceLine" id="cb7-3" title="3"><span class="ot">  freeVarsF ::</span> f (<span class="dt">Set</span> b) <span class="ot">-&gt;</span> <span class="dt">Set</span> b</a>
<a class="sourceLine" id="cb7-4" title="4"></a>
<a class="sourceLine" id="cb7-5" title="5"><span class="co">-- see below for the instances</span></a></code></pre></div>
<p>And then we finally use the catamorphism recursion-scheme (renamed to <code>bottomUp</code>) to write our generic <code>freeVars</code> function:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="ot">freeVars ::</span> <span class="kw">forall</span> b xs<span class="op">.</span> <span class="dt">BottomUpF</span> (<span class="dt">FreeVars</span> b) xs <span class="ot">=&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">Set</span> b</a>
<a class="sourceLine" id="cb8-2" title="2">freeVars xs <span class="ot">=</span> bottomUp (toBottomUp <span class="op">@</span>(<span class="dt">FreeVars</span> b) freeVarsF) xs</a>
<a class="sourceLine" id="cb8-3" title="3">  <span class="co">-- &quot;bottomUp&quot; is just &quot;cata&quot; with a less cryptic name </span></a></code></pre></div>
<p>A fully working example:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="pp">#!/usr/bin/env cabal</span></a>
<a class="sourceLine" id="cb9-2" title="2"><span class="co">{- cabal:</span></a>
<a class="sourceLine" id="cb9-3" title="3"><span class="co">build-depends: base, containers, variant</span></a>
<a class="sourceLine" id="cb9-4" title="4"><span class="co">-}</span>  </a>
<a class="sourceLine" id="cb9-5" title="5"><span class="ot">{-# LANGUAGE DataKinds #-}</span></a>
<a class="sourceLine" id="cb9-6" title="6"><span class="ot">{-# LANGUAGE DeriveFunctor #-}</span></a>
<a class="sourceLine" id="cb9-7" title="7"><span class="ot">{-# LANGUAGE FlexibleInstances #-}</span></a>
<a class="sourceLine" id="cb9-8" title="8"><span class="ot">{-# LANGUAGE MultiParamTypeClasses #-}</span></a>
<a class="sourceLine" id="cb9-9" title="9"><span class="ot">{-# LANGUAGE TemplateHaskell #-}</span></a>
<a class="sourceLine" id="cb9-10" title="10"><span class="ot">{-# LANGUAGE KindSignatures #-}</span></a>
<a class="sourceLine" id="cb9-11" title="11"><span class="ot">{-# LANGUAGE PatternSynonyms #-}</span></a>
<a class="sourceLine" id="cb9-12" title="12"><span class="ot">{-# LANGUAGE TypeOperators #-}</span></a>
<a class="sourceLine" id="cb9-13" title="13"><span class="ot">{-# LANGUAGE TypeApplications #-}</span></a>
<a class="sourceLine" id="cb9-14" title="14"><span class="ot">{-# LANGUAGE ScopedTypeVariables #-}</span></a>
<a class="sourceLine" id="cb9-15" title="15"></a>
<a class="sourceLine" id="cb9-16" title="16"><span class="kw">module</span> <span class="dt">Main</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb9-17" title="17"></a>
<a class="sourceLine" id="cb9-18" title="18"><span class="kw">import</span> <span class="dt">Data.Variant.EADT</span></a>
<a class="sourceLine" id="cb9-19" title="19"><span class="kw">import</span> <span class="dt">Data.Variant.EADT.TH</span></a>
<a class="sourceLine" id="cb9-20" title="20"><span class="kw">import</span> <span class="dt">Data.Set</span> (<span class="dt">Set</span>)</a>
<a class="sourceLine" id="cb9-21" title="21"><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Set</span> <span class="kw">as</span> <span class="dt">Set</span></a>
<a class="sourceLine" id="cb9-22" title="22"></a>
<a class="sourceLine" id="cb9-23" title="23"><span class="co">-- Definitions of the EADTs</span></a>
<a class="sourceLine" id="cb9-24" title="24"></a>
<a class="sourceLine" id="cb9-25" title="25"><span class="kw">data</span> <span class="dt">VarF</span> b e <span class="ot">=</span> <span class="dt">VarF</span> b     <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb9-26" title="26"><span class="kw">data</span> <span class="dt">AbsF</span> b e <span class="ot">=</span> <span class="dt">AbsF</span> b e   <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb9-27" title="27"><span class="kw">data</span> <span class="dt">AppF</span>   e <span class="ot">=</span> <span class="dt">AppF</span> e e   <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb9-28" title="28"><span class="kw">data</span> <span class="dt">LetF</span> b e <span class="ot">=</span> <span class="dt">LetF</span> b e e <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb9-29" title="29"></a>
<a class="sourceLine" id="cb9-30" title="30">eadtPattern <span class="dt">'VarF</span> <span class="st">&quot;Var&quot;</span></a>
<a class="sourceLine" id="cb9-31" title="31">eadtPattern <span class="dt">'AbsF</span> <span class="st">&quot;Abs&quot;</span></a>
<a class="sourceLine" id="cb9-32" title="32">eadtPattern <span class="dt">'AppF</span> <span class="st">&quot;App&quot;</span></a>
<a class="sourceLine" id="cb9-33" title="33">eadtPattern <span class="dt">'LetF</span> <span class="st">&quot;Let&quot;</span></a>
<a class="sourceLine" id="cb9-34" title="34"></a>
<a class="sourceLine" id="cb9-35" title="35"><span class="kw">type</span> <span class="dt">LC</span>        b <span class="ot">=</span> <span class="dt">EADT</span> [<span class="dt">VarF</span> b, <span class="dt">AbsF</span> b, <span class="dt">AppF</span>]</a>
<a class="sourceLine" id="cb9-36" title="36"><span class="kw">type</span> <span class="dt">LCWithLet</span> b <span class="ot">=</span> <span class="dt">EADT</span> [<span class="dt">VarF</span> b, <span class="dt">AbsF</span> b, <span class="dt">AppF</span>, <span class="dt">LetF</span> b]</a>
<a class="sourceLine" id="cb9-37" title="37"></a>
<a class="sourceLine" id="cb9-38" title="38"></a>
<a class="sourceLine" id="cb9-39" title="39"><span class="co">-- Generic traversal for FreeVars</span></a>
<a class="sourceLine" id="cb9-40" title="40"></a>
<a class="sourceLine" id="cb9-41" title="41"><span class="kw">class</span> <span class="dt">FreeVars</span> b f <span class="kw">where</span></a>
<a class="sourceLine" id="cb9-42" title="42">  <span class="co">-- | Compute free variables set</span></a>
<a class="sourceLine" id="cb9-43" title="43"><span class="ot">  freeVarsF ::</span> f (<span class="dt">Set</span> b) <span class="ot">-&gt;</span> <span class="dt">Set</span> b</a>
<a class="sourceLine" id="cb9-44" title="44"></a>
<a class="sourceLine" id="cb9-45" title="45"><span class="kw">instance</span> <span class="dt">FreeVars</span> b (<span class="dt">VarF</span> b) <span class="kw">where</span></a>
<a class="sourceLine" id="cb9-46" title="46">  freeVarsF (<span class="dt">VarF</span> b) <span class="ot">=</span> Set.singleton b</a>
<a class="sourceLine" id="cb9-47" title="47"></a>
<a class="sourceLine" id="cb9-48" title="48"><span class="kw">instance</span> <span class="dt">Eq</span> b <span class="ot">=&gt;</span> <span class="dt">FreeVars</span> b (<span class="dt">AbsF</span> b) <span class="kw">where</span></a>
<a class="sourceLine" id="cb9-49" title="49">  freeVarsF (<span class="dt">AbsF</span> b vs) <span class="ot">=</span> Set.filter (<span class="op">/=</span> b) vs</a>
<a class="sourceLine" id="cb9-50" title="50"></a>
<a class="sourceLine" id="cb9-51" title="51"><span class="kw">instance</span> (<span class="dt">Eq</span> b, <span class="dt">Ord</span> b) <span class="ot">=&gt;</span> <span class="dt">FreeVars</span> b <span class="dt">AppF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb9-52" title="52">  freeVarsF (<span class="dt">AppF</span> vs1 vs2) <span class="ot">=</span> Set.union vs1 vs2</a>
<a class="sourceLine" id="cb9-53" title="53"></a>
<a class="sourceLine" id="cb9-54" title="54"><span class="kw">instance</span> (<span class="dt">Eq</span> b, <span class="dt">Ord</span> b) <span class="ot">=&gt;</span> <span class="dt">FreeVars</span> b (<span class="dt">LetF</span> b) <span class="kw">where</span></a>
<a class="sourceLine" id="cb9-55" title="55">  freeVarsF (<span class="dt">LetF</span> b vs1 vs2) <span class="ot">=</span> Set.filter (<span class="op">/=</span> b) (Set.union vs1 vs2)</a>
<a class="sourceLine" id="cb9-56" title="56"></a>
<a class="sourceLine" id="cb9-57" title="57"><span class="ot">freeVars ::</span> <span class="kw">forall</span> b xs<span class="op">.</span> <span class="dt">BottomUpF</span> (<span class="dt">FreeVars</span> b) xs <span class="ot">=&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">Set</span> b</a>
<a class="sourceLine" id="cb9-58" title="58">freeVars xs <span class="ot">=</span> bottomUp (toBottomUp <span class="op">@</span>(<span class="dt">FreeVars</span> b) freeVarsF) xs</a>
<a class="sourceLine" id="cb9-59" title="59">  <span class="co">-- &quot;bottomUp&quot; is just &quot;cata&quot;</span></a>
<a class="sourceLine" id="cb9-60" title="60"></a>
<a class="sourceLine" id="cb9-61" title="61"></a>
<a class="sourceLine" id="cb9-62" title="62"><span class="co">-- Examples</span></a>
<a class="sourceLine" id="cb9-63" title="63"></a>
<a class="sourceLine" id="cb9-64" title="64"><span class="kw">type</span> <span class="dt">Name</span> <span class="ot">=</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb9-65" title="65"></a>
<a class="sourceLine" id="cb9-66" title="66"><span class="ot">example1 ::</span> <span class="dt">LC</span> <span class="dt">Name</span></a>
<a class="sourceLine" id="cb9-67" title="67">example1 <span class="ot">=</span> <span class="dt">Abs</span> <span class="st">&quot;x&quot;</span> (<span class="dt">Var</span> <span class="st">&quot;k&quot;</span> <span class="ot">`App`</span> (<span class="dt">Var</span> <span class="st">&quot;(+)&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;foo&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;x&quot;</span>))</a>
<a class="sourceLine" id="cb9-68" title="68"></a>
<a class="sourceLine" id="cb9-69" title="69"><span class="ot">example2 ::</span> <span class="dt">LCWithLet</span> <span class="dt">Name</span></a>
<a class="sourceLine" id="cb9-70" title="70">example2 <span class="ot">=</span> <span class="dt">Let</span> <span class="st">&quot;foo&quot;</span> (<span class="dt">Var</span> <span class="st">&quot;(+)&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;a&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;b&quot;</span>) <span class="op">$</span></a>
<a class="sourceLine" id="cb9-71" title="71">             <span class="dt">Abs</span> <span class="st">&quot;x&quot;</span> (<span class="dt">Var</span> <span class="st">&quot;k&quot;</span> <span class="ot">`App`</span> (<span class="dt">Var</span> <span class="st">&quot;(+)&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;foo&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;x&quot;</span>)) </a>
<a class="sourceLine" id="cb9-72" title="72"></a>
<a class="sourceLine" id="cb9-73" title="73"><span class="ot">example3 ::</span> <span class="dt">LCWithLet</span> <span class="dt">Name</span></a>
<a class="sourceLine" id="cb9-74" title="74">example3 <span class="ot">=</span> <span class="dt">Let</span> <span class="st">&quot;foo&quot;</span> (<span class="dt">Var</span> <span class="st">&quot;(+)&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;a&quot;</span> <span class="ot">`App`</span> <span class="dt">Var</span> <span class="st">&quot;b&quot;</span>) <span class="op">$</span></a>
<a class="sourceLine" id="cb9-75" title="75">            liftEADT example1</a>
<a class="sourceLine" id="cb9-76" title="76"></a>
<a class="sourceLine" id="cb9-77" title="77"><span class="ot">main ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb9-78" title="78">main <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb9-79" title="79">  <span class="co">-- call `freeVars` on different AST types</span></a>
<a class="sourceLine" id="cb9-80" title="80">  <span class="fu">print</span> (freeVars <span class="op">@</span><span class="dt">Name</span> example1)</a>
<a class="sourceLine" id="cb9-81" title="81">  <span class="fu">print</span> (freeVars <span class="op">@</span><span class="dt">Name</span> example2)</a>
<a class="sourceLine" id="cb9-82" title="82">  <span class="fu">print</span> (freeVars <span class="op">@</span><span class="dt">Name</span> example3)</a></code></pre></div>
<p>When executed it prints this expected result:</p>
<pre><code>&gt; ./Main.hs
fromList [&quot;(+)&quot;,&quot;foo&quot;,&quot;k&quot;]
fromList [&quot;(+)&quot;,&quot;a&quot;,&quot;b&quot;,&quot;k&quot;]
fromList [&quot;(+)&quot;,&quot;a&quot;,&quot;b&quot;,&quot;k&quot;]</code></pre>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>About GHC's stability in 2024</title>
    <link href="http://www.hsyl20.fr/home/posts/2024-08-07-about-ghcs-stability.html" />
    <id>http://www.hsyl20.fr/home/posts/2024-08-07-about-ghcs-stability.html</id>
    <published>2024-08-07T00:00:00Z</published>
    <updated>2024-08-07T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">About GHC's stability in 2024</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">August  7, 2024</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p><strong>Changelog</strong></p>
<ul>
<li>2024-08-08: added mention of <a href="https://github.com/haskell/cabal/issues/2965">cabal#2965</a>, <a href="https://discourse.haskell.org/t/plugin-dependency-conflict/10121">real world issue with plugins</a>, and Teofil’s answer.</li>
</ul>
<hr />
<p>There are lots of discussions about GHC’s “stability”, making <code>base</code> “reinstallable”, and similar topics. As we’ve been harping on about these topics for years now, I figured I would try to summarize the issues and the current status here.</p>
<p><strong>What are the issues?</strong></p>
<p>A compiler <code>LC</code> for a language <code>L</code> takes some source code <code>SC</code> written in <code>L</code> (hopefully) and generates object code <code>OC</code> for a target platform <code>T</code>. The compiler runs on an host platform <code>H</code>.</p>
<p>We’ll use and abuse of the following notation to summarize this:</p>
<pre><code>SC(L) --LC(H)--&gt; OC(T)</code></pre>
<p>The issue is that GHC is different from this in two aspects:</p>
<ol type="1">
<li>L isn’t independent of LC</li>
<li>OC(T) must be linkable with LC(H) (by default)
<ul>
<li>This implies some constraints on L too, so double on (1)</li>
</ul></li>
</ol>
<p>Let’s discuss this more.</p>
<h1 id="l-isnt-independent-of-lc">L isn’t independent of LC</h1>
<p>A new version of GHC supports only a “new” Haskell language. There may be backward incompatible changes in the compiler (e.g. to the way GHC typechecks programs), but these are rare. What’s more frequent is that the standard API offered to Haskell programs (i.e. boot libraries such as <code>base</code>) changes with the compiler.</p>
<p>As a result, a program compiling with GHC version N may not compile with GHC version N+1. It’s as if the language was versionned, as illustrated below.</p>
<pre><code>We have some source code SC compiling with LC-1.0:

SC(L-1.0) --LC-1.0(H)--&gt; OC(T)

A new compiler is released. Let's try to use it!

SC(L-1.0) --LC-2.0(H)--&gt; FAILURE

We need to tweak the source code to make it compilable with LC-2.0:

SC-2.0(L-2.0) --LC-2.0(H)--&gt; OC(T)</code></pre>
<p>The issue is: we can’t use a new compiler without modifying the source code we want to compile. As a result:</p>
<ul>
<li>we can’t know if regressions arise from code changes or compiler upgrade.</li>
<li>as changing code can be costly (all the dependencies need to be fixed in cascade…), some code bases are stuck with old compiler versions and new compilers get less testing than we would hope for.</li>
</ul>
<p>The project to fix this is referred to as <strong>reinstallable base</strong>. The idea is to decouple the <code>base</code> library from the GHC compiler used:</p>
<ul>
<li>Let’s call <code>ghc-base</code> the standard library provided by GHC and versioned with it.
<ul>
<li>Note: currently <code>ghc-base</code> is split into <code>ghc-prim</code>, <code>ghc-bignum</code>, and <code>ghc-internal</code>.</li>
</ul></li>
<li><p><code>ghc-base</code> changes with every GHC release to add/remove/rename/deprecate/modify stuff</p></li>
<li><p><code>base</code> abstracts over changes in <code>ghc-base</code> for some releases, <strong>with some overlap</strong> to allow incremental updates: e.g.</p></li>
</ul>
<pre><code>base-1.0 depends on ghc-base &gt;= 8.10 &amp;&amp; &lt; 9.8
base-2.0 depends on ghc-base &gt;= 9.6 &amp;&amp; &lt; 9.10
base-3.0 depends on ghc-base &gt;= 9.8 &amp;&amp; &lt; 9.12</code></pre>
<p>When a new <code>ghc-base</code> is released, existing <code>base</code> releases may be adapted to support it or not:</p>
<pre><code>base-1.0 depends on ghc-base &gt;= 8.10 &amp;&amp; &lt; 9.8
base-2.0 depends on ghc-base &gt;= 9.6 &amp;&amp; &lt; 9.10
base-3.0.1 depends on ghc-base &gt;= 9.8 &amp;&amp; &lt; 9.14</code></pre>
<p>It’s up to <code>base</code> maintainers to decide how many releases they want to support and when to make major breaking releases. But:</p>
<ul>
<li><code>base</code> support for <code>ghc-base</code> should overlap to allow bumping <code>base</code> without bumping <code>ghc-base</code>, and vice-versa.</li>
<li>as GHC depends on <code>base</code>, there should always be a <code>base</code> version supporting the development version of <code>ghc-base</code> so that it can bootstrap itself (maybe with <code>--allow-newer</code> set only for <code>ghc-base</code> when compiling <code>base</code> for GHC).</li>
</ul>
<p>Now if we have some source code depending on <code>base</code> (and not <code>ghc-base</code>):</p>
<ul>
<li><p>we can switch to a new compiler (i.e. bumping <code>ghc-base</code> too) without modifying the code, as long as the <code>base</code> version used supports the <code>ghc-base</code> version provided by the new compiler.</p></li>
<li><p>we can switch to a new version of <code>base</code> without switching to a new compiler, as long as the new <code>base</code> version used support the <code>ghc-base</code> version provided by the current compiler.</p></li>
</ul>
<h2 id="template-haskell">Template Haskell</h2>
<p><code>ghc-base</code> contains the data types expected by the compiler for the abstract syntax of Template Haskell.</p>
<p>So, similarly to <code>base</code>, the <code>template-haskell</code> package also needs to be versionned to support several <code>ghc-base</code> versions so that packages using <code>template-haskell</code> aren’t tied to a specific <code>ghc-base</code> version through their <code>template-haskell</code> dependency:</p>
<pre><code>template-haskell-1.0 depends on ghc-base &gt;= 8.10 &amp;&amp; &lt; 9.4
template-haskell-2.0 depends on ghc-base &gt;= 9.2 &amp;&amp; &lt; 9.10
template-haskell-3.0 depends on ghc-base &gt;= 9.8 &amp;&amp; &lt; 9.12
...</code></pre>
<p>Note: should <code>template-haskell</code> be merged into <code>base</code> to make dependencies simpler? [Edit: Teofil Camarasu explained to me that <code>template-haskell</code> has dependencies that <code>base</code> doesn’t have, so that’s probably a no-go]</p>
<h2 id="status-of-the-reinstallable-base-project">Status of the “reinstallable base” project</h2>
<ul>
<li><code>base</code> has been split in two parts: <code>ghc-internal</code> and <code>base</code></li>
<li>wired-in entities have been moved from <code>template-haskell</code> to <code>ghc-internal</code></li>
<li>technical changes have been made: removal of wired unit-ids, fix of cabal knowledge about reinstallable packages, hadrian support for 2 versions of template-haskell, etc.</li>
<li>changes to <code>base</code> interface (exports…) are tracked on CI and aren’t done lightly anymore (they require an accepted CLC proposal)</li>
<li>I’ve suggested merging <code>ghc-prim</code>, <code>ghc-bignum</code>, <code>ghc-internal</code> into a single package in <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/24453">#24453</a>. Not done yet.</li>
<li>Probably more. I’m not involved much in this project.</li>
</ul>
<p>Note that contrary to the model exposed above, there is still a single version of <code>base</code> and <code>template-haskell</code> actively maintained for now.</p>
<h2 id="what-about-reinstallable-ghc-base">What about “reinstallable ghc-base”?</h2>
<p>We may want to reinstall <code>ghc-base</code> (and the RTS) too! For example to change the bignum backend used to back <code>Integer</code> operations (<code>native</code> vs <code>GMP</code>).</p>
<p>Doing this should be possible. As it’s similar to performing cross-compilation, it’s discussed in the relevant section below.</p>
<h1 id="oct-must-be-linkable-with-lch">OC(T) must be linkable with LC(H)</h1>
<p>In plain english: the object code produced by the compiler must be loadable/linkable with the running compiler.</p>
<p>This is required by the internal interpreter used to implement:</p>
<ul>
<li>Template Haskell</li>
<li>Annotations</li>
<li>Plugins</li>
<li>(GHCi; we don’t really care for this here as it’s not used to compile code)</li>
</ul>
<p>Here is how the internal interpreter executes code at compilation time:</p>
<ul>
<li>GHC compiles the code it wants to run into object code (<code>OC(T)</code>)</li>
<li>it loads/links the object code into its process (e.g. with <code>dlopen</code> when GHC is dynamically linked)</li>
<li>it lookups the symbol of the function it wants to call in the loaded object code</li>
<li>it unsafe-coerces the function pointer into a proper Haskell function type</li>
<li>it calls the function normally</li>
</ul>
<p>It is safe to unsafe-coerce here because values live in the same heap (the one of the GHC process).</p>
<p>Note: we ignore ByteCode here as the same issue would arise anyway with ByteCode calling into native code (FFI calls, precompiled boot libraries without ByteCode, etc.).</p>
<p>Note: called functions must be pure because if GHC is linked statically with <code>libFOO</code>, then loading some code depending on <code>libFOO</code> will load <code>libFOO</code> again without linking global variables of both <code>libFOO</code> instances together. This was an issue for code depending on the <code>ghc</code> library which used global variables unsafely (now these global variables are properly shared via the RTS).</p>
<p>“OC(T) must be linkable with LC(H)” is a <strong>major constraint</strong> because it means the object code must have the same ABI as the compiler.</p>
<p>It is however necessary to work around it:</p>
<ul>
<li>to build new GHCs</li>
<li>to support GHC ways</li>
<li>to support cross-compilation</li>
</ul>
<h2 id="how-do-we-build-a-new-ghc">How do we build a new GHC?</h2>
<p>Suppose we want to build GHC-2.0 using the GHC-1.0 program and that they don’t have the same ABI. We use a two-step process as follows:</p>
<pre><code>SC-GHC-2.0 --GHC-1.0(ABI-1.0)--&gt; GHC-2.0(ABI-1.0)

And then:

SC-GHC-2.0 --GHC-2.0(ABI-1.0)--&gt; GHC-2.0(ABI-2.0)</code></pre>
<p>After the two-step process, GHC-2.0(ABI-2.0) has ABI-2.0 and produces object code with ABI-2.0, so it can load it. All good.</p>
<p>Note however that the second step shouldn’t be allowed because of our constraint “OC(T) must be linkable with LC(H)”, i.e. “GHC-2.0(ABI-2.0) must be linkable with GHC-2.0(ABI-1.0)”: the ABIs don’t match! We are only allowed to do this because <strong>GHC’s source code doesn’t use any of the features above (TH, annotations, plugins)</strong>! This is a constraint but it’s less inconvenient than not being able to modify the ABI ever.</p>
<p>Note: GHC’s newer source code (SC-GHC-2.0) must be compilable by two different GHCs: an old GHC (e.g. GHC-1.0) and the new GHC itself (GHC-2.0). That’s a reason why we are reluctant to add new dependencies to GHC because then we have to adapt them ourselves for them to be usable with the newer GHC. If GHC becomes more stable, then maybe we can start adding more dependencies.</p>
<h2 id="what-about-cross-compilation-and-compiler-ways">What about cross-compilation and compiler ways?</h2>
<p>Remember our illustration:</p>
<pre><code>SC(L) --LC(H)--&gt; OC(T)</code></pre>
<p>With cross-compilation, the compiler host platform <code>H</code> is really different from the object code target platform <code>T</code>. For example, if <code>H</code> is <code>linux-x86-64</code> and <code>T</code> is <code>javascript</code> then we really can’t link JavaScript “object code” with Linux x86-64 ELF object code.</p>
<p>The same is true for GHC’s “ways”. For example when <strong>profiling</strong> is enabled, the compiler generates object code with a different ABI. E.g. a heap object for an <code>Int</code> has 1 more field when profiling is enabled so we can’t unsafe-coerce it into an <code>Int</code> expected by a non-profiled compiler without risking segfaults.</p>
<p><strong>External interpreter</strong></p>
<p>This is where the <strong>external interpreter</strong> is useful. If we have another interpreter process that is built using the target ABI <code>T</code>, then this interpreter can load the object code <code>OC(T)</code> produced by our cross-compiler. The compiler and this external interpreter then just have to exchange properly serialized data (without unsafe coercions) over a pipe or a socket.</p>
<ol type="1">
<li><code>SC(L) --LC(H)--&gt; OC(T)</code></li>
<li><code>LC(H)</code> spawns an external interpreter <code>EI(T)</code> for the <code>T</code> target</li>
<li><code>LC(H)</code> asks <code>EI(T)</code> to load <code>OC(T)</code> (and its dependencies)</li>
<li><code>LC(H)</code> asks <code>EI(T)</code> to run function <code>foo</code> and to return its result serialized (e.g. a Template Haskell abstract syntax tree).</li>
</ol>
<p>Note: step 2 assumes that <code>EI(T)</code> can be spawned on the compiler host platform <code>H</code>. If it isn’t the case, it is possible to spawn a proxy interpreter that communicates with <code>EI(T)</code> spawned on the appropriate platform (e.g. in <code>qemu</code>, <code>wine</code>, or on a remote server). See <code>iserv-proxy</code>.</p>
<p>Who provides the <code>EI(T)</code> external interpreter program?</p>
<ul>
<li>GHC distributes some for the ways it has been built to support (profiling, etc.)</li>
<li><code>haskell.nix</code> supports even more of them, even automatically using <code>qemu</code> and <code>wine</code>.</li>
<li>I’ve suggested that they should be built on-demand by GHC (<a href="https://gitlab.haskell.org/ghc/ghc/-/issues/24731">#24731</a>) to avoid the need to distribute them (still to be done).</li>
</ul>
<p>The external interpreter has a better/safer design than the internal interpreter: why isn’t it the default?</p>
<ul>
<li><p>It’s slower: it needs to spawn another process with its own RTS (GC…) and to serialize data for communication. It’s difficult to compete with the internal interpreter that uses the same process/GC and that (unsafe) coerces values at zero cost.</p></li>
<li><p>Plugins aren’t supported by the external interpreter!</p></li>
</ul>
<h2 id="why-arent-plugins-supported-by-the-external-interpreter">Why aren’t plugins supported by the external interpreter?</h2>
<p>In theory, plugins could be supported by the external interpreter: a plugin provides some functions that GHC could call remotely, just as it does for Template Haskell. BUT:</p>
<ul>
<li><p>GHC uses mutable global state (e.g. for the FastString table and for the Unique counter): the external interpreter process would have to query the compiler process every time it wants to read or modify this state. The code would need to be refactored to ensure that a remote command is sent instead of using global variables <em>in the external interpreter itself</em>.</p></li>
<li><p>Plugins have access to the whole compiler state (e.g. via the <code>HscEnv</code> datatype) and it contains mutable variables (<code>MVar</code>)… We would need to be able to serialize these data types to send them back and forth between the compiler and the external interpreter.</p></li>
</ul>
<p>A better alternative would be to refine the plugin interface to only allow access to easily serializable types. This requires the design of a proper protocole instead of assuming that GHC internals are fully accessible from a plugin. This would be a massive undertaking that would break every plugin, so it’s unlikely to happen.</p>
<h2 id="hey-couldnt-we-run-plugins-with-the-internal-interpreter-and-the-rest-with-the-external-interpreter">Hey, couldn’t we run plugins with the internal interpreter and the rest with the external interpreter?</h2>
<p>In theory maybe, in practice no.</p>
<p>A GHC process isn’t multi-target: it assumes that there is a single target platform, a single interpreter, a single loader state, etc.</p>
<p>Package databases are somewhat distinct between packages for plugins and target packages, but not always. Sometimes it’s on purpose (the same packages are expected to be used for the plugins and for the target code) and sometimes not (we reported some occasional leaks between plugins and target code in <a href="https://hsyl20.fr/posts/2022-05-03-modularizing-ghc-paper.html">our paper</a>).</p>
<p>Also, <code>cabal</code> doesn’t provide an interface to declare plugin dependencies separately from target code dependencies (see <a href="https://github.com/haskell/cabal/issues/2965">cabal#2965</a>). So the GHC distinction between plugin packages and target packages is probably never used, except in GHC’s testsuite.</p>
<p>I’ve spent countless hours refactoring GHC’s code to make progress towards supporting several targets in the same process but we’re still far from supporting it. There are many open questions:</p>
<ul>
<li>plugins may depend on different wired-in packages than target code. How do we deal with this internally?</li>
<li>plugins are allowed in the home-unit (the library we’re building): should we build the library twice? (for plugins then for the target)
<ul>
<li>where do we look for the plugin object code in one-shot mode?</li>
</ul></li>
<li>what about multiple home-units?</li>
</ul>
<p>We’re quickly reinventing <code>cabal</code> inside GHC just for plugins… As I was getting nowhere with the refactoring, I’ve switched to another approach as a workaround: <code>-fplugin-library</code>.</p>
<h2 id="whats-the--fplugin-library-workaround">What’s the -fplugin-library workaround?</h2>
<p>The idea is to totally bypass GHC’s compilation pipeline for plugins and to load them directly from <code>.so/.dll</code> libraries. It requires two compilers:</p>
<ul>
<li>the one used to build plugins (<code>GHC(H,H)</code>: runs on <code>H</code> and targets <code>H</code>)</li>
<li>the one used to generate target code (<code>GHC(H,T)</code>: runs on <code>H</code> and targets <code>T</code>).</li>
</ul>
<p>Both compilers are used like this:</p>
<pre><code>SC-Plugin --GHC(H,H)--&gt; OC-Plugin(H) (e.g. myplugin.so)

SC(L) --{GHC(H,T) -fplugin-library=myplugin.so;... }--&gt; OC(T)</code></pre>
<p>Issues are:</p>
<ul>
<li>we need to manage two GHCs; the first one must produce code ABI compatible with the second for plugins</li>
<li>plugins need to be built manually before calling the GHC process using them.</li>
<li>plugins loaded with the usual <code>-fplugin</code> flag aren’t automatically supported.</li>
</ul>
<p>Perhaps GHC could spawn another GHC process to build its plugins and then load them as with <code>-fplugin-library</code>. That would work around the isolation issue without having to refactor the compiler code.</p>
<h2 id="could-we-make-ghc-multi-target-instead-of-using-two-separate-ghcs">Could we make GHC multi-target instead of using two separate GHCs?</h2>
<p>Instead of managing two GHCs or more (one for plugins that will be loaded with <code>-fplugin-library</code> by other GHCs, some more for the targets), we could use a single ghc program to which we pass different flags to select the target.</p>
<p>It is already possible as we’ve made GHC target agnostic: we just have to pass a different “top-dir” with the <code>-B</code> flag to select different settings and boot packages.</p>
<p>We could imagine:</p>
<ul>
<li><p>GHC being aware of the <code>-B</code> flag required to build plugins. Then it would invoke itself to build them with the proper settings/packages.</p></li>
<li><p>a tool with a nice UI that would be used to generate fresh “top-dirs” (settings, boot packages…) for different targets.</p></li>
</ul>
<p>The second point would also allow the “reinstallation” of <code>ghc-base</code> mentioned earlier. Using a different <code>ghc-base</code> would be similar to cross-compiling to a different platform: we can’t link the generated code with the compiler because of the discrepancies between the <code>ghc-base</code> used to build the compiler and <code>ghc-base</code> used to build the target code. Similarly, we could “reinstall” all the boot packages: <code>rts</code>, <code>directory</code>, <code>unix</code>, <code>base</code>… Just like what Hadrian does.</p>
<p>Note: plugins depend on the <code>ghc</code> library (<code>ghc-lib</code>), which itself depends on third-party libraries (<code>directory</code>, <code>unix</code>, <code>base</code>…) so they would still be forced to use the libraries used to build GHC itself. This is a real issue. Someone <a href="https://discourse.haskell.org/t/plugin-dependency-conflict/10121">reported exactly this</a> just while I was writing this post:</p>
<blockquote>
<p>I am trying to write a plugin but am having the problem where the ghc package want transformers 0.5.6.2 but the package I want the plugin to modify requires 0.6.1.1.</p>
<p>Since, the compiled plugin objects do not intermix with the compiled project objects it seems like this should not actually be a conflict. Is there a way to resolve this?</p>
</blockquote>
<h2 id="pluginsth-status">Plugins/TH status</h2>
<ul>
<li><code>-fplugin-library</code> is implemented since 9.6.</li>
<li>It requires compilers to be stage2, which cross-compilers aren’t by default yet
<ul>
<li>there is some work in progress to fix this: <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/19174">#19174</a></li>
</ul></li>
<li>Automatic build of the external interpreter is what the JavaScript backend does (approximately)
<ul>
<li>Generalization to other targets is still to do: <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/24731">#24731</a></li>
</ul></li>
<li><code>ghc-toolchain</code> is a new tool that should give the nice UI to generate new target “top-dir”
<ul>
<li>I’m not fully aware of its status and roadmap</li>
</ul></li>
</ul>
<p>Ultimately it would be nice to only distribute:</p>
<ul>
<li>programs: <code>ghc</code>, <code>ghc-pkg</code>, <code>ghc-toolchain</code>…</li>
<li>libraries for plugins: <code>ghc-base</code>, <code>ghc-lib</code>…</li>
<li>settings for plugins</li>
</ul>
<p>and to let <code>ghc-toolchain</code> (maybe called via <code>cabal</code>) initialize for every target:</p>
<ul>
<li>the settings (toolchain to use, etc.)</li>
<li>the boot packages (<code>ghc-base</code>, <code>base</code>, <code>template-haskell</code>, <code>ghci</code>…)</li>
<li>an external interpreter</li>
</ul>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Contributions to GHC 9.8</title>
    <link href="http://www.hsyl20.fr/home/posts/2023-11-01-contributions-ghc-98.html" />
    <id>http://www.hsyl20.fr/home/posts/2023-11-01-contributions-ghc-98.html</id>
    <published>2023-11-01T00:00:00Z</published>
    <updated>2023-11-01T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Contributions to GHC 9.8</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">November  1, 2023</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This is my GHC activities report for GHC 9.8</p>
<p>I’ve made roughly 62 commits for the GHC 9.8 series at the time of writing (it’s difficult to know for sure because of the backports).</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1">❯ <span class="fu">git</span> merge-base origin/ghc-9.8 origin/ghc-9.6</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="ex">93ee7e9004c6acf01bf850a9be65c6cfe482e6f0</span></a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4">❯ <span class="fu">git</span> log --author <span class="st">&quot;Sylvain Henry&quot;</span> --oneline \</a>
<a class="sourceLine" id="cb1-5" title="5">    93ee7e9004c6acf01bf850a9be65c6cfe482e6f0..origin/ghc-9.8 <span class="kw">|</span> <span class="fu">wc</span> --lines</a>
<a class="sourceLine" id="cb1-6" title="6"><span class="ex">62</span></a></code></pre></div>
<p>This blog post only lists my personal contributions and thoughts and doesn’t engage my team nor IOG.</p>
<h1 id="javascript-backend">JavaScript backend</h1>
<p>This time the focus of my team was to make the JavaScript backend more usable. We’ve fixed a lot of issues. I’ve implemented Template-Haskell support by reusing some of the external interpreter code.</p>
<h1 id="appendix-commit-list">Appendix: commit list</h1>
<div class="sourceCode" id="cb2"><pre class="sourceCode txt"><code class="sourceCode default"><a class="sourceLine" id="cb2-1" title="1"># JavaScript backend</a>
<a class="sourceLine" id="cb2-2" title="2"></a>
<a class="sourceLine" id="cb2-3" title="3">a3623053daa JS: implement openat(AT_FDCWD...) (#23697)</a>
<a class="sourceLine" id="cb2-4" title="4">bdf2adf7133 JS: implement getMonotonicTime (fix #23687)</a>
<a class="sourceLine" id="cb2-5" title="5">b0b88c240d9 JS: support levity-polymorphic datatypes (#22360,#22291)</a>
<a class="sourceLine" id="cb2-6" title="6">27df38c2503 JS: better implementation for plusWord64 (#23597)</a>
<a class="sourceLine" id="cb2-7" title="7">90846d43179 JS: support -this-unit-id for programs in the linker (#23613)</a>
<a class="sourceLine" id="cb2-8" title="8">fb4ecd83171 JS: fix JS stack printing (#23565)</a>
<a class="sourceLine" id="cb2-9" title="9">dbb4ad519c3 JS: always recompile when TH is enabled (cf #23013)</a>
<a class="sourceLine" id="cb2-10" title="10">a897dc13d2f TH_import_loop is now broken as expected</a>
<a class="sourceLine" id="cb2-11" title="11">fab2ad23c9c Fix some recompilation avoidance tests</a>
<a class="sourceLine" id="cb2-12" title="12">f84ff161395 Stg: return imported FVs</a>
<a class="sourceLine" id="cb2-13" title="13">3249cf1216f Don't use getKey</a>
<a class="sourceLine" id="cb2-14" title="14">4d356ea3049 JS: implement TH support</a>
<a class="sourceLine" id="cb2-15" title="15">c3a1274c451 JS: don't dump eventlog to stderr by default</a>
<a class="sourceLine" id="cb2-16" title="16">9132d529ad2 JS: testsuite: use correct ticket numbers</a>
<a class="sourceLine" id="cb2-17" title="17">a5f0c00ee19 JS: factorize SaneDouble into its own module</a>
<a class="sourceLine" id="cb2-18" title="18">08d8e9efa24 JS: more triage</a>
<a class="sourceLine" id="cb2-19" title="19">15f150c8fcb JS: testsuite: update ticket numbers</a>
<a class="sourceLine" id="cb2-20" title="20">4a41ba752fd JS: testsuite: use correct ticket number</a>
<a class="sourceLine" id="cb2-21" title="21">f53ac0ae30a JS: fix and enhance non-minimized code generation (#22455)</a>
<a class="sourceLine" id="cb2-22" title="22">2972fd66f91 JS: fix getpid (fix #23399)</a>
<a class="sourceLine" id="cb2-23" title="23">2f571afe1c2 Fix GHCJS OS platform (fix #23346)</a>
<a class="sourceLine" id="cb2-24" title="24">2d5c1ddecf1 Fix remaining issues with bound checking (#23123)</a>
<a class="sourceLine" id="cb2-25" title="25">1e9caa1a54e Bump Cabal submodule (#22356)</a>
<a class="sourceLine" id="cb2-26" title="26">113e21d7636 Testsuite: replace some js_broken/js_skip predicates with req_c</a>
<a class="sourceLine" id="cb2-27" title="27">ab6c1d295cd Testsuite: don't use obsolescent egrep (#22351)</a>
<a class="sourceLine" id="cb2-28" title="28">d442ac053f9 JS: fix thread-related primops</a>
<a class="sourceLine" id="cb2-29" title="29">eed0d9307b3 GHCi.RemoteTypes: fix doc and avoid unsafeCoerce (#23201)</a>
<a class="sourceLine" id="cb2-30" title="30">a8e36892689 JS: fix issues with FD api support</a>
<a class="sourceLine" id="cb2-31" title="31">ab9cd52d4fa ghc-heap: remove wrong Addr# coercion (#23181)</a>
<a class="sourceLine" id="cb2-32" title="32">f4f1f14f800 ghc-heap: remove wrong Addr# coercion (#23181)</a>
<a class="sourceLine" id="cb2-33" title="33">30d45e971d9 Testsuite: use js_skip for T2615 (#22374)</a>
<a class="sourceLine" id="cb2-34" title="34">ad765b6f0bb Testsuite: use req_interp predicate for T20214</a>
<a class="sourceLine" id="cb2-35" title="35">a1528b68318 Testsuite: use req_interp predicate for T16318 (#22370)</a>
<a class="sourceLine" id="cb2-36" title="36">0ab0cc119c6 Testsuite: use appropriate predicate for ManyUbxSums test (#22576)</a>
<a class="sourceLine" id="cb2-37" title="37">5b4628aeeca JS: remove dead code for old integer-gmp</a>
<a class="sourceLine" id="cb2-38" title="38">239202a2b14 Testsuite: replace some js_skip with req_cmm</a>
<a class="sourceLine" id="cb2-39" title="39">8b77f9bfceb JS: fix for overlap with copyMutableByteArray# (#23033)</a>
<a class="sourceLine" id="cb2-40" title="40">7825fef9f20 JS: Store CI perf results (fix #22923)</a>
<a class="sourceLine" id="cb2-41" title="41">4eb9c234886 JS: make some arithmetic primops faster (#22835)</a>
<a class="sourceLine" id="cb2-42" title="42">a203ad854ff Merge libiserv with ghci</a>
<a class="sourceLine" id="cb2-43" title="43">324e925be84 JS: disable debugging info for heap objects</a>
<a class="sourceLine" id="cb2-44" title="44">df3d94bd295 Testsuite: mark T13167 as fragile for JS (#22921)</a>
<a class="sourceLine" id="cb2-45" title="45">c44e5f30cac Testsuite: decrease length001 timeout for JS (#22921)</a>
<a class="sourceLine" id="cb2-46" title="46">c1670c6bb0b JS: avoid head/tail and unpackFS</a>
<a class="sourceLine" id="cb2-47" title="47">6636b670233 JS: replace &quot;js&quot; architecture with &quot;javascript&quot;</a>
<a class="sourceLine" id="cb2-48" title="48">6932cfc798e Fix spurious change from !9568</a>
<a class="sourceLine" id="cb2-49" title="49">5640cb1d84d Hadrian: fix doc generation</a>
<a class="sourceLine" id="cb2-50" title="50">2fdf22aebda configure: support &quot;windows&quot; as an OS</a>
<a class="sourceLine" id="cb2-51" title="51">288fa0179a2 Fix RTS build on Windows</a>
<a class="sourceLine" id="cb2-52" title="52">48131ee2d8b Hadrian: fix Windows cross-compilation</a>
<a class="sourceLine" id="cb2-53" title="53">e987e345c80 Hadrian: correctly detect AR at-file support</a>
<a class="sourceLine" id="cb2-54" title="54">06036d931f5 testsuite: req_smp --&gt; req_target_smp, req_ghc_smp</a>
<a class="sourceLine" id="cb2-55" title="55">99757ce8e32 JS: fix support for -outputdir (#22641)</a>
<a class="sourceLine" id="cb2-56" title="56"></a>
<a class="sourceLine" id="cb2-57" title="57"></a>
<a class="sourceLine" id="cb2-58" title="58"># Misc</a>
<a class="sourceLine" id="cb2-59" title="59"></a>
<a class="sourceLine" id="cb2-60" title="60">db31f25c5ea Add missing int64/word64-to-double/float rules (#23907)</a>
<a class="sourceLine" id="cb2-61" title="61">07f858eb1ff Factorize getLinkDeps</a>
<a class="sourceLine" id="cb2-62" title="62">b56d737974f NCG: remove useless .align directive (#20758)</a>
<a class="sourceLine" id="cb2-63" title="63">1bd32a355bd Factorize hptModulesBelow</a>
<a class="sourceLine" id="cb2-64" title="64">4158722a6cf linker: fix linking with aligned sections (#23066)</a>
<a class="sourceLine" id="cb2-65" title="65">8af401ccfbe Make WordQuotRem2Op ok-for-speculation too</a>
<a class="sourceLine" id="cb2-66" title="66">1148ac723d6 Make Int64/Word64 division ok for speculation too.</a>
<a class="sourceLine" id="cb2-67" title="67">4dd02122755 Add quot folding rule (#22152)</a>
<a class="sourceLine" id="cb2-68" title="68">59321879419 Add quotRem rules (#22152)</a></code></pre></div>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Contributions to GHC 9.6</title>
    <link href="http://www.hsyl20.fr/home/posts/2023-04-01-contributions-ghc-96.html" />
    <id>http://www.hsyl20.fr/home/posts/2023-04-01-contributions-ghc-96.html</id>
    <published>2023-04-01T00:00:00Z</published>
    <updated>2023-04-01T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Contributions to GHC 9.6</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">April  1, 2023</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This is my GHC activities report for GHC 9.6</p>
<p>I’ve made roughly 38 commits for the GHC 9.6 series at the time of writing.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1">❯ <span class="fu">git</span> merge-base origin/ghc-9.6 origin/ghc-9.4</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="ex">27362265e50b59aee9a0ae17560ce091f5501985</span></a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4">❯ <span class="fu">git</span> log --author <span class="st">&quot;Sylvain Henry&quot;</span> --oneline \</a>
<a class="sourceLine" id="cb1-5" title="5">    27362265e50b59aee9a0ae17560ce091f5501985..origin/ghc-9.6 <span class="kw">|</span> <span class="fu">wc</span> --lines</a>
<a class="sourceLine" id="cb1-6" title="6"><span class="ex">38</span></a></code></pre></div>
<p>This blog post only lists my personal contributions and thoughts and doesn’t engage my team nor IOG.</p>
<h1 id="javascript-backend">JavaScript backend</h1>
<p>This time the focus of my team was to upstream GHCJS (Haskell to GHC compiler) into GHC. The commit adding the JS backend is a squash of a few hundreds of commits (about 522 commits in a branch before the squash) of which I’ve made over 60% (not that commits are a very good metrics).</p>
<h1 id="external-static-plugins">External static plugins</h1>
<p>I’ve spent quite some time trying to make GHC support more than one context at once to support plugins while doing cross-compilation: one context for the target, one context for the host (for plugins). I now think it’s a dead-end because the code still isn’t modular enough. It would be a lot of work to fix and there are opposing forces which make it very unlikely to happen in practice.</p>
<p>I’ve implemented a workaround called “external static plugins”. GHC still doesn’t know how to build plugins in a cross compiler, but if there are built beforehand and put in a library, it can now load them.</p>
<h1 id="appendix-commit-list">Appendix: commit list</h1>
<div class="sourceCode" id="cb2"><pre class="sourceCode txt"><code class="sourceCode default"><a class="sourceLine" id="cb2-1" title="1"># JavaScript</a>
<a class="sourceLine" id="cb2-2" title="2"></a>
<a class="sourceLine" id="cb2-3" title="3">cc25d52e0f6 Add Javascript backend</a>
<a class="sourceLine" id="cb2-4" title="4">d86cd08b268 Fix remaining issues with bound checking (#23123)</a>
<a class="sourceLine" id="cb2-5" title="5">d5de8a2ab9d Hadrian: enable `-fcheck-prim-bounds` in validate flavour</a>
<a class="sourceLine" id="cb2-6" title="6">86a9404a8bc Fix GHCJS OS platform (fix #23346)</a>
<a class="sourceLine" id="cb2-7" title="7">5292bdf87f1 JS: fix getpid (fix #23399)</a>
<a class="sourceLine" id="cb2-8" title="8">7083db5a7ff JS: fix thread-related primops</a>
<a class="sourceLine" id="cb2-9" title="9">b821cdbd911 JS: fix for overlap with copyMutableByteArray# (#23033)</a>
<a class="sourceLine" id="cb2-10" title="10">e0cfea59a30 Testsuite: decrease length001 timeout for JS (#22921)</a>
<a class="sourceLine" id="cb2-11" title="11">6164ceb89b2 JS: disable debugging info for heap objects</a>
<a class="sourceLine" id="cb2-12" title="12">bafa3899758 JS: replace &quot;js&quot; architecture with &quot;javascript&quot;</a>
<a class="sourceLine" id="cb2-13" title="13">42ea9cea6ab JS: fix support for -outputdir (#22641)</a>
<a class="sourceLine" id="cb2-14" title="14">8b1f1b4503b JS: fix object file name comparison (#22578)</a>
<a class="sourceLine" id="cb2-15" title="15"></a>
<a class="sourceLine" id="cb2-16" title="16"># External static plugins</a>
<a class="sourceLine" id="cb2-17" title="17"></a>
<a class="sourceLine" id="cb2-18" title="18">f95bbdcae3e Add support for external static plugins (#20964)</a>
<a class="sourceLine" id="cb2-19" title="19"></a>
<a class="sourceLine" id="cb2-20" title="20"># Numeric</a>
<a class="sourceLine" id="cb2-21" title="21"></a>
<a class="sourceLine" id="cb2-22" title="22">c284a3e8b1c Bignum: fix right shift of negative BigNat with native backend</a>
<a class="sourceLine" id="cb2-23" title="23">9283b7d388d Avoid out-of-bound array access in bigNatIsPowerOf2 (fix #24066)</a>
<a class="sourceLine" id="cb2-24" title="24">b6bd8c09e1e Add missing int64/word64-to-double/float rules (#23907)</a>
<a class="sourceLine" id="cb2-25" title="25">7f203d00edd Numeric exceptions: replace FFI calls with primops</a>
<a class="sourceLine" id="cb2-26" title="26"></a>
<a class="sourceLine" id="cb2-27" title="27"># Misc</a>
<a class="sourceLine" id="cb2-28" title="28"></a>
<a class="sourceLine" id="cb2-29" title="29">1ae57288cab Fix unusable units and module reexport interaction (#21097)</a>
<a class="sourceLine" id="cb2-30" title="30">1838c3d8ed5 GHC.HsToCore.Breakpoints: Slightly improve perf</a>
<a class="sourceLine" id="cb2-31" title="31">83467435c4e Avoid using DynFlags in GHC.Linker.Unit (#17957)</a>
<a class="sourceLine" id="cb2-32" title="32">f2e707077bf Hadrian: remove unused code</a>
<a class="sourceLine" id="cb2-33" title="33">6f5ff4fa0ee Bump hadrian to LTS-19.8 (GHC 9.0.2)</a>
<a class="sourceLine" id="cb2-34" title="34">5a5a28dafbb Split GHC.HsToCore.Foreign.Decl</a>
<a class="sourceLine" id="cb2-35" title="35">5878f439d42 Enable USE_INLINE_SRT_FIELD on ARM64</a>
<a class="sourceLine" id="cb2-36" title="36">acc268064da Some fixes to SRT documentation</a>
<a class="sourceLine" id="cb2-37" title="37">913963271f9 MachO linker: fix handling of ARM64_RELOC_SUBTRACTOR</a>
<a class="sourceLine" id="cb2-38" title="38">ef3c8d9e077 Don't store LlvmConfig into DynFlags</a>
<a class="sourceLine" id="cb2-39" title="39">a4fbb589fd1 STG: only print cost-center if asked to</a>
<a class="sourceLine" id="cb2-40" title="40">7a51125dff1 Rts: expose rtsOutOfBoundsAccess symbol</a>
<a class="sourceLine" id="cb2-41" title="41">2d7ca624481 linker: fix linking with aligned sections (#23066)</a>
<a class="sourceLine" id="cb2-42" title="42">826a311221c configure: support &quot;windows&quot; as an OS</a>
<a class="sourceLine" id="cb2-43" title="43">e0d9ef66737 Fix RTS build on Windows</a>
<a class="sourceLine" id="cb2-44" title="44">7d86db2be74 Hadrian: fix Windows cross-compilation</a>
<a class="sourceLine" id="cb2-45" title="45">ef21780f8b8 Hadrian: correctly detect AR at-file support</a>
<a class="sourceLine" id="cb2-46" title="46">b5c714545ab Don't let configure perform trivial substitutions (#21846)</a>
<a class="sourceLine" id="cb2-47" title="47">9ab31f42da8 Testsuite: more precise test options</a>
<a class="sourceLine" id="cb2-48" title="48">a2f53ac8d96 Add GHC.SysTools.Cpp module</a>
<a class="sourceLine" id="cb2-49" title="49">0988a23d211 Enable popcount rewrite rule when cross-compiling</a></code></pre></div>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Contributions to GHC 9.4</title>
    <link href="http://www.hsyl20.fr/home/posts/2022-08-10-contributions-ghc-94.html" />
    <id>http://www.hsyl20.fr/home/posts/2022-08-10-contributions-ghc-94.html</id>
    <published>2022-08-10T00:00:00Z</published>
    <updated>2022-08-10T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Contributions to GHC 9.4</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">August 10, 2022</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This is my GHC activities report for GHC 9.4</p>
<p>I’ve made roughly 176 commits for the GHC 9.4 series at the time of writing.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1">❯ <span class="fu">git</span> merge-base origin/ghc-9.4 origin/ghc-9.2</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="ex">05c5c0549bee022be84344cef46f0eded5564c3b</span></a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4">❯ <span class="fu">git</span> log --author <span class="st">&quot;Sylvain Henry&quot;</span> --oneline \</a>
<a class="sourceLine" id="cb1-5" title="5">    05c5c0549bee022be84344cef46f0eded5564c3b..origin/ghc-9.4 <span class="kw">|</span> <span class="fu">wc</span> --lines</a>
<a class="sourceLine" id="cb1-6" title="6"><span class="ex">176</span></a></code></pre></div>
<p>This blog post only lists my personal contributions and thoughts and doesn’t engage my team nor IOG.</p>
<p>Mostly a continuation of my work for GHC-9.2.</p>
<p>Quite a lot of work in progress towards:</p>
<ul>
<li>allowing bignum primitives to inline</li>
<li>supporting plugins in cross-compilers</li>
<li>Windows support</li>
<li>performance</li>
<li>and a few other things.</li>
</ul>
<h1 id="appendix-commit-list">Appendix: commit list</h1>
<div class="sourceCode" id="cb2"><pre class="sourceCode txt"><code class="sourceCode default"><a class="sourceLine" id="cb2-1" title="1"># Numeric</a>
<a class="sourceLine" id="cb2-2" title="2"></a>
<a class="sourceLine" id="cb2-3" title="3">0d758dc36e1 Add missing int64/word64-to-double/float rules (#23907)</a>
<a class="sourceLine" id="cb2-4" title="4">3570eda512d Fix comments about Int64/Word64 primops</a>
<a class="sourceLine" id="cb2-5" title="5">c48a7c3a616 Use Word64# primops in Word64 Num instance</a>
<a class="sourceLine" id="cb2-6" title="6">be9d78625f1 Fix Int64/Word64's Enum instance fusion</a>
<a class="sourceLine" id="cb2-7" title="7">4c86df25d36 Fix Int64ToInt/Word64ToWord rules on 32-bit architectures</a>
<a class="sourceLine" id="cb2-8" title="8">e279ea64792 Add missing Int64/Word64 constant-folding rules</a>
<a class="sourceLine" id="cb2-9" title="9">c8d89f62a32 Bignum: add missing rule</a>
<a class="sourceLine" id="cb2-10" title="10">a901a1ae670 Bignum: allow Integer's signum to inline (#20361)</a>
<a class="sourceLine" id="cb2-11" title="11">758e0d7bbe5 Bignum: allow Integer predicates to inline (#20361)</a>
<a class="sourceLine" id="cb2-12" title="12">0b575899eca Bignum: constant folding for bigNatCompareWord# (#20361)</a>
<a class="sourceLine" id="cb2-13" title="13">4d44058d631 Bignum: transfer NOINLINE from Natural to BigNat</a>
<a class="sourceLine" id="cb2-14" title="14">714568bb9e6 Bignum: remove outdated comment</a>
<a class="sourceLine" id="cb2-15" title="15">3a5a5c859b5 Bignum: allow naturalToWordClamp/Negate/Signum to inline (#20361)</a>
<a class="sourceLine" id="cb2-16" title="16">44886aaba46 Bignum: allow inlining of naturalEq/Ne/Gt/Lt/Ge/Le/Compare (#20361)</a>
<a class="sourceLine" id="cb2-17" title="17">e1d02fb0f04 Bignum: allow naturalEq#/Ne# to inline (#20361)</a>
<a class="sourceLine" id="cb2-18" title="18">11240b7427c Constant folding for (.&amp;.) maxBound (#20448)</a>
<a class="sourceLine" id="cb2-19" title="19">b3267fadd42 Constant folding for negate (#20347)</a>
<a class="sourceLine" id="cb2-20" title="20">33eb4a4e396 Constant-folding for timesInt2# (#20374)</a>
<a class="sourceLine" id="cb2-21" title="21">d41cfdd4455 Constant folding for ctz/clz/popCnt (#20376)</a>
<a class="sourceLine" id="cb2-22" title="22">089de88ef52 Canonicalize bignum literals</a>
<a class="sourceLine" id="cb2-23" title="23">f72aa31d36f Bignum: refactor conversion rules</a>
<a class="sourceLine" id="cb2-24" title="24">247684adc83 Bignum: remove unused extra files</a>
<a class="sourceLine" id="cb2-25" title="25">54880c131db Bignum: fix invalid hs-boot declaration (#19638)</a>
<a class="sourceLine" id="cb2-26" title="26">a951e06921f Bignum: add BigNat Eq/Ord instances (#19647)</a>
<a class="sourceLine" id="cb2-27" title="27">7bb3443a4fe Fix inlining of division wrappers</a>
<a class="sourceLine" id="cb2-28" title="28">c308c9af2e1 Make divModInt# branchless</a>
<a class="sourceLine" id="cb2-29" title="29">e50d06752e2 Allow divInt#/modInt# to inline (#18067)</a>
<a class="sourceLine" id="cb2-30" title="30">8d069477b77 Refactor modInt# to make it branchless</a>
<a class="sourceLine" id="cb2-31" title="31">59cf287d372 Refactor divInt# to make it branchless (#18067, #19636)</a>
<a class="sourceLine" id="cb2-32" title="32">df4a0a53691 Bignum: bump to version 1.1 (#19846)</a>
<a class="sourceLine" id="cb2-33" title="33">941d3792b2e Rules for sized conversion primops (#19769)</a>
<a class="sourceLine" id="cb2-34" title="34">5798357d939 StgToCmm: use correct bounds for switches on sized values</a>
<a class="sourceLine" id="cb2-35" title="35">748636388b0 Remove ad-hoc fromIntegral rules</a>
<a class="sourceLine" id="cb2-36" title="36">a820f9002d8 Detect underflow in fromIntegral/Int-&gt;Natural rule</a>
<a class="sourceLine" id="cb2-37" title="37">e5a4cfa5189 Bignum: don't allocate in bignat_mul (#20028)</a>
<a class="sourceLine" id="cb2-38" title="38">8838241f7d6 Fix naturalToFloat/Double</a>
<a class="sourceLine" id="cb2-39" title="39">453877600b7 Bignum: match on DataCon workers in rules (#19892)</a>
<a class="sourceLine" id="cb2-40" title="40">df997fac54b Use quotRemWord in showWord</a>
<a class="sourceLine" id="cb2-41" title="41">737b0ae194c Fix Integral instances for Words</a>
<a class="sourceLine" id="cb2-42" title="42"></a>
<a class="sourceLine" id="cb2-43" title="43"># Cross-compilation, build system, Windows support...</a>
<a class="sourceLine" id="cb2-44" title="44"></a>
<a class="sourceLine" id="cb2-45" title="45">69ab7f358a0 configure: support &quot;windows&quot; as an OS</a>
<a class="sourceLine" id="cb2-46" title="46">9e07003f2aa Fix RTS build on Windows</a>
<a class="sourceLine" id="cb2-47" title="47">35b059d8b52 Hadrian: fix Windows cross-compilation</a>
<a class="sourceLine" id="cb2-48" title="48">3247e44aa25 Hadrian: correctly detect AR at-file support</a>
<a class="sourceLine" id="cb2-49" title="49">8f8194539b6 linker: fix linking with aligned sections (#23066)</a>
<a class="sourceLine" id="cb2-50" title="50">cc59648adbf Hadrian: allow testsuite to run with cross-compilers (#21292)</a>
<a class="sourceLine" id="cb2-51" title="51">ed04aed2b2d Hadrian: use IntSet Binary instance for Way (#19209)</a>
<a class="sourceLine" id="cb2-52" title="52">c82fb93476b Hadrian: avoid allocations in WayUnit's Read instance (#19209)</a>
<a class="sourceLine" id="cb2-53" title="53">c062fac0023 Hadrian: remove useless imports</a>
<a class="sourceLine" id="cb2-54" title="54">2509d676a77 Hadrian: avoid allocating in stageString (#19209)</a>
<a class="sourceLine" id="cb2-55" title="55">88a945410fe Hadrian: avoid useless allocations in trackArgument</a>
<a class="sourceLine" id="cb2-56" title="56">68a3665a73c Hadrian: bump stackage LTS to 18.18 (GHC 8.10.7)</a>
<a class="sourceLine" id="cb2-57" title="57">bdeea37efc7 More support for optional home-unit</a>
<a class="sourceLine" id="cb2-58" title="58">d9f5490591c Hadrian: fix windows cross-build (#20657)</a>
<a class="sourceLine" id="cb2-59" title="59">3302f42a57a Fix windres invocation</a>
<a class="sourceLine" id="cb2-60" title="60">8c0aec38c12 Hadrian: fix building/registering of .dll libraries</a>
<a class="sourceLine" id="cb2-61" title="61">79a26df1475 Don't expose bignum backend in ghc --info (#20495)</a>
<a class="sourceLine" id="cb2-62" title="62">bc498fdfa48 Bignum: expose backendName (#20495)</a>
<a class="sourceLine" id="cb2-63" title="63">2800eee24d0 Make Word64 use Word64# on every architecture</a>
<a class="sourceLine" id="cb2-64" title="64">20956e5784f Remove target dependent CPP for Word64/Int64 (#11470)</a>
<a class="sourceLine" id="cb2-65" title="65">bbb1f6dab34 Hadrian: display command line above errors (#20490)</a>
<a class="sourceLine" id="cb2-66" title="66">ecd6d14215e i386: fix codegen of 64-bit comparisons</a>
<a class="sourceLine" id="cb2-67" title="67">3d31f11e83a Don't link plugins' units with target code (#20218)</a>
<a class="sourceLine" id="cb2-68" title="68">41d6cfc4d36 Add Word64#/Int64# primops</a>
<a class="sourceLine" id="cb2-69" title="69">5741caeb045 Only update config.sub when it already exists (#19574)</a>
<a class="sourceLine" id="cb2-70" title="70">d014ab0db0c Remove dynamic-by-default (#16782)</a>
<a class="sourceLine" id="cb2-71" title="71">8d87975ebe9 Produce constant file atomically (#19684)</a>
<a class="sourceLine" id="cb2-72" title="72">b699c4fb0d2 Constants: add a note and fix minor doc glitches</a>
<a class="sourceLine" id="cb2-73" title="73">2cdc95f9c06 Don't produce platformConstants file</a>
<a class="sourceLine" id="cb2-74" title="74">085983e63bf Read constants header instead of global platformConstants</a>
<a class="sourceLine" id="cb2-75" title="75">9c762f27d54 Generate parser for DerivedConstants.h</a>
<a class="sourceLine" id="cb2-76" title="76">6623790d748 Hadrian: build check-* with -Wall/-Werror</a>
<a class="sourceLine" id="cb2-77" title="77">f0b73ddd8bd Hadrian: add comment to avoid surprises</a>
<a class="sourceLine" id="cb2-78" title="78">92257abd4b6 Link with libm dynamically (#19877)</a>
<a class="sourceLine" id="cb2-79" title="79">8b9acc4d58f Hadrian: fix .cabal file</a>
<a class="sourceLine" id="cb2-80" title="80">323473e86d4 Hadrian: disable profiled RTS with no_profiled_libs flavour transformer</a>
<a class="sourceLine" id="cb2-81" title="81">cddafcf6a96 PIC: test for cross-module references</a>
<a class="sourceLine" id="cb2-82" title="82">e2d8023dfe1 Add some tests for sized primops</a>
<a class="sourceLine" id="cb2-83" title="83">703c0c3c13c Bump libffi submodule to libffi-3.3 (#16940)</a>
<a class="sourceLine" id="cb2-84" title="84">82b097b3d43 Remove wired-in names hs-boot check bypass (#19855)</a>
<a class="sourceLine" id="cb2-85" title="85">fc9546caf3e genprimopcode: fix bootstrap errors</a>
<a class="sourceLine" id="cb2-86" title="86"></a>
<a class="sourceLine" id="cb2-87" title="87"># Modularity, refactorings</a>
<a class="sourceLine" id="cb2-88" title="88"></a>
<a class="sourceLine" id="cb2-89" title="89">940feaf3c23 Modularize Tidy (#17957)</a>
<a class="sourceLine" id="cb2-90" title="90">e6585ca168b Define filterOut with filter</a>
<a class="sourceLine" id="cb2-91" title="91">e3f60577b5c Reverse dependency between StgToCmm and Runtime.Heap.Layout</a>
<a class="sourceLine" id="cb2-92" title="92">1a7cf0963e3 Avoid redundant imports of GHC.Driver.Session</a>
<a class="sourceLine" id="cb2-93" title="93">52ffd38c610 Avoid some SOURCE imports</a>
<a class="sourceLine" id="cb2-94" title="94">929c280f991 Derive Enum instances for CCallConv and Safety</a>
<a class="sourceLine" id="cb2-95" title="95">ad04953b0d2 Allow hscGenHardCode to not return CgInfos</a>
<a class="sourceLine" id="cb2-96" title="96">677c6c913a9 Testsuite: remove arch conditional in T8832</a>
<a class="sourceLine" id="cb2-97" title="97">2b1cced1815 NCG: minor code factorization</a>
<a class="sourceLine" id="cb2-98" title="98">a31ace56209 Untangled GHC.Types.Id.Make from the driver</a>
<a class="sourceLine" id="cb2-99" title="99">7b0c938483b Abstract BangOpts</a>
<a class="sourceLine" id="cb2-100" title="100">9728d6c2b62 Give plugins a better interface (#17957)</a>
<a class="sourceLine" id="cb2-101" title="101">14e9cab675f Use Monoid in hptSomeThingsBelowUs</a>
<a class="sourceLine" id="cb2-102" title="102">b0a1ed5579a Add test for T15547 (#15547)</a>
<a class="sourceLine" id="cb2-103" title="103">806e49ae36a Refactor package imports</a>
<a class="sourceLine" id="cb2-104" title="104">6fd7da745a5 Remove Indefinite</a>
<a class="sourceLine" id="cb2-105" title="105">fa5870d3ac0 Add test for #19641</a>
<a class="sourceLine" id="cb2-106" title="106">f6a69fb897b Use an ADT for RecompReason</a>
<a class="sourceLine" id="cb2-107" title="107">c662ac7e39a Refactor module dependencies code</a>
<a class="sourceLine" id="cb2-108" title="108">da60e6276e4 Fix annoying warning about Data.List unqualified import</a>
<a class="sourceLine" id="cb2-109" title="109">628417b42c9 Fix lint issue</a>
<a class="sourceLine" id="cb2-110" title="110">a9c0b3ca1d4 Bump haddock submodule</a>
<a class="sourceLine" id="cb2-111" title="111">89ee9206548 Use foldGet in getSymbolTable</a>
<a class="sourceLine" id="cb2-112" title="112">532c6a54157 Remove UniqSupply from NameCache</a>
<a class="sourceLine" id="cb2-113" title="113">599efd90d54 Refactor FinderCache</a>
<a class="sourceLine" id="cb2-114" title="114">872a9444df4 Refactor NameCache</a>
<a class="sourceLine" id="cb2-115" title="115">d930fecb6d2 Refactor interface loading</a>
<a class="sourceLine" id="cb2-116" title="116">751b21448c8 Encapsulate the EPS IORef in a newtype</a>
<a class="sourceLine" id="cb2-117" title="117">706fad606db Fix tests</a>
<a class="sourceLine" id="cb2-118" title="118">85d7056a53f Move the EPS into UnitEnv</a>
<a class="sourceLine" id="cb2-119" title="119">7acfb61777c Move HPT in UnitEnv</a>
<a class="sourceLine" id="cb2-120" title="120">0219297c874 Move unit DBs in UnitEnv</a>
<a class="sourceLine" id="cb2-121" title="121">29326979eeb Properly initialise UnitEnv</a>
<a class="sourceLine" id="cb2-122" title="122">48c2c2af41a Fix genprimopcode warning</a>
<a class="sourceLine" id="cb2-123" title="123">491266eeaa6 Make GHC.Runtime.Interpreter independent of GHC.Driver</a>
<a class="sourceLine" id="cb2-124" title="124">c7ca3619e25 Interpreter: replace DynFlags with EvalOpts/BCOOpts</a>
<a class="sourceLine" id="cb2-125" title="125">8d6b25254e7 Move shift ops out of GHC.Base</a>
<a class="sourceLine" id="cb2-126" title="126">67a5a91ef5e Remove useless {-# LANGUAGE CPP #-} pragmas</a>
<a class="sourceLine" id="cb2-127" title="127">0ef11907134 Fully remove HsVersions.h</a>
<a class="sourceLine" id="cb2-128" title="128">bfabf94f63b Replace CPP assertions with Haskell functions</a>
<a class="sourceLine" id="cb2-129" title="129">da56ed41b62 Ensure assert from Control.Exception isn't used</a>
<a class="sourceLine" id="cb2-130" title="130">f78c25da058 Move GlobalVar macros into GHC.Utils.GlobalVars</a>
<a class="sourceLine" id="cb2-131" title="131">6d712150f8f Dynflags: introduce DiagOpts</a>
<a class="sourceLine" id="cb2-132" title="132">58b960d2af0 Make TmpFs independent of DynFlags</a>
<a class="sourceLine" id="cb2-133" title="133">c367b39e523 Refactoring module dependencies</a>
<a class="sourceLine" id="cb2-134" title="134">4f6726779fa Don't store tmpDir in Settings</a>
<a class="sourceLine" id="cb2-135" title="135">6ad25367fbd Fix ASSERTS_ENABLED CPP</a>
<a class="sourceLine" id="cb2-136" title="136">2d4cdfda6a7 Avoid unsafePerformIO for getProgName</a>
<a class="sourceLine" id="cb2-137" title="137">354ac99de09 Use target platform in guessOutputFile</a>
<a class="sourceLine" id="cb2-138" title="138">6f097a8161d Remove useless .hs-boot</a>
<a class="sourceLine" id="cb2-139" title="139">b51b4b9777d Make withException use SDocContext instead of DynFlags</a>
<a class="sourceLine" id="cb2-140" title="140">61c51c00b6e Fix redundant import</a>
<a class="sourceLine" id="cb2-141" title="141">4dc681c7c03 Make Logger independent of DynFlags</a>
<a class="sourceLine" id="cb2-142" title="142">9a28680d2e2 Put Unique related global variables in the RTS (#19940)</a>
<a class="sourceLine" id="cb2-143" title="143">14956cb89d8 Put tracing functions into their own module</a>
<a class="sourceLine" id="cb2-144" title="144">40c0f67fb55 Bump haddock submodule</a>
<a class="sourceLine" id="cb2-145" title="145">3a90814fdf5 Parser: make less DynFlags dependent</a>
<a class="sourceLine" id="cb2-146" title="146">6b2952cfab2 RTS: fix indentation warning</a>
<a class="sourceLine" id="cb2-147" title="147">3e4ef4b2d05 Move warning flag handling into Flags module</a>
<a class="sourceLine" id="cb2-148" title="148"></a>
<a class="sourceLine" id="cb2-149" title="149"># Performance</a>
<a class="sourceLine" id="cb2-150" title="150"></a>
<a class="sourceLine" id="cb2-151" title="151">bc8de322d31 NCG: inline some 64-bit primops on x86/32-bit (#5444)</a>
<a class="sourceLine" id="cb2-152" title="152">6fa7591e832 NCG: refactor the way registers are handled</a>
<a class="sourceLine" id="cb2-153" title="153">f07b13e38a2 NCG: refactor X86 codegen</a>
<a class="sourceLine" id="cb2-154" title="154">90a26f8b0dd Fix documentation about Word64Rep/Int64Rep (#16964)</a>
<a class="sourceLine" id="cb2-155" title="155">bc6ba8ef663 Make most shifts branchless</a>
<a class="sourceLine" id="cb2-156" title="156">ec26c38bfac Use primOpIds cache more often (#20857)</a>
<a class="sourceLine" id="cb2-157" title="157">c080b443142 Perf: use SmallArray for primops' Ids cache (#20857)</a>
<a class="sourceLine" id="cb2-158" title="158">9529d859fef Perf: avoid using (replicateM . length) when possible</a>
<a class="sourceLine" id="cb2-159" title="159">3f31bfe8c3c Perf: inline exprIsCheapX</a>
<a class="sourceLine" id="cb2-160" title="160">352284de379 Perf: remove allocation in writeBlocks and fix comment (#14309)</a>
<a class="sourceLine" id="cb2-161" title="161">4c6985cc91b Perf: remove an indirection when fetching the unique mask</a>
<a class="sourceLine" id="cb2-162" title="162">4bdafb48b40 Add (++)/literal rule</a>
<a class="sourceLine" id="cb2-163" title="163">8b3d98ff376 Don't use FastString for UTF-8 encoding only</a>
<a class="sourceLine" id="cb2-164" title="164">0bdb867e37b CoreTidy: handle special cases to preserve more sharing.</a>
<a class="sourceLine" id="cb2-165" title="165">3f851bbd473 Enhance pretty-printing perf</a>
<a class="sourceLine" id="cb2-166" title="166">1d03d8bef96 Replace (ptext .. sLit) with `text`</a>
<a class="sourceLine" id="cb2-167" title="167">e61d2d47c49 Make sized division primops ok-for-spec (#19026)</a>
<a class="sourceLine" id="cb2-168" title="168">b128a880b22 Ensure that newtype deriving strategy is used for CTypes</a>
<a class="sourceLine" id="cb2-169" title="169">901c79d8de4 Lookup string literals in top-level thunks (fix #16373)</a>
<a class="sourceLine" id="cb2-170" title="170">3968cd0c928 Constant-fold unpackAppendCString (fix #20174)</a>
<a class="sourceLine" id="cb2-171" title="171">fd7e272eab1 Perf: fix strictness in OccurAnal</a>
<a class="sourceLine" id="cb2-172" title="172">de98a0ce8f1 Additional constant-folding rule for binary AND/OR</a>
<a class="sourceLine" id="cb2-173" title="173">6eed426bf24 SysTools: make file copy more efficient</a>
<a class="sourceLine" id="cb2-174" title="174">23bb09c919a Perf: fix appendFS</a>
<a class="sourceLine" id="cb2-175" title="175"></a>
<a class="sourceLine" id="cb2-176" title="176"># RTS</a>
<a class="sourceLine" id="cb2-177" title="177"></a>
<a class="sourceLine" id="cb2-178" title="178">2929850f013 RTS: open timerfd synchronously (#20618)</a>
<a class="sourceLine" id="cb2-179" title="179">5f3991c7cab RTS: try to fix timer races</a>
<a class="sourceLine" id="cb2-180" title="180"></a>
<a class="sourceLine" id="cb2-181" title="181"># Misc</a>
<a class="sourceLine" id="cb2-182" title="182"></a>
<a class="sourceLine" id="cb2-183" title="183">e01ffec2456 ByteCode: avoid out-of-bound read</a>
<a class="sourceLine" id="cb2-184" title="184">646c3e21dd3 CI: allow perf-nofib to fail</a>
<a class="sourceLine" id="cb2-185" title="185">45a674aacf3 Add `-dsuppress-core-sizes` flag (#20342)</a>
<a class="sourceLine" id="cb2-186" title="186">87d93745fa1 Only dump Core stats when requested to do so (#20342)</a>
<a class="sourceLine" id="cb2-187" title="187">3fb1afea019 GHCi: don't discard plugins on reload (#20335)</a>
<a class="sourceLine" id="cb2-188" title="188">7bff8bf527d Fix pprDeps</a>
<a class="sourceLine" id="cb2-189" title="189">92b0037b3e1 Fix recomp021 locale</a>
<a class="sourceLine" id="cb2-190" title="190">7bad93a2866 Only create callstack in DEBUG builds</a>
<a class="sourceLine" id="cb2-191" title="191">4ae1e53c49f Fix spelling</a>
<a class="sourceLine" id="cb2-192" title="192">f192e623f57 Cmm: fix sinking after suspendThread</a>
<a class="sourceLine" id="cb2-193" title="193">0f8872ecac4 Fix and slight improvement to datacon worker/wrapper notes</a></code></pre></div>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Modularizing GHC paper</title>
    <link href="http://www.hsyl20.fr/home/posts/2022-05-03-modularizing-ghc-paper.html" />
    <id>http://www.hsyl20.fr/home/posts/2022-05-03-modularizing-ghc-paper.html</id>
    <published>2022-05-03T00:00:00Z</published>
    <updated>2022-05-03T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Modularizing GHC paper</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a></td>
               <td class="date">May  3, 2022</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This post is to announce the first public release of a <a href="http://www.hsyl20.fr/home/files/papers/2022-ghc-modularity.pdf">paper we wrote about modularizing GHC (PDF)</a></p>
<p>As you may know, I’ve been involved into several refactorings of GHC (adding some module hierarchy, ditching DynFlags, etc.). I have been asked a few times to write a document providing an overview of the design that we wanted to reach.</p>
<p>I dutily started to write this document more than two years ago. It started as a compilation of issues about the current design. However it was a bit difficult to state refactoring principles: for example, it seems obvious to me that <code>SDoc</code> mustn’t be coupled with <code>DynFlags</code>, but why? What’s the underlying principle?</p>
<p>Later I found out that I was in fact reinventing Domain-Driven Design (DDD). So I’ve started to reframe the paper as applying DDD principles to GHC. However the paper was put on hold, mostly because welcoming a baby sucked most of my time and energy to work on it.</p>
<p>A few weeks ago, we figured out with John (who had read the draft) that the paper could help a HSoC applicant: <a href="https://github.com/haskell-org/summer-of-haskell/issues/143">https://github.com/haskell-org/summer-of-haskell/issues/143</a> With the invaluable help of John and Jeff, we strove to make a first release of the paper in less than a week. We obviously failed to meet this deadline. But a few more weeks later, it’s finally there: <a href="http://www.hsyl20.fr/home/files/papers/2022-ghc-modularity.pdf">“Modularizing GHC” paper (PDF)</a> (in case you missed the link above)</p>
<p>It’s an odd paper because it’s a mix of:</p>
<ul>
<li>an audit report: a compilation of design issues, with some historical perspectives</li>
<li>a proposal: a proposed design for GHC, based on DDD</li>
<li>an experience report: our experience with refactoring GHC, and some method hints for doing it efficiently</li>
<li>an exposition of DDD to a FP audience, using GHC as an example</li>
</ul>
<p>Note that in the first draft I planned to also include mentions of Cabal. It was finally left out because it was a highway to despair, and the paper was already very long. We also only briefly mention Hadrian. Both could deserve their own paper of this kind.</p>
<hr />
<p>This post has been discussed on:</p>
<ul>
<li>Reddit: <a href="https://www.reddit.com/r/haskell/comments/uhdu4l/modularizing_ghc_paper/">https://www.reddit.com/r/haskell/comments/uhdu4l/modularizing_ghc_paper/</a></li>
<li>Discourse: <a href="https://discourse.haskell.org/t/modularizing-ghc-paper/4471">https://discourse.haskell.org/t/modularizing-ghc-paper/4471</a></li>
<li>ghc-devs: <a href="https://mail.haskell.org/pipermail/ghc-devs/2022-May/020673.html">https://mail.haskell.org/pipermail/ghc-devs/2022-May/020673.html</a></li>
<li>HN: <a href="https://news.ycombinator.com/item?id=31250141">https://news.ycombinator.com/item?id=31250141</a></li>
</ul>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>On the inlining of Integer and Natural operations</title>
    <link href="http://www.hsyl20.fr/home/posts/2022-04-28-inlining-bignum.html" />
    <id>http://www.hsyl20.fr/home/posts/2022-04-28-inlining-bignum.html</id>
    <published>2022-04-28T00:00:00Z</published>
    <updated>2022-04-28T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">On the inlining of Integer and Natural operations</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Bignum.html">Bignum</a></td>
               <td class="date">April 28, 2022</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>In this post I discuss the inlining of Integer and Natural operations in Haskell. It’s a promising performance work I’ve been conducting six months ago, which was blocked by an independent issue, but that I will likely resume soon as the issue has been fixed in the meantime.</p>
<p>Note: this post has been first published on IOHK Engineering blog.</p>
<hr />
<p>To follow this post, you must know that <code>Natural</code> numbers are represented as follows in <code>ghc-bignum</code>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="co">-- | Natural number</span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="co">--</span></a>
<a class="sourceLine" id="cb1-3" title="3"><span class="co">-- Invariant: numbers &lt;= WORD_MAXBOUND use the `NS` constructor</span></a>
<a class="sourceLine" id="cb1-4" title="4"><span class="kw">data</span> <span class="dt">Natural</span></a>
<a class="sourceLine" id="cb1-5" title="5">   <span class="ot">=</span> <span class="dt">NS</span> <span class="op">!</span><span class="dt">Word</span><span class="op">#</span></a>
<a class="sourceLine" id="cb1-6" title="6">   <span class="op">|</span> <span class="dt">NB</span> <span class="op">!</span><span class="dt">BigNat</span><span class="op">#</span></a></code></pre></div>
<p>Small naturals are represented with a <code>Word#</code> and large ones with a <code>BigNat#</code> (a <code>ByteArray#</code>).</p>
<p>Now consider the following simple example using Natural:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="co">-- | Add 2 to a Word. Use Natural to avoid Word overflow</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="ot">foo ::</span> <span class="dt">Word</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span></a>
<a class="sourceLine" id="cb2-3" title="3">foo x <span class="ot">=</span> <span class="fu">fromIntegral</span> x <span class="op">+</span> <span class="dv">2</span></a></code></pre></div>
<p>There are only small naturals involved: <code>fromIntegral x</code> is small because <code>x</code> is a <code>Word</code>, and <code>2</code> is small. We could hope that GHC would use <code>Word#</code> primops to implement this and would allocate a <code>Natural</code> heap object for the result <em>only</em>. However it’s not what happens currently, even in GHC HEAD. In the following STG dump, we can see that a <code>Natural</code> heap object is allocated for <code>x</code> before calling <code>naturalAdd</code> (<code>let</code> bindings in STG reflect heap allocations):</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1">foo1 <span class="ot">=</span> <span class="dt">NS</span><span class="op">!</span> [<span class="dv">2</span><span class="op">##</span>];</a>
<a class="sourceLine" id="cb3-2" title="2"></a>
<a class="sourceLine" id="cb3-3" title="3">foo <span class="ot">=</span></a>
<a class="sourceLine" id="cb3-4" title="4">    \r [x_sXn]</a>
<a class="sourceLine" id="cb3-5" title="5">        <span class="kw">case</span> x_sXn <span class="kw">of</span> {</a>
<a class="sourceLine" id="cb3-6" title="6">        <span class="dt">W</span><span class="op">#</span> x<span class="op">#</span>_sXp <span class="ot">-&gt;</span></a>
<a class="sourceLine" id="cb3-7" title="7">        <span class="kw">let</span> { sat_sXq <span class="ot">=</span> <span class="dt">NS</span><span class="op">!</span> [x<span class="op">#</span>_sXp]; } <span class="kw">in</span>  naturalAdd sat_sXq foo1;</a>
<a class="sourceLine" id="cb3-8" title="8">        };</a></code></pre></div>
<p>Let’s look at <code>naturalAdd</code>:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="co">-- | Add two naturals</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="ot">naturalAdd ::</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span></a>
<a class="sourceLine" id="cb4-3" title="3"><span class="ot">{-# NOINLINE naturalAdd #-}</span></a>
<a class="sourceLine" id="cb4-4" title="4">naturalAdd (<span class="dt">NS</span> x) (<span class="dt">NB</span> y) <span class="ot">=</span> <span class="dt">NB</span> (bigNatAddWord<span class="op">#</span> y x)</a>
<a class="sourceLine" id="cb4-5" title="5">naturalAdd (<span class="dt">NB</span> x) (<span class="dt">NS</span> y) <span class="ot">=</span> <span class="dt">NB</span> (bigNatAddWord<span class="op">#</span> x y)</a>
<a class="sourceLine" id="cb4-6" title="6">naturalAdd (<span class="dt">NB</span> x) (<span class="dt">NB</span> y) <span class="ot">=</span> <span class="dt">NB</span> (bigNatAdd x y)</a>
<a class="sourceLine" id="cb4-7" title="7">naturalAdd (<span class="dt">NS</span> x) (<span class="dt">NS</span> y) <span class="ot">=</span></a>
<a class="sourceLine" id="cb4-8" title="8">   <span class="kw">case</span> addWordC<span class="op">#</span> x y <span class="kw">of</span></a>
<a class="sourceLine" id="cb4-9" title="9">      (<span class="op">#</span> l,<span class="dv">0</span><span class="op">#</span> <span class="op">#</span>) <span class="ot">-&gt;</span> <span class="dt">NS</span> l</a>
<a class="sourceLine" id="cb4-10" title="10">      (<span class="op">#</span> l,c  <span class="op">#</span>) <span class="ot">-&gt;</span> <span class="dt">NB</span> (bigNatFromWord2<span class="op">#</span> (int2Word<span class="op">#</span> c) l)</a></code></pre></div>
<p>We are clearly in the last case where both arguments are small. It seems beneficial to allow this function to be inlined. If we did we would get:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode javascript"><code class="sourceCode javascript"><a class="sourceLine" id="cb5-1" title="1">foo <span class="op">=</span></a>
<a class="sourceLine" id="cb5-2" title="2">    \r [x_s158]</a>
<a class="sourceLine" id="cb5-3" title="3">        <span class="cf">case</span> x_s158 <span class="kw">of</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb5-4" title="4">        W# x#_s15a <span class="op">-&gt;</span></a>
<a class="sourceLine" id="cb5-5" title="5">        <span class="cf">case</span> addWordC# [x#_s15a <span class="dv">2</span>##] <span class="kw">of</span> <span class="op">{</span></a>
<a class="sourceLine" id="cb5-6" title="6">        (#<span class="op">,</span>#) l_s15c ds_s15d <span class="op">-&gt;</span></a>
<a class="sourceLine" id="cb5-7" title="7">        <span class="cf">case</span> ds_s15d<span class="op">&lt;</span>TagProper<span class="op">&gt;</span> <span class="kw">of</span> ds1_s15e <span class="op">{</span></a>
<a class="sourceLine" id="cb5-8" title="8">          __DEFAULT <span class="op">-&gt;</span></a>
<a class="sourceLine" id="cb5-9" title="9">              <span class="cf">case</span> int2Word# [ds1_s15e] <span class="kw">of</span> sat_s15f <span class="op">{</span></a>
<a class="sourceLine" id="cb5-10" title="10">              __DEFAULT <span class="op">-&gt;</span></a>
<a class="sourceLine" id="cb5-11" title="11">              <span class="cf">case</span> bigNatFromWord2# sat_s15f l_s15c <span class="kw">of</span> ds2_s15g <span class="op">{</span></a>
<a class="sourceLine" id="cb5-12" title="12">              __DEFAULT <span class="op">-&gt;</span> NB [ds2_s15g]<span class="op">;</span></a>
<a class="sourceLine" id="cb5-13" title="13">              <span class="op">};</span></a>
<a class="sourceLine" id="cb5-14" title="14">              <span class="op">};</span></a>
<a class="sourceLine" id="cb5-15" title="15">          <span class="dv">0</span># <span class="op">-&gt;</span> NS [l_s15c]<span class="op">;</span></a>
<a class="sourceLine" id="cb5-16" title="16">        <span class="op">};</span></a>
<a class="sourceLine" id="cb5-17" title="17">        <span class="op">};</span></a>
<a class="sourceLine" id="cb5-18" title="18">        <span class="op">};</span></a></code></pre></div>
<p>which produces much better assembly code, especially if there is no carry:</p>
<pre><code>    addq $2,%rax       ; add 2 to a machine word
	setc %bl           ; test the carry.
	movzbl %bl,%ebx    ; it could be done
	testq %rbx,%rbx    ; more efficiently
	jne _blk_c17c      ; with &quot;jc&quot;
_blk_c17i:
	movq $NS_con_info,-8(%r12) ; alloc NS datacon value
	movq %rax,(%r12)           ; with the addition result as payload.
	leaq -7(%r12),%rbx         ; make it the first argument
	addq $8,%rbp               ; and then
	jmp *(%rbp)                ; call continuation
...</code></pre>
<p>So why aren’t we always inlining <code>naturalAdd</code>? We even explicitly disallow it with a <code>NOINLINE</code> pragma. The reason is that <code>naturalAdd</code> and friends are involved in constant-folding rules.</p>
<p>For example, consider:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="ot">bar ::</span> <span class="dt">Natural</span> <span class="ot">-&gt;</span> <span class="dt">Natural</span></a>
<a class="sourceLine" id="cb7-2" title="2">bar x <span class="ot">=</span> x <span class="op">+</span> <span class="dv">2</span></a>
<a class="sourceLine" id="cb7-3" title="3"></a>
<a class="sourceLine" id="cb7-4" title="4">baz <span class="ot">=</span> bar <span class="bn">0x12345678913245678912345679123456798</span></a></code></pre></div>
<p>Currently we get the following Core:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1">bar1 <span class="ot">=</span> <span class="dt">NS</span> <span class="dv">2</span><span class="op">##</span></a>
<a class="sourceLine" id="cb8-2" title="2"></a>
<a class="sourceLine" id="cb8-3" title="3">bar <span class="ot">=</span> \ x_aHU <span class="ot">-&gt;</span> naturalAdd x_aHU bar1</a>
<a class="sourceLine" id="cb8-4" title="4"></a>
<a class="sourceLine" id="cb8-5" title="5">baz <span class="ot">=</span> <span class="dt">NB</span> <span class="dv">99114423092485377935703335253042771879834</span></a></code></pre></div>
<p>You can see that <code>baz</code> is a constant thanks to constant-folding.</p>
<p>However if we let <code>naturalAdd</code> inline we get:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1">baz</a>
<a class="sourceLine" id="cb9-2" title="2">  <span class="ot">=</span> <span class="kw">case</span> bigNatAddWord<span class="op">#</span> <span class="dv">99114423092485377935703335253042771879832</span> <span class="dv">2</span><span class="op">##</span></a>
<a class="sourceLine" id="cb9-3" title="3">    <span class="kw">of</span> ds_d11H</a>
<a class="sourceLine" id="cb9-4" title="4">    { __DEFAULT <span class="ot">-&gt;</span></a>
<a class="sourceLine" id="cb9-5" title="5">    <span class="dt">NB</span> ds_d11H</a>
<a class="sourceLine" id="cb9-6" title="6">    }</a></code></pre></div>
<p><code>baz</code> is no longer a constant.</p>
<p>A solution would be to add constant-folding rules for <code>BigNat#</code> functions, such as <code>bigNatAddWord#</code>. This is exactly what we have started doing in <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/20361">#20361</a>. Our new plan is:</p>
<ul>
<li>Make <code>BigNat#</code> operation <code>NOINLINE</code> and add constant-folding rules for them</li>
<li>Make Integer/Natural operations <code>INLINEABLE</code> (expose their unfolding)</li>
<li>Hence rely on constant-folding for <code>Word#/Int#/BigNat#</code> to provide constant folding for <code>Integer</code> and <code>Natural</code></li>
</ul>
<p>The good consequences of this plan are:</p>
<ul>
<li>Less allocations when bignum operations are inlined and some of the arguments are known to be small/big or fully known (constant).</li>
<li><code>Integer</code> and <code>Natural</code> are less magical: you can implement your own similar types and expect the same performance without having to add new rewrite rules</li>
</ul>
<p>There were some unforeseen difficulties with this plan though:</p>
<ol type="1">
<li>Some of the rewrite rules we need involve unboxed values such as <code>BigNat#</code> and <code>Word#</code> and the weren’t supported. Luckily, this has been recently fixed (<a href="https://gitlab.haskell.org/ghc/ghc/-/issues/19313">#19313</a>) by removing the “app invariant” (<a href="https://gitlab.haskell.org/ghc/ghc/-/issues/20554">#20554</a>). Thanks Joachim! That’s the reason why we could resume this work now.</li>
<li>Some unfoldings (RHSs) become bigger due to the inlining of bignum operations. Hence they may not themselves be inlined further due to inlining thresholds even if it would be beneficial. A better inlining heuristic would fix this (see <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/20516">#20516</a>). It will likely be the topic of the next post.</li>
</ol>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Contributions to GHC 9.2</title>
    <link href="http://www.hsyl20.fr/home/posts/2021-10-28-contributions-ghc-92.html" />
    <id>http://www.hsyl20.fr/home/posts/2021-10-28-contributions-ghc-92.html</id>
    <published>2021-10-28T00:00:00Z</published>
    <updated>2021-10-28T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Contributions to GHC 9.2</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">October 28, 2021</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This is my GHC activities report for GHC 9.2.</p>
<p>I’ve made roughly 204 commits for the GHC 9.2 series at the time of writing.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1">❯ <span class="fu">git</span> merge-base origin/ghc-9.2 origin/ghc-9.0</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="ex">19e80b9af252eee760dc047765a9930ef00067ec</span></a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4">❯ <span class="fu">git</span> log --author <span class="st">&quot;Sylvain Henry&quot;</span> --oneline \</a>
<a class="sourceLine" id="cb1-5" title="5">    19e80b9af252eee760dc047765a9930ef00067ec..origin/ghc-9.2 <span class="kw">|</span> <span class="fu">wc</span> --lines</a>
<a class="sourceLine" id="cb1-6" title="6"><span class="ex">204</span> </a></code></pre></div>
<p>This blog post only lists my personal contributions and thoughts and doesn’t engage my team nor IOG.</p>
<h1 id="constant-folding">Constant-folding</h1>
<p><code>fromIntegral</code> is the go-to function to convert between integral types. It is implemented as follows:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="fu">fromIntegral</span><span class="ot"> ::</span> (<span class="dt">Integral</span> a, <span class="dt">Num</span> b) <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> b</a>
<a class="sourceLine" id="cb2-2" title="2"><span class="fu">fromIntegral</span> <span class="ot">=</span> <span class="fu">fromInteger</span> <span class="op">.</span> <span class="fu">toInteger</span></a></code></pre></div>
<p>It used to be a bit magical because it had a <em>lot</em> of associated rewrite rules to avoid passing through <code>Integer</code> when possible. For example, <code>fromIntegral :: Int -&gt; Word</code> can be implemented much more efficiently by using the <code>int2Word#</code> primop (which is a no-op in assembly). This was done with a rewrite rule on <code>fromIntegral</code>.</p>
<p>Now, all the rewrite rules for <code>fromIntegral</code> are gone as the rewriting is done on <code>Integer</code> primitives themselves. For example, <code>integerToWord# (integerFromInt# x) ~~&gt; int2Word# x</code>.</p>
<p>It is especially useful for alternatives <code>Prelude</code> that can now provide safer numeric conversion functions without relying on <code>fromIntegral</code>. Also as <code>fromIntegral</code> was (and still is) inlined to avoid function calls, we are more likely to catch constant-folding occuring after some inlining happened, as well as constant-folding occuring from direct use of <code>toInteger/fromInteger</code> or underlying primitives.</p>
<p>Note that <code>Natural</code> is also taken into account everytime I’m changing something <code>Integer</code> related to avoid differences between the two bignum types.</p>
<h1 id="bit-primops">64-bit primops</h1>
<p>GHC provides a few primitive types: <code>Int#, Word#</code> but also <code>Int8#, Word32#, etc.</code>. <code>Word64#</code> and <code>Int64#</code> were only used on 32-bit architectures (on 64-bit architectures <code>Int#/Word#</code> are 64-bit and can be used instead) but we are working (with John Ericson) on making them available on 64-bit architectures too. To make GHC a multi-target compiler, we want to avoid having primops whose <em>type</em> depend on the target so we want to use the explicitly sized <code>Int64#/Word64#</code> types for them.</p>
<p>At this point it is only teasing for the GHC 9.4 activities report. But in the process, in GHC 9.2 we have made all the operations on <code>Int64#/Word64#</code> proper primops instead of FFI calls. It allowed us to add constant-folding for these operations! There were some noticeable performance improvements on 32-bit architectures:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode txt"><code class="sourceCode default"><a class="sourceLine" id="cb3-1" title="1">T9203(normal) run/alloc    89870808.0    66662456.0 -25.8% GOOD</a></code></pre></div>
<blockquote>
<dl>
<dt>haddock.Cabal(normal) run/alloc 14215777340.8 12780374172.0 -10.1% GOOD</dt>
<dd><p>haddock.base(normal) run/alloc 15420020877.6 13643834480.0 -11.5% GOOD</p>
</dd>
</dl>
</blockquote>
<h1 id="target-constants">Target constants</h1>
<p>GHC doesn’t fully control code generation by the C toolchain used to build the runtime system (RTS). As such, GHC’s build system <em>queries</em> some structure sizes, field offsets and other values from object files generated by the C toolchain (this is the role of <code>utils/deriveConstants</code> program). These constants are then used when compiling Haskell code, e.g. the native code generator uses them to generate assembly.</p>
<p>These constants were stored in a globally installed <code>platformConstants</code> file. As we want to make GHC multi-target and the RTS reinstallable, it had to change. For example the reinstalled RTS may slightly change the structure representations (e.g. have packed fields, some field order changes, some alignment changes…). Hence platform constants are now only stored in the RTS unit, not globally.</p>
<h1 id="windows">Windows</h1>
<p>At some point GHC’s Windows CI capacity became too small and it started slowing the merge process too much. So I’ve decided to rent a Windows machine and to install a Gitlab runner on it to build GHC…</p>
<p>I’ve discovered that Windows is a very hostile (Haskell) development platform. For example Git automatically converts LF line-ending characters into CRLF on checkout by default leading to weird build failures.</p>
<p>It seems I was the first one using a newer Cabal version which failed building GHC because a Windows-only utility (<code>touchy</code>) had a wrong <code>cabal-version</code> in its <code>.cabal</code> file.</p>
<p>More importantly it seems that I was also the first one building GHC on Windows with autotools 2.70 (first new version after 8 years) which broke the support of auxiliary files (e.g. <code>config.guess</code>) on Windows (<a href="https://gitlab.haskell.org/ghc/ghc/-/issues/19189">https://gitlab.haskell.org/ghc/ghc/-/issues/19189</a>). The handling of paths and path separators is a complete mess (see <a href="https://github.com/haskell/cabal/issues/7494">https://github.com/haskell/cabal/issues/7494</a> and <a href="https://github.com/haskell/cabal/issues/7649">https://github.com/haskell/cabal/issues/7649</a> where cabal devs try to fix the issue properly) so it was simpler to fix the issue by removing the use of <code>config.guess</code> and <code>config.sub</code>. We support 3.5 OSs and 4 architectures, why do we have to use these scripts anyway?</p>
<h1 id="modularity">Modularity</h1>
<p>A lot of time has been spent refactoring the compiler. I’ve started writing a paper/report about it so I won’t go into much details here.</p>
<h1 id="error-as-adts">Error as ADTs</h1>
<p>I’ve kicked off the use of ADTs to represent errors and warnings so that they are easier to consume by other tools (instead of forcing them to parse text messages). This [first patch](<a href="https://gitlab.haskell.org/ghc/ghc/-/commit/a5aaceecaa">https://gitlab.haskell.org/ghc/ghc/-/commit/a5aaceecaa</a>) fixed the parser.</p>
<p>For some reason this patch improves performance:</p>
<pre class="sourceCode "><code>Surprisingly, this patch enhances performance. On CI
(x86_64/deb9/hadrian, ghc/alloc):

   parsing001         -11.5%
   T13719             -2.7%
   MultiLayerModules  -3.5%
   Naperian           -3.1%</code></pre>
<h1 id="appendix-commit-list">Appendix: commit list</h1>
<div class="sourceCode" id="cb5"><pre class="sourceCode txt"><code class="sourceCode default"><a class="sourceLine" id="cb5-1" title="1"># numeric</a>
<a class="sourceLine" id="cb5-2" title="2"></a>
<a class="sourceLine" id="cb5-3" title="3">4d2bbd676e Remove ad-hoc fromIntegral rules</a>
<a class="sourceLine" id="cb5-4" title="4">a24044dcb0 Ensure that newtype deriving strategy is used for CTypes</a>
<a class="sourceLine" id="cb5-5" title="5">ab14cdbecb Fix naturalToFloat/Double</a>
<a class="sourceLine" id="cb5-6" title="6">d1a9167606 Additional constant-folding rule for binary AND/OR</a>
<a class="sourceLine" id="cb5-7" title="7">e552296414 Bignum: bump to version 1.1 (#19846)</a>
<a class="sourceLine" id="cb5-8" title="8">1d7840f509 Detect underflow in fromIntegral/Int-&gt;Natural rule</a>
<a class="sourceLine" id="cb5-9" title="9">882cc36382 Bignum: add BigNat Eq/Ord instances (#19647)</a>
<a class="sourceLine" id="cb5-10" title="10">d197fb3d5c Bignum: remove unused extra files</a>
<a class="sourceLine" id="cb5-11" title="11">3dc0815eea Bignum: fix invalid hs-boot declaration (#19638)</a>
<a class="sourceLine" id="cb5-12" title="12">e594d067b2 Bignum: match on DataCon workers in rules (#19892)</a>
<a class="sourceLine" id="cb5-13" title="13">773e2828fd Bignum: add Natural constant folding rules (#15821)</a>
<a class="sourceLine" id="cb5-14" title="14">5e71dd3379 Bignum: fix bogus rewrite rule (#19345)</a>
<a class="sourceLine" id="cb5-15" title="15">6f9a817fff Bignum: fix for Integer/Natural Ord instances</a>
<a class="sourceLine" id="cb5-16" title="16">bff74de713 Bignum: make GMP's bignat_add not recursive</a>
<a class="sourceLine" id="cb5-17" title="17">74ee1237bf Bignum: fix bigNatCompareWord# bug (#18813)</a>
<a class="sourceLine" id="cb5-18" title="18">12191a99d3 Bignum: match on small Integer/Natural</a>
<a class="sourceLine" id="cb5-19" title="19">8dd4f40512 Bignum: implement integerPowMod (#18427)</a>
<a class="sourceLine" id="cb5-20" title="20">12c06927a0 Bignum: implement integerRecipMod (#18427)</a>
<a class="sourceLine" id="cb5-21" title="21">e5523324d2 Bignum: add integerNegate RULE</a>
<a class="sourceLine" id="cb5-22" title="22">1cde295c54 Bignum: add bigNatFromWordArray</a>
<a class="sourceLine" id="cb5-23" title="23">04bc50b3c8 Bignum: implement extended GCD (#18427)</a>
<a class="sourceLine" id="cb5-24" title="24">92daad241b Bignum: refactor backend modules</a>
<a class="sourceLine" id="cb5-25" title="25">b689f3db02 Bignum: add clamping naturalToWord (fix #18697)</a>
<a class="sourceLine" id="cb5-26" title="26">85e6212349 Bignum: add missing compat import/export functions</a>
<a class="sourceLine" id="cb5-27" title="27">a8a2568b7b Bignum: add BigNat compat functions (#18613)</a>
<a class="sourceLine" id="cb5-28" title="28">dc476a5040 Bignum: fix BigNat subtraction (#18604)</a>
<a class="sourceLine" id="cb5-29" title="29">3f2f771869 Bignum: add more BigNat compat functions in integer-gmp</a>
<a class="sourceLine" id="cb5-30" title="30">d613ed7624 Bignum: add backward compat integer-gmp functions</a>
<a class="sourceLine" id="cb5-31" title="31">380638a336 Bignum: fix powMod for gmp backend (#18515)</a>
<a class="sourceLine" id="cb5-32" title="32">6ee07b494d Bignum: add support for negative shifts (fix #18499)</a>
<a class="sourceLine" id="cb5-33" title="33">96c31ea1f0 Fix bug in Natural multiplication (fix #18509)</a>
<a class="sourceLine" id="cb5-34" title="34">0a3723876c Fix documentation and fix &quot;check&quot; bignum backend (#18604)</a>
<a class="sourceLine" id="cb5-35" title="35">2754419673 Natural: fix left shift of 0 (fix #19170)</a>
<a class="sourceLine" id="cb5-36" title="36">730ef38f46 Simplify constant-folding (#18032)</a>
<a class="sourceLine" id="cb5-37" title="37">a98593f0c7 Refactor numeric constant folding rules</a>
<a class="sourceLine" id="cb5-38" title="38">ffc3da474b Remove outdated note</a>
<a class="sourceLine" id="cb5-39" title="39">85d899c8d3 Make proper fixed-width number literals</a>
<a class="sourceLine" id="cb5-40" title="40"></a>
<a class="sourceLine" id="cb5-41" title="41"># cross-compilation / multi-target</a>
<a class="sourceLine" id="cb5-42" title="42"></a>
<a class="sourceLine" id="cb5-43" title="43">52e5208367 Add Word64#/Int64# primops</a>
<a class="sourceLine" id="cb5-44" title="44">ffb4762f2c Constants: add a note and fix minor doc glitches</a>
<a class="sourceLine" id="cb5-45" title="45">201e29c74e Don't produce platformConstants file</a>
<a class="sourceLine" id="cb5-46" title="46">0e9069be0e Read constants header instead of global platformConstants</a>
<a class="sourceLine" id="cb5-47" title="47">ddd8fe23fd Generate parser for DerivedConstants.h</a>
<a class="sourceLine" id="cb5-48" title="48">6c8702aede Remove dynamic-by-default (#16782)</a>
<a class="sourceLine" id="cb5-49" title="49">a91dcb669b Don't get host RTS ways via settings (#18651)</a>
<a class="sourceLine" id="cb5-50" title="50">accdb24a08 Expose RTS-only ways (#18651)</a>
<a class="sourceLine" id="cb5-51" title="51">b695e7d736 Rename ghci flag into internal-interpreter</a>
<a class="sourceLine" id="cb5-52" title="52">7721b923d5 Move GHC.Platform into the compiler</a>
<a class="sourceLine" id="cb5-53" title="53">73145d57f9 Remove dead code in utils/derivConstants</a>
<a class="sourceLine" id="cb5-54" title="54">9dfeca6c20 Remove platform constant wrappers</a>
<a class="sourceLine" id="cb5-55" title="55">6333d73910 Put PlatformConstants into Platform</a>
<a class="sourceLine" id="cb5-56" title="56">f7cc431341 Replace HscTarget with Backend</a>
<a class="sourceLine" id="cb5-57" title="57">735f9d6bac Replace ghcWithNativeCodeGen with a proper Backend datatype</a>
<a class="sourceLine" id="cb5-58" title="58">e079bb721e Correctly test active backend</a>
<a class="sourceLine" id="cb5-59" title="59">8ea33edb2b Remove unused sGhcWithNativeCodeGen</a>
<a class="sourceLine" id="cb5-60" title="60">bab4ec8f62 Don't panic if the NCG isn't built (it is always built)</a>
<a class="sourceLine" id="cb5-61" title="61">0f17b930c1 Remove unused &quot;ncg&quot; flag</a>
<a class="sourceLine" id="cb5-62" title="62">cdbd16f545 Fix toArgRep to support 64-bit reps on all systems</a>
<a class="sourceLine" id="cb5-63" title="63">05c5c0549b Move loader state into Interp</a>
<a class="sourceLine" id="cb5-64" title="64">d8dc0f9623 Fix array and cleanup conversion primops (#19026)</a>
<a class="sourceLine" id="cb5-65" title="65">94bbc45df3 Use target Int/Word when detecting literal overflows (#17336)</a>
<a class="sourceLine" id="cb5-66" title="66">2895fa6035 ghci: reuse Arch from ghc-boot</a>
<a class="sourceLine" id="cb5-67" title="67">37f0434d65 Constant-folding: don't pass through GHC's Int/Word (fix #11704)</a>
<a class="sourceLine" id="cb5-68" title="68"></a>
<a class="sourceLine" id="cb5-69" title="69"># Windows</a>
<a class="sourceLine" id="cb5-70" title="70"></a>
<a class="sourceLine" id="cb5-71" title="71">dd23bd740f Windows: fix crlf on checkout</a>
<a class="sourceLine" id="cb5-72" title="72">bcaa36c427 Fix Windows build with autoconf &gt;=2.70 (#19189)</a>
<a class="sourceLine" id="cb5-73" title="73">5b752b1d5c touchy: use a valid cabal-version</a>
<a class="sourceLine" id="cb5-74" title="74">42ab06f793 Replace more autotools obsolete macros (#19189)</a>
<a class="sourceLine" id="cb5-75" title="75">0f2891f018 configure: avoid empty lines in AC_CONFIG_FILES</a>
<a class="sourceLine" id="cb5-76" title="76"></a>
<a class="sourceLine" id="cb5-77" title="77"># Modularity / Refactorings</a>
<a class="sourceLine" id="cb5-78" title="78"></a>
<a class="sourceLine" id="cb5-79" title="79">d0e8c10d58 Move Unit related fields from DynFlags to HscEnv</a>
<a class="sourceLine" id="cb5-80" title="80">76be0e32d6 Move SizedSeq into ghc-boot</a>
<a class="sourceLine" id="cb5-81" title="81">690c894616 Parser: move parser utils into their own module</a>
<a class="sourceLine" id="cb5-82" title="82">1ff61314fa Fix wrong comment about UnitState</a>
<a class="sourceLine" id="cb5-83" title="83">c85f4928d4 Refactor -dynamic-too handling</a>
<a class="sourceLine" id="cb5-84" title="84">72f2257c79 Don't initialize plugins in the Core2Core pipeline</a>
<a class="sourceLine" id="cb5-85" title="85">ecfd0278cb Move Plugins into HscEnv (#17957)</a>
<a class="sourceLine" id="cb5-86" title="86">14ce454f72 Linker: reorganize linker related code</a>
<a class="sourceLine" id="cb5-87" title="87">08e6993a1b Move loadDecl into IfaceToCore</a>
<a class="sourceLine" id="cb5-88" title="88">0e9f6defbd Split GHC.Driver.Types</a>
<a class="sourceLine" id="cb5-89" title="89">9648d680b4 Remove pdocPrec</a>
<a class="sourceLine" id="cb5-90" title="90">0a5f291859 Parser: don't require the HomeUnitId</a>
<a class="sourceLine" id="cb5-91" title="91">9bbc84d20d DynFlags: refactor DmdAnal</a>
<a class="sourceLine" id="cb5-92" title="92">6a243e9daa Cache HomeUnit in HscEnv (#17957)</a>
<a class="sourceLine" id="cb5-93" title="93">386c2d7ff8 Use UnitId in the backend instead of Unit</a>
<a class="sourceLine" id="cb5-94" title="94">93d5de165a Don't import GHC.Unit to reduce the number of dependencies</a>
<a class="sourceLine" id="cb5-95" title="95">dafe79433c Parser: remove some unused imports</a>
<a class="sourceLine" id="cb5-96" title="96">a946c7ef9e Less DynFlags in Header parsing</a>
<a class="sourceLine" id="cb5-97" title="97">a5aaceecaa Use ADTs for parser errors/warnings</a>
<a class="sourceLine" id="cb5-98" title="98">9befd94d79 Remove unused global variables</a>
<a class="sourceLine" id="cb5-99" title="99">df3f588075 Remove unsafeGlobalDynFlags (#17957, #14597)</a>
<a class="sourceLine" id="cb5-100" title="100">8e3f00dd24 Make the parser module less dependent on DynFlags</a>
<a class="sourceLine" id="cb5-101" title="101">a997fa01d9 Preliminary work towards removing DynFlags -&gt; Driver.Ppr dependency</a>
<a class="sourceLine" id="cb5-102" title="102">a584366b1d Remove sdocWithDynFlags (fix #10143)</a>
<a class="sourceLine" id="cb5-103" title="103">667d63558a Refactor CLabel pretty-printing</a>
<a class="sourceLine" id="cb5-104" title="104">7f2785f2d6 Remove pprPrec from Outputable (unused)</a>
<a class="sourceLine" id="cb5-105" title="105">37aa224ad5 Add note about OutputableP</a>
<a class="sourceLine" id="cb5-106" title="106">e45c85446d Generalize OutputableP</a>
<a class="sourceLine" id="cb5-107" title="107">ca48076ae8 Introduce OutputableP</a>
<a class="sourceLine" id="cb5-108" title="108">8af954d202 Make ghc-boot reexport modules from ghc-boot-th</a>
<a class="sourceLine" id="cb5-109" title="109">ffae579211 Add comments about sm_dflags and simpleOptExpr</a>
<a class="sourceLine" id="cb5-110" title="110">b3df72a699 DynFlags: add sm_pre_inline field into SimplMode (#17957)</a>
<a class="sourceLine" id="cb5-111" title="111">3f32a9c0f4 DynFlags: add UnfoldingOpts and SimpleOpts</a>
<a class="sourceLine" id="cb5-112" title="112">8c89268905 DynFlags: add OptCoercionOpts</a>
<a class="sourceLine" id="cb5-113" title="113">df04b81e12 Move DynFlags test into updateModDetailsIdInfos's caller (#17957)</a>
<a class="sourceLine" id="cb5-114" title="114">220ad8d67a DynFlags: don't pass DynFlags to cmmImplementSwitchPlans</a>
<a class="sourceLine" id="cb5-115" title="115">89ce7cdf97 DynFlags: use Platform in foldRegs*</a>
<a class="sourceLine" id="cb5-116" title="116">1d6d648866 Don't rely on CLabel's Outputable instance in CmmToC</a>
<a class="sourceLine" id="cb5-117" title="117">bcb68a3f7f Don't store HomeUnit in UnitConfig</a>
<a class="sourceLine" id="cb5-118" title="118">0b17fa185a Refactor UnitId pretty-printing</a>
<a class="sourceLine" id="cb5-119" title="119">659eb31b7a NCG: Dwarf configuration</a>
<a class="sourceLine" id="cb5-120" title="120">50eb4460cd Don't use DynFlags in CmmToAsm.BlockLayout (#17957)</a>
<a class="sourceLine" id="cb5-121" title="121">293c7fba6c Put CFG weights into their own module (#17957)</a>
<a class="sourceLine" id="cb5-122" title="122">0c5ed5c7eb DynFlags: refactor GHC.CmmToAsm (#17957, #10143)</a>
<a class="sourceLine" id="cb5-123" title="123">accbc242e5 DynFlags: disentangle Outputable</a>
<a class="sourceLine" id="cb5-124" title="124">6334815540 Use a type alias for Ways</a>
<a class="sourceLine" id="cb5-125" title="125">3b15dc3cfb DynFlags: don't use sdocWithDynFlags in GHC.CmmToAsm.Dwarf.Types</a>
<a class="sourceLine" id="cb5-126" title="126">56a7c19337 Refactor CLabel pretty-printing</a>
<a class="sourceLine" id="cb5-127" title="127">175cb5b404 DynFlags: don't use sdocWithDynFlags in datacon ppr</a>
<a class="sourceLine" id="cb5-128" title="128">342a01af62 Add GHC.Platform.Profile</a>
<a class="sourceLine" id="cb5-129" title="129">15b2b44fe3 Rename GHC.Driver.Ways into GHC.Platform.Ways</a>
<a class="sourceLine" id="cb5-130" title="130">e443846ba0 DynFlags: store printer in TraceBinIfaceReading</a>
<a class="sourceLine" id="cb5-131" title="131">7f44df1ec6 Minor refactoring of Unit display</a>
<a class="sourceLine" id="cb5-132" title="132">6e2db34bdf Add accessors to ArchOS</a>
<a class="sourceLine" id="cb5-133" title="133">ffc0d578ea Add HomeUnit type</a>
<a class="sourceLine" id="cb5-134" title="134">8e2f85f6b4 Refactor Logger</a>
<a class="sourceLine" id="cb5-135" title="135">e9d0dd4554 Move showSDocUnsafe/showPprUnsafe back into GHC.Utils.Outputable</a>
<a class="sourceLine" id="cb5-136" title="136">daa6363f49 DynFlags: move temp file management into HscEnv (#17957)</a>
<a class="sourceLine" id="cb5-137" title="137">3aceea907f Don't pass homeUnitId at ExternalPackageState creation time (#10827)</a>
<a class="sourceLine" id="cb5-138" title="138">957b53760e Core: introduce Alt/AnnAlt/IfaceAlt datatypes</a>
<a class="sourceLine" id="cb5-139" title="139">fd0945b7bf Move Hooks into HscEnv</a>
<a class="sourceLine" id="cb5-140" title="140"></a>
<a class="sourceLine" id="cb5-141" title="141"># performance</a>
<a class="sourceLine" id="cb5-142" title="142"></a>
<a class="sourceLine" id="cb5-143" title="143">e393f213f5 Allow fusion with catMaybes (#18574)</a>
<a class="sourceLine" id="cb5-144" title="144">05550a5abc Avoid roundtrip through SDoc</a>
<a class="sourceLine" id="cb5-145" title="145">b1eb38a0a7 Perf: make SDoc monad one-shot (#18202)</a>
<a class="sourceLine" id="cb5-146" title="146">8a51b2ab74 Make IOEnv monad one-shot (#18202)</a>
<a class="sourceLine" id="cb5-147" title="147">bee43aca82 Rewrite and move the monad-state hack note</a>
<a class="sourceLine" id="cb5-148" title="148">77398b678a Avoid allocations in `splitAtList` (#18535)</a>
<a class="sourceLine" id="cb5-149" title="149">acf537f9fe Make splitAtList strict in its arguments</a>
<a class="sourceLine" id="cb5-150" title="150">fe4202cef7 Always INLINE ($!)</a>
<a class="sourceLine" id="cb5-151" title="151">b677d09344 Make sized division primops ok-for-spec (#19026)</a>
<a class="sourceLine" id="cb5-152" title="152">87ae062ab8 Compute length only once in foldBal</a>
<a class="sourceLine" id="cb5-153" title="153">d412cd108b Write explicit IOEnv's Functor and MonadIO instances (#18202)</a>
<a class="sourceLine" id="cb5-154" title="154">8a433a3c88 Fix leaks of the HscEnv with quick flavour (#19356)</a>
<a class="sourceLine" id="cb5-155" title="155">72c0e07869 Make known names simple ConApps (#19386)</a>
<a class="sourceLine" id="cb5-156" title="156">887eb6ec23 Enhance Data instance generation</a>
<a class="sourceLine" id="cb5-157" title="157">ae8379abb8 Ppr: compute length of string literals at compile time (#19266)</a>
<a class="sourceLine" id="cb5-158" title="158">0249974e76 Fix strictness in TyCo.Tidy (#14738)</a>
<a class="sourceLine" id="cb5-159" title="159">5ae73f69e5 Add regression test for #16577</a>
<a class="sourceLine" id="cb5-160" title="160">6c771aafa3 Implement Unique supply with Addr# atomic primop</a>
<a class="sourceLine" id="cb5-161" title="161">4af6126d17 Use static array in zeroCount</a>
<a class="sourceLine" id="cb5-162" title="162"></a>
<a class="sourceLine" id="cb5-163" title="163"># build system / CI</a>
<a class="sourceLine" id="cb5-164" title="164"></a>
<a class="sourceLine" id="cb5-165" title="165">a3129aa743 Hadrian: fix .cabal file</a>
<a class="sourceLine" id="cb5-166" title="166">31ee48dc64 CI: reduce xz compression for non release/nightly jobs</a>
<a class="sourceLine" id="cb5-167" title="167">18e106a8df Add missing .hi-boot dependencies with ghc -M (#14482)</a>
<a class="sourceLine" id="cb5-168" title="168">9c87f97ee9 Fix spurious failures of T16916 on CI (#16966)</a>
<a class="sourceLine" id="cb5-169" title="169">e516ef7eb7 Hadrian: fix flavour parser</a>
<a class="sourceLine" id="cb5-170" title="170">bd877edd94 Hadrian: show default ghc-bignum backend (fix #18912)</a>
<a class="sourceLine" id="cb5-171" title="171">659fcb1493 Fix project version for ProjectVersionMunged (fix #19058)</a>
<a class="sourceLine" id="cb5-172" title="172">7cb5df9617 hadrian: fix ghc-pkg uses (#17601)</a>
<a class="sourceLine" id="cb5-173" title="173">75fc1ed58b Hadrian: fix detection of ghc-pkg for cross-compilers</a>
<a class="sourceLine" id="cb5-174" title="174">66414bdf40 configure: fix the use of some obsolete macros (#19189)</a>
<a class="sourceLine" id="cb5-175" title="175">4813486f87 Move Hadrian's wiki pages in tree (fix #16165)</a>
<a class="sourceLine" id="cb5-176" title="176">3486ebe6f9 Hadrian: don't fail if ghc-tarballs dir doesn't exist</a>
<a class="sourceLine" id="cb5-177" title="177">b4a929a1e5 Hadrian: fix libffi tarball parsing</a>
<a class="sourceLine" id="cb5-178" title="178">aaa8f00fa0 Validate script: fix configure command when using stack</a>
<a class="sourceLine" id="cb5-179" title="179">db236ffc03 Testsuite: increase timeout for T18223 (#18795)</a>
<a class="sourceLine" id="cb5-180" title="180">3a16d764f3 ghci: don't compile unneeded modules</a>
<a class="sourceLine" id="cb5-181" title="181">e691a5a046 Hadrian: add quick-debug flavour</a>
<a class="sourceLine" id="cb5-182" title="182">f1accd0096 Add quick-validate Hadrian flavour (quick + -Werror)</a>
<a class="sourceLine" id="cb5-183" title="183">2da933084b Hadrian: fix slow-validate flavour (#18586)</a>
<a class="sourceLine" id="cb5-184" title="184">459afeb592 Fix build systems</a>
<a class="sourceLine" id="cb5-185" title="185">b3143f5a08 Enhance metrics output</a>
<a class="sourceLine" id="cb5-186" title="186">9c1b8ad931 Bump Stack resolver</a>
<a class="sourceLine" id="cb5-187" title="187">a01e78cc5b Don't build extra object with -no-hs-main</a>
<a class="sourceLine" id="cb5-188" title="188">226cefd0a8 Fix fake import in GHC.Exception.Type boot module</a>
<a class="sourceLine" id="cb5-189" title="189"></a>
<a class="sourceLine" id="cb5-190" title="190"># misc</a>
<a class="sourceLine" id="cb5-191" title="191"></a>
<a class="sourceLine" id="cb5-192" title="192">644424afc5 GHCi: don't discard plugins on reload (#20335)</a>
<a class="sourceLine" id="cb5-193" title="193">3a81545208 RTS: try to fix timer races</a>
<a class="sourceLine" id="cb5-194" title="194">6b10163e0d Disable bogus assertion (#19489)</a>
<a class="sourceLine" id="cb5-195" title="195">d14a20686c Enhance pass result forcing</a>
<a class="sourceLine" id="cb5-196" title="196">3f9af89128 Add a flag to dump the FastString table</a>
<a class="sourceLine" id="cb5-197" title="197">38748d5fb4 Minor simplification for leak indicators</a>
<a class="sourceLine" id="cb5-198" title="198">fe78997845 IntVar: fix allocation size</a>
<a class="sourceLine" id="cb5-199" title="199">a3d995fa18 Fix -dynamic-too with wired-in modules (#19264)</a>
<a class="sourceLine" id="cb5-200" title="200">13d876bab3 Enhance nested TransCo pretty-printing</a>
<a class="sourceLine" id="cb5-201" title="201">db16302cfd LLVM: fix sized shift primops (#19215)</a>
<a class="sourceLine" id="cb5-202" title="202">29173f8888 Factorize and document binder collect functions</a>
<a class="sourceLine" id="cb5-203" title="203">01ea56a22d Arrows: collect evidence binders</a>
<a class="sourceLine" id="cb5-204" title="204">84dcb8440e Revert &quot;Remove SpecConstrAnnotation (#13681)&quot; (#19168)</a>
<a class="sourceLine" id="cb5-205" title="205">fe344da9be Missing fields: enhance error messages (#18869)</a>
<a class="sourceLine" id="cb5-206" title="206">d930687a07 Show missing field types (#18869)</a>
<a class="sourceLine" id="cb5-207" title="207">f59c34b8e4 Support package qualifier in Prelude import</a>
<a class="sourceLine" id="cb5-208" title="208">480a38d4ad rts: don't use siginterrupt (#19019)</a>
<a class="sourceLine" id="cb5-209" title="209">f9f9f030d7 Arrows: correctly query arrow methods (#17423)</a>
<a class="sourceLine" id="cb5-210" title="210">381eb66012 Display FFI labels (fix #18539)</a>
<a class="sourceLine" id="cb5-211" title="211">52114fa0f9 Add Addr# atomic primops (#17751)</a>
<a class="sourceLine" id="cb5-212" title="212">4c407f6e71 Export SPEC from GHC.Exts (#13681)</a>
<a class="sourceLine" id="cb5-213" title="213">81560981fd Don't use LEA with 8-bit registers (#18614)</a>
<a class="sourceLine" id="cb5-214" title="214">22f5d9a951 GC: Avoid data race (#18717, #17964)</a>
<a class="sourceLine" id="cb5-215" title="215">809f09e8a7 Fix parsing of PIE flags</a>
<a class="sourceLine" id="cb5-216" title="216">0e8b923d3c Apply suggestion to compiler/GHC/SysTools.hs</a>
<a class="sourceLine" id="cb5-217" title="217">74d4017b74 Fix -flink-rts (#18651)</a>
<a class="sourceLine" id="cb5-218" title="218">0bb02873ee Add test for T18574</a>
<a class="sourceLine" id="cb5-219" title="219">4b4fbc58d3 Remove &quot;Ord FastString&quot; instance</a>
<a class="sourceLine" id="cb5-220" title="220">884245dd29 Fix FastString lexicographic ordering (fix #18562)</a>
<a class="sourceLine" id="cb5-221" title="221">2d8ca91703 Fix -ddump-stg flag</a>
<a class="sourceLine" id="cb5-222" title="222">7c274cd530 Fix minimal imports dump for boot files (fix #18497)</a>
<a class="sourceLine" id="cb5-223" title="223">9e2930c3e1 Bump CountParserDeps</a>
<a class="sourceLine" id="cb5-224" title="224">ff1b7710c9 Add test for #18064</a></code></pre></div>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Contributions to GHC 9.0</title>
    <link href="http://www.hsyl20.fr/home/posts/2021-03-13-contributions-to-ghc-90.html" />
    <id>http://www.hsyl20.fr/home/posts/2021-03-13-contributions-to-ghc-90.html</id>
    <published>2021-03-13T00:00:00Z</published>
    <updated>2021-03-13T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Contributions to GHC 9.0</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">March 13, 2021</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p><strong>Changelog</strong></p>
<ul>
<li>2021-03-15: discussed on <a href="https://www.reddit.com/r/haskell/comments/m4bgg7/contributions_to_ghc_90/">reddit</a></li>
</ul>
<hr />
<p>This is my GHC activities report for GHC 9.0.</p>
<p>If I’ve got the following script right, I’ve made 225 commits for the GHC 9.0 series at the time of writing.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1">❯ <span class="fu">git</span> merge-base origin/ghc-9.0 origin/ghc-8.10</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="ex">098d50176a2521d08efe6fdbab0ede2b7419786a</span></a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4">❯ <span class="fu">git</span> log --author <span class="st">&quot;Sylvain Henry&quot;</span> --oneline \</a>
<a class="sourceLine" id="cb1-5" title="5">    098d50176a2521d08efe6fdbab0ede2b7419786a..origin/ghc-9.0 <span class="kw">|</span> <span class="fu">wc</span> --lines</a>
<a class="sourceLine" id="cb1-6" title="6"><span class="ex">225</span></a></code></pre></div>
<h1 id="module-hierarchy">Module hierarchy</h1>
<p>I have completed the renaming of every GHC module to introduce a hierarchy.</p>
<p>Haddock for the GHC library <a href="https://hackage.haskell.org/package/ghc-8.10.1">before</a> and <a href="https://ghc.gitlab.haskell.org/ghc/doc/libraries/ghc-9.1/index.html">after</a> the changes:</p>
<p><img src="http://www.hsyl20.fr/home/images/2021-ghc9/modules.png" alt="image" /></p>
<p>You might think: “So what? You only renamed a few modules”. But in fact it wasn’t that simple as I had neglected the amount of discussion that this kind of change would trigger.</p>
<p>First attempt: I did the work once in June 2017 in a single big patch that was very difficult to review and to rebase and consequently that has never been merged. I have been asked to write a <a href="https://github.com/ghc-proposals/ghc-proposals/pull/57">ghc-proposal</a> which has then been flagged out-of-scope (quite demoralizingly). I have implemented <a href="https://github.com/hsyl20/ghc-api-compat">ghc-api-compat</a>, a package to help compiling codes using the old naming (sadly the latest version can’t be uploaded on Hackage because of <a href="https://github.com/haskell/cabal/issues/4629">Cabal bug #4629</a>). So I finally gave up in December 2017.</p>
<p>After enough time had passed to forget about this, I made a second attempt in 2019. This time with much smaller patches and waiting for one patch to be merged before starting working on the other to avoid too much rebasing work. As the process took longer than expected (it ended in 2020), the refactoring wasn’t completed for the 8.10 release. That’s why 8.10 has only some hierarchy (e.g. <code>GHC.Hs</code> and <code>GHC.StgToCmm</code>).</p>
<p>The whole story is tracked in <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/13009">#13009</a>.</p>
<p>This change mostly matters if you are a GHC developer or a user of the GHC API because that’s what you interact directly with. But doing this was only a first step before starting to modularise GHC’s codebase. The latter is still a lot of (functional) spaghetti code but it’s getting better. Now we can try to enforce some rules such as “no, every part of the compiler shouldn’t directly use the driver state (HscEnv)”, etc.</p>
<p>Thanks to Takenobu Tani for fixing many references after these changes (in code comments, in the Wiki, etc.). Thanks to Richard Eisenberg and Simon Peyton Jones for their support.</p>
<h1 id="users-guide">Users guide</h1>
<p>I found GHC’s users guide quite difficult to navigate especially because of its theme: the table of contents on the right was often useless because we had to scroll up a lot to find it. So I’ve <a href="https://gitlab.haskell.org/ghc/ghc/-/commit/aeea92ef6ffa514793b1d37b38aaed3616c5c24a">switched to</a> the now very common ReadTheDocs theme which has the TOC always visible on the left.</p>
<ul>
<li>GHC 8.10: <a href="https://downloads.haskell.org/ghc/8.10.1/docs/html/users_guide/index.html">https://downloads.haskell.org/ghc/8.10.1/docs/html/users_guide/index.html</a></li>
<li>GHC 9.0.1: <a href="https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/index.html">https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/index.html</a></li>
</ul>
<p>I had to adapt the CSS of the theme to try to match the old theme in some cases. It’s far from being perfect so anyone with CSS skills should feel free to enhance it.</p>
<p>While doing this change I noticed that the <a href="https://downloads.haskell.org/ghc/8.10.1/docs/html/users_guide/glasgow_exts.html">GHC Language Features</a> page was huge and slow to render. So I’ve done the <a href="https://gitlab.haskell.org/ghc/ghc/-/commit/0a5e4f5f7d6cef16b6b11ac8d3a269b92016ed5d">tedious work</a> of splitting it. By doing this I fixed issue <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/17316">#17316</a> that I had missed before and where other devs had been discussing doing this. <a href="https://downloads.haskell.org/ghc/9.0.1/docs/html/users_guide/exts.html">It looks better now</a> but I have done the split my own way (I don’t even remember exactly which criteria I’ve followed, it was more than a year ago). So don’t hesitate to propose changes to enhance this.</p>
<h1 id="ghc-bignum">ghc-bignum</h1>
<p>In August 2019 I <a href="https://github.com/haskus/packages/commit/dba11a8d8c022efda22fef0a95f534f8738c4d8c">started toying</a> with an implementation of <code>Natural</code> numbers. When I started working for IOHK in September 2019 it turned out it would be useful to replace the previous Haskell native implementation (<span class="title-ref">integer-simple</span>) with a faster one for cross-compilation concerns. So I worked on it and <span class="title-ref">ghc-bignum</span> <a href="https://gitlab.haskell.org/ghc/ghc/-/commit/9f96bc127d6231b5e76bbab442244eb303b08867">was merged</a> in June 2020.</p>
<p>We published a post about this work in July 2020 on IOHK blog: <a href="https://iohk.io/en/blog/posts/2020/07/28/improving-haskells-big-numbers-support/">https://iohk.io/en/blog/posts/2020/07/28/improving-haskells-big-numbers-support/</a></p>
<p>I have implemented only simple algorithms (division was tricky enough to implement) but performance is pretty good, especially compared to <code>integer-simple</code>. The following chart from the blog post linked above compares performance results of some basic operations (note the log scale):</p>
<p><img src="http://www.hsyl20.fr/home/images/2021-ghc9/perf.png" alt="image" /></p>
<p>Providing a new native Haskell implementation of Integer/Natural was only part of the project. <code>ghc-bignum</code> also refactors the way support for big numbers is implemented. Instead of two separate packages (<code>integer-gmp</code> or <code>integer-simple</code>), it’s now always <code>ghc-bignum</code> but built with different Cabal flags to select the backend. This simple change allows other packages to depend on <code>ghc-bignum</code> unconditionally starting with GHC 9.0.</p>
<p>Note that a <code>integer-gmp</code> package is still distributed for backward compatibility, but it relies on <code>ghc-bignum</code>.</p>
<p>Implementing <code>ghc-bignum</code> led me to learn about and to modify <em>both</em> build systems of GHC, something that you don’t want to have to do. It also uncovered tricky issues like raising exceptions defined in <code>base</code> package from a package that <code>base</code> depends on…</p>
<p>Thanks a lot to early testers who uncovered bugs in <code>ghc-bignum</code>! Implementing this library led me to learn more about program proofs. A stupid error in such library could easily go unnoticed and then any user of such numeric code could compute some wrong results: it’s quite scary!</p>
<p>By the way, you shouldn’t use GHC 9.0.1 in production because of a <a href="https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html">silly bug</a> I’ve introduced. My patch implementing constant folding for Natural numbers has been merged only in the final release of GHC 9.0.1 and sadly it introduced a bogus rule. Constant folding rules in GHC are the second reason for me to learn about program transformation proofs.</p>
<h1 id="modularisation">Modularisation</h1>
<p>Finally most of my time has been spent in modularising the GHC codebase. Or more precisely, disentangling the codebase (modularisation should come later).</p>
<p>If you have ever used the ghc-api or looked at the codebase, your first reaction has probably been “WTF?!”. In particular, you must have encountered the most infamous datatype in the compiler: <a href="https://hackage.haskell.org/package/ghc-8.10.2/docs/DynFlags.html#t:DynFlags">DynFlags</a>. Despite its name, it contains a lot of random stuff. My guess is that as there was always a <code>DynFlags</code> in scope, it ended up being used as a Reader monad state with some <code>IORefs</code> in it. And when it wasn’t in scope… well it always was because there was a <code>unsafeGlobalDynFlags</code> global variable too.</p>
<p>As we were (and still are) working towards making GHC multi-target (currently a <code>ghc</code> executable can only produce code for a single target, e.g. x86-64-linux), it became necessary to untangle all this.</p>
<p>For example, before, the compiler could assume that there was only a single platform: the target one. So it just had to query <code>DynFlags.targetPlatform</code> everywhere. Now we have to pass the platform as a parameter to the appropriate functions. That’s why many functions that used to take a <code>DynFlags</code> parameter now take a <code>Platform</code> parameter. See <a href="https://gitlab.haskell.org/ghc/ghc/-/commit/64f207566931469648e791df4f0f0384d45cddd0">this commit</a> for an example of such huge patches.</p>
<p>As my current objective is to implement support for compiler plugins (i.e. Haskell code for the host) in cross-compilers (i.e. GHC compiler producing codes for a target different of the host, e.g. JavaScript), I have also made a lot of changes to the code handling units (compiled packages).</p>
<p><a href="https://gitlab.haskell.org/ghc/ghc/-/issues/17957">#17957</a> is the ticket that I use to track generic refactorings. <a href="https://gitlab.haskell.org/ghc/ghc/-/issues/14335">#14335</a> is more specific to compiler plugins. There is still a lot of work to do in both cases.</p>
<p>Thanks to John Ericson who has made and still makes a lot of similar refactorings.</p>
<h1 id="conclusion">Conclusion</h1>
<p>If you are a GHC API user, there is 100% chance that I contributed to break your code with this release. Hopefully it’s for the best in the future so please don’t be too mad!</p>
<p>Don’t forget to wait for GHC 9.0.2 before using GHC 9.0 in production.</p>
<p>I have done a few other random things; see the commit list below.</p>
<h1 id="appendix-commit-list">Appendix: commit list</h1>
<div class="sourceCode" id="cb2"><pre class="sourceCode txt"><code class="sourceCode default"><a class="sourceLine" id="cb2-1" title="1"># ghc-bignum</a>
<a class="sourceLine" id="cb2-2" title="2"></a>
<a class="sourceLine" id="cb2-3" title="3">f5e5a1febf Bignum: fix bogus rewrite rule (#19345)</a>
<a class="sourceLine" id="cb2-4" title="4">ba089952f0 Bignum: add Natural constant folding rules (#15821)</a>
<a class="sourceLine" id="cb2-5" title="5">f4b11d23fe Bignum: add clamping naturalToWord (fix #18697)</a>
<a class="sourceLine" id="cb2-6" title="6">c6851770e7 Bignum: fix for Integer/Natural Ord instances</a>
<a class="sourceLine" id="cb2-7" title="7">bba8f79c7e Bignum: make GMP's bignat_add not recursive</a>
<a class="sourceLine" id="cb2-8" title="8">d09e7e41cf Bignum: fix bigNatCompareWord# bug (#18813)</a>
<a class="sourceLine" id="cb2-9" title="9">a740aa0bfc Bignum: match on small Integer/Natural</a>
<a class="sourceLine" id="cb2-10" title="10">5d414fdc01 Bignum: implement integerPowMod (#18427)</a>
<a class="sourceLine" id="cb2-11" title="11">175d714126 Bignum: implement integerRecipMod (#18427)</a>
<a class="sourceLine" id="cb2-12" title="12">89a001505a Bignum: add integerNegate RULE</a>
<a class="sourceLine" id="cb2-13" title="13">ebcc09687b Bignum: add bigNatFromWordArray</a>
<a class="sourceLine" id="cb2-14" title="14">74f3f581dd Bignum: implement extended GCD (#18427)</a>
<a class="sourceLine" id="cb2-15" title="15">6c98a930ee Bignum: refactor backend modules</a>
<a class="sourceLine" id="cb2-16" title="16">c23275f4dd Bignum: add missing compat import/export functions</a>
<a class="sourceLine" id="cb2-17" title="17">d5c3a027ec Bignum: add BigNat compat functions (#18613)</a>
<a class="sourceLine" id="cb2-18" title="18">bf8bb9e785 Bignum: fix BigNat subtraction (#18604)</a>
<a class="sourceLine" id="cb2-19" title="19">3745bdb69b Bignum: add more BigNat compat functions in integer-gmp</a>
<a class="sourceLine" id="cb2-20" title="20">eab2511ed2 Bignum: add backward compat integer-gmp functions</a>
<a class="sourceLine" id="cb2-21" title="21">817f94f51a Bignum: fix powMod for gmp backend (#18515)</a>
<a class="sourceLine" id="cb2-22" title="22">b4cccab3cc Fix bug in Natural multiplication (fix #18509)</a>
<a class="sourceLine" id="cb2-23" title="23">324967891a Bignum: add support for negative shifts (fix #18499)</a>
<a class="sourceLine" id="cb2-24" title="24">929d26db30 Bignum: don't build ghc-bignum with stage0</a>
<a class="sourceLine" id="cb2-25" title="25">d3bd689784 BigNum: rename BigNat types</a>
<a class="sourceLine" id="cb2-26" title="26">1b3d13b68c Fix ghc-bignum exceptions</a>
<a class="sourceLine" id="cb2-27" title="27">bccf3351a2 Add ghc-bignum to 8.12 release notes</a>
<a class="sourceLine" id="cb2-28" title="28">a403eb917b ghc-bignum: fix division by zero (#18359)</a>
<a class="sourceLine" id="cb2-29" title="29">9f96bc127d ghc-bignum library</a>
<a class="sourceLine" id="cb2-30" title="30">fa4281d672 Bump bytestring and text submodules</a>
<a class="sourceLine" id="cb2-31" title="31">dceecb093c Update Hadrian</a>
<a class="sourceLine" id="cb2-32" title="32">f817d816e6 Update testsuite</a>
<a class="sourceLine" id="cb2-33" title="33">aa9e7b7196 Update `make` based build system</a>
<a class="sourceLine" id="cb2-34" title="34">0f67e3447e Update `base` package</a>
<a class="sourceLine" id="cb2-35" title="35">96aa57878f Update compiler</a>
<a class="sourceLine" id="cb2-36" title="36">57db91d8ee Remove integer-simple</a>
<a class="sourceLine" id="cb2-37" title="37">f82a2f90ce Document GMP build [skip ci]</a>
<a class="sourceLine" id="cb2-38" title="38">a3e907630f Fix documentation and fix &quot;check&quot; bignum backend (#18604)</a>
<a class="sourceLine" id="cb2-39" title="39">a589fb949c Natural: fix left shift of 0 (fix #19170)</a>
<a class="sourceLine" id="cb2-40" title="40">558d4d4a2b Split integerGmpInternals test in several parts</a>
<a class="sourceLine" id="cb2-41" title="41">581753790d Hadrian: minor GMP refactoring</a>
<a class="sourceLine" id="cb2-42" title="42"></a>
<a class="sourceLine" id="cb2-43" title="43"># Build system</a>
<a class="sourceLine" id="cb2-44" title="44"></a>
<a class="sourceLine" id="cb2-45" title="45">faa36e5b36 Hadrian: ignore in-tree GMP objects with ``--lint``</a>
<a class="sourceLine" id="cb2-46" title="46">c3c801e3c3 Replace more autotools obsolete macros (#19189)</a>
<a class="sourceLine" id="cb2-47" title="47">062b3a7e8b touchy: use a valid cabal-version</a>
<a class="sourceLine" id="cb2-48" title="48">bea3df2e85 Fix Windows build with autoconf &gt;=2.70 (#19189)</a>
<a class="sourceLine" id="cb2-49" title="49">0789f7a18a Hadrian: show default ghc-bignum backend (fix #18912)</a>
<a class="sourceLine" id="cb2-50" title="50">d1de5c2271 Use Hadrian by default in validate script (#17527)</a>
<a class="sourceLine" id="cb2-51" title="51">d25b6851bb Hadrian: ghc-gmp.h shouldn't be a compiler dependency</a>
<a class="sourceLine" id="cb2-52" title="52">23e4e04700 Hadrian: fix PowerPC64le support (#17601)</a>
<a class="sourceLine" id="cb2-53" title="53">b420fb2474 Hadrian: fix hp2ps error during cross-compilation</a>
<a class="sourceLine" id="cb2-54" title="54">15ccca16e2 Hadrian: fix distDir per stage</a>
<a class="sourceLine" id="cb2-55" title="55">7a07aa7181 Hadrian: fix cross-compiler build (#16051)</a>
<a class="sourceLine" id="cb2-56" title="56">95da76c2b9 Hadrian: fix binary-dist target for cross-compilation</a>
<a class="sourceLine" id="cb2-57" title="57">85fc32f03a Hadrian: fix dyn_o/dyn_hi rule (#17534)</a>
<a class="sourceLine" id="cb2-58" title="58">75a185dc2a Hadrian: fix --summary</a>
<a class="sourceLine" id="cb2-59" title="59">729bcb0271 Hadrian: fix build on Mac OS Catalina (#17798)</a>
<a class="sourceLine" id="cb2-60" title="60">b989845e37 Hadrian: fix absolute buildroot support (#17822)</a>
<a class="sourceLine" id="cb2-61" title="61">ee2c50cbee Hadrian: track missing configure results</a>
<a class="sourceLine" id="cb2-62" title="62">2a2f51d79f Use configure script to detect that we should use in-tree GMP on Windows</a>
<a class="sourceLine" id="cb2-63" title="63">34c7d23074 Fix Hadrian's ``--configure`` (fix #17883)</a>
<a class="sourceLine" id="cb2-64" title="64">9d09411122 Hadrian: `docs` rule needs `configure` (#17840)</a>
<a class="sourceLine" id="cb2-65" title="65">e2cce99732 Hadrian: fix source-dist target (#17849)</a>
<a class="sourceLine" id="cb2-66" title="66">3cea67955a Make: fix sdist target (#17848)</a>
<a class="sourceLine" id="cb2-67" title="67">d7029cc09e Hadrian: refactor GMP in-tree build support (#17756)</a>
<a class="sourceLine" id="cb2-68" title="68">7550417ac8 Hadrian: drop Sphinx flag checking for PDF documentation (#17825)</a>
<a class="sourceLine" id="cb2-69" title="69">9f2c3677b3 GMP expects the Target platform as --host parameter</a>
<a class="sourceLine" id="cb2-70" title="70">1bfd825943 Ensure that Hadrian is built correctly before using it</a>
<a class="sourceLine" id="cb2-71" title="71">414e2f6263 Force -fPIC for intree GMP (fix #17799)</a>
<a class="sourceLine" id="cb2-72" title="72">4f11713567 Make: refactor GMP rules</a>
<a class="sourceLine" id="cb2-73" title="73"></a>
<a class="sourceLine" id="cb2-74" title="74"># Numeric stuff (preliminaries to ghc-bignum)</a>
<a class="sourceLine" id="cb2-75" title="75"></a>
<a class="sourceLine" id="cb2-76" title="76">fdcc53babb Optimise genericIntMul2Op</a>
<a class="sourceLine" id="cb2-77" title="77">7a51b587ad Add constant folding rule (#16402)</a>
<a class="sourceLine" id="cb2-78" title="78">35afe4f3b1 Use Int# primops in `Bits Int{8,16,32,64}` instances</a>
<a class="sourceLine" id="cb2-79" title="79">fbbe18a274 Use the new timesInt2# primop in integer-gmp (#9431)</a>
<a class="sourceLine" id="cb2-80" title="80">5f7cb423d7 Add `timesInt2#` primop</a>
<a class="sourceLine" id="cb2-81" title="81">3656dff825 LLVM: fix MO_S_Mul2 support (#18434)</a>
<a class="sourceLine" id="cb2-82" title="82">b5768cce02 Don't use timesInt2# with GHC &lt; 8.11 (fix #18358)</a>
<a class="sourceLine" id="cb2-83" title="83">1cca12edaa Constant-folding: don't pass through GHC's Int/Word (fix #11704)</a>
<a class="sourceLine" id="cb2-84" title="84">aba51b6586 Add arithmetic exception primops (#14664)</a>
<a class="sourceLine" id="cb2-85" title="85"></a>
<a class="sourceLine" id="cb2-86" title="86"># Module hierarchy</a>
<a class="sourceLine" id="cb2-87" title="87"></a>
<a class="sourceLine" id="cb2-88" title="88">20800b9a9e Split GHC.Iface.Utils module</a>
<a class="sourceLine" id="cb2-89" title="89">a426abb9b4 Rename GHC.Hs.Types into GHC.Hs.Type</a>
<a class="sourceLine" id="cb2-90" title="90">37430251c3 Rename GHC.Core.Arity into GHC.Core.Opt.Arity</a>
<a class="sourceLine" id="cb2-91" title="91">528df8ecb4 Modules: Core operations (#13009)</a>
<a class="sourceLine" id="cb2-92" title="92">18a346a4b5 Modules: Core (#13009)</a>
<a class="sourceLine" id="cb2-93" title="93">1941ef4f05 Modules: Types (#13009)</a>
<a class="sourceLine" id="cb2-94" title="94">255418da5d Modules: type-checker (#13009)</a>
<a class="sourceLine" id="cb2-95" title="95">15312bbb53 Modules (#13009)</a>
<a class="sourceLine" id="cb2-96" title="96">af33244212 Modules: Utils and Data (#13009)</a>
<a class="sourceLine" id="cb2-97" title="97">1500f0898e Modules: Llvm (#13009)</a>
<a class="sourceLine" id="cb2-98" title="98">240f5bf6f5 Modules: Driver (#13009)</a>
<a class="sourceLine" id="cb2-99" title="99">817f93eac4 Modules: Core (#13009)</a>
<a class="sourceLine" id="cb2-100" title="100">1b1067d14b Modules: CmmToAsm (#13009)</a>
<a class="sourceLine" id="cb2-101" title="101">cf739945b8 Module hierarchy: HsToCore (cf #13009)</a>
<a class="sourceLine" id="cb2-102" title="102">da7f74797e Module hierarchy: ByteCode and Runtime (cf #13009)</a>
<a class="sourceLine" id="cb2-103" title="103">6e2d9ee25b Module hierarchy: Cmm (cf #13009)</a>
<a class="sourceLine" id="cb2-104" title="104">d491a6795d Module hierarchy: Renamer (cf #13009)</a>
<a class="sourceLine" id="cb2-105" title="105">99a9f51bf8 Module hierarchy: Iface (cf #13009)</a>
<a class="sourceLine" id="cb2-106" title="106">eb6082358c Module hierarchy (#13009): Stg</a>
<a class="sourceLine" id="cb2-107" title="107"></a>
<a class="sourceLine" id="cb2-108" title="108"># Users guide</a>
<a class="sourceLine" id="cb2-109" title="109"></a>
<a class="sourceLine" id="cb2-110" title="110">0a5e4f5f7d Split glasgow_exts into several files (#17316)</a>
<a class="sourceLine" id="cb2-111" title="111">aeea92ef6f Switch to ReadTheDocs theme for the user-guide</a>
<a class="sourceLine" id="cb2-112" title="112"></a>
<a class="sourceLine" id="cb2-113" title="113"># Modularisation</a>
<a class="sourceLine" id="cb2-114" title="114"></a>
<a class="sourceLine" id="cb2-115" title="115">ce5408c062 Replace ghcWithNativeCodeGen with a proper Backend datatype</a>
<a class="sourceLine" id="cb2-116" title="116">666acbd43d Correctly test active backend</a>
<a class="sourceLine" id="cb2-117" title="117">e27698ce0b Remove unused sGhcWithNativeCodeGen</a>
<a class="sourceLine" id="cb2-118" title="118">dbf77b79d9 Remove unused &quot;ncg&quot; flag</a>
<a class="sourceLine" id="cb2-119" title="119">4e22de2a6f Don't panic if the NCG isn't built (it is always built)</a>
<a class="sourceLine" id="cb2-120" title="120">30caeee751 DynFlags: remove use of sdocWithDynFlags from GHC.Stg.* (#17957)</a>
<a class="sourceLine" id="cb2-121" title="121">0ddae2ba97 DynFlags: factor out pprUnitId from &quot;Outputable UnitId&quot; instance</a>
<a class="sourceLine" id="cb2-122" title="122">41d2649288 DynFlags: avoid the use of sdocWithDynFlags in GHC.Core.Rules (#17957)</a>
<a class="sourceLine" id="cb2-123" title="123">f08d6316d3 Replace Opt_SccProfilingOn flag with sccProfilingEnabled helper function</a>
<a class="sourceLine" id="cb2-124" title="124">3cdd8d69f5 NCG: correctly handle addresses with huge offsets (#15570)</a>
<a class="sourceLine" id="cb2-125" title="125">a04020b88d DynFlags: don't store buildTag</a>
<a class="sourceLine" id="cb2-126" title="126">7ad4085c22 Fix invalid printf format</a>
<a class="sourceLine" id="cb2-127" title="127">cad62ef119 Add tests for #17920</a>
<a class="sourceLine" id="cb2-128" title="128">5f6a066551 LLVM: refactor and comment register padding code (#17920)</a>
<a class="sourceLine" id="cb2-129" title="129">2636794d1a CmmToC: don't add extern decl to parsed Cmm data</a>
<a class="sourceLine" id="cb2-130" title="130">7750bd456f Cmm: introduce SAVE_REGS/RESTORE_REGS</a>
<a class="sourceLine" id="cb2-131" title="131">d4a0be7580 Move tablesNextToCode field into Platform</a>
<a class="sourceLine" id="cb2-132" title="132">2af0ec9059 DynFlags: store default depth in SDocContext (#17957)</a>
<a class="sourceLine" id="cb2-133" title="133">eb8115a8c4 Move CLabel assertions into smart constructors (#17957)</a>
<a class="sourceLine" id="cb2-134" title="134">456e17f035 Bump haddock submodule and allow metric decrease</a>
<a class="sourceLine" id="cb2-135" title="135">c10ff7e7e5 Doc: fix some comments</a>
<a class="sourceLine" id="cb2-136" title="136">1fbb4bf5f3 NCGConfig: remove useless ncgUnitId field</a>
<a class="sourceLine" id="cb2-137" title="137">bfd0a78cdd Don't return preload units when we set DyNFlags</a>
<a class="sourceLine" id="cb2-138" title="138">ac964c8350 Put database cache in UnitConfig</a>
<a class="sourceLine" id="cb2-139" title="139">28d804e1e1 Create helper upd_wired_in_home_instantiations</a>
<a class="sourceLine" id="cb2-140" title="140">4274688a63 Move distrustAll into mkUnitState</a>
<a class="sourceLine" id="cb2-141" title="141">fca2d25ff7 DynFlags: add UnitConfig datatype</a>
<a class="sourceLine" id="cb2-142" title="142">8408d521a6 DynFlags: merge_databases</a>
<a class="sourceLine" id="cb2-143" title="143">a444d01bc9 DynFlags: reportCycles, reportUnusable</a>
<a class="sourceLine" id="cb2-144" title="144">42c054f6cd DynFlags: findWiredInUnits</a>
<a class="sourceLine" id="cb2-145" title="145">4b53aac1e2 Refactor and document closeUnitDeps</a>
<a class="sourceLine" id="cb2-146" title="146">5226da3784 Refactor and document add_package</a>
<a class="sourceLine" id="cb2-147" title="147">36e1daf0a6 DynFlags: make listVisibleModuleNames take a UnitState</a>
<a class="sourceLine" id="cb2-148" title="148">bd5810dc4e DynFlags: remove useless add_package parameter</a>
<a class="sourceLine" id="cb2-149" title="149">9e715c1b84 Document getPreloadUnitsAnd</a>
<a class="sourceLine" id="cb2-150" title="150">266bc3d9c3 DynFlags: refactor unwireUnit</a>
<a class="sourceLine" id="cb2-151" title="151">9400aa9348 Remove preload parameter of mkUnitState</a>
<a class="sourceLine" id="cb2-152" title="152">598cc1dde5 Move wiring of homeUnitInstantiations outside of mkUnitState</a>
<a class="sourceLine" id="cb2-153" title="153">ae900605c4 Move dump_mod_map into initUnits</a>
<a class="sourceLine" id="cb2-154" title="154">653d17bdd5 Rename Package into Unit (2)</a>
<a class="sourceLine" id="cb2-155" title="155">55b4263e1a Remove ClosureUnitInfoMap</a>
<a class="sourceLine" id="cb2-156" title="156">202728e529 Make ClosureUnitInfoMap uses UnitInfoMap</a>
<a class="sourceLine" id="cb2-157" title="157">ed533ec217 Rename Package into Unit</a>
<a class="sourceLine" id="cb2-158" title="158">f50c19b8a7 Rename listUnitInfoMap into listUnitInfo</a>
<a class="sourceLine" id="cb2-159" title="159">d2109b4f10 Remove PreloadUnitId type alias</a>
<a class="sourceLine" id="cb2-160" title="160">3d171cd6d5 Document and refactor `mkUnit` and `mkUnitInfoMap`</a>
<a class="sourceLine" id="cb2-161" title="161">d345edfe96 Refactor WiredMap</a>
<a class="sourceLine" id="cb2-162" title="162">9c5572cd29 Remove LinkerUnitId type alias</a>
<a class="sourceLine" id="cb2-163" title="163">e7272d53e6 Enhance UnitId use</a>
<a class="sourceLine" id="cb2-164" title="164">f6be6e432e Add allowVirtualUnits field in PackageState</a>
<a class="sourceLine" id="cb2-165" title="165">8dc71f5577 Rename unsafeGetUnitInfo into unsafeLookupUnit</a>
<a class="sourceLine" id="cb2-166" title="166">72d086106d Refactor homeUnit</a>
<a class="sourceLine" id="cb2-167" title="167">7a02599afe Remove unused code</a>
<a class="sourceLine" id="cb2-168" title="168">2517a51c0f DynFlags refactoring VIII (#17957)</a>
<a class="sourceLine" id="cb2-169" title="169">cf772f19c0 Enhance Note [About units] for Backpack</a>
<a class="sourceLine" id="cb2-170" title="170">1c91a7a095 Bump haddock submodule</a>
<a class="sourceLine" id="cb2-171" title="171">a0ea59d641 Move Config module into GHC.Settings</a>
<a class="sourceLine" id="cb2-172" title="172">566cc73f46 Move isDynLinkName into GHC.Types.Name</a>
<a class="sourceLine" id="cb2-173" title="173">94e7c563ab Don't use DynFlags in showLinkerState (#17957)</a>
<a class="sourceLine" id="cb2-174" title="174">cab1871ab9 Move LeadingUnderscore into Platform (#17957)</a>
<a class="sourceLine" id="cb2-175" title="175">40c71c2cf3 Fix colorized error messages (#18128)</a>
<a class="sourceLine" id="cb2-176" title="176">1d8f80cd64 Remove references to -package-key</a>
<a class="sourceLine" id="cb2-177" title="177">de9fc995c2 Fully remove PprDebug</a>
<a class="sourceLine" id="cb2-178" title="178">b3df9e780f Remove PprStyle param of logging actions</a>
<a class="sourceLine" id="cb2-179" title="179">f8386c7b6a Refactor PprDebug handling</a>
<a class="sourceLine" id="cb2-180" title="180">780de9e110 Use platform in Iface Binary</a>
<a class="sourceLine" id="cb2-181" title="181">8bfb021958 Unit: split and rename modules</a>
<a class="sourceLine" id="cb2-182" title="182">10d15f1ec4 Refactoring unit management code</a>
<a class="sourceLine" id="cb2-183" title="183">ea717aa424 Factorize mungePackagePaths code</a>
<a class="sourceLine" id="cb2-184" title="184">9e2c8e0e37 Refactor UnitInfo load/store from databases</a>
<a class="sourceLine" id="cb2-185" title="185">69562e34fb Remove unused `emptyGenericUnitInfo`</a>
<a class="sourceLine" id="cb2-186" title="186">10a2ba90aa Refactor UnitInfo</a>
<a class="sourceLine" id="cb2-187" title="187">2cfc4ab971 Document backpack fields in DynFlags</a>
<a class="sourceLine" id="cb2-188" title="188">747093b7c2 CmmToAsm DynFlags refactoring (#17957)</a>
<a class="sourceLine" id="cb2-189" title="189">f2a98996e7 Avoid `sdocWithDynFlags` in `pprCLbl` (#17957)</a>
<a class="sourceLine" id="cb2-190" title="190">ce5c2999d2 Avoid using sdocWithDynFlags (#17957)</a>
<a class="sourceLine" id="cb2-191" title="191">35e43d48a9 Avoid DynFlags in Ppr code (#17957)</a>
<a class="sourceLine" id="cb2-192" title="192">70be0fbcef GHC.Runtime: avoid DynFlags (#17957)</a>
<a class="sourceLine" id="cb2-193" title="193">6655f93324 Use ParserFlags in GHC.Runtime.Eval (#17957)</a>
<a class="sourceLine" id="cb2-194" title="194">3ca5215188 GHC.Core.Opt renaming</a>
<a class="sourceLine" id="cb2-195" title="195">cc2918a040 Refactor CmmStatics</a>
<a class="sourceLine" id="cb2-196" title="196">a485c3c404 Move blob handling into StgToCmm</a>
<a class="sourceLine" id="cb2-197" title="197">f7597aa0c0 Testsuite: measure compiler stats for T16190</a>
<a class="sourceLine" id="cb2-198" title="198">4980200255 Update Stack resolver for hadrian/build-stack</a>
<a class="sourceLine" id="cb2-199" title="199">0002db1bf4 Kill wORDS_BIGENDIAN and replace it with platformByteOrder (#17957)</a>
<a class="sourceLine" id="cb2-200" title="200">e54500c12d Store ComponentId details</a>
<a class="sourceLine" id="cb2-201" title="201">f1a6c73d01 Merge GHC.Types.CostCentre.Init into GHC.Driver.CodeOutput</a>
<a class="sourceLine" id="cb2-202" title="202">1c7c6f1afc Remove GHC.Types.Unique.Map module</a>
<a class="sourceLine" id="cb2-203" title="203">0de03cd787 DynFlags refactoring III</a>
<a class="sourceLine" id="cb2-204" title="204">64f2075669 Refactoring: use Platform instead of DynFlags when possible</a>
<a class="sourceLine" id="cb2-205" title="205">2e82465fff Refactor CmmToAsm (disentangle DynFlags)</a>
<a class="sourceLine" id="cb2-206" title="206">44fad4a925 Rename isDllName</a>
<a class="sourceLine" id="cb2-207" title="207">a698997137 Use a Set to represent Ways</a>
<a class="sourceLine" id="cb2-208" title="208">bc41e47123 Refactor interpreterDynamic and interpreterProfiled</a>
<a class="sourceLine" id="cb2-209" title="209">8e6febcee4 Refactor GHC.Driver.Session (Ways and Flags)</a>
<a class="sourceLine" id="cb2-210" title="210">18757cab04 Refactor runtime interpreter code</a>
<a class="sourceLine" id="cb2-211" title="211">6880d6aa1e Disentangle DynFlags and SDoc</a>
<a class="sourceLine" id="cb2-212" title="212">fa28ae95e4 Fix flag documentation (#17826)</a>
<a class="sourceLine" id="cb2-213" title="213">16d643cfe6 Remove -ddump-srts flag</a>
<a class="sourceLine" id="cb2-214" title="214">fb5c19122e Remove redundant case</a>
<a class="sourceLine" id="cb2-215" title="215">29c701c154 Refactor package related code</a>
<a class="sourceLine" id="cb2-216" title="216">bf38a20eef Call `interpretPackageEnv` from `setSessionDynFlags`</a>
<a class="sourceLine" id="cb2-217" title="217">c8636da514 Fix LANG=C for readelf invocation in T14999</a>
<a class="sourceLine" id="cb2-218" title="218">1ca9adbc88 Remove `parallel` check from configure.ac</a>
<a class="sourceLine" id="cb2-219" title="219"></a>
<a class="sourceLine" id="cb2-220" title="220"># Misc</a>
<a class="sourceLine" id="cb2-221" title="221"></a>
<a class="sourceLine" id="cb2-222" title="222">f307ed226f Revert &quot;Remove SpecConstrAnnotation (#13681)&quot; (#19168)</a>
<a class="sourceLine" id="cb2-223" title="223">753fecd273 Display FFI labels (fix #18539)</a>
<a class="sourceLine" id="cb2-224" title="224">c94c56d5a7 Export SPEC from GHC.Exts (#13681)</a>
<a class="sourceLine" id="cb2-225" title="225">6dbd105421 Remove outdated note</a>
<a class="sourceLine" id="cb2-226" title="226">fb544de7cd Fix parsing of PIE flags</a>
<a class="sourceLine" id="cb2-227" title="227">6653e139db Fix minimal imports dump for boot files (fix #18497)</a>
<a class="sourceLine" id="cb2-228" title="228">d3c2d59baf RTS: avoid overflow on 32-bit arch (#18375)</a>
<a class="sourceLine" id="cb2-229" title="229">edc8d22b2e LLVM: support R9 and R10 registers</a>
<a class="sourceLine" id="cb2-230" title="230">8d07c48ce3 test: fix conc038</a>
<a class="sourceLine" id="cb2-231" title="231">951c1fb03d Fix unboxed-sums GC ptr-slot rubbish value (#17791)</a>
<a class="sourceLine" id="cb2-232" title="232">58655b9da7 Add GHC-API logging hooks</a>
<a class="sourceLine" id="cb2-233" title="233">d561c8f624 Add Cmm related hooks</a>
<a class="sourceLine" id="cb2-234" title="234">40327b037f Remove outdated comment</a>
<a class="sourceLine" id="cb2-235" title="235">0c114c6599 Handle large ARR_WORDS in heap census (fix #17572)</a>
<a class="sourceLine" id="cb2-236" title="236">7bc3a65b46 Remove SpecConstrAnnotation (#13681)</a>
<a class="sourceLine" id="cb2-237" title="237">f024b6e385 Expect T4267 to pass</a>
<a class="sourceLine" id="cb2-238" title="238">dce50062e3 Rts: show errno on failure (#18033)</a>
<a class="sourceLine" id="cb2-239" title="239">3445b96526 Only test T16190 with the NCG</a>
<a class="sourceLine" id="cb2-240" title="240">0639dc10e2 T16190: only measure bytes_allocated</a>
<a class="sourceLine" id="cb2-241" title="241">7432b327a3 Use correct option name (-opti) (fix #17314)</a>
<a class="sourceLine" id="cb2-242" title="242">437265eb26 Avoid timing module map dump in initUnits</a>
<a class="sourceLine" id="cb2-243" title="243">99823ed24b TH: fix Show/Eq/Ord instances for Bytes (#16457)</a>
<a class="sourceLine" id="cb2-244" title="244">cd4434c8e7 Fix misleading Ptr phantom type in SerializedCompact (#15653)</a>
<a class="sourceLine" id="cb2-245" title="245">8ea37b01b6 RTS: workaround a Linux kernel bug in timerfd</a></code></pre></div>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Stack: building GHC from source</title>
    <link href="http://www.hsyl20.fr/home/posts/2019-04-17-ghc-hacking-with-stack.html" />
    <id>http://www.hsyl20.fr/home/posts/2019-04-17-ghc-hacking-with-stack.html</id>
    <published>2019-04-17T00:00:00Z</published>
    <updated>2019-04-17T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Stack: building GHC from source</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Stack.html">Stack</a></td>
               <td class="date">April 17, 2019</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>Stack can build packages from source with the following syntax:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode yaml"><code class="sourceCode yaml"><a class="sourceLine" id="cb1-1" title="1"><span class="fu">extra-deps:</span></a>
<a class="sourceLine" id="cb1-2" title="2">   <span class="fu">git:</span><span class="at"> https://github.com/me/mypackage</span></a>
<a class="sourceLine" id="cb1-3" title="3">   <span class="fu">commit:</span><span class="at"> aaaaabbbbccccdddeeeefff123456</span></a></code></pre></div>
<p>With Stack 1.9.* we can’t use this kind of syntax to build GHC (and the other global packages such as <code>base</code> or <code>template-haskell</code>) from source.</p>
<p>But as <a href="https://github.com/commercialhaskell/stack/pull/4655">my patch</a> has been merged, the next major release of Stack will support it! With it we can easily select the compiler repository, commit ID and Hadrian flavour with the following syntax:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode yaml"><code class="sourceCode yaml"><a class="sourceLine" id="cb2-1" title="1"><span class="fu">compiler:</span><span class="at"> ghc-git-aaaaabbbbccccdddeeeefff123456-perf</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="co"># commit ID: aaaaabbbbccccdddeeeefff123456</span></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="co"># Hadrian flavour: &quot;perf&quot;</span></a>
<a class="sourceLine" id="cb2-4" title="4"></a>
<a class="sourceLine" id="cb2-5" title="5"><span class="fu">compiler-repository:</span><span class="at"> https://github.com/me/ghc</span></a>
<a class="sourceLine" id="cb2-6" title="6"><span class="co"># OPTIONAL. Default compiler repository is &quot;https://gitlab.haskell.org/ghc/ghc&quot;</span></a></code></pre></div>
<p>Then we can use <code>stack build</code> as usual.</p>
<p>This will be particularly useful for people developing software that depends on features only available in a fork of GHC (e.g. if it uses some GHC API not available in a released GHC).</p>
<p>I think it could also be used to implement custom CI for GHC. For instance, a cron job could track new commits pushed into GHC repository and could use this feature to easily try to build some packages (Stackage packages?) with the corresponding compiler to track build errors, GHC regressions, etc. To help revive something like <a href="https://perf.haskell.org/ghc/">https://perf.haskell.org/ghc/</a> maybe?</p>
<p>It could also be useful to make the use of derived compilers easier without having to provide bindists (GHCJS?).</p>
<p>It could also be used when the official bindist is broken (e.g. <a href="https://gitlab.haskell.org/ghc/ghc/issues/16408">https://gitlab.haskell.org/ghc/ghc/issues/16408</a>).</p>
<h1 id="details">Details</h1>
<p>Hadrian is the newer build system of GHC. An Hadrian “flavour” is a set of configuration options for a GHC build (e.g. the <code>Integer</code> library to use, the RTS ways, etc.). You can add or modify flavours in your GHC fork if necessary.</p>
<p>Stack uses <code>hadrian/build.stack.[sh,bat]</code> scripts to build GHC, which themselves rely on Stack and on the <code>hadrian/stack.yaml</code> file. It means that the bootstrap GHC compiler is installed by Stack and its version is defined in this file (e.g. at the time of writing, the resolver used in <code>hadrian/stack.yaml</code> means that GHC 8.6.4 is used as bootstrap compiler). Other tools such as “alex” and “happy” are managed by Stack too. This makes the build environment quite reproducible!</p>
<h1 id="references">References</h1>
<ul>
<li>Stack documentation:
<ul>
<li><a href="https://github.com/commercialhaskell/stack/blob/master/doc/yaml_configuration.md#building-ghc-from-source-experimental">https://github.com/commercialhaskell/stack/blob/master/doc/yaml_configuration.md#building-ghc-from-source-experimental</a></li>
</ul></li>
<li>Stack patches and ticket:
<ul>
<li><a href="https://github.com/commercialhaskell/stack/issues/4567">https://github.com/commercialhaskell/stack/issues/4567</a></li>
<li><a href="https://github.com/commercialhaskell/stack/pull/4581">https://github.com/commercialhaskell/stack/pull/4581</a></li>
<li><a href="https://github.com/commercialhaskell/stack/pull/4655">https://github.com/commercialhaskell/stack/pull/4655</a></li>
</ul></li>
<li>GHC patches related to this work:
<ul>
<li><a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/305">https://gitlab.haskell.org/ghc/ghc/merge_requests/305</a></li>
<li><a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/651">https://gitlab.haskell.org/ghc/ghc/merge_requests/651</a></li>
<li><a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/654">https://gitlab.haskell.org/ghc/ghc/merge_requests/654</a></li>
<li><a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/678">https://gitlab.haskell.org/ghc/ghc/merge_requests/678</a></li>
<li><a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/741">https://gitlab.haskell.org/ghc/ghc/merge_requests/741</a></li>
</ul></li>
</ul>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Fast file embedding with GHC!</title>
    <link href="http://www.hsyl20.fr/home/posts/2019-01-15-fast-file-embedding-with-ghc.html" />
    <id>http://www.hsyl20.fr/home/posts/2019-01-15-fast-file-embedding-with-ghc.html</id>
    <published>2019-01-15T00:00:00Z</published>
    <updated>2019-01-15T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Fast file embedding with GHC!</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Haskus.html">Haskus</a></td>
               <td class="date">January 15, 2019</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>If like me you sometimes want to embed resources files into executable binaries generated by GHC, you may have already used <a href="https://hackage.haskell.org/package/file-embed">file-embed</a> package. We are not alone as it is <a href="https://packdeps.haskellers.com/reverse/file-embed">directly used by 101 other packages</a> on Hackage at the time of writing.</p>
<p>The problem is: compile time and memory usage are <strong>awful</strong> for “big” files, where “big” = a few megabytes.</p>
<p>Here is the result of a <a href="https://github.com/haskus/packages/blob/ef893138620e8cea1b9ecb2983f5e38b997bd387/haskus-binary/bench.sh">small benchmark I wrote</a> showing the time needed to compile an Haskell source file that embeds a zero-filled data file of the given size with <code>file-embed</code>:</p>
<pre class="sourceCode "><code>================================
| Benchmarking file-embed      |
================================
Warming up...
# Benchmarking size: 128b
real    0m1,394s
user    0m1,191s
sys     0m0,315s

# Benchmarking size: 3K
real    0m1,259s
user    0m1,060s
sys     0m0,269s

# Benchmarking size: 3M
real    0m7,611s
user    0m6,510s
sys     0m1,183s

# Benchmarking size: 15M
real    0m32,582s
user    0m28,553s
sys     0m3,866s

# Benchmarking size: 150M
... I had to kill the process as GHC was freezing my box (i7 930, 20GB memory)</code></pre>
<p>This is a <a href="https://github.com/snoyberg/file-embed/issues/24">known problem</a>, so can we do better? No suspense, the answer is “yes”. The same <a href="https://github.com/haskus/packages/blob/ef893138620e8cea1b9ecb2983f5e38b997bd387/haskus-binary/bench.sh">small benchmark</a> also benches my <a href="https://github.com/haskus/packages/blob/ef893138620e8cea1b9ecb2983f5e38b997bd387/haskus-binary/src/lib/Haskus/Memory/Embed.hs">shiny new buffer embedding module</a> and gives the following results:</p>
<pre class="sourceCode "><code>================================
| Benchmarking haskus-binary   |
================================
Warming up...
# Benchmarking size: 128b
real    0m1,489s
user    0m1,218s
sys     0m0,371s

# Benchmarking size: 3K
real    0m1,448s
user    0m1,179s
sys     0m0,336s

# Benchmarking size: 3M
real    0m1,477s
user    0m1,245s
sys     0m0,308s

# Benchmarking size: 15M
real    0m1,660s
user    0m1,304s
sys     0m0,409s

# Benchmarking size: 150M
real    0m3,163s
user    0m1,961s
sys     0m1,291s

# Benchmarking size: 1G
real    0m21,852s
user    0m7,123s
sys     0m7,054s</code></pre>
<p>So it seems like we can. At this point I don’t suggest that you use my module as it is still a work in progress and as I don’t provide an easy way to create <code>ByteString</code> from the embedded file. Instead I will explain how the two approaches work and how <code>file-embed</code> implementation could be enhanced.</p>
<h1 id="file-embed-approach">file-embed approach</h1>
<p>When we want to embed a file with <code>file-embed</code>, the latter uses Template Haskell (TH) to create a literal string containing the file contents. GHC compiles literal strings into the equivalent of C arrays and we can get their addresses via TH: this is what <code>file-embed</code> does and it creates an expression calling <a href="https://www.stackage.org/haddock/lts-13.3/bytestring-0.10.8.2/Data-ByteString-Unsafe.html#v:unsafePackAddressLen">unsafePackAddressLen</a> with the appropriate address and size (see <a href="https://github.com/snoyberg/file-embed/blob/47b499c3c58ca465c56ee0295d0a76782a66751d/Data/FileEmbed.hs#L148">here</a>).</p>
<p>Literal strings were not supposed to contain big chunks of binary data, hence it is not surprising that GHC chokes on them. <a href="https://ghc.haskell.org/trac/ghc/ticket/14741">#14741</a> tracks this issue and there is even a <a href="https://ghc.haskell.org/trac/ghc/wiki/StaticData">StaticData proposal</a> (disclaimer: I am the author) suggesting that we add new things to GHC to improve on the situation.</p>
<h1 id="my-approach">My approach</h1>
<p>Now that I’m re-reading my aforementionned <a href="https://ghc.haskell.org/trac/ghc/wiki/StaticData">StaticData proposal</a> almost a year after writing it, the approach I use is basically what I have called “Step 2” in this document and it subsumes “Step 3”.</p>
<p>Suppose we want to include a file “data.bin”. We follow 3 steps:</p>
<ol type="1">
<li>Via TH, we generate an assembly file containing something like:</li>
</ol>
<div class="sourceCode" id="cb3"><pre class="sourceCode asm"><code class="sourceCode fasm"><a class="sourceLine" id="cb3-1" title="1">.<span class="bu">section</span> <span class="st">&quot;.data&quot;</span></a>
<a class="sourceLine" id="cb3-2" title="2">.global <span class="st">&quot;myfilesymbol&quot;</span></a>
<a class="sourceLine" id="cb3-3" title="3">.<span class="bu">align</span> <span class="dv">8</span></a>
<a class="sourceLine" id="cb3-4" title="4"><span class="fu">myfilesymbol:</span></a>
<a class="sourceLine" id="cb3-5" title="5">   .incbin <span class="st">&quot;data.bin&quot;</span>,<span class="dv">10</span>,<span class="dv">128</span></a></code></pre></div>
<p>It basically tells the assembler to include the “data.bin” file as-is into the output binary. We specify the section where to add it (“.data” or “.rodata” for read-only files), the alignment constraint, an optional file offset/size and finally we attach a global symbol to it.</p>
<ol start="2" type="1">
<li>We include this file in the compilation chain.</li>
</ol>
<p>We use a combination of <a href="https://www.stackage.org/haddock/lts-13.3/template-haskell-2.14.0.0/Language-Haskell-TH-Syntax.html#v:addForeignFilePath">addForeignFilePath</a>, <a href="https://www.stackage.org/haddock/lts-13.3/template-haskell-2.14.0.0/Language-Haskell-TH-Syntax.html#v:addTempFile">addTempFile</a> and <a href="https://www.stackage.org/haddock/lts-13.3/template-haskell-2.14.0.0/Language-Haskell-TH-Syntax.html#v:addDependentFile">addDependentFile</a> to add a dependency on the input file and the assembly file into the compilation chain.</p>
<p>There is a small issue: <a href="https://www.stackage.org/haddock/lts-13.3/template-haskell-2.14.0.0/Language-Haskell-TH-Syntax.html#t:ForeignSrcLang">ForeignSrcLang</a> doesn’t support assembly files yet. A workaround is to embed the assembly file into a C file by using GCC’s <a href="https://gcc.gnu.org/onlinedocs/gcc/Basic-Asm.html#Basic-Asm">asm directive</a>. It is suboptimal and it would be better to add direct support of assembly files to TH. I have opened a ticket (<a href="https://ghc.haskell.org/trac/ghc/ticket/16180">#16180</a>) with the feature request and a <a href="https://gitlab.haskell.org/ghc/ghc/merge_requests/122/">merge request</a> implementing it. I don’t know if/when it will be merged but we can use the workaround in the meantime.</p>
<ol start="3" type="1">
<li>Via TH, we generate an expression to create a Buffer (or a ByteString) from the symbol in the assembly file.</li>
</ol>
<p>We can get access to a global symbol with a foreign import declaration such as the following one:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="co">-- Don't forget the &quot;&amp;&quot; before the symbol name</span></a>
<a class="sourceLine" id="cb4-2" title="2">foreign <span class="kw">import</span> ccall &quot;&amp;myfilesymbol&quot; myfile_addr :: <span class="dt">Ptr</span> ()</a></code></pre></div>
<p>To build a ByteString, we only have to generate something like the following:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="ot">myfile ::</span> <span class="dt">ByteString</span></a>
<a class="sourceLine" id="cb5-2" title="2">myfile <span class="ot">=</span> unsafePerformIO (unsafePackCStringLen (castPtr myfile_addr, <span class="dv">128</span>))</a>
<a class="sourceLine" id="cb5-3" title="3"><span class="co">-- the size (128 here) is known statically ---------------------------^</span></a></code></pre></div>
<p>And that’s it.</p>
<h1 id="conclusion">Conclusion</h1>
<p>Using my approach is much faster as the benchmark results show. It’s because we totally bypass GHC’s pipeline: we don’t try to apply CSE to huge binary chunks; we don’t keep these huge binary chunks into memory; they don’t end up into interface files; etc.</p>
<p>It should be quite portable. We would have to adapt section names (“rodata”, “data”) on non ELF architectures I guess, but otherwise it should be OK.</p>
<p>As a bonus, with this approach we control the data alignment (useful with vector instructions) and we can choose to make the buffer read-only or not (if one tries to write a read-only buffer, it segfaults as expected).</p>
<p>You can find my implementation <a href="https://github.com/haskus/packages/blob/7db4d7609c2291de2ab4250e19a083c6de671ec9/haskus-binary/src/lib/Haskus/Memory/Embed.hs">here</a>. It is part of a larger work-in-progress on explicit memory management documented <a href="https://docs.haskus.org/memory.html">here</a> (<a href="https://docs.haskus.org/memory/embed.html">chapter on buffer embedding</a>).</p>
<p>If someone is up to implement this into <code>file-embed</code>, I guess it will make a few people happy.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>An answer to "The Trouble with Typed Errors"</title>
    <link href="http://www.hsyl20.fr/home/posts/2018-11-04-trouble-with-typed-errors.html" />
    <id>http://www.hsyl20.fr/home/posts/2018-11-04-trouble-with-typed-errors.html</id>
    <published>2018-11-04T00:00:00Z</published>
    <updated>2018-11-04T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">An answer to "The Trouble with Typed Errors"</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Variant.html">Variant</a></td>
               <td class="date">November  4, 2018</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p><strong>Changelog</strong></p>
<ul>
<li>2018-11-08 (20h30): I’ve added the “Variant + Either” approach in reaction to a <a href="https://www.reddit.com/r/haskell/comments/9vbfpk/an_answer_to_the_trouble_with_typed_errors/">reddit discussion</a></li>
<li>2018-11-08 (23h00): added section about the <code>FlowT</code> approach</li>
</ul>
<hr />
<p>This post is a follow-up to a post Matt Parsons has just published: <a href="http://www.parsonsmatt.org/2018/11/03/trouble_with_typed_errors.html">The Trouble with Typed Errors</a> (<a href="https://www.reddit.com/r/haskell/comments/9ty6nw/the_trouble_with_typed_errors/">discussion on Reddit</a>).</p>
<p>While I totally agree with the diagnostic, I don’t fully agree with the conclusion. in particular:</p>
<blockquote>
<p>In PureScript or OCaml, you can use open variant types to do this flawlessly. Haskell doesn’t have open variants, and the attempts to mock them end up quite clumsy to use in practice.</p>
</blockquote>
<p>Being the author of an <a href="https://hackage.haskell.org/package/haskus-utils-variant">open Variant type</a> (<a href="https://docs.haskus.org/variant.html">doc</a>) in Haskell, I don’t think they are that clumsy, so let’s compare!</p>
<h1 id="variant-either-approach">Variant + Either approach</h1>
<p>First let’s rewrite the safe functions <code>head</code>, <code>lookup</code> and <code>parse</code> by making them return a <code>Variant</code> on the <code>Left</code> side:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="ot">{-# LANGUAGE TypeApplications #-}</span></a>
<a class="sourceLine" id="cb1-2" title="2"></a>
<a class="sourceLine" id="cb1-3" title="3"><span class="kw">import</span> <span class="dt">Haskus.Utils.Variant</span></a>
<a class="sourceLine" id="cb1-4" title="4"></a>
<a class="sourceLine" id="cb1-5" title="5"><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> (head,lookup)</a>
<a class="sourceLine" id="cb1-6" title="6"><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Prelude</span></a>
<a class="sourceLine" id="cb1-7" title="7"><span class="kw">import</span> <span class="dt">Text.Read</span></a>
<a class="sourceLine" id="cb1-8" title="8"></a>
<a class="sourceLine" id="cb1-9" title="9"><span class="kw">data</span> <span class="dt">ParseError</span> <span class="ot">=</span> <span class="dt">ParseError</span> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb1-10" title="10"></a>
<a class="sourceLine" id="cb1-11" title="11"><span class="ot">parse ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> '[<span class="dt">ParseError</span>]) <span class="dt">Integer</span></a>
<a class="sourceLine" id="cb1-12" title="12">parse s <span class="ot">=</span> <span class="kw">case</span> readMaybe s <span class="kw">of</span></a>
<a class="sourceLine" id="cb1-13" title="13">   <span class="dt">Just</span> i  <span class="ot">-&gt;</span> <span class="dt">Right</span> i</a>
<a class="sourceLine" id="cb1-14" title="14">   <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="dt">Left</span> (<span class="dt">V</span> <span class="dt">ParseError</span>)</a>
<a class="sourceLine" id="cb1-15" title="15"></a>
<a class="sourceLine" id="cb1-16" title="16"></a>
<a class="sourceLine" id="cb1-17" title="17"><span class="kw">data</span> <span class="dt">HeadError</span> <span class="ot">=</span> <span class="dt">ListWasEmpty</span> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb1-18" title="18"></a>
<a class="sourceLine" id="cb1-19" title="19"><span class="fu">head</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> '[<span class="dt">HeadError</span>]) a</a>
<a class="sourceLine" id="cb1-20" title="20"><span class="fu">head</span> []    <span class="ot">=</span> <span class="dt">Left</span> (<span class="dt">V</span> <span class="dt">ListWasEmpty</span>)</a>
<a class="sourceLine" id="cb1-21" title="21"><span class="fu">head</span> (x<span class="op">:</span>_) <span class="ot">=</span> <span class="dt">Right</span> x</a>
<a class="sourceLine" id="cb1-22" title="22"></a>
<a class="sourceLine" id="cb1-23" title="23"><span class="kw">data</span> <span class="dt">LookupError</span> k <span class="ot">=</span> <span class="dt">KeyWasNotPresent</span> k <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb1-24" title="24"></a>
<a class="sourceLine" id="cb1-25" title="25"><span class="fu">lookup</span><span class="ot"> ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> k <span class="ot">-&gt;</span> [(k,v)] <span class="ot">-&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> '[<span class="dt">LookupError</span> k]) v</a>
<a class="sourceLine" id="cb1-26" title="26"><span class="fu">lookup</span> k vs <span class="ot">=</span> <span class="kw">case</span> Prelude.lookup k vs <span class="kw">of</span></a>
<a class="sourceLine" id="cb1-27" title="27">   <span class="dt">Just</span> v  <span class="ot">-&gt;</span> <span class="dt">Right</span> v</a>
<a class="sourceLine" id="cb1-28" title="28">   <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="dt">Left</span> (<span class="dt">V</span> (<span class="dt">KeyWasNotPresent</span> k))</a></code></pre></div>
<p>Now to compose these functions, we just have to write:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="kw">import</span> <span class="dt">Data.Bifunctor</span> (first)</a>
<a class="sourceLine" id="cb2-2" title="2"></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="ot">liftLeft ::</span> <span class="dt">LiftVariant</span> xs ys <span class="ot">=&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> xs) r <span class="ot">-&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> ys) r</a>
<a class="sourceLine" id="cb2-4" title="4">liftLeft <span class="ot">=</span> first liftVariant</a>
<a class="sourceLine" id="cb2-5" title="5"></a>
<a class="sourceLine" id="cb2-6" title="6">foo str <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb2-7" title="7">   c <span class="ot">&lt;-</span> liftLeft <span class="op">$</span> <span class="fu">head</span> str</a>
<a class="sourceLine" id="cb2-8" title="8">   r <span class="ot">&lt;-</span> liftLeft <span class="op">$</span> <span class="fu">lookup</span> c codeMap</a>
<a class="sourceLine" id="cb2-9" title="9">   liftLeft <span class="op">$</span> parse (r <span class="op">++</span> <span class="fu">tail</span> str)</a>
<a class="sourceLine" id="cb2-10" title="10"></a>
<a class="sourceLine" id="cb2-11" title="11">   <span class="kw">where</span></a>
<a class="sourceLine" id="cb2-12" title="12"><span class="ot">      codeMap ::</span> [(<span class="dt">Char</span>, <span class="dt">String</span>)]</a>
<a class="sourceLine" id="cb2-13" title="13">      codeMap <span class="ot">=</span> [ (<span class="ch">'x'</span>, <span class="st">&quot;0x&quot;</span>)</a>
<a class="sourceLine" id="cb2-14" title="14">                , (<span class="ch">'d'</span>, <span class="st">&quot;&quot;</span>)</a>
<a class="sourceLine" id="cb2-15" title="15">                ]</a></code></pre></div>
<ol type="1">
<li>We can fix the <code>Variant</code> type at the definition site:</li>
</ol>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="ot">foo ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> '[<span class="dt">ParseError</span>, <span class="dt">LookupError</span> <span class="dt">Char</span>, <span class="dt">HeadError</span>]) <span class="dt">Integer</span></a>
<a class="sourceLine" id="cb3-2" title="2"></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="co">-- The order of the error types doesn't matter and we can add additional error</span></a>
<a class="sourceLine" id="cb3-4" title="4"><span class="co">-- types if we want:</span></a>
<a class="sourceLine" id="cb3-5" title="5"><span class="ot">foo ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> '[<span class="dt">Float</span>,<span class="dt">Int</span>,<span class="dt">Double</span>,<span class="dt">ParseError</span>,<span class="dt">LookupError</span> <span class="dt">Char</span>,<span class="dt">HeadError</span>,<span class="dt">String</span>]) <span class="dt">Integer</span></a></code></pre></div>
<p>Test:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="op">&gt;</span> foo <span class="st">&quot;d10&quot;</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="dt">Right</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb4-3" title="3"></a>
<a class="sourceLine" id="cb4-4" title="4"><span class="op">&gt;</span> foo <span class="st">&quot;x10&quot;</span></a>
<a class="sourceLine" id="cb4-5" title="5"><span class="dt">Right</span> <span class="dv">16</span></a>
<a class="sourceLine" id="cb4-6" title="6"></a>
<a class="sourceLine" id="cb4-7" title="7"><span class="op">&gt;</span> foo <span class="st">&quot;u10&quot;</span></a>
<a class="sourceLine" id="cb4-8" title="8"><span class="dt">Left</span> <span class="dt">V</span> <span class="op">@</span>(<span class="dt">LookupError</span> <span class="dt">Char</span>) (<span class="dt">KeyWasNotPresent</span> <span class="ch">'u'</span>)</a>
<a class="sourceLine" id="cb4-9" title="9"></a>
<a class="sourceLine" id="cb4-10" title="10"><span class="op">&gt;</span> foo <span class="st">&quot;&quot;</span></a>
<a class="sourceLine" id="cb4-11" title="11"><span class="dt">Left</span> <span class="dt">V</span> <span class="op">@</span><span class="dt">HeadError</span> <span class="dt">ListWasEmpty</span></a>
<a class="sourceLine" id="cb4-12" title="12"></a>
<a class="sourceLine" id="cb4-13" title="13"><span class="op">&gt;</span> foo <span class="st">&quot;d10X&quot;</span></a>
<a class="sourceLine" id="cb4-14" title="14"><span class="dt">Left</span> <span class="dt">V</span> <span class="op">@</span><span class="dt">ParseError</span> <span class="dt">ParseError</span></a></code></pre></div>
<ol start="2" type="1">
<li>Or if don’t give <code>foo</code> a type signature we can fix the <code>Variant</code> type when we call it:</li>
</ol>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="op">&gt;</span> foo <span class="st">&quot;d10&quot;</span><span class="ot"> ::</span> <span class="dt">Either</span> (<span class="dt">V</span> '[<span class="dt">ParseError</span>,<span class="dt">HeadError</span>,<span class="dt">LookupError</span> <span class="dt">Char</span>]) <span class="dt">Integer</span></a>
<a class="sourceLine" id="cb5-2" title="2"><span class="dt">Right</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb5-3" title="3"></a>
<a class="sourceLine" id="cb5-4" title="4"><span class="co">-- The order of the error types still doesn't matter and we can add additional</span></a>
<a class="sourceLine" id="cb5-5" title="5"><span class="co">-- error types if we want:</span></a>
<a class="sourceLine" id="cb5-6" title="6"><span class="op">&gt;</span> foo <span class="st">&quot;d10&quot;</span><span class="ot"> ::</span> <span class="dt">Either</span> (<span class="dt">V</span> '[<span class="dt">Float</span>,<span class="dt">Int</span>,<span class="dt">Double</span>,<span class="dt">ParseError</span>,<span class="dt">LookupError</span> <span class="dt">Char</span>,<span class="dt">HeadError</span>,<span class="dt">String</span>]) <span class="dt">Integer</span></a>
<a class="sourceLine" id="cb5-7" title="7"><span class="dt">Right</span> <span class="dv">10</span></a></code></pre></div>
<ol start="3" type="1">
<li>Or we can give a generic type signature to <code>foo</code>:</li>
</ol>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="ot">foo ::</span> <span class="kw">forall</span> es<span class="op">.</span></a>
<a class="sourceLine" id="cb6-2" title="2">   ('[<span class="dt">HeadError</span>,<span class="dt">ParseError</span>,<span class="dt">LookupError</span> <span class="dt">Char</span>] <span class="op">:&lt;&lt;</span> es</a>
<a class="sourceLine" id="cb6-3" title="3">   ) <span class="ot">=&gt;</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> (<span class="dt">V</span> es) <span class="dt">Integer</span></a></code></pre></div>
<p>It allows us to use <code>TypeApplications</code> to pass the list of error types:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="op">&gt;</span> foo <span class="op">@</span>'[<span class="dt">ParseError</span>,<span class="dt">HeadError</span>,<span class="dt">LookupError</span> <span class="dt">Char</span>] <span class="st">&quot;d10&quot;</span></a>
<a class="sourceLine" id="cb7-2" title="2"><span class="dt">Right</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb7-3" title="3"></a>
<a class="sourceLine" id="cb7-4" title="4"><span class="op">&gt;</span> foo <span class="op">@</span>'[<span class="dt">HeadError</span>,<span class="dt">LookupError</span> <span class="dt">Char</span>,<span class="dt">ParseError</span>] <span class="st">&quot;d10X&quot;</span></a>
<a class="sourceLine" id="cb7-5" title="5"><span class="dt">Left</span> <span class="dt">V</span> <span class="op">@</span><span class="dt">ParseError</span> <span class="dt">ParseError</span></a></code></pre></div>
<h1 id="exceptt-like-approach">ExceptT-like approach</h1>
<p>Just like <a href="https://www.stackage.org/haddock/lts-12.17/transformers-0.5.5.0/Control-Monad-Trans-Except.html#t:ExceptT">ExceptT</a> wraps <code>Either</code>, we can use a <code>FlowT</code> newtype to wraps a <code>Variant</code>. Compared to the approach above (“Either + Variant”), we avoid the <code>Either</code> indirection: the first value of the Variant is considered as the <code>Right</code> value and the other ones as the error values.</p>
<p>The example above becomes:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="ot">{-# LANGUAGE TypeApplications #-}</span></a>
<a class="sourceLine" id="cb8-2" title="2"><span class="ot">{-# LANGUAGE TypeOperators #-}</span></a>
<a class="sourceLine" id="cb8-3" title="3"></a>
<a class="sourceLine" id="cb8-4" title="4"><span class="kw">import</span> <span class="dt">Haskus.Utils.Variant.Flow</span></a>
<a class="sourceLine" id="cb8-5" title="5"></a>
<a class="sourceLine" id="cb8-6" title="6"><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> (head,lookup)</a>
<a class="sourceLine" id="cb8-7" title="7"><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Prelude</span></a>
<a class="sourceLine" id="cb8-8" title="8"><span class="kw">import</span> <span class="dt">Text.Read</span></a>
<a class="sourceLine" id="cb8-9" title="9"></a>
<a class="sourceLine" id="cb8-10" title="10"><span class="kw">data</span> <span class="dt">ParseError</span> <span class="ot">=</span> <span class="dt">ParseError</span> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb8-11" title="11"></a>
<a class="sourceLine" id="cb8-12" title="12"><span class="ot">parse ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> '[<span class="dt">ParseError</span>] <span class="dt">Integer</span></a>
<a class="sourceLine" id="cb8-13" title="13">parse s <span class="ot">=</span> <span class="kw">case</span> readMaybe s <span class="kw">of</span></a>
<a class="sourceLine" id="cb8-14" title="14">   <span class="dt">Just</span> i  <span class="ot">-&gt;</span> <span class="fu">pure</span> i</a>
<a class="sourceLine" id="cb8-15" title="15">   <span class="dt">Nothing</span> <span class="ot">-&gt;</span> throwE <span class="dt">ParseError</span></a>
<a class="sourceLine" id="cb8-16" title="16"></a>
<a class="sourceLine" id="cb8-17" title="17"></a>
<a class="sourceLine" id="cb8-18" title="18"><span class="kw">data</span> <span class="dt">HeadError</span> <span class="ot">=</span> <span class="dt">ListWasEmpty</span> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb8-19" title="19"></a>
<a class="sourceLine" id="cb8-20" title="20"><span class="fu">head</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Flow</span> '[<span class="dt">HeadError</span>] a</a>
<a class="sourceLine" id="cb8-21" title="21"><span class="fu">head</span> []    <span class="ot">=</span> throwE <span class="dt">ListWasEmpty</span></a>
<a class="sourceLine" id="cb8-22" title="22"><span class="fu">head</span> (x<span class="op">:</span>_) <span class="ot">=</span> <span class="fu">pure</span> x</a>
<a class="sourceLine" id="cb8-23" title="23"></a>
<a class="sourceLine" id="cb8-24" title="24"><span class="kw">data</span> <span class="dt">LookupError</span> k <span class="ot">=</span> <span class="dt">KeyWasNotPresent</span> k <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb8-25" title="25"></a>
<a class="sourceLine" id="cb8-26" title="26"><span class="fu">lookup</span><span class="ot"> ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> k <span class="ot">-&gt;</span> [(k,v)] <span class="ot">-&gt;</span> <span class="dt">Flow</span> '[<span class="dt">LookupError</span> k] v</a>
<a class="sourceLine" id="cb8-27" title="27"><span class="fu">lookup</span> k vs <span class="ot">=</span> <span class="kw">case</span> Prelude.lookup k vs <span class="kw">of</span></a>
<a class="sourceLine" id="cb8-28" title="28">   <span class="dt">Just</span> v  <span class="ot">-&gt;</span> <span class="fu">pure</span> v</a>
<a class="sourceLine" id="cb8-29" title="29">   <span class="dt">Nothing</span> <span class="ot">-&gt;</span> throwE (<span class="dt">KeyWasNotPresent</span> k)</a>
<a class="sourceLine" id="cb8-30" title="30"></a>
<a class="sourceLine" id="cb8-31" title="31"></a>
<a class="sourceLine" id="cb8-32" title="32"><span class="ot">foo ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> '[<span class="dt">ParseError</span>, <span class="dt">LookupError</span> <span class="dt">Char</span>, <span class="dt">HeadError</span>] <span class="dt">Integer</span></a>
<a class="sourceLine" id="cb8-33" title="33"><span class="co">-- foo :: forall es.</span></a>
<a class="sourceLine" id="cb8-34" title="34"><span class="co">--    ('[HeadError,ParseError,LookupError Char] :&lt;&lt; es</span></a>
<a class="sourceLine" id="cb8-35" title="35"><span class="co">--    ) =&gt; String -&gt; Flow es Integer</span></a>
<a class="sourceLine" id="cb8-36" title="36">foo str <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb8-37" title="37">   c <span class="ot">&lt;-</span> liftFlowT <span class="op">$</span> <span class="fu">head</span> str</a>
<a class="sourceLine" id="cb8-38" title="38">   r <span class="ot">&lt;-</span> liftFlowT <span class="op">$</span> <span class="fu">lookup</span> c codeMap</a>
<a class="sourceLine" id="cb8-39" title="39">   liftFlowT <span class="op">$</span> parse (r <span class="op">++</span> <span class="fu">tail</span> str)</a>
<a class="sourceLine" id="cb8-40" title="40"></a>
<a class="sourceLine" id="cb8-41" title="41">   <span class="kw">where</span></a>
<a class="sourceLine" id="cb8-42" title="42"><span class="ot">      codeMap ::</span> [(<span class="dt">Char</span>, <span class="dt">String</span>)]</a>
<a class="sourceLine" id="cb8-43" title="43">      codeMap <span class="ot">=</span> [ (<span class="ch">'x'</span>, <span class="st">&quot;0x&quot;</span>)</a>
<a class="sourceLine" id="cb8-44" title="44">                , (<span class="ch">'d'</span>, <span class="st">&quot;&quot;</span>)</a>
<a class="sourceLine" id="cb8-45" title="45">                ]</a></code></pre></div>
<p>Test:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="op">&gt;</span> runFlow (foo <span class="st">&quot;d10&quot;</span>)</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="dt">V</span> <span class="op">@</span><span class="dt">Integer</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb9-3" title="3"></a>
<a class="sourceLine" id="cb9-4" title="4"><span class="op">&gt;</span> runFlow (foo <span class="st">&quot;x10&quot;</span>)</a>
<a class="sourceLine" id="cb9-5" title="5"><span class="dt">V</span> <span class="op">@</span><span class="dt">Integer</span> <span class="dv">16</span></a>
<a class="sourceLine" id="cb9-6" title="6"></a>
<a class="sourceLine" id="cb9-7" title="7"><span class="op">&gt;</span> runFlow (foo <span class="st">&quot;u10&quot;</span>)</a>
<a class="sourceLine" id="cb9-8" title="8"><span class="dt">V</span> <span class="op">@</span>(<span class="dt">LookupError</span> <span class="dt">Char</span>) (<span class="dt">KeyWasNotPresent</span> <span class="ch">'u'</span>)</a>
<a class="sourceLine" id="cb9-9" title="9"></a>
<a class="sourceLine" id="cb9-10" title="10"><span class="op">&gt;</span> runFlow (foo <span class="st">&quot;&quot;</span>)</a>
<a class="sourceLine" id="cb9-11" title="11"><span class="dt">V</span> <span class="op">@</span><span class="dt">HeadError</span> <span class="dt">ListWasEmpty</span></a>
<a class="sourceLine" id="cb9-12" title="12"></a>
<a class="sourceLine" id="cb9-13" title="13"><span class="op">&gt;</span> runFlow (foo <span class="st">&quot;d10X&quot;</span>)</a>
<a class="sourceLine" id="cb9-14" title="14"><span class="dt">V</span> <span class="op">@</span><span class="dt">ParseError</span> <span class="dt">ParseError</span></a>
<a class="sourceLine" id="cb9-15" title="15"></a>
<a class="sourceLine" id="cb9-16" title="16"><span class="op">&gt;</span> foo <span class="st">&quot;&quot;</span> <span class="ot">`catchE`</span> (\<span class="dt">ListWasEmpty</span> <span class="ot">-&gt;</span> success <span class="dv">42</span>)<span class="ot"> ::</span> <span class="dt">Flow</span> '[<span class="dt">ParseError</span>,<span class="dt">LookupError</span> <span class="dt">Char</span>] <span class="dt">Integer</span></a>
<a class="sourceLine" id="cb9-17" title="17"><span class="dt">FlowT</span> (<span class="dt">Identity</span> <span class="dt">V</span> <span class="op">@</span><span class="dt">Integer</span> <span class="dv">42</span>)</a></code></pre></div>
<p>(<code>FlowT</code> is available from release 2.4 of <code>haskus-utils-variant</code> package).</p>
<h1 id="full-variant-approach">Full Variant approach</h1>
<p>Finally, there is another approach that directly uses <code>Variant</code> with <code>RebindableSyntax</code> extension.</p>
<p>First let’s rewrite the safe functions <code>head</code>, <code>lookup</code> and <code>parse</code> by making them return a <code>Variant</code>:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="ot">{-# LANGUAGE TypeApplications #-}</span></a>
<a class="sourceLine" id="cb10-2" title="2"></a>
<a class="sourceLine" id="cb10-3" title="3"><span class="kw">import</span> <span class="dt">Haskus.Utils.Variant</span></a>
<a class="sourceLine" id="cb10-4" title="4"></a>
<a class="sourceLine" id="cb10-5" title="5"><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> (head,lookup)</a>
<a class="sourceLine" id="cb10-6" title="6"><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Prelude</span></a>
<a class="sourceLine" id="cb10-7" title="7"><span class="kw">import</span> <span class="dt">Text.Read</span></a>
<a class="sourceLine" id="cb10-8" title="8"></a>
<a class="sourceLine" id="cb10-9" title="9"><span class="kw">data</span> <span class="dt">ParseError</span> <span class="ot">=</span> <span class="dt">ParseError</span> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb10-10" title="10"></a>
<a class="sourceLine" id="cb10-11" title="11"><span class="ot">parse ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">V</span> '[<span class="dt">Integer</span>,<span class="dt">ParseError</span>]</a>
<a class="sourceLine" id="cb10-12" title="12">parse s <span class="ot">=</span> <span class="kw">case</span> readMaybe s <span class="kw">of</span></a>
<a class="sourceLine" id="cb10-13" title="13">   <span class="dt">Just</span> i  <span class="ot">-&gt;</span> <span class="dt">V</span> <span class="op">@</span><span class="dt">Integer</span> i    <span class="co">-- we use the `V` pattern to index the</span></a>
<a class="sourceLine" id="cb10-14" title="14">   <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="dt">V</span> <span class="dt">ParseError</span>    <span class="co">-- Variant by type</span></a>
<a class="sourceLine" id="cb10-15" title="15"></a>
<a class="sourceLine" id="cb10-16" title="16"></a>
<a class="sourceLine" id="cb10-17" title="17"><span class="kw">data</span> <span class="dt">HeadError</span> <span class="ot">=</span> <span class="dt">ListWasEmpty</span> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb10-18" title="18"></a>
<a class="sourceLine" id="cb10-19" title="19"><span class="fu">head</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">V</span> '[a,<span class="dt">HeadError</span>]</a>
<a class="sourceLine" id="cb10-20" title="20"><span class="fu">head</span> []    <span class="ot">=</span> toVariantAt <span class="op">@</span><span class="dv">1</span> <span class="dt">ListWasEmpty</span>  <span class="co">-- we can't index the Variant by</span></a>
<a class="sourceLine" id="cb10-21" title="21"><span class="fu">head</span> (x<span class="op">:</span>_) <span class="ot">=</span> toVariantAt <span class="op">@</span><span class="dv">0</span> x             <span class="co">-- type because `a` is ambiguous,</span></a>
<a class="sourceLine" id="cb10-22" title="22">                                          <span class="co">-- so we do it by index explicitly</span></a>
<a class="sourceLine" id="cb10-23" title="23"></a>
<a class="sourceLine" id="cb10-24" title="24"><span class="kw">data</span> <span class="dt">LookupError</span> k <span class="ot">=</span> <span class="dt">KeyWasNotPresent</span> k <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb10-25" title="25"></a>
<a class="sourceLine" id="cb10-26" title="26"><span class="fu">lookup</span><span class="ot"> ::</span> <span class="dt">Eq</span> k <span class="ot">=&gt;</span> k <span class="ot">-&gt;</span> [(k,v)] <span class="ot">-&gt;</span> <span class="dt">V</span> '[v,<span class="dt">LookupError</span> k]</a>
<a class="sourceLine" id="cb10-27" title="27"><span class="fu">lookup</span> k vs <span class="ot">=</span> <span class="kw">case</span> Prelude.lookup k vs <span class="kw">of</span></a>
<a class="sourceLine" id="cb10-28" title="28">   <span class="dt">Just</span> v  <span class="ot">-&gt;</span> toVariantAt <span class="op">@</span><span class="dv">0</span> v            <span class="co">-- ditto</span></a>
<a class="sourceLine" id="cb10-29" title="29">   <span class="dt">Nothing</span> <span class="ot">-&gt;</span> toVariantAt <span class="op">@</span><span class="dv">1</span> (<span class="dt">KeyWasNotPresent</span> k)</a></code></pre></div>
<p>Now we could use <code>Variant</code>’s primitives to compose these functions (again see the <a href="https://docs.haskus.org/variant.html">documentation</a>). But instead I will show how we can use them implicitly with do-notation thanks to the <code>RebindableSyntax</code> extension:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1"><span class="ot">{-# LANGUAGE RebindableSyntax #-}</span></a>
<a class="sourceLine" id="cb11-2" title="2"></a>
<a class="sourceLine" id="cb11-3" title="3"><span class="kw">import</span> <span class="dt">Haskus.Utils.Variant.Syntax</span></a>
<a class="sourceLine" id="cb11-4" title="4"></a>
<a class="sourceLine" id="cb11-5" title="5"><span class="kw">import</span> <span class="dt">Prelude</span> <span class="kw">hiding</span> ((&gt;&gt;=),(&gt;&gt;),return)</a>
<a class="sourceLine" id="cb11-6" title="6"></a>
<a class="sourceLine" id="cb11-7" title="7"><span class="ot">foo ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">V</span> '[<span class="dt">Integer</span>, <span class="dt">ParseError</span>, <span class="dt">LookupError</span> <span class="dt">Char</span>, <span class="dt">HeadError</span>]</a>
<a class="sourceLine" id="cb11-8" title="8">foo str <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb11-9" title="9">   c <span class="ot">&lt;-</span> <span class="fu">head</span> str</a>
<a class="sourceLine" id="cb11-10" title="10">   r <span class="ot">&lt;-</span> <span class="fu">lookup</span> c codeMap</a>
<a class="sourceLine" id="cb11-11" title="11">   parse (r <span class="op">++</span> <span class="fu">tail</span> str)</a>
<a class="sourceLine" id="cb11-12" title="12"></a>
<a class="sourceLine" id="cb11-13" title="13">   <span class="kw">where</span></a>
<a class="sourceLine" id="cb11-14" title="14"><span class="ot">      codeMap ::</span> [(<span class="dt">Char</span>, <span class="dt">String</span>)]</a>
<a class="sourceLine" id="cb11-15" title="15">      codeMap <span class="ot">=</span> [ (<span class="ch">'x'</span>, <span class="st">&quot;0x&quot;</span>)</a>
<a class="sourceLine" id="cb11-16" title="16">                , (<span class="ch">'d'</span>, <span class="st">&quot;&quot;</span>)</a>
<a class="sourceLine" id="cb11-17" title="17">                ]</a></code></pre></div>
<p>Test:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" title="1"><span class="op">&gt;</span> foo <span class="st">&quot;d10&quot;</span></a>
<a class="sourceLine" id="cb12-2" title="2"><span class="dt">V</span> <span class="op">@</span><span class="dt">Integer</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb12-3" title="3"></a>
<a class="sourceLine" id="cb12-4" title="4"><span class="op">&gt;</span> foo <span class="st">&quot;x10&quot;</span></a>
<a class="sourceLine" id="cb12-5" title="5"><span class="dt">V</span> <span class="op">@</span><span class="dt">Integer</span> <span class="dv">16</span></a>
<a class="sourceLine" id="cb12-6" title="6"></a>
<a class="sourceLine" id="cb12-7" title="7"><span class="op">&gt;</span> foo <span class="st">&quot;u10&quot;</span></a>
<a class="sourceLine" id="cb12-8" title="8"><span class="dt">V</span> <span class="op">@</span>(<span class="dt">LookupError</span> <span class="dt">Char</span>) (<span class="dt">KeyWasNotPresent</span> <span class="ch">'u'</span>)</a>
<a class="sourceLine" id="cb12-9" title="9"></a>
<a class="sourceLine" id="cb12-10" title="10"><span class="op">&gt;</span> foo <span class="st">&quot;&quot;</span></a>
<a class="sourceLine" id="cb12-11" title="11"><span class="dt">V</span> <span class="op">@</span><span class="dt">HeadError</span> <span class="dt">ListWasEmpty</span></a>
<a class="sourceLine" id="cb12-12" title="12"></a>
<a class="sourceLine" id="cb12-13" title="13"><span class="op">&gt;</span> foo <span class="st">&quot;d10X&quot;</span></a>
<a class="sourceLine" id="cb12-14" title="14"><span class="dt">V</span> <span class="op">@</span><span class="dt">ParseError</span> <span class="dt">ParseError</span></a></code></pre></div>
<h1 id="conclusion">Conclusion</h1>
<p>It doesn’t look that clumsy to me! ;-)</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Announcing Variant and EADT 2.0</title>
    <link href="http://www.hsyl20.fr/home/posts/2018-10-28-announcing-eadt.html" />
    <id>http://www.hsyl20.fr/home/posts/2018-10-28-announcing-eadt.html</id>
    <published>2018-10-28T00:00:00Z</published>
    <updated>2018-10-28T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Announcing Variant and EADT 2.0</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/EADT.html">EADT</a>, <a href="http://www.hsyl20.fr/home/tags/Variant.html">Variant</a></td>
               <td class="date">October 28, 2018</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>A short post to announce that I have just released <a href="https://hackage.haskell.org/package/haskus-utils-variant">version 2.0.1</a> of my <code>haskus-utils-variant</code> package (containing Variant and EADT).</p>
<p>The documentation has also been greatly enhanced thanks to the feedback I’ve received:</p>
<ul>
<li>Variant: <a href="https://docs.haskus.org/variant.html">https://docs.haskus.org/variant.html</a></li>
<li>EADT: <a href="https://docs.haskus.org/eadt.html">https://docs.haskus.org/eadt.html</a></li>
</ul>
<p>As a short introduction, a Variant is a generic sum type (i.e. like <code>Either</code> but supporting any number of value types instead of just 2):</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1">w,x,y,<span class="ot">z ::</span> <span class="dt">V</span> '[<span class="dt">String</span>,<span class="dt">Int</span>,<span class="dt">Float</span>,<span class="dt">Maybe</span> <span class="dt">String</span>]</a>
<a class="sourceLine" id="cb1-2" title="2">w <span class="ot">=</span> <span class="dt">V</span> <span class="st">&quot;test&quot;</span></a>
<a class="sourceLine" id="cb1-3" title="3">x <span class="ot">=</span> <span class="dt">V</span> <span class="op">@</span><span class="dt">Int</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb1-4" title="4">y <span class="ot">=</span> <span class="dt">V</span> <span class="op">@</span><span class="dt">Float</span> <span class="fl">5.0</span></a>
<a class="sourceLine" id="cb1-5" title="5">z <span class="ot">=</span> <span class="dt">V</span> (<span class="dt">Just</span> <span class="st">&quot;Hello World&quot;</span>)</a></code></pre></div>
<p>Similarly, an EADT is an extensible algebraic data type (ADT). Compared to Variant, it supports recursively defined ADT. For instance a list EADT can be defined with:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="ot">{-# LANGUAGE TemplateHaskell #-}</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="ot">{-# LANGUAGE DeriveFunctor #-}</span></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="ot">{-# LANGUAGE PatternSynonyms #-}</span></a>
<a class="sourceLine" id="cb2-4" title="4"><span class="ot">{-# LANGUAGE TypeFamilies #-}</span></a>
<a class="sourceLine" id="cb2-5" title="5"></a>
<a class="sourceLine" id="cb2-6" title="6"><span class="kw">data</span> <span class="dt">ConsF</span> a l <span class="ot">=</span> <span class="dt">ConsF</span> a l <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb2-7" title="7"><span class="kw">data</span> <span class="dt">NilF</span>    l <span class="ot">=</span> <span class="dt">NilF</span>      <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb2-8" title="8"></a>
<a class="sourceLine" id="cb2-9" title="9">eadtPattern <span class="dt">'ConsF</span> <span class="st">&quot;Cons&quot;</span></a>
<a class="sourceLine" id="cb2-10" title="10">eadtPattern <span class="dt">'NilF</span>  <span class="st">&quot;Nil&quot;</span></a>
<a class="sourceLine" id="cb2-11" title="11"></a>
<a class="sourceLine" id="cb2-12" title="12"><span class="kw">type</span> <span class="dt">List</span> a <span class="ot">=</span> <span class="dt">EADT</span> '[<span class="dt">ConsF</span> a, <span class="dt">NilF</span>]</a>
<a class="sourceLine" id="cb2-13" title="13"></a>
<a class="sourceLine" id="cb2-14" title="14"><span class="ot">x ::</span> <span class="dt">List</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb2-15" title="15">x <span class="ot">=</span> <span class="dt">Cons</span> <span class="st">&quot;Hello&quot;</span> (<span class="dt">Cons</span> <span class="st">&quot;World&quot;</span> <span class="dt">Nil</span>)</a></code></pre></div>
<p>Of course the whole point of EADT is not to redefine lists in a weird way but to help with codes where we would like to add or remove ADT constructors (e.g. different abstract syntax trees (AST) in a compiler) or to support generic recursive object hierarchies (e.g. extensible GUI widget hierarchies).</p>
<p>Any feedback appreciated!</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Extensible ADT (EADT)</title>
    <link href="http://www.hsyl20.fr/home/posts/2018-05-22-extensible-adt.html" />
    <id>http://www.hsyl20.fr/home/posts/2018-05-22-extensible-adt.html</id>
    <published>2018-05-22T00:00:00Z</published>
    <updated>2018-05-22T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Extensible ADT (EADT)</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/EADT.html">EADT</a>, <a href="http://www.hsyl20.fr/home/tags/Variant.html">Variant</a>, <a href="http://www.hsyl20.fr/home/tags/Expression%20problem.html">Expression problem</a></td>
               <td class="date">May 22, 2018</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <h1 id="introduction">Introduction</h1>
<h2 id="the-expression-problem-1998">The expression problem (1998)</h2>
<p>In 1998, Philip Wadler defined the <a href="https://en.wikipedia.org/wiki/Expression_problem">Expression</a> <a href="http://homepages.inf.ed.ac.uk/wadler/papers/expression/expression.txt">Problem</a> as follow:</p>
<blockquote>
<p>The Expression Problem is a new name for an old problem. The goal is to define a datatype by cases, where one can add new cases to the datatype and new functions over the datatype, without recompiling existing code, and while retaining static type safety</p>
</blockquote>
<p>In basic Haskell it is straightforward to add new functions over a data type. Suppose we have the following arithmetic expression data type:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">data</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">Val</span> <span class="dt">Int</span> <span class="op">|</span> <span class="dt">Add</span> <span class="dt">Expr</span> <span class="dt">Expr</span></a></code></pre></div>
<p>We can independently add an evaluator function, potentially in another module:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="ot">eval ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb2-2" title="2">eval (<span class="dt">Val</span> x)   <span class="ot">=</span>  x</a>
<a class="sourceLine" id="cb2-3" title="3">eval (<span class="dt">Add</span> x y) <span class="ot">=</span> eval x <span class="op">+</span> eval y</a></code></pre></div>
<p>However if we want to add a new case to the data type (say support for multiplication), we have to modify both the data type definition and the functions using it:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">data</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="op">....</span> <span class="op">|</span> <span class="dt">Mul</span> <span class="dt">Expr</span> <span class="dt">Expr</span></a>
<a class="sourceLine" id="cb3-2" title="2"></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="ot">eval ::</span> <span class="dt">Expr</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb3-4" title="4"><span class="op">....</span></a>
<a class="sourceLine" id="cb3-5" title="5">eval (<span class="dt">Mul</span> x y) <span class="ot">=</span> eval x <span class="op">*</span> eval y</a></code></pre></div>
<h2 id="data-types-à-la-carte-2008">Data types à la carte (2008)</h2>
<p>Ten years later (in 2008), Wouter Swierstra described a technique to handle this in his well-known <a href="http://www.cs.ru.nl/~W.Swierstra/Publications/DataTypesALaCarte.pdf">Data types à la carte</a> paper. The first idea is to define data constructors independently and to use a type parameter to leave open the data type they are part of.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="co">-- Independent data constructors. Parameter `e` represents the data type they</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="co">-- will be part of. It is required even if it is not used in the right hand</span></a>
<a class="sourceLine" id="cb4-3" title="3"><span class="co">-- side.</span></a>
<a class="sourceLine" id="cb4-4" title="4"><span class="kw">data</span> <span class="dt">Val</span> e <span class="ot">=</span> <span class="dt">Val</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb4-5" title="5"><span class="kw">data</span> <span class="dt">Add</span> e <span class="ot">=</span> <span class="dt">Add</span> e e</a></code></pre></div>
<p>Defining a new independent constructor is easy:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">data</span> <span class="dt">Mul</span> e <span class="ot">=</span> <span class="dt">Mul</span> e e</a></code></pre></div>
<p>The second idea is to use a combining data type:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">data</span> (f <span class="op">:+:</span> g) e <span class="ot">=</span> <span class="dt">Inl</span> (f e) <span class="op">|</span> <span class="dt">Inr</span> (g e)</a></code></pre></div>
<p>It is similar to <code>Either</code> except that it passes the same additional type parameter to both <code>f</code> and <code>g</code> type constructors. It can be used to compose independent data constructors without creating a new data type:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">type</span> <span class="dt">ExprF</span> <span class="ot">=</span> <span class="dt">Val</span> <span class="op">:+:</span> <span class="dt">Add</span></a></code></pre></div>
<p><code>ExprF</code> has kind <code>Type -&gt; Type</code> and its type parameter is used as the <code>e</code> parameter of the independent data constructors. We can set it to arbitrary types such as <code>Int</code> to build valid values:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1">y <span class="ot">=</span> <span class="dt">Inr</span> (<span class="dt">Add</span> <span class="dv">5</span> <span class="dv">8</span>)<span class="ot"> ::</span> <span class="dt">ExprF</span> <span class="dt">Int</span></a></code></pre></div>
<p>However the main use of this parameter should be to indicate the type of the expression data type we want to build, say <code>Expr</code>. Hence we would like to write something like this:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">type</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">ExprF</span> <span class="dt">Expr</span></a>
<a class="sourceLine" id="cb9-2" title="2"></a>
<a class="sourceLine" id="cb9-3" title="3"> <span class="op">&gt;</span><span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb9-4" title="4"> <span class="dt">Cycle</span> <span class="kw">in</span> <span class="kw">type</span> synonym declarations<span class="op">:</span></a>
<a class="sourceLine" id="cb9-5" title="5">   <span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">12</span><span class="op">:</span><span class="dv">1</span><span class="op">-</span><span class="dv">22</span><span class="op">:</span> <span class="kw">type</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">ExprF</span> <span class="dt">Expr</span></a></code></pre></div>
<p>Oops, we can’t build this cyclic (infinite) type. This leads us to the third idea: use another data type to handle the recursive nature of the expression type:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="kw">data</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">Expr</span> (<span class="dt">ExprF</span> <span class="dt">Expr</span>)</a></code></pre></div>
<p>We can abstract on it to use the same data type for different expression types:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1"><span class="co">-- `Fix` type as defined in Data.Functor.Foldable for instance</span></a>
<a class="sourceLine" id="cb11-2" title="2"><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))</a>
<a class="sourceLine" id="cb11-3" title="3"></a>
<a class="sourceLine" id="cb11-4" title="4"><span class="kw">type</span> <span class="dt">Expr</span> <span class="ot">=</span> <span class="dt">Fix</span> <span class="dt">ExprF</span></a></code></pre></div>
<h2 id="summary">Summary</h2>
<p>We use 3 different kinds of data types:</p>
<ol type="1">
<li>Constructor data types: <code>Val</code>, <code>Add</code>, <code>Mul</code>…</li>
<li>Combinator data type: <code>:+:</code></li>
<li>Recursivity handling data type: <code>Fix</code></li>
</ol>
<p>By using these different data types we have untangled the construction of ADTs (algebraic data types) and we can freely add new constructor data types and mix them into different algebraic data types.</p>
<p>Operations on these algebraic data types can be defined independently by using type-classes and recursion schemes.</p>
<h1 id="eadt---extensible-adt-2018">EADT - Extensible ADT (2018)</h1>
<p>In this post I’d like to slightly revisit and enhance the approach by using modern Haskell and in particular another combinator data type and pattern synonyms.</p>
<h2 id="a-different-combinator-data-type">A different combinator data type</h2>
<p><code>Variant (xs :: [*])</code> is a sum type that contains a value whose type can be any type in the <code>xs</code> list (see <a href="http://hsyl20.fr/home/posts/2018-02-21-heterogeneous-collections.html">this previous post</a>). We can use it to define the following <code>VariantF</code> type:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" title="1"><span class="kw">newtype</span> <span class="dt">VariantF</span> (<span class="ot">xs ::</span> [<span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>]) e <span class="ot">=</span> <span class="dt">VariantF</span> (<span class="dt">Variant</span> (<span class="dt">ApplyAll</span> e xs))</a>
<a class="sourceLine" id="cb12-2" title="2"></a>
<a class="sourceLine" id="cb12-3" title="3"><span class="co">-- ApplyAll e '[f,g,h] ==&gt; '[f e, g e, h e]</span></a>
<a class="sourceLine" id="cb12-4" title="4"></a>
<a class="sourceLine" id="cb12-5" title="5"><span class="kw">instance</span> <span class="dt">Functor</span> (<span class="dt">VariantF</span> xs) <span class="kw">where</span> <span class="op">....</span></a></code></pre></div>
<p>We will use this type as a combinator data type. Similarly to the <code>:+:</code> combinator data type presented in the introduction, <code>VariantF</code> passes its <code>e</code> parameter to all of its “member” types and has an instance of the <code>Functor</code> class.</p>
<p>Now instead of writing <code>f :+: g :+: h :+: i</code> to combine constructor data types to form an ADT we can write <code>VariantF '[f,g,h,i]</code>.</p>
<p>First benefit: just like using <code>Variant</code> is more efficient – O(1) memory usage and (de)construction – than using a nest of <code>Either</code>, using <code>VariantF</code> is more efficient than using a nest of <code>:+:</code>.</p>
<h2 id="a-generic-eadt-type">A generic EADT type</h2>
<p>Let’s define an EADT type synonym as follow:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb13-1" title="1"><span class="kw">type</span> <span class="dt">EADT</span> xs <span class="ot">=</span> <span class="dt">Fix</span> (<span class="dt">VariantF</span> xs)</a></code></pre></div>
<p>And a pattern synonym to easily build EADT values:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb14-1" title="1"><span class="kw">pattern</span> <span class="dt">VF</span><span class="ot"> ::</span> <span class="kw">forall</span> e f cs<span class="op">.</span></a>
<a class="sourceLine" id="cb14-2" title="2">   ( e <span class="op">~</span> <span class="dt">EADT</span> cs  <span class="co">-- allow easy use of TypeApplication to set the EADT type</span></a>
<a class="sourceLine" id="cb14-3" title="3">   , f <span class="op">:&lt;:</span> cs     <span class="co">-- constraint synonym ensuring `f` is in `cs`</span></a>
<a class="sourceLine" id="cb14-4" title="4">   ) <span class="ot">=&gt;</span> f (<span class="dt">EADT</span> cs) <span class="ot">-&gt;</span> <span class="dt">EADT</span> cs</a>
<a class="sourceLine" id="cb14-5" title="5"><span class="kw">pattern</span> <span class="dt">VF</span> x <span class="ot">=</span> <span class="dt">Fix</span> (<span class="dt">VariantF</span> (<span class="dt">V'</span> x))   <span class="co">-- `V'` match a variant value (without</span></a>
<a class="sourceLine" id="cb14-6" title="6">                                       <span class="co">-- checking the membership: we already</span></a>
<a class="sourceLine" id="cb14-7" title="7">                                       <span class="co">-- do it with :&lt;:)</span></a></code></pre></div>
<p>Second benefit: with modern Haskell we can define bidirectional pattern synonyms that make creation and matching of EADT values much more nicer.</p>
<h1 id="examples-using-eadt">Examples using EADT</h1>
<h2 id="defining-an-eadt-and-building-some-values">Defining an EADT and building some values</h2>
<p>Let’s define some constructors:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb15-1" title="1"><span class="ot">{-# LANGUAGE DeriveFunctor #-}</span></a>
<a class="sourceLine" id="cb15-2" title="2"></a>
<a class="sourceLine" id="cb15-3" title="3"><span class="kw">data</span> <span class="dt">ValF</span> e <span class="ot">=</span> <span class="dt">ValF</span> <span class="dt">Int</span> <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb15-4" title="4"><span class="kw">data</span> <span class="dt">AddF</span> e <span class="ot">=</span> <span class="dt">AddF</span> e e <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a></code></pre></div>
<p>And an algebraic data type:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb16-1" title="1"><span class="kw">type</span> <span class="dt">AddValADT</span> <span class="ot">=</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">AddF</span>]</a></code></pre></div>
<p>We can build EADT values in the following (equivalent) ways:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb17-1" title="1"><span class="ot">x ::</span> <span class="dt">AddValADT</span></a>
<a class="sourceLine" id="cb17-2" title="2">x <span class="ot">=</span> <span class="dt">VF</span> (<span class="dt">ValF</span> <span class="dv">10</span>)</a>
<a class="sourceLine" id="cb17-3" title="3"></a>
<a class="sourceLine" id="cb17-4" title="4">y <span class="ot">=</span> <span class="dt">VF</span> <span class="op">@</span><span class="dt">AddValADT</span> (<span class="dt">ValF</span> <span class="dv">10</span>)</a>
<a class="sourceLine" id="cb17-5" title="5"></a>
<a class="sourceLine" id="cb17-6" title="6">z <span class="ot">=</span> <span class="dt">VF</span> (<span class="dt">ValF</span> <span class="dv">10</span><span class="ot"> ::</span> <span class="dt">ValF</span> <span class="dt">AddValADT</span>)</a></code></pre></div>
<p>But it’s nicer to define some additional pattern synonyms:</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb18-1" title="1"><span class="kw">pattern</span> <span class="dt">Val</span><span class="ot"> ::</span> <span class="dt">ValF</span> <span class="op">:&lt;:</span> xs <span class="ot">=&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs</a>
<a class="sourceLine" id="cb18-2" title="2"><span class="kw">pattern</span> <span class="dt">Val</span> a <span class="ot">=</span> <span class="dt">VF</span> (<span class="dt">ValF</span> a)</a>
<a class="sourceLine" id="cb18-3" title="3"></a>
<a class="sourceLine" id="cb18-4" title="4"><span class="kw">pattern</span> <span class="dt">Add</span><span class="ot"> ::</span> <span class="dt">AddF</span> <span class="op">:&lt;:</span> xs <span class="ot">=&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs</a>
<a class="sourceLine" id="cb18-5" title="5"><span class="kw">pattern</span> <span class="dt">Add</span> a b <span class="ot">=</span> <span class="dt">VF</span> (<span class="dt">AddF</span> a b)</a>
<a class="sourceLine" id="cb18-6" title="6"></a>
<a class="sourceLine" id="cb18-7" title="7"><span class="ot">x ::</span> <span class="dt">AddValADT</span></a>
<a class="sourceLine" id="cb18-8" title="8">x <span class="ot">=</span> <span class="dt">Val</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb18-9" title="9"></a>
<a class="sourceLine" id="cb18-10" title="10">xx <span class="ot">=</span> <span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">AddValADT</span></a></code></pre></div>
<p>We can pattern-match EADT values with <code>VF</code> or with pattern synonyms too:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb19-1" title="1"><span class="ot">showAddValADT ::</span> <span class="dt">AddValADT</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb19-2" title="2">showAddValADT e <span class="ot">=</span> <span class="kw">case</span> e <span class="kw">of</span></a>
<a class="sourceLine" id="cb19-3" title="3">   <span class="co">-- match with VF</span></a>
<a class="sourceLine" id="cb19-4" title="4">   <span class="dt">VF</span> (<span class="dt">ValF</span> u)  <span class="ot">-&gt;</span> <span class="fu">show</span> u</a>
<a class="sourceLine" id="cb19-5" title="5"></a>
<a class="sourceLine" id="cb19-6" title="6">   <span class="co">-- match with additional pattern synonym</span></a>
<a class="sourceLine" id="cb19-7" title="7">   <span class="dt">Add</span> u v      <span class="ot">-&gt;</span> <span class="st">&quot;(&quot;</span> <span class="op">++</span> showAddValADT u <span class="op">++</span> <span class="st">&quot; + &quot;</span> <span class="op">++</span> showAddValADT v <span class="op">++</span> <span class="st">&quot;)&quot;</span></a>
<a class="sourceLine" id="cb19-8" title="8"></a>
<a class="sourceLine" id="cb19-9" title="9">   _            <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;showAddValADT: unhandled AddValADT constructor&quot;</span></a>
<a class="sourceLine" id="cb19-10" title="10"></a>
<a class="sourceLine" id="cb19-11" title="11"><span class="op">&gt;</span> showAddValADT (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))</a>
<a class="sourceLine" id="cb19-12" title="12"><span class="st">&quot;(10 + 3)&quot;</span></a></code></pre></div>
<p>Note that the wildcard match is necessary, otherwise the pattern-match is reported as non exhaustive by GHC (warning). This is one shortcoming due to the use of the <code>Variant</code> type.</p>
<p>Anyway it isn’t really an issue in this case because <code>showAddValADT</code> shouldn’t be written like this to be extensible.</p>
<h2 id="extending-an-eadt-and-converting-values-from-one-eadt-to-another">Extending an EADT and converting values from one EADT to another</h2>
<p>Suppose we add a constructor:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb20-1" title="1"><span class="kw">data</span> <span class="dt">MulF</span> e <span class="ot">=</span> <span class="dt">MulF</span> e e <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a></code></pre></div>
<p>We can define a new EADT:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb21-1" title="1"><span class="kw">type</span> <span class="dt">MulAddValADT</span> <span class="ot">=</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">AddF</span>,<span class="dt">MulF</span>]</a></code></pre></div>
<p>We only need to change the type to declare values of the new EADT:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb22-1" title="1"><span class="ot">x' ::</span> <span class="dt">MulAddValADT</span></a>
<a class="sourceLine" id="cb22-2" title="2">x' <span class="ot">=</span> <span class="dt">Val</span> <span class="dv">10</span></a></code></pre></div>
<p>We can explicitly add constructors to an EADT:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb23-1" title="1"><span class="op">&gt;</span> x' <span class="ot">=</span> <span class="dt">Val</span> <span class="dv">10</span><span class="ot"> ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">AddF</span>]</a>
<a class="sourceLine" id="cb23-2" title="2"></a>
<a class="sourceLine" id="cb23-3" title="3"><span class="op">&gt;</span> <span class="op">:</span>t appendEADT <span class="op">@</span>'[<span class="dt">MulF</span>] x'</a>
<a class="sourceLine" id="cb23-4" title="4">appendEADT <span class="op">@</span>'[<span class="dt">MulF</span>]<span class="ot"> x' ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>, <span class="dt">AddF</span>, <span class="dt">MulF</span>]</a></code></pre></div>
<p>We can also lift values from one EADT to the other as follow:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb24-1" title="1"><span class="ot">xx' ::</span> <span class="dt">MulAddValADT</span></a>
<a class="sourceLine" id="cb24-2" title="2">xx' <span class="ot">=</span> liftEADT (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">AddValADT</span>)</a></code></pre></div>
<p>Thanks to the type-checking, the opposite direction is not allowed:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb25-1" title="1"><span class="op">&gt;</span> liftEADT<span class="ot"> xx' ::</span> <span class="dt">AddValADT</span></a>
<a class="sourceLine" id="cb25-2" title="2"></a>
<a class="sourceLine" id="cb25-3" title="3"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">83</span><span class="op">:</span><span class="dv">1</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb25-4" title="4">    • '[<span class="dt">MulF</span>]</a>
<a class="sourceLine" id="cb25-5" title="5">      is <span class="fu">not</span> a subset <span class="kw">of</span></a>
<a class="sourceLine" id="cb25-6" title="6">      '[<span class="dt">ValF</span>, <span class="dt">AddF</span>]</a>
<a class="sourceLine" id="cb25-7" title="7">    • <span class="dt">In</span> the expression<span class="op">:</span> liftEADT<span class="ot"> xx' ::</span> <span class="dt">AddValADT</span></a>
<a class="sourceLine" id="cb25-8" title="8">      <span class="dt">In</span> an equation for ‘it’<span class="op">:</span> it <span class="ot">=</span> liftEADT<span class="ot"> xx' ::</span> <span class="dt">AddValADT</span></a></code></pre></div>
<h2 id="defining-operations-on-eadts">Defining operations on EADTs</h2>
<p>Extensible operations on EADTS (i.e. that need to be extended when we add new constructors) are defined with type-classes.</p>
<h3 id="type-classes-and-recursion-schemes">Type classes and recursion schemes</h3>
<p>We can use recursion schemes, for example:</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb26-1" title="1"><span class="kw">import</span> <span class="dt">Data.Functor.Foldable</span></a>
<a class="sourceLine" id="cb26-2" title="2"></a>
<a class="sourceLine" id="cb26-3" title="3"><span class="kw">class</span> <span class="dt">ShowEADT</span> (<span class="ot">f ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) <span class="kw">where</span></a>
<a class="sourceLine" id="cb26-4" title="4"><span class="ot">   showEADT' ::</span> f <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb26-5" title="5"></a>
<a class="sourceLine" id="cb26-6" title="6"><span class="co">-- boilerplate instances for the combinator data type</span></a>
<a class="sourceLine" id="cb26-7" title="7"></a>
<a class="sourceLine" id="cb26-8" title="8"><span class="kw">instance</span> <span class="dt">ShowEADT</span> (<span class="dt">VariantF</span> '[]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb26-9" title="9">   showEADT' <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb26-10" title="10"></a>
<a class="sourceLine" id="cb26-11" title="11"><span class="kw">instance</span> (<span class="dt">ShowEADT</span> x, <span class="dt">ShowEADT</span> (<span class="dt">VariantF</span> xs))  <span class="ot">=&gt;</span> <span class="dt">ShowEADT</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb26-12" title="12">   showEADT' v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb26-13" title="13">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> showEADT' u</a>
<a class="sourceLine" id="cb26-14" title="14">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> showEADT' w</a>
<a class="sourceLine" id="cb26-15" title="15"></a>
<a class="sourceLine" id="cb26-16" title="16"></a>
<a class="sourceLine" id="cb26-17" title="17"><span class="co">-- instances for constructors data types</span></a>
<a class="sourceLine" id="cb26-18" title="18"></a>
<a class="sourceLine" id="cb26-19" title="19"><span class="kw">instance</span> <span class="dt">ShowEADT</span> <span class="dt">ValF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb26-20" title="20">   showEADT' (<span class="dt">ValF</span> i) <span class="ot">=</span> <span class="fu">show</span> i</a>
<a class="sourceLine" id="cb26-21" title="21"></a>
<a class="sourceLine" id="cb26-22" title="22"><span class="kw">instance</span> <span class="dt">ShowEADT</span> <span class="dt">AddF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb26-23" title="23">   showEADT' (<span class="dt">AddF</span> u v) <span class="ot">=</span> <span class="st">&quot;(&quot;</span> <span class="op">++</span> u <span class="op">++</span> <span class="st">&quot; + &quot;</span> <span class="op">++</span> v <span class="op">++</span> <span class="st">&quot;)&quot;</span> <span class="co">-- no recursive call</span></a>
<a class="sourceLine" id="cb26-24" title="24"></a>
<a class="sourceLine" id="cb26-25" title="25"><span class="kw">instance</span> <span class="dt">ShowEADT</span> <span class="dt">MulF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb26-26" title="26">   showEADT' (<span class="dt">MulF</span> u v) <span class="ot">=</span> <span class="st">&quot;(&quot;</span> <span class="op">++</span> u <span class="op">++</span> <span class="st">&quot; * &quot;</span> <span class="op">++</span> v <span class="op">++</span> <span class="st">&quot;)&quot;</span> <span class="co">-- no recursive call</span></a>
<a class="sourceLine" id="cb26-27" title="27"></a>
<a class="sourceLine" id="cb26-28" title="28"></a>
<a class="sourceLine" id="cb26-29" title="29"><span class="co">-- `cata` (for catamorphism) handles the recursion/fold</span></a>
<a class="sourceLine" id="cb26-30" title="30"></a>
<a class="sourceLine" id="cb26-31" title="31"><span class="op">&gt;</span> cata showEADT' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))<span class="ot"> ::</span> <span class="dt">AddValADT</span>)</a>
<a class="sourceLine" id="cb26-32" title="32"><span class="st">&quot;(2 + (10 + 3))&quot;</span></a>
<a class="sourceLine" id="cb26-33" title="33"></a>
<a class="sourceLine" id="cb26-34" title="34"><span class="op">&gt;</span> cata showEADT' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))<span class="ot"> ::</span> <span class="dt">MulAddValADT</span>)</a>
<a class="sourceLine" id="cb26-35" title="35"><span class="st">&quot;(2 + (10 + 3))&quot;</span></a>
<a class="sourceLine" id="cb26-36" title="36"></a>
<a class="sourceLine" id="cb26-37" title="37"><span class="op">&gt;</span> cata showEADT' (<span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))<span class="ot"> ::</span> <span class="dt">MulAddValADT</span>)</a>
<a class="sourceLine" id="cb26-38" title="38"><span class="st">&quot;(2 * (10 + 3))&quot;</span></a>
<a class="sourceLine" id="cb26-39" title="39"></a>
<a class="sourceLine" id="cb26-40" title="40"></a>
<a class="sourceLine" id="cb26-41" title="41"><span class="ot">showEADT ::</span> (<span class="dt">ShowEADT</span> (<span class="dt">Base</span> t), <span class="dt">Recursive</span> t) <span class="ot">=&gt;</span> t <span class="ot">-&gt;</span> <span class="dt">String</span> <span class="co">-- type inferred by GHC</span></a>
<a class="sourceLine" id="cb26-42" title="42">showEADT <span class="ot">=</span> cata showEADT'</a>
<a class="sourceLine" id="cb26-43" title="43"></a>
<a class="sourceLine" id="cb26-44" title="44"><span class="op">&gt;</span> showEADT (<span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))<span class="ot"> ::</span> <span class="dt">MulAddValADT</span>)</a>
<a class="sourceLine" id="cb26-45" title="45"><span class="st">&quot;(2 * (10 + 3))&quot;</span></a></code></pre></div>
<h3 id="type-classes-and-explicit-recursion">Type classes and explicit recursion</h3>
<p>We can also use explicit recursion, for example:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb27-1" title="1"><span class="kw">class</span> <span class="dt">Eval</span> e <span class="kw">where</span></a>
<a class="sourceLine" id="cb27-2" title="2">   <span class="co">-- evaluate an expression</span></a>
<a class="sourceLine" id="cb27-3" title="3"><span class="ot">   eval ::</span> e <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb27-4" title="4"></a>
<a class="sourceLine" id="cb27-5" title="5"><span class="co">-- same boilerplate</span></a>
<a class="sourceLine" id="cb27-6" title="6"></a>
<a class="sourceLine" id="cb27-7" title="7"><span class="kw">instance</span> <span class="dt">Eval</span> (<span class="dt">VariantF</span> '[] e) <span class="kw">where</span></a>
<a class="sourceLine" id="cb27-8" title="8">   eval <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb27-9" title="9"></a>
<a class="sourceLine" id="cb27-10" title="10"><span class="kw">instance</span> (<span class="dt">Eval</span> (x e), <span class="dt">Eval</span> (<span class="dt">VariantF</span> xs e))  <span class="ot">=&gt;</span> <span class="dt">Eval</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs) e) <span class="kw">where</span></a>
<a class="sourceLine" id="cb27-11" title="11">   eval v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb27-12" title="12">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> eval u</a>
<a class="sourceLine" id="cb27-13" title="13">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> eval w</a>
<a class="sourceLine" id="cb27-14" title="14"></a>
<a class="sourceLine" id="cb27-15" title="15"><span class="co">-- evaluating an EADT value</span></a>
<a class="sourceLine" id="cb27-16" title="16"></a>
<a class="sourceLine" id="cb27-17" title="17"><span class="kw">type</span> <span class="dt">EvalAll</span> xs <span class="ot">=</span> <span class="dt">Eval</span> (<span class="dt">VariantF</span> xs (<span class="dt">EADT</span> xs))</a>
<a class="sourceLine" id="cb27-18" title="18"></a>
<a class="sourceLine" id="cb27-19" title="19"><span class="ot">evalEADT ::</span> <span class="dt">EvalAll</span> xs <span class="ot">=&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb27-20" title="20">evalEADT <span class="ot">=</span> eval <span class="op">.</span> unfix</a>
<a class="sourceLine" id="cb27-21" title="21"></a>
<a class="sourceLine" id="cb27-22" title="22"><span class="co">-- instances for constructors</span></a>
<a class="sourceLine" id="cb27-23" title="23"></a>
<a class="sourceLine" id="cb27-24" title="24"><span class="kw">instance</span> <span class="dt">Eval</span> (<span class="dt">ValF</span> e) <span class="kw">where</span></a>
<a class="sourceLine" id="cb27-25" title="25">   eval (<span class="dt">ValF</span> i) <span class="ot">=</span> i</a>
<a class="sourceLine" id="cb27-26" title="26"></a>
<a class="sourceLine" id="cb27-27" title="27"><span class="kw">instance</span> <span class="dt">EvalAll</span> xs <span class="ot">=&gt;</span> <span class="dt">Eval</span> (<span class="dt">AddF</span> (<span class="dt">EADT</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb27-28" title="28">   eval (<span class="dt">AddF</span> u v) <span class="ot">=</span> evalEADT u <span class="op">+</span> evalEADT v <span class="co">-- explicit recursion</span></a>
<a class="sourceLine" id="cb27-29" title="29"></a>
<a class="sourceLine" id="cb27-30" title="30"><span class="kw">instance</span> <span class="dt">EvalAll</span> xs <span class="ot">=&gt;</span> <span class="dt">Eval</span> (<span class="dt">MulF</span> (<span class="dt">EADT</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb27-31" title="31">   eval (<span class="dt">MulF</span> u v) <span class="ot">=</span> evalEADT u <span class="op">*</span> evalEADT v <span class="co">-- explicit recursion</span></a>
<a class="sourceLine" id="cb27-32" title="32"></a>
<a class="sourceLine" id="cb27-33" title="33"></a>
<a class="sourceLine" id="cb27-34" title="34"><span class="op">&gt;</span> evalEADT (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))<span class="ot"> ::</span> <span class="dt">AddValADT</span>)</a>
<a class="sourceLine" id="cb27-35" title="35"><span class="dv">15</span></a>
<a class="sourceLine" id="cb27-36" title="36"><span class="op">&gt;</span> evalEADT (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))<span class="ot"> ::</span> <span class="dt">MulAddValADT</span>)</a>
<a class="sourceLine" id="cb27-37" title="37"><span class="dv">15</span></a>
<a class="sourceLine" id="cb27-38" title="38"><span class="op">&gt;</span> evalEADT (<span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">3</span>))<span class="ot"> ::</span> <span class="dt">MulAddValADT</span>)</a>
<a class="sourceLine" id="cb27-39" title="39"><span class="dv">26</span></a></code></pre></div>
<h3 id="transformation-example">Transformation example</h3>
<p>Let’s rewrite Swiestra’s example to apply the distributivity law. The operation is not extensible, hence we don’t have to use type classes to define it. It works on any EADT as long as the constraints are fulfilled: supporting Add and Mul constructors.</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb28-1" title="1"><span class="kw">import</span> <span class="dt">Control.Arrow</span></a>
<a class="sourceLine" id="cb28-2" title="2"></a>
<a class="sourceLine" id="cb28-3" title="3"><span class="co">-- distribute multiplication over addition if it matches</span></a>
<a class="sourceLine" id="cb28-4" title="4"><span class="ot">distr ::</span> (<span class="dt">AddF</span> <span class="op">:&lt;:</span> f, <span class="dt">MulF</span> <span class="op">:&lt;:</span> f) <span class="ot">=&gt;</span> <span class="dt">EADT</span> f <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">EADT</span> f)</a>
<a class="sourceLine" id="cb28-5" title="5">distr (<span class="dt">Mul</span> a (<span class="dt">Add</span> c d)) <span class="ot">=</span> <span class="dt">Just</span> (<span class="dt">Add</span> (<span class="dt">Mul</span> a c) (<span class="dt">Mul</span> a d))</a>
<a class="sourceLine" id="cb28-6" title="6">distr _                 <span class="ot">=</span> <span class="dt">Nothing</span></a>
<a class="sourceLine" id="cb28-7" title="7"></a>
<a class="sourceLine" id="cb28-8" title="8"><span class="co">-- bottom up traversal that performs an additional bottom up traversal in</span></a>
<a class="sourceLine" id="cb28-9" title="9"><span class="co">-- the transformed sub-tree when a transformation occurs. </span></a>
<a class="sourceLine" id="cb28-10" title="10"><span class="ot">bottomUpFixed ::</span> <span class="dt">Functor</span> f <span class="ot">=&gt;</span> (<span class="dt">Fix</span> f <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Fix</span> f)) <span class="ot">-&gt;</span> <span class="dt">Fix</span> f <span class="ot">-&gt;</span> <span class="dt">Fix</span> f</a>
<a class="sourceLine" id="cb28-11" title="11">bottomUpFixed f <span class="ot">=</span> unfix <span class="op">&gt;&gt;&gt;</span> <span class="fu">fmap</span> (bottomUpFixed f) <span class="op">&gt;&gt;&gt;</span> <span class="dt">Fix</span> <span class="op">&gt;&gt;&gt;</span> f'</a>
<a class="sourceLine" id="cb28-12" title="12">   <span class="kw">where</span></a>
<a class="sourceLine" id="cb28-13" title="13">      f' u <span class="ot">=</span> <span class="kw">case</span> f u <span class="kw">of</span></a>
<a class="sourceLine" id="cb28-14" title="14">         <span class="dt">Nothing</span> <span class="ot">-&gt;</span> u</a>
<a class="sourceLine" id="cb28-15" title="15">         <span class="dt">Just</span> v  <span class="ot">-&gt;</span> bottomUpFixed f v</a>
<a class="sourceLine" id="cb28-16" title="16"></a>
<a class="sourceLine" id="cb28-17" title="17"><span class="co">-- example</span></a>
<a class="sourceLine" id="cb28-18" title="18"><span class="ot">expr ::</span> <span class="dt">MulAddValADT</span></a>
<a class="sourceLine" id="cb28-19" title="19">expr <span class="ot">=</span> <span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">3</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">5</span>) (<span class="dt">Val</span> <span class="dv">20</span>))))</a>
<a class="sourceLine" id="cb28-20" title="20"></a>
<a class="sourceLine" id="cb28-21" title="21"><span class="op">&gt;</span> showEADT expr</a>
<a class="sourceLine" id="cb28-22" title="22"><span class="st">&quot;(2 * (10 + (3 * (5 + 20))))&quot;</span></a>
<a class="sourceLine" id="cb28-23" title="23"></a>
<a class="sourceLine" id="cb28-24" title="24"><span class="op">&gt;</span> showEADT (bottomUpFixed distr expr)</a>
<a class="sourceLine" id="cb28-25" title="25"><span class="st">&quot;((2 * 10) + ((2 * (3 * 5)) + (2 * (3 * 20))))&quot;</span></a></code></pre></div>
<h3 id="constructor-removal-example-desugaring">Constructor removal example (~desugaring)</h3>
<p>Let’s show how to transform each multiplication into an addition while removing the <code>MulF</code> constructor from the EADT in a generic type-safe manner:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb29-1" title="1"><span class="kw">class</span> <span class="dt">MulToAdd</span> (<span class="ot">f ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb29-2" title="2"><span class="ot">   mulToAdd ::</span> f (<span class="dt">EADT</span> ys) <span class="ot">-&gt;</span> <span class="dt">EADT</span> ys</a>
<a class="sourceLine" id="cb29-3" title="3"></a>
<a class="sourceLine" id="cb29-4" title="4"><span class="co">-- boilerplate</span></a>
<a class="sourceLine" id="cb29-5" title="5"></a>
<a class="sourceLine" id="cb29-6" title="6"><span class="kw">instance</span> <span class="dt">MulToAdd</span> (<span class="dt">VariantF</span> '[]) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb29-7" title="7">   mulToAdd <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb29-8" title="8"></a>
<a class="sourceLine" id="cb29-9" title="9"><span class="kw">instance</span> (<span class="dt">MulToAdd</span> x ys, <span class="dt">MulToAdd</span> (<span class="dt">VariantF</span> xs) ys)  <span class="ot">=&gt;</span> <span class="dt">MulToAdd</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs)) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb29-10" title="10">   mulToAdd v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb29-11" title="11">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> mulToAdd u</a>
<a class="sourceLine" id="cb29-12" title="12">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> mulToAdd w</a>
<a class="sourceLine" id="cb29-13" title="13"></a>
<a class="sourceLine" id="cb29-14" title="14"><span class="co">-- constructor instances</span></a>
<a class="sourceLine" id="cb29-15" title="15"></a>
<a class="sourceLine" id="cb29-16" title="16"><span class="kw">instance</span><span class="ot">{-# OVERLAPPING #-}</span> <span class="dt">AddF</span> <span class="op">:&lt;:</span> ys <span class="ot">=&gt;</span> <span class="dt">MulToAdd</span> <span class="dt">MulF</span> ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb29-17" title="17">   mulToAdd (<span class="dt">MulF</span> u v) <span class="ot">=</span> <span class="dt">Add</span> u v <span class="co">-- Mul becomes Add</span></a>
<a class="sourceLine" id="cb29-18" title="18">                                 <span class="co">-- (it makes no sense but it's just an example)</span></a>
<a class="sourceLine" id="cb29-19" title="19"></a>
<a class="sourceLine" id="cb29-20" title="20"><span class="kw">instance</span> <span class="ot">{-# OVERLAPPABLE #-}</span> f <span class="op">:&lt;:</span> ys <span class="ot">=&gt;</span> <span class="dt">MulToAdd</span> f ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb29-21" title="21">   mulToAdd <span class="ot">=</span> <span class="dt">VF</span>  <span class="co">-- the other constructors are kept as-is</span></a>
<a class="sourceLine" id="cb29-22" title="22"></a>
<a class="sourceLine" id="cb29-23" title="23"><span class="co">-- example</span></a>
<a class="sourceLine" id="cb29-24" title="24"><span class="ot">expr ::</span> <span class="dt">MulAddValADT</span></a>
<a class="sourceLine" id="cb29-25" title="25">expr <span class="ot">=</span> <span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">3</span>) (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">5</span>) (<span class="dt">Val</span> <span class="dv">20</span>))))</a>
<a class="sourceLine" id="cb29-26" title="26"></a>
<a class="sourceLine" id="cb29-27" title="27"><span class="op">&gt;</span> showEADT (cata mulToAdd<span class="ot"> expr ::</span> <span class="dt">AddValADT</span>)</a>
<a class="sourceLine" id="cb29-28" title="28"><span class="st">&quot;(2 + (10 + (3 + (5 + 20))))&quot;</span></a>
<a class="sourceLine" id="cb29-29" title="29"></a>
<a class="sourceLine" id="cb29-30" title="30"><span class="op">&gt;</span> showEADT (cata mulToAdd (bottomUpFixed distr expr)<span class="ot"> ::</span> <span class="dt">AddValADT</span>)</a>
<a class="sourceLine" id="cb29-31" title="31"><span class="st">&quot;((2 + 10) + ((2 + (3 + 5)) + (2 + (3 + 20))))&quot;</span></a></code></pre></div>
<p>This kind of transformation can be used to transform a big language into a smaller one (e.g. Haskell into Core).</p>
<h3 id="annotation-examples-parameter-example">Annotation examples (parameter example)</h3>
<p>Let’s add a constructor to support annotations in the AST. We let the annotation type parametric.</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb30-1" title="1"><span class="co">-- | Annotate `e` with a value having type `a`</span></a>
<a class="sourceLine" id="cb30-2" title="2"><span class="kw">data</span> <span class="dt">AnnotF</span> a e <span class="ot">=</span> <span class="dt">AnnotF</span> a e <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb30-3" title="3"></a>
<a class="sourceLine" id="cb30-4" title="4"><span class="kw">pattern</span> <span class="dt">Annot</span><span class="ot"> ::</span> <span class="dt">AnnotF</span> a <span class="op">:&lt;:</span> xs <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs</a>
<a class="sourceLine" id="cb30-5" title="5"><span class="kw">pattern</span> <span class="dt">Annot</span> a e <span class="ot">=</span> <span class="dt">VF</span> (<span class="dt">AnnotF</span> a e)</a>
<a class="sourceLine" id="cb30-6" title="6"></a>
<a class="sourceLine" id="cb30-7" title="7"><span class="kw">instance</span> <span class="dt">Show</span> a <span class="ot">=&gt;</span> <span class="dt">ShowEADT</span> (<span class="dt">AnnotF</span> a) <span class="kw">where</span></a>
<a class="sourceLine" id="cb30-8" title="8">   showEADT' (<span class="dt">AnnotF</span> a e) <span class="ot">=</span> <span class="st">&quot;{&quot;</span> <span class="op">++</span> <span class="fu">show</span> a <span class="op">++</span> <span class="st">&quot;} &quot;</span> <span class="op">++</span> e</a></code></pre></div>
<p>We can easily define an EADT supporting parametric annotations, for instance:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb31-1" title="1"><span class="kw">type</span> <span class="dt">AnnotExp</span> a <span class="ot">=</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">AddF</span>,<span class="dt">MulF</span>,<span class="dt">AnnotF</span> a]</a></code></pre></div>
<p>Now we can build an example of an annotated expression where the annotation type is <code>String</code>:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb32-1" title="1"><span class="ot">annotExpr ::</span> <span class="dt">AnnotExp</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb32-2" title="2">annotExpr <span class="ot">=</span> <span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">8</span>) (<span class="dt">Annot</span> <span class="st">&quot;An addition&quot;</span> (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)))</a>
<a class="sourceLine" id="cb32-3" title="3"></a>
<a class="sourceLine" id="cb32-4" title="4"><span class="op">&gt;</span> showEADT annotExpr </a>
<a class="sourceLine" id="cb32-5" title="5"><span class="st">&quot;(8 * {\&quot;An addition\&quot;} (10 + 5))&quot;</span></a></code></pre></div>
<p>We can easily prune annotations from the expression similarly to what we did above to transform multiplications into additions:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb33-1" title="1"><span class="kw">class</span> <span class="dt">RemoveAnnot</span> (<span class="ot">f ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb33-2" title="2"><span class="ot">   removeAnnot' ::</span> f (<span class="dt">EADT</span> ys) <span class="ot">-&gt;</span> <span class="dt">EADT</span> ys</a>
<a class="sourceLine" id="cb33-3" title="3"></a>
<a class="sourceLine" id="cb33-4" title="4"><span class="kw">instance</span> <span class="dt">RemoveAnnot</span> (<span class="dt">VariantF</span> '[]) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb33-5" title="5">   removeAnnot' <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb33-6" title="6"></a>
<a class="sourceLine" id="cb33-7" title="7"><span class="kw">instance</span></a>
<a class="sourceLine" id="cb33-8" title="8">   ( <span class="dt">RemoveAnnot</span> x ys</a>
<a class="sourceLine" id="cb33-9" title="9">   , <span class="dt">RemoveAnnot</span> (<span class="dt">VariantF</span> xs) ys</a>
<a class="sourceLine" id="cb33-10" title="10">   )  <span class="ot">=&gt;</span> <span class="dt">RemoveAnnot</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs)) ys</a>
<a class="sourceLine" id="cb33-11" title="11">   <span class="kw">where</span></a>
<a class="sourceLine" id="cb33-12" title="12">   removeAnnot' v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb33-13" title="13">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> removeAnnot' u</a>
<a class="sourceLine" id="cb33-14" title="14">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> removeAnnot' w</a>
<a class="sourceLine" id="cb33-15" title="15"></a>
<a class="sourceLine" id="cb33-16" title="16"><span class="kw">instance</span><span class="ot">{-# OVERLAPPING #-}</span> <span class="dt">RemoveAnnot</span> (<span class="dt">AnnotF</span> a) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb33-17" title="17">   removeAnnot' (<span class="dt">AnnotF</span> _a e) <span class="ot">=</span> e</a>
<a class="sourceLine" id="cb33-18" title="18"></a>
<a class="sourceLine" id="cb33-19" title="19"><span class="kw">instance</span> <span class="ot">{-# OVERLAPPABLE #-}</span> f <span class="op">:&lt;:</span> ys <span class="ot">=&gt;</span> <span class="dt">RemoveAnnot</span> f ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb33-20" title="20">   removeAnnot' <span class="ot">=</span> <span class="dt">VF</span></a>
<a class="sourceLine" id="cb33-21" title="21"></a>
<a class="sourceLine" id="cb33-22" title="22"><span class="op">&gt;</span> showEADT (cata removeAnnot'<span class="ot"> annotExpr ::</span> <span class="dt">MulAddValADT</span>)</a>
<a class="sourceLine" id="cb33-23" title="23"><span class="st">&quot;(8 * (10 + 5))&quot;</span></a></code></pre></div>
<p>As it is a bit sad to have to specify the type of the resulting EADT without the annotations, we can define the following helper function:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb34-1" title="1"><span class="co">-- remove `AnnotF a` (for all `a`) in `xs`</span></a>
<a class="sourceLine" id="cb34-2" title="2"><span class="kw">type</span> <span class="kw">family</span> <span class="dt">FilterAnnot</span> xs <span class="kw">where</span></a>
<a class="sourceLine" id="cb34-3" title="3">   <span class="dt">FilterAnnot</span> '[]              <span class="ot">=</span> '[]</a>
<a class="sourceLine" id="cb34-4" title="4">   <span class="dt">FilterAnnot</span> (<span class="dt">AnnotF</span> a '<span class="op">:</span> xs) <span class="ot">=</span> <span class="dt">FilterAnnot</span> xs</a>
<a class="sourceLine" id="cb34-5" title="5">   <span class="dt">FilterAnnot</span> (x '<span class="op">:</span> xs)        <span class="ot">=</span> x '<span class="op">:</span> <span class="dt">FilterAnnot</span> xs</a>
<a class="sourceLine" id="cb34-6" title="6"></a>
<a class="sourceLine" id="cb34-7" title="7"><span class="ot">removeAnnot ::</span></a>
<a class="sourceLine" id="cb34-8" title="8">   ( <span class="dt">Functor</span> (<span class="dt">VariantF</span> xs)</a>
<a class="sourceLine" id="cb34-9" title="9">   , <span class="dt">RemoveAnnot</span> (<span class="dt">VariantF</span> xs) (<span class="dt">FilterAnnot</span> xs)</a>
<a class="sourceLine" id="cb34-10" title="10">   ) <span class="ot">=&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">EADT</span> (<span class="dt">FilterAnnot</span> xs)</a>
<a class="sourceLine" id="cb34-11" title="11">removeAnnot <span class="ot">=</span> cata removeAnnot'</a>
<a class="sourceLine" id="cb34-12" title="12"></a>
<a class="sourceLine" id="cb34-13" title="13"><span class="op">&gt;</span> showEADT (removeAnnot annotExpr)</a>
<a class="sourceLine" id="cb34-14" title="14"><span class="st">&quot;(8 * (10 + 5))&quot;</span></a></code></pre></div>
<h3 id="type-checking-example-paramorphism-example">Type-checking example (paramorphism example)</h3>
<p>First let’s add support for Float values:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb35-1" title="1"><span class="kw">data</span> <span class="dt">FloatValF</span> e <span class="ot">=</span> <span class="dt">FloatValF</span> <span class="dt">Float</span> <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb35-2" title="2"></a>
<a class="sourceLine" id="cb35-3" title="3"><span class="kw">pattern</span> <span class="dt">FloatVal</span><span class="ot"> ::</span> <span class="dt">FloatValF</span> <span class="op">:&lt;:</span> xs <span class="ot">=&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs</a>
<a class="sourceLine" id="cb35-4" title="4"><span class="kw">pattern</span> <span class="dt">FloatVal</span> a <span class="ot">=</span> <span class="dt">VF</span> (<span class="dt">FloatValF</span> a)</a>
<a class="sourceLine" id="cb35-5" title="5"></a>
<a class="sourceLine" id="cb35-6" title="6"><span class="kw">instance</span> <span class="dt">ShowEADT</span> <span class="dt">FloatValF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb35-7" title="7">   showEADT' (<span class="dt">FloatValF</span> i) <span class="ot">=</span> <span class="fu">show</span> i</a></code></pre></div>
<p>Now we can write invalid expressions mixing both Int and Float values:</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb36-1" title="1"><span class="op">&gt;</span> showEADT (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">FloatVal</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">FloatValF</span>,<span class="dt">AddF</span>])</a>
<a class="sourceLine" id="cb36-2" title="2"><span class="st">&quot;(10 + 5.0)&quot;</span></a></code></pre></div>
<p>Let’s write a type-checker to detect these cases. For a given expression, our type-checker will either return its valid type (Int or Float) or an erroneous type with an explanation message:</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb37-1" title="1"><span class="kw">data</span> <span class="dt">Typ</span></a>
<a class="sourceLine" id="cb37-2" title="2">   <span class="ot">=</span> <span class="dt">TInt</span></a>
<a class="sourceLine" id="cb37-3" title="3">   <span class="op">|</span> <span class="dt">TFloat</span></a>
<a class="sourceLine" id="cb37-4" title="4">   <span class="op">|</span> <span class="dt">TError</span> <span class="dt">String</span>   <span class="co">-- the type of an invalid expression with some explanation</span></a>
<a class="sourceLine" id="cb37-5" title="5">   <span class="kw">deriving</span> (<span class="dt">Show</span>,<span class="dt">Eq</span>)</a>
<a class="sourceLine" id="cb37-6" title="6"></a>
<a class="sourceLine" id="cb37-7" title="7"><span class="kw">class</span> <span class="dt">TypeCheck</span> (<span class="ot">f ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-8" title="8"><span class="ot">   typeCheck' ::</span> f <span class="dt">Typ</span> <span class="ot">-&gt;</span> <span class="dt">Typ</span></a>
<a class="sourceLine" id="cb37-9" title="9"></a>
<a class="sourceLine" id="cb37-10" title="10"><span class="kw">instance</span> <span class="dt">TypeCheck</span> (<span class="dt">VariantF</span> '[]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-11" title="11">   typeCheck' <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb37-12" title="12"></a>
<a class="sourceLine" id="cb37-13" title="13"><span class="kw">instance</span> (<span class="dt">TypeCheck</span> x, <span class="dt">TypeCheck</span> (<span class="dt">VariantF</span> xs))  <span class="ot">=&gt;</span> <span class="dt">TypeCheck</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-14" title="14">   typeCheck' v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb37-15" title="15">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> typeCheck' u</a>
<a class="sourceLine" id="cb37-16" title="16">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> typeCheck' w</a>
<a class="sourceLine" id="cb37-17" title="17"></a>
<a class="sourceLine" id="cb37-18" title="18"><span class="kw">instance</span> <span class="dt">TypeCheck</span> <span class="dt">ValF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-19" title="19">   typeCheck' _ <span class="ot">=</span> <span class="dt">TInt</span></a>
<a class="sourceLine" id="cb37-20" title="20"></a>
<a class="sourceLine" id="cb37-21" title="21"><span class="kw">instance</span> <span class="dt">TypeCheck</span> <span class="dt">FloatValF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-22" title="22">   typeCheck' _ <span class="ot">=</span> <span class="dt">TFloat</span></a>
<a class="sourceLine" id="cb37-23" title="23"></a>
<a class="sourceLine" id="cb37-24" title="24"><span class="kw">instance</span> <span class="dt">TypeCheck</span> <span class="dt">AddF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-25" title="25">   typeCheck' (<span class="dt">AddF</span> t1 t2)</a>
<a class="sourceLine" id="cb37-26" title="26">      <span class="op">|</span> t1 <span class="op">==</span> t2       <span class="ot">=</span> t1</a>
<a class="sourceLine" id="cb37-27" title="27">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t1 <span class="ot">=</span> t1 <span class="co">-- propagate errors</span></a>
<a class="sourceLine" id="cb37-28" title="28">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t2 <span class="ot">=</span> t2</a>
<a class="sourceLine" id="cb37-29" title="29">      <span class="op">|</span> <span class="fu">otherwise</span>      <span class="ot">=</span> <span class="dt">TError</span> <span class="op">$</span> <span class="st">&quot;can't match &quot;</span> <span class="op">++</span> <span class="fu">show</span> t1 <span class="op">++</span> <span class="st">&quot; with &quot;</span> <span class="op">++</span> <span class="fu">show</span> t2</a></code></pre></div>
<p>Let’s try it:</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb38-1" title="1"><span class="op">&gt;</span> cata typeCheck' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">FloatValF</span>,<span class="dt">AddF</span>])</a>
<a class="sourceLine" id="cb38-2" title="2"><span class="dt">TInt</span></a>
<a class="sourceLine" id="cb38-3" title="3"></a>
<a class="sourceLine" id="cb38-4" title="4"><span class="op">&gt;</span> cata typeCheck' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">FloatVal</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">FloatValF</span>,<span class="dt">AddF</span>])</a>
<a class="sourceLine" id="cb38-5" title="5"><span class="dt">TError</span> <span class="st">&quot;can't match TInt with TFloat&quot;</span></a></code></pre></div>
<p>The error message is not very useful, let’s write a better type-checker that indicates which expressions are at fault:</p>
<div class="sourceCode" id="cb39"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb39-1" title="1"><span class="kw">class</span> <span class="dt">TypeCheck2</span> (<span class="ot">f ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb39-2" title="2"><span class="ot">   typeCheck2' ::</span> f (<span class="dt">EADT</span> ys, <span class="dt">Typ</span>) <span class="ot">-&gt;</span> <span class="dt">Typ</span></a>
<a class="sourceLine" id="cb39-3" title="3"></a>
<a class="sourceLine" id="cb39-4" title="4"><span class="kw">instance</span> <span class="dt">TypeCheck2</span> (<span class="dt">VariantF</span> '[]) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb39-5" title="5">   typeCheck2' <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb39-6" title="6"></a>
<a class="sourceLine" id="cb39-7" title="7"><span class="kw">instance</span> (<span class="dt">TypeCheck2</span> x ys, <span class="dt">TypeCheck2</span> (<span class="dt">VariantF</span> xs) ys)  <span class="ot">=&gt;</span> <span class="dt">TypeCheck2</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs)) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb39-8" title="8">   typeCheck2' v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb39-9" title="9">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> typeCheck2' u</a>
<a class="sourceLine" id="cb39-10" title="10">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> typeCheck2' w</a>
<a class="sourceLine" id="cb39-11" title="11"></a>
<a class="sourceLine" id="cb39-12" title="12"><span class="kw">instance</span> <span class="dt">TypeCheck2</span> <span class="dt">ValF</span> ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb39-13" title="13">   typeCheck2' _ <span class="ot">=</span> <span class="dt">TInt</span></a>
<a class="sourceLine" id="cb39-14" title="14"></a>
<a class="sourceLine" id="cb39-15" title="15"><span class="kw">instance</span> <span class="dt">TypeCheck2</span> <span class="dt">FloatValF</span> ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb39-16" title="16">   typeCheck2' _ <span class="ot">=</span> <span class="dt">TFloat</span></a>
<a class="sourceLine" id="cb39-17" title="17"></a>
<a class="sourceLine" id="cb39-18" title="18"><span class="kw">instance</span> (<span class="dt">AddF</span> <span class="op">:&lt;:</span> ys, <span class="dt">ShowEADT</span> (<span class="dt">VariantF</span> ys), <span class="dt">Functor</span> (<span class="dt">VariantF</span> ys)) <span class="ot">=&gt;</span> <span class="dt">TypeCheck2</span> <span class="dt">AddF</span> ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb39-19" title="19">   typeCheck2' (<span class="dt">AddF</span> (u,t1) (v,t2))</a>
<a class="sourceLine" id="cb39-20" title="20">      <span class="op">|</span> t1 <span class="op">==</span> t2       <span class="ot">=</span> t1</a>
<a class="sourceLine" id="cb39-21" title="21">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t1 <span class="ot">=</span> t1 <span class="co">-- propagate errors</span></a>
<a class="sourceLine" id="cb39-22" title="22">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t2 <span class="ot">=</span> t2</a>
<a class="sourceLine" id="cb39-23" title="23">      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">TError</span> <span class="op">$</span> <span class="st">&quot;can't add `&quot;</span> <span class="op">++</span> showEADT u <span class="op">++</span> <span class="st">&quot;` whose type is &quot;</span> <span class="op">++</span> <span class="fu">show</span> t1 <span class="op">++</span></a>
<a class="sourceLine" id="cb39-24" title="24">                             <span class="st">&quot; with `&quot;</span> <span class="op">++</span> showEADT v <span class="op">++</span> <span class="st">&quot;` whose type is &quot;</span> <span class="op">++</span> <span class="fu">show</span> t2</a></code></pre></div>
<p>This time instead of using <code>cata</code> we will use another recursion scheme called <code>para</code> (for paramorphism) that also passes expression values (<code>u</code> and <code>v</code> in <code>AddF</code> instance):</p>
<div class="sourceCode" id="cb40"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb40-1" title="1"><span class="op">&gt;</span> para typeCheck2' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">FloatValF</span>,<span class="dt">AddF</span>])</a>
<a class="sourceLine" id="cb40-2" title="2"><span class="dt">TInt</span></a>
<a class="sourceLine" id="cb40-3" title="3"></a>
<a class="sourceLine" id="cb40-4" title="4"><span class="op">&gt;</span> para typeCheck2' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">FloatVal</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">FloatValF</span>,<span class="dt">AddF</span>])</a>
<a class="sourceLine" id="cb40-5" title="5"><span class="dt">TError</span> <span class="st">&quot;can't add `10` whose type is TInt with `5.0` whose type is TFloat&quot;</span></a></code></pre></div>
<p>Let’s check that we can easily extend our expression language and our type-checker without rewriting anything by adding support for type ascriptions (i.e., types specified by the programmer):</p>
<div class="sourceCode" id="cb41"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb41-1" title="1"><span class="kw">data</span> <span class="dt">TypedF</span> e <span class="ot">=</span> <span class="dt">TypedF</span> <span class="dt">Typ</span> e <span class="kw">deriving</span> (<span class="dt">Functor</span>)</a>
<a class="sourceLine" id="cb41-2" title="2"></a>
<a class="sourceLine" id="cb41-3" title="3"><span class="kw">pattern</span> <span class="dt">Typed</span><span class="ot"> ::</span> <span class="dt">TypedF</span> <span class="op">:&lt;:</span> xs <span class="ot">=&gt;</span> <span class="dt">Typ</span> <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs</a>
<a class="sourceLine" id="cb41-4" title="4"><span class="kw">pattern</span> <span class="dt">Typed</span> t e <span class="ot">=</span> <span class="dt">VF</span> (<span class="dt">TypedF</span> t e)</a>
<a class="sourceLine" id="cb41-5" title="5"></a>
<a class="sourceLine" id="cb41-6" title="6"><span class="kw">instance</span> <span class="dt">ShowEADT</span> <span class="dt">TypedF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb41-7" title="7">   showEADT' (<span class="dt">TypedF</span> t e) <span class="ot">=</span> <span class="st">&quot;(&quot;</span> <span class="op">++</span> e <span class="op">++</span> <span class="st">&quot; :: &quot;</span> <span class="op">++</span> <span class="fu">show</span> t <span class="op">++</span> <span class="st">&quot;)&quot;</span></a>
<a class="sourceLine" id="cb41-8" title="8"></a>
<a class="sourceLine" id="cb41-9" title="9"><span class="kw">instance</span> (<span class="dt">Functor</span> (<span class="dt">VariantF</span> ys), <span class="dt">ShowEADT</span> (<span class="dt">VariantF</span> ys)) <span class="ot">=&gt;</span> <span class="dt">TypeCheck2</span> <span class="dt">TypedF</span> ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb41-10" title="10">   typeCheck2' (<span class="dt">TypedF</span> t (e,te))</a>
<a class="sourceLine" id="cb41-11" title="11">      <span class="op">|</span> t <span class="op">==</span> te   <span class="ot">=</span> t</a>
<a class="sourceLine" id="cb41-12" title="12">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t  <span class="ot">=</span> t</a>
<a class="sourceLine" id="cb41-13" title="13">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> te <span class="ot">=</span> te</a>
<a class="sourceLine" id="cb41-14" title="14">      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">TError</span> <span class="op">$</span> <span class="st">&quot;wrong type ascription &quot;</span> <span class="op">++</span> <span class="fu">show</span> t <span class="op">++</span></a>
<a class="sourceLine" id="cb41-15" title="15">                             <span class="st">&quot; for expression `&quot;</span> <span class="op">++</span> showEADT e <span class="op">++</span></a>
<a class="sourceLine" id="cb41-16" title="16">                             <span class="st">&quot;` with inferred type &quot;</span> <span class="op">++</span> <span class="fu">show</span> te</a></code></pre></div>
<p>Now let’s check that asserting some types is correctly supported:</p>
<div class="sourceCode" id="cb42"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb42-1" title="1"><span class="op">&gt;</span> <span class="kw">type</span> <span class="dt">E</span> <span class="ot">=</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">FloatValF</span>,<span class="dt">AddF</span>,<span class="dt">TypedF</span>]</a>
<a class="sourceLine" id="cb42-2" title="2"></a>
<a class="sourceLine" id="cb42-3" title="3"><span class="op">&gt;</span> para typeCheck2' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Typed</span> <span class="dt">TInt</span> <span class="op">$</span> <span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">E</span>)</a>
<a class="sourceLine" id="cb42-4" title="4"><span class="dt">TInt</span></a>
<a class="sourceLine" id="cb42-5" title="5"></a>
<a class="sourceLine" id="cb42-6" title="6"><span class="op">&gt;</span> para typeCheck2' (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Typed</span> <span class="dt">TFloat</span> <span class="op">$</span> <span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">E</span>)</a>
<a class="sourceLine" id="cb42-7" title="7"><span class="dt">TError</span> <span class="st">&quot;wrong type ascription TFloat for expression `5` with inferred type TInt&quot;</span></a>
<a class="sourceLine" id="cb42-8" title="8"></a>
<a class="sourceLine" id="cb42-9" title="9"><span class="op">&gt;</span> para typeCheck2' (<span class="dt">Typed</span> <span class="dt">TInt</span> <span class="op">$</span> <span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">E</span>)</a>
<a class="sourceLine" id="cb42-10" title="10"><span class="dt">TInt</span></a>
<a class="sourceLine" id="cb42-11" title="11"></a>
<a class="sourceLine" id="cb42-12" title="12"><span class="op">&gt;</span> para typeCheck2' (<span class="dt">Typed</span> <span class="dt">TFloat</span> <span class="op">$</span> <span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">E</span>)</a>
<a class="sourceLine" id="cb42-13" title="13"><span class="dt">TError</span> <span class="st">&quot;wrong type ascription TFloat for expression `(10 + 5)` with inferred type TInt&quot;</span></a></code></pre></div>
<p>Finally let’s write another type-checker that adds inferred types as type-ascriptions to every node of the expression.</p>
<div class="sourceCode" id="cb43"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb43-1" title="1"><span class="kw">class</span> <span class="dt">TypeCheck3</span> (<span class="ot">f ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-2" title="2"><span class="ot">   typeCheck3' ::</span> f (<span class="dt">TypedF</span> (<span class="dt">EADT</span> ys)) <span class="ot">-&gt;</span> <span class="dt">TypedF</span> (<span class="dt">EADT</span> ys)</a>
<a class="sourceLine" id="cb43-3" title="3"></a>
<a class="sourceLine" id="cb43-4" title="4"><span class="kw">instance</span> <span class="dt">TypeCheck3</span> (<span class="dt">VariantF</span> '[]) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-5" title="5">   typeCheck3' <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb43-6" title="6"></a>
<a class="sourceLine" id="cb43-7" title="7"><span class="kw">instance</span> (<span class="dt">TypeCheck3</span> x ys, <span class="dt">TypeCheck3</span> (<span class="dt">VariantF</span> xs) ys)  <span class="ot">=&gt;</span> <span class="dt">TypeCheck3</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs)) ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-8" title="8">   typeCheck3' v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb43-9" title="9">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> typeCheck3' u</a>
<a class="sourceLine" id="cb43-10" title="10">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> typeCheck3' w</a>
<a class="sourceLine" id="cb43-11" title="11"></a>
<a class="sourceLine" id="cb43-12" title="12"><span class="kw">instance</span> (<span class="dt">TypedF</span> <span class="op">:&lt;:</span> ys, <span class="dt">ValF</span> <span class="op">:&lt;:</span> ys) <span class="ot">=&gt;</span> <span class="dt">TypeCheck3</span> <span class="dt">ValF</span> ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-13" title="13">   typeCheck3' (<span class="dt">ValF</span> i) <span class="ot">=</span> <span class="dt">TypedF</span> <span class="dt">TInt</span> (<span class="dt">Val</span> i)</a>
<a class="sourceLine" id="cb43-14" title="14"></a>
<a class="sourceLine" id="cb43-15" title="15"><span class="kw">instance</span> (<span class="dt">TypedF</span> <span class="op">:&lt;:</span> ys, <span class="dt">FloatValF</span> <span class="op">:&lt;:</span> ys) <span class="ot">=&gt;</span> <span class="dt">TypeCheck3</span> <span class="dt">FloatValF</span> ys <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-16" title="16">   typeCheck3' (<span class="dt">FloatValF</span> f) <span class="ot">=</span> <span class="dt">TypedF</span> <span class="dt">TFloat</span> (<span class="dt">FloatVal</span> f)</a>
<a class="sourceLine" id="cb43-17" title="17"></a>
<a class="sourceLine" id="cb43-18" title="18"><span class="kw">instance</span></a>
<a class="sourceLine" id="cb43-19" title="19">   ( <span class="dt">TypedF</span> <span class="op">:&lt;:</span> ys</a>
<a class="sourceLine" id="cb43-20" title="20">   , <span class="dt">AddF</span> <span class="op">:&lt;:</span> ys</a>
<a class="sourceLine" id="cb43-21" title="21">   , <span class="dt">ShowEADT</span> (<span class="dt">VariantF</span> ys)</a>
<a class="sourceLine" id="cb43-22" title="22">   , <span class="dt">Functor</span> (<span class="dt">VariantF</span> ys)</a>
<a class="sourceLine" id="cb43-23" title="23">   ) <span class="ot">=&gt;</span> <span class="dt">TypeCheck3</span> <span class="dt">AddF</span> ys</a>
<a class="sourceLine" id="cb43-24" title="24">   <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-25" title="25">   typeCheck3' (<span class="dt">AddF</span> u<span class="op">@</span>(<span class="dt">TypedF</span> t1 _) v<span class="op">@</span>(<span class="dt">TypedF</span> t2 _))</a>
<a class="sourceLine" id="cb43-26" title="26">      <span class="op">|</span> t1 <span class="op">==</span> t2       <span class="ot">=</span> <span class="dt">TypedF</span> t1 addVal</a>
<a class="sourceLine" id="cb43-27" title="27">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t1 <span class="ot">=</span> <span class="dt">TypedF</span> (<span class="dt">TError</span> <span class="st">&quot;&quot;</span>) addVal <span class="co">-- don't propagate errors</span></a>
<a class="sourceLine" id="cb43-28" title="28">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t2 <span class="ot">=</span> <span class="dt">TypedF</span> (<span class="dt">TError</span> <span class="st">&quot;&quot;</span>) addVal</a>
<a class="sourceLine" id="cb43-29" title="29">      <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">TypedF</span> (<span class="dt">TError</span> <span class="op">$</span> <span class="st">&quot;can't add &quot;</span> <span class="op">++</span> <span class="fu">show</span> t1 <span class="op">++</span> <span class="st">&quot; with &quot;</span> <span class="op">++</span> <span class="fu">show</span> t2) addVal</a>
<a class="sourceLine" id="cb43-30" title="30">      <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-31" title="31">         addVal <span class="ot">=</span> <span class="dt">Add</span> (<span class="dt">VF</span> u) (<span class="dt">VF</span> v)</a>
<a class="sourceLine" id="cb43-32" title="32"></a>
<a class="sourceLine" id="cb43-33" title="33"><span class="co">-- similar for MulF...</span></a>
<a class="sourceLine" id="cb43-34" title="34"></a>
<a class="sourceLine" id="cb43-35" title="35"><span class="kw">instance</span></a>
<a class="sourceLine" id="cb43-36" title="36">   ( <span class="dt">TypedF</span> <span class="op">:&lt;:</span> ys</a>
<a class="sourceLine" id="cb43-37" title="37">   , <span class="dt">Functor</span> (<span class="dt">VariantF</span> ys)</a>
<a class="sourceLine" id="cb43-38" title="38">   , <span class="dt">ShowEADT</span> (<span class="dt">VariantF</span> ys)</a>
<a class="sourceLine" id="cb43-39" title="39">   ) <span class="ot">=&gt;</span> <span class="dt">TypeCheck3</span> <span class="dt">TypedF</span> ys</a>
<a class="sourceLine" id="cb43-40" title="40">   <span class="kw">where</span></a>
<a class="sourceLine" id="cb43-41" title="41">   typeCheck3' (<span class="dt">TypedF</span> t u<span class="op">@</span>(<span class="dt">TypedF</span> te _))</a>
<a class="sourceLine" id="cb43-42" title="42">      <span class="op">|</span> t <span class="op">==</span> te        <span class="ot">=</span> u                         <span class="co">-- Remove redundant ascription</span></a>
<a class="sourceLine" id="cb43-43" title="43">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> t  <span class="ot">=</span> <span class="dt">TypedF</span> t (<span class="dt">VF</span> u)           <span class="co">-- keep erroring ascription as-is</span></a>
<a class="sourceLine" id="cb43-44" title="44">      <span class="op">|</span> <span class="dt">TError</span> _ <span class="ot">&lt;-</span> te <span class="ot">=</span> <span class="dt">TypedF</span> (<span class="dt">TError</span> <span class="st">&quot;&quot;</span>) (<span class="dt">VF</span> u) <span class="co">-- don't propagate errors</span></a>
<a class="sourceLine" id="cb43-45" title="45">      <span class="op">|</span> <span class="fu">otherwise</span>      <span class="ot">=</span> <span class="dt">TypedF</span> (<span class="dt">TError</span> <span class="op">$</span> <span class="st">&quot;wrong type ascription&quot;</span> <span class="op">++</span></a>
<a class="sourceLine" id="cb43-46" title="46">                                          <span class="st">&quot; (inferred type: &quot;</span> <span class="op">++</span> <span class="fu">show</span> te <span class="op">++</span> <span class="st">&quot;)&quot;</span>) (<span class="dt">Typed</span> t (<span class="dt">VF</span> u))</a>
<a class="sourceLine" id="cb43-47" title="47"></a>
<a class="sourceLine" id="cb43-48" title="48"></a>
<a class="sourceLine" id="cb43-49" title="49"><span class="ot">typeCheck3 ::</span> <span class="kw">forall</span> xs<span class="op">.</span></a>
<a class="sourceLine" id="cb43-50" title="50">   ( <span class="dt">TypeCheck3</span> (<span class="dt">VariantF</span> xs) xs</a>
<a class="sourceLine" id="cb43-51" title="51">   , <span class="dt">Functor</span> (<span class="dt">VariantF</span> xs)</a>
<a class="sourceLine" id="cb43-52" title="52">   , <span class="dt">TypedF</span> <span class="op">:&lt;:</span> xs</a>
<a class="sourceLine" id="cb43-53" title="53">   ) <span class="ot">=&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">EADT</span> xs</a>
<a class="sourceLine" id="cb43-54" title="54">typeCheck3 e <span class="ot">=</span> <span class="dt">VF</span> (cata typeCheck3'<span class="ot"> e ::</span> <span class="dt">TypedF</span> (<span class="dt">EADT</span> xs))</a></code></pre></div>
<p>Let’s try it:</p>
<div class="sourceCode" id="cb44"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb44-1" title="1"><span class="op">&gt;</span> <span class="kw">type</span> <span class="dt">E</span> <span class="ot">=</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">FloatValF</span>,<span class="dt">AddF</span>,<span class="dt">MulF</span>,<span class="dt">TypedF</span>]</a>
<a class="sourceLine" id="cb44-2" title="2"></a>
<a class="sourceLine" id="cb44-3" title="3"><span class="op">&gt;</span> showEADT (typeCheck3 (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">E</span>))</a>
<a class="sourceLine" id="cb44-4" title="4"><span class="st">&quot;(((10 :: TInt) + (5 :: TInt)) :: TInt)&quot;</span></a>
<a class="sourceLine" id="cb44-5" title="5"></a>
<a class="sourceLine" id="cb44-6" title="6"><span class="op">&gt;</span> showEADT (typeCheck3 (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">FloatVal</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">E</span>))</a>
<a class="sourceLine" id="cb44-7" title="7"><span class="st">&quot;(((10 :: TInt) + (5.0 :: TFloat)) :: TError \&quot;can't add TInt with TFloat\&quot;)&quot;</span></a>
<a class="sourceLine" id="cb44-8" title="8"></a>
<a class="sourceLine" id="cb44-9" title="9"><span class="op">&gt;</span> showEADT (typeCheck3 (<span class="dt">Add</span> (<span class="dt">Add</span> (<span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Val</span> <span class="dv">3</span>)) (<span class="dt">FloatVal</span> <span class="dv">10</span>)) (<span class="dt">Val</span> <span class="dv">5</span>))<span class="ot"> ::</span> <span class="dt">E</span>)</a>
<a class="sourceLine" id="cb44-10" title="10"><span class="st">&quot;(((((((2 :: TInt) * (3 :: TInt)) :: TInt) + (10.0 :: TFloat))</span></a>
<a class="sourceLine" id="cb44-11" title="11"><span class="st">   :: TError \&quot;can't add TInt with TFloat\&quot;) + (5 :: TInt)) :: TError \&quot;\&quot;)&quot;</span></a></code></pre></div>
<p>It’s a bit hard to read, let’s add an helper:</p>
<div class="sourceCode" id="cb45"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb45-1" title="1"><span class="kw">import</span> <span class="dt">Data.Tree</span></a>
<a class="sourceLine" id="cb45-2" title="2"></a>
<a class="sourceLine" id="cb45-3" title="3"><span class="kw">class</span> <span class="dt">DisplayEADT</span> (<span class="ot">f ::</span> <span class="op">*</span> <span class="ot">-&gt;</span> <span class="op">*</span>) <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-4" title="4"><span class="ot">   displayEADT' ::</span> f (<span class="dt">Tree</span> <span class="dt">String</span>) <span class="ot">-&gt;</span> <span class="dt">Tree</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb45-5" title="5"></a>
<a class="sourceLine" id="cb45-6" title="6"><span class="kw">instance</span> <span class="dt">DisplayEADT</span> (<span class="dt">VariantF</span> '[]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-7" title="7">   displayEADT' <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb45-8" title="8"></a>
<a class="sourceLine" id="cb45-9" title="9"><span class="kw">instance</span> (<span class="dt">DisplayEADT</span> x, <span class="dt">DisplayEADT</span> (<span class="dt">VariantF</span> xs))  <span class="ot">=&gt;</span> <span class="dt">DisplayEADT</span> (<span class="dt">VariantF</span> (x '<span class="op">:</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-10" title="10">   displayEADT' v <span class="ot">=</span> <span class="kw">case</span> popVariantFHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb45-11" title="11">      <span class="dt">Right</span> u <span class="ot">-&gt;</span> displayEADT' u</a>
<a class="sourceLine" id="cb45-12" title="12">      <span class="dt">Left</span>  w <span class="ot">-&gt;</span> displayEADT' w</a>
<a class="sourceLine" id="cb45-13" title="13"></a>
<a class="sourceLine" id="cb45-14" title="14"><span class="kw">instance</span> <span class="dt">DisplayEADT</span> <span class="dt">ValF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-15" title="15">   displayEADT' (<span class="dt">ValF</span> i) <span class="ot">=</span> <span class="dt">Node</span> (<span class="fu">show</span> i) []</a>
<a class="sourceLine" id="cb45-16" title="16"></a>
<a class="sourceLine" id="cb45-17" title="17"><span class="kw">instance</span> <span class="dt">DisplayEADT</span> <span class="dt">FloatValF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-18" title="18">   displayEADT' (<span class="dt">FloatValF</span> i) <span class="ot">=</span> <span class="dt">Node</span> (<span class="fu">show</span> i) []</a>
<a class="sourceLine" id="cb45-19" title="19"></a>
<a class="sourceLine" id="cb45-20" title="20"><span class="kw">instance</span> <span class="dt">DisplayEADT</span> <span class="dt">AddF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-21" title="21">   displayEADT' (<span class="dt">AddF</span> u v) <span class="ot">=</span> <span class="dt">Node</span> <span class="st">&quot;(+)&quot;</span> [u,v]</a>
<a class="sourceLine" id="cb45-22" title="22"></a>
<a class="sourceLine" id="cb45-23" title="23"><span class="kw">instance</span> <span class="dt">DisplayEADT</span> <span class="dt">MulF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-24" title="24">   displayEADT' (<span class="dt">MulF</span> u v) <span class="ot">=</span> <span class="dt">Node</span> <span class="st">&quot;(*)&quot;</span> [u,v]</a>
<a class="sourceLine" id="cb45-25" title="25"></a>
<a class="sourceLine" id="cb45-26" title="26"><span class="kw">instance</span> <span class="dt">DisplayEADT</span> <span class="dt">TypedF</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb45-27" title="27">   displayEADT' (<span class="dt">TypedF</span> t (<span class="dt">Node</span> l ts)) <span class="ot">=</span> <span class="dt">Node</span> (l <span class="op">++</span> <span class="st">&quot; :: &quot;</span> <span class="op">++</span> <span class="fu">show</span> t) ts</a>
<a class="sourceLine" id="cb45-28" title="28"></a>
<a class="sourceLine" id="cb45-29" title="29"><span class="ot">drawEADT ::</span> (<span class="dt">Functor</span> (<span class="dt">VariantF</span> xs), <span class="dt">DisplayEADT</span> (<span class="dt">VariantF</span> xs)) <span class="ot">=&gt;</span> <span class="dt">EADT</span> xs <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb45-30" title="30">drawEADT <span class="ot">=</span> <span class="fu">putStr</span> <span class="op">.</span> drawTree <span class="op">.</span> cata displayEADT'</a></code></pre></div>
<p>And try it:</p>
<pre class="sourceCode "><code>&gt; drawEADT (typeCheck3 (Add (Add (Mul (Val 2) (Val 3)) (FloatVal 10)) (Val 5)) :: E)

(+) :: TError &quot;&quot;
|
+- (+) :: TError &quot;can't add TInt with TFloat&quot;
|  |
|  +- (*) :: TInt
|  |  |
|  |  +- 2 :: TInt
|  |  |
|  |  `- 3 :: TInt
|  |
|  `- 10.0 :: TFloat
|
`- 5 :: TInt</code></pre>
<h3 id="composition-example">Composition example</h3>
<p>Finally, we can write the following one-line example that strips annotations, adds support for type-ascriptions, performs type-checking and displays the resulting EADT:</p>
<div class="sourceCode" id="cb47"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb47-1" title="1"><span class="ot">annotExpr ::</span> <span class="dt">EADT</span> '[<span class="dt">ValF</span>,<span class="dt">AddF</span>,<span class="dt">MulF</span>,<span class="dt">AnnotF</span> <span class="dt">String</span>]</a>
<a class="sourceLine" id="cb47-2" title="2">annotExpr <span class="ot">=</span> <span class="dt">Mul</span> (<span class="dt">Val</span> <span class="dv">8</span>) (<span class="dt">Annot</span> <span class="st">&quot;An addition&quot;</span> (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">10</span>) (<span class="dt">Val</span> <span class="dv">5</span>)))</a>
<a class="sourceLine" id="cb47-3" title="3"></a>
<a class="sourceLine" id="cb47-4" title="4"><span class="op">&gt;</span> drawEADT (typeCheck3 (appendEADT <span class="op">@</span>'[<span class="dt">TypedF</span>] (removeAnnot annotExpr)))</a>
<a class="sourceLine" id="cb47-5" title="5"></a>
<a class="sourceLine" id="cb47-6" title="6"><span class="ot">(*) ::</span> <span class="dt">TInt</span></a>
<a class="sourceLine" id="cb47-7" title="7"><span class="op">|</span></a>
<a class="sourceLine" id="cb47-8" title="8"><span class="op">+-</span> <span class="dv">8</span><span class="ot"> ::</span> <span class="dt">TInt</span></a>
<a class="sourceLine" id="cb47-9" title="9"><span class="op">|</span></a>
<a class="sourceLine" id="cb47-10" title="10"><span class="ot">`- (+) :: TInt</span></a>
<a class="sourceLine" id="cb47-11" title="11"><span class="ot">   |</span></a>
<a class="sourceLine" id="cb47-12" title="12"><span class="ot">   +- 10 :: TInt</span></a>
<a class="sourceLine" id="cb47-13" title="13"><span class="ot">   |</span></a>
<a class="sourceLine" id="cb47-14" title="14"><span class="ot">   `</span><span class="op">-</span> <span class="dv">5</span><span class="ot"> ::</span> <span class="dt">TInt</span></a></code></pre></div>
<p>The compiler ensures that the EADT is valid at each phase. For instance if we forget to remove annotations, type-checking and drawing phases will complain at compile time:</p>
<div class="sourceCode" id="cb48"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb48-1" title="1"><span class="op">&gt;</span> drawEADT (typeCheck3 (appendEADT <span class="op">@</span>'[<span class="dt">TypedF</span>] annotExpr))</a>
<a class="sourceLine" id="cb48-2" title="2"></a>
<a class="sourceLine" id="cb48-3" title="3"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">367</span><span class="op">:</span><span class="dv">1</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb48-4" title="4">    • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">DisplayEADT</span> (<span class="dt">AnnotF</span> <span class="dt">String</span>))</a>
<a class="sourceLine" id="cb48-5" title="5">        arising from a use <span class="kw">of</span> ‘drawEADT’</a>
<a class="sourceLine" id="cb48-6" title="6">    • <span class="dt">In</span> the expression<span class="op">:</span></a>
<a class="sourceLine" id="cb48-7" title="7">        drawEADT (typeCheck3 (appendEADT <span class="op">@</span>'[<span class="dt">TypedF</span>] annotExpr))</a>
<a class="sourceLine" id="cb48-8" title="8">      <span class="dt">In</span> an equation for ‘it’<span class="op">:</span></a>
<a class="sourceLine" id="cb48-9" title="9">          it <span class="ot">=</span> drawEADT (typeCheck3 (appendEADT <span class="op">@</span>'[<span class="dt">TypedF</span>] annotExpr))</a>
<a class="sourceLine" id="cb48-10" title="10"></a>
<a class="sourceLine" id="cb48-11" title="11"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">367</span><span class="op">:</span><span class="dv">11</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb48-12" title="12">    • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">TypeCheck3</span></a>
<a class="sourceLine" id="cb48-13" title="13">                         (<span class="dt">AnnotF</span> <span class="dt">String</span>) '[<span class="dt">ValF</span>, <span class="dt">AddF</span>, <span class="dt">MulF</span>, <span class="dt">AnnotF</span> <span class="dt">String</span>, <span class="dt">TypedF</span>])</a>
<a class="sourceLine" id="cb48-14" title="14">        arising from a use <span class="kw">of</span> ‘typeCheck3’</a>
<a class="sourceLine" id="cb48-15" title="15">    • <span class="dt">In</span> the first argument <span class="kw">of</span> ‘drawEADT’, namely</a>
<a class="sourceLine" id="cb48-16" title="16">        ‘(typeCheck3 (appendEADT <span class="op">@</span>'[<span class="dt">TypedF</span>] annotExpr))’</a>
<a class="sourceLine" id="cb48-17" title="17">      <span class="dt">In</span> the expression<span class="op">:</span></a>
<a class="sourceLine" id="cb48-18" title="18">        drawEADT (typeCheck3 (appendEADT <span class="op">@</span>'[<span class="dt">TypedF</span>] annotExpr))</a>
<a class="sourceLine" id="cb48-19" title="19">      <span class="dt">In</span> an equation for ‘it’<span class="op">:</span></a>
<a class="sourceLine" id="cb48-20" title="20">          it <span class="ot">=</span> drawEADT (typeCheck3 (appendEADT <span class="op">@</span>'[<span class="dt">TypedF</span>] annotExpr))</a></code></pre></div>
<p>This way we can easily encode phase invariants in the types.</p>
<h1 id="remarks">Remarks</h1>
<p>This post has been motivated by <a href="https://www.reddit.com/r/haskell/comments/82q4dw/modern_compiler_implementation_in_ml_tiger_book/">a discussion on Reddit</a> about AST transformations: each phase of a compiler transforms an AST into another and there is a tension between using a different AST data type per phase (best approach if we consider phases independently) or a generic AST data type that can be used by every phase (best approach to easily compose/interleave phases).</p>
<p>The usual answer (as used by GHC) is taken from the <a href="https://www.microsoft.com/en-us/research/wp-content/uploads/2016/11/trees-that-grow.pdf">“Trees that grow”</a> paper and consists in using an ADT as a generic AST and to parameterize it with type families. I don’t really like it and I think that using EADTs instead could probably avoid the use of AST specific type-families and hence could make the AST more generic (easier to add phases, etc.).</p>
<p>I have used recursion schemes in this post without really introducing them. Patrick Thomson wrote a <a href="http://blog.sumtypeofway.com/an-introduction-to-recursion-schemes">very good series of posts</a> about them that I highly recommend.</p>
<p>Please let me know if you do some fun or interesting things with EADTs!</p>
<p>Sources can be found here: <a href="https://github.com/haskus/haskus-utils">https://github.com/haskus/haskus-utils</a> in <code>Haskus.Utils.VariantF</code>.</p>
<h1 id="addendum">ADDENDUM</h1>
<p>Following the <a href="https://www.reddit.com/r/haskell/comments/8lcmef/extensible_adt_eadt/">discussion on Reddit</a> about this post, I have implemented the speculated “project” function from the <a href="https://www.researchgate.net/profile/Patrick_Bahr/publication/228841104_Compositional_data_types/links/09e415056f0d9cee41000000/Compositional-data-types.pdf">Compositional data types</a> paper (Future Work section) with the proposed type. I have called it <code>popEADT</code> and it allows us to perform complete case analysis (with its friends <code>popVariantF</code> and <code>variantFToValue</code>), e.g.:</p>
<div class="sourceCode" id="cb49"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb49-1" title="1"><span class="ot">showMulAddValADT ::</span> <span class="dt">MulAddValADT</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb49-2" title="2">showMulAddValADT e <span class="ot">=</span> <span class="kw">case</span> popEADT e <span class="kw">of</span></a>
<a class="sourceLine" id="cb49-3" title="3">   <span class="dt">Right</span> (<span class="dt">ValF</span> u) <span class="ot">-&gt;</span> <span class="fu">show</span> u</a>
<a class="sourceLine" id="cb49-4" title="4">   <span class="dt">Left</span> w         <span class="ot">-&gt;</span> <span class="kw">case</span> popVariantF w <span class="kw">of</span></a>
<a class="sourceLine" id="cb49-5" title="5">      <span class="dt">Right</span> (<span class="dt">AddF</span> u v) <span class="ot">-&gt;</span>  <span class="st">&quot;(&quot;</span> <span class="op">++</span> showMulAddValADT u <span class="op">++</span> <span class="st">&quot; + &quot;</span> <span class="op">++</span> showMulAddValADT v <span class="op">++</span> <span class="st">&quot;)&quot;</span></a>
<a class="sourceLine" id="cb49-6" title="6">      <span class="dt">Left</span> z           <span class="ot">-&gt;</span> <span class="kw">case</span> variantFToValue z <span class="kw">of</span></a>
<a class="sourceLine" id="cb49-7" title="7">         <span class="dt">MulF</span> u v <span class="ot">-&gt;</span>  <span class="st">&quot;(&quot;</span> <span class="op">++</span> showMulAddValADT u <span class="op">++</span> <span class="st">&quot; * &quot;</span> <span class="op">++</span> showMulAddValADT v <span class="op">++</span> <span class="st">&quot;)&quot;</span></a>
<a class="sourceLine" id="cb49-8" title="8"></a>
<a class="sourceLine" id="cb49-9" title="9"><span class="op">&gt;</span> v <span class="ot">=</span> <span class="dt">Mul</span> (<span class="dt">Add</span> (<span class="dt">Val</span> <span class="dv">2</span>) (<span class="dt">Val</span> <span class="dv">3</span>)) (<span class="dt">Val</span> <span class="dv">5</span>)<span class="ot"> ::</span> <span class="dt">MulAddValADT</span> </a>
<a class="sourceLine" id="cb49-10" title="10"><span class="op">&gt;</span> showMulAddValADT v</a>
<a class="sourceLine" id="cb49-11" title="11"><span class="st">&quot;((2 + 3) * 5)&quot;</span></a></code></pre></div>
<p>Notice that contrary to the previous <code>showAddValADT</code> example in the post, there is no need for any extra wildcard match this time because GHC detects that the pattern-matching is complete.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Heterogeneous collections</title>
    <link href="http://www.hsyl20.fr/home/posts/2018-02-21-heterogeneous-collections.html" />
    <id>http://www.hsyl20.fr/home/posts/2018-02-21-heterogeneous-collections.html</id>
    <published>2018-02-21T00:00:00Z</published>
    <updated>2018-02-21T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Heterogeneous collections</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Variant.html">Variant</a>, <a href="http://www.hsyl20.fr/home/tags/Heterogeneous%20collections.html">Heterogeneous collections</a></td>
               <td class="date">February 21, 2018</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This post is about managing collections (e.g., lists) of heterogeneous data types in Haskell.</p>
<p>Summary: in my opinion, using the data type I’ve called <code>Variant</code> to handle heterogeneous collections is currently the best alternative. It is type-safe, efficient (both storage-wise and performance-wise) and easy to use.</p>
<h1 id="the-problem">The problem</h1>
<p>Suppose we have several algebraic data types for different geometric shapes:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">data</span> <span class="dt">Circle</span> <span class="ot">=</span> <span class="dt">Circle</span></a>
<a class="sourceLine" id="cb1-2" title="2">         {<span class="ot"> circleRadius ::</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb1-3" title="3">         ,<span class="ot"> circleCenter ::</span> (<span class="dt">Float</span>,<span class="dt">Float</span>)</a>
<a class="sourceLine" id="cb1-4" title="4">         }</a>
<a class="sourceLine" id="cb1-5" title="5">         <span class="kw">deriving</span> (<span class="dt">Show</span>)</a>
<a class="sourceLine" id="cb1-6" title="6"></a>
<a class="sourceLine" id="cb1-7" title="7"><span class="kw">data</span> <span class="dt">Square</span> <span class="ot">=</span> <span class="dt">Square</span></a>
<a class="sourceLine" id="cb1-8" title="8">         {<span class="ot"> squareTopLeft ::</span> (<span class="dt">Float</span>,<span class="dt">Float</span>)</a>
<a class="sourceLine" id="cb1-9" title="9">         ,<span class="ot"> squareWidth   ::</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb1-10" title="10">         }</a>
<a class="sourceLine" id="cb1-11" title="11">         <span class="kw">deriving</span> (<span class="dt">Show</span>)</a></code></pre></div>
<p>and that we know how to resize them by a factor:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="kw">class</span> <span class="dt">Resizable</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="ot">   resize ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb2-3" title="3"></a>
<a class="sourceLine" id="cb2-4" title="4"><span class="kw">instance</span> <span class="dt">Resizable</span> <span class="dt">Circle</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb2-5" title="5">   resize f (<span class="dt">Circle</span> r c) <span class="ot">=</span> <span class="dt">Circle</span> (f<span class="op">*</span>r) c</a>
<a class="sourceLine" id="cb2-6" title="6"></a>
<a class="sourceLine" id="cb2-7" title="7"><span class="kw">instance</span> <span class="dt">Resizable</span> <span class="dt">Square</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb2-8" title="8">   resize f (<span class="dt">Square</span> tl w) <span class="ot">=</span> <span class="dt">Square</span> tl (f<span class="op">*</span>w)</a></code></pre></div>
<p>We can write a function to resize a list of shapes:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="ot">resizeAll ::</span> <span class="dt">Resizable</span> a <span class="ot">=&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</a>
<a class="sourceLine" id="cb3-2" title="2">resizeAll f <span class="ot">=</span> <span class="fu">fmap</span> (resize f)</a></code></pre></div>
<p>Let’s test it on a collection of circles:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="op">&gt;</span> resizeAll <span class="dv">2</span> [<span class="dt">Circle</span> <span class="dv">5</span> (<span class="dv">1</span>,<span class="dv">2</span>), <span class="dt">Circle</span> <span class="dv">4</span> (<span class="dv">2</span>,<span class="dv">3</span>)]</a>
<a class="sourceLine" id="cb4-2" title="2"></a>
<a class="sourceLine" id="cb4-3" title="3">[<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">10.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>)}</a>
<a class="sourceLine" id="cb4-4" title="4">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">8.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}]</a></code></pre></div>
<p>Now on a collection of squares:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="op">&gt;</span> resizeAll <span class="dv">2</span> [<span class="dt">Square</span> (<span class="dv">1</span>,<span class="dv">2</span>) <span class="dv">5</span>, <span class="dt">Square</span> (<span class="dv">2</span>,<span class="dv">3</span>) <span class="dv">4</span>]</a>
<a class="sourceLine" id="cb5-2" title="2"></a>
<a class="sourceLine" id="cb5-3" title="3">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">10.0</span>}</a>
<a class="sourceLine" id="cb5-4" title="4">,<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>), squareWidth <span class="ot">=</span> <span class="fl">8.0</span>}]</a></code></pre></div>
<p>And finally on a collection mixing circles and squares:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="op">&gt;</span> resizeAll <span class="dv">2</span> [<span class="dt">Square</span> (<span class="dv">1</span>,<span class="dv">2</span>) <span class="dv">5</span>, <span class="dt">Circle</span> <span class="dv">4</span> (<span class="dv">2</span>,<span class="dv">3</span>)]</a>
<a class="sourceLine" id="cb6-2" title="2"></a>
<a class="sourceLine" id="cb6-3" title="3"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">10</span><span class="op">:</span><span class="dv">30</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb6-4" title="4">    • <span class="dt">Couldn't</span> match expected <span class="kw">type</span> ‘<span class="dt">Square</span>’ with actual <span class="kw">type</span> ‘<span class="dt">Circle</span>’</a>
<a class="sourceLine" id="cb6-5" title="5">    • <span class="dt">In</span> the expression<span class="op">:</span> <span class="dt">Circle</span> <span class="dv">4</span> (<span class="dv">2</span>, <span class="dv">3</span>)</a>
<a class="sourceLine" id="cb6-6" title="6">      <span class="dt">In</span> the second argument <span class="kw">of</span> ‘resizeAll’, namely</a>
<a class="sourceLine" id="cb6-7" title="7">        ‘[<span class="dt">Square</span> (<span class="dv">1</span>, <span class="dv">2</span>) <span class="dv">5</span>, <span class="dt">Circle</span> <span class="dv">4</span> (<span class="dv">2</span>, <span class="dv">3</span>)]’</a>
<a class="sourceLine" id="cb6-8" title="8">      <span class="dt">In</span> the expression<span class="op">:</span> resizeAll <span class="dv">2</span> [<span class="dt">Square</span> (<span class="dv">1</span>, <span class="dv">2</span>) <span class="dv">5</span>, <span class="dt">Circle</span> <span class="dv">4</span> (<span class="dv">2</span>, <span class="dv">3</span>)]</a></code></pre></div>
<p>Argh! We forgot that lists can only contain elements having the same type! We would like an heterogeneous collection that can contain both squares and circles (and maybe more shapes)!</p>
<h1 id="heterogeneous-collections">Heterogeneous Collections</h1>
<p>We can use the <code>Variant</code> data type (or its alias <code>V</code>) and the pattern synonym <code>V</code> to wrap our values:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">import</span> <span class="dt">Haskus.Utils.Variant</span></a>
<a class="sourceLine" id="cb7-2" title="2"></a>
<a class="sourceLine" id="cb7-3" title="3"><span class="co">-- a collection of circles and squares</span></a>
<a class="sourceLine" id="cb7-4" title="4"><span class="ot">shapes ::</span> [<span class="dt">V</span> '[<span class="dt">Circle</span>,<span class="dt">Square</span>]]</a>
<a class="sourceLine" id="cb7-5" title="5">shapes <span class="ot">=</span> [ <span class="dt">V</span> <span class="op">$</span> <span class="dt">Square</span> (<span class="dv">1</span>,<span class="dv">2</span>) <span class="dv">5</span></a>
<a class="sourceLine" id="cb7-6" title="6">         , <span class="dt">V</span> <span class="op">$</span> <span class="dt">Circle</span> <span class="dv">4</span> (<span class="dv">2</span>,<span class="dv">3</span>)</a>
<a class="sourceLine" id="cb7-7" title="7">         , <span class="dt">V</span> <span class="op">$</span> <span class="dt">Circle</span> <span class="dv">1</span> (<span class="dv">5</span>,<span class="dv">7</span>)</a>
<a class="sourceLine" id="cb7-8" title="8">         ]</a>
<a class="sourceLine" id="cb7-9" title="9"></a>
<a class="sourceLine" id="cb7-10" title="10"></a>
<a class="sourceLine" id="cb7-11" title="11"><span class="kw">data</span> <span class="dt">Triangle</span> <span class="ot">=</span> <span class="dt">Triangle</span> <span class="kw">deriving</span> (<span class="dt">Show</span>)</a>
<a class="sourceLine" id="cb7-12" title="12"></a>
<a class="sourceLine" id="cb7-13" title="13"><span class="co">-- a collection of circles, squares and triangles</span></a>
<a class="sourceLine" id="cb7-14" title="14"><span class="ot">shapes2 ::</span> [<span class="dt">V</span> '[<span class="dt">Circle</span>,<span class="dt">Square</span>,<span class="dt">Triangle</span>]]</a>
<a class="sourceLine" id="cb7-15" title="15">shapes2 <span class="ot">=</span> [ <span class="dt">V</span> <span class="op">$</span> <span class="dt">Square</span> (<span class="dv">1</span>,<span class="dv">2</span>) <span class="dv">5</span></a>
<a class="sourceLine" id="cb7-16" title="16">          , <span class="dt">V</span> <span class="op">$</span> <span class="dt">Circle</span> <span class="dv">4</span> (<span class="dv">2</span>,<span class="dv">3</span>)</a>
<a class="sourceLine" id="cb7-17" title="17">          , <span class="dt">V</span> <span class="op">$</span> <span class="dt">Triangle</span></a>
<a class="sourceLine" id="cb7-18" title="18">          , <span class="dt">V</span> <span class="op">$</span> <span class="dt">Circle</span> <span class="dv">1</span> (<span class="dv">5</span>,<span class="dv">7</span>)</a>
<a class="sourceLine" id="cb7-19" title="19">          ]</a></code></pre></div>
<p>We can rewrite <code>resizeAll</code> as follows:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="ot">resizeAllV ::</span> <span class="dt">AlterVariant</span> <span class="dt">Resizable</span> cs <span class="ot">=&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> [<span class="dt">V</span> cs] <span class="ot">-&gt;</span> [<span class="dt">V</span> cs]</a>
<a class="sourceLine" id="cb8-2" title="2">resizeAllV f <span class="ot">=</span> <span class="fu">fmap</span> (alterVariant <span class="op">@</span><span class="dt">Resizable</span> (resize f))</a></code></pre></div>
<p>It works on any list of variants as long as all the possible types in the heterogeneous list (i.e., types in <code>cs</code>) have an associated <code>Resizable</code> instance.</p>
<p>Let’s test it:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="op">&gt;</span> shapes</a>
<a class="sourceLine" id="cb9-2" title="2">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}</a>
<a class="sourceLine" id="cb9-3" title="3">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">4.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb9-4" title="4">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">1.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}]</a>
<a class="sourceLine" id="cb9-5" title="5"></a>
<a class="sourceLine" id="cb9-6" title="6"><span class="op">&gt;</span> resizeAllV <span class="dv">2</span> shapes</a>
<a class="sourceLine" id="cb9-7" title="7">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">10.0</span>}</a>
<a class="sourceLine" id="cb9-8" title="8">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">8.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb9-9" title="9">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">2.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}]</a></code></pre></div>
<p>We can check that type-checking works as expected by using this function on <code>shapes2</code>:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="op">&gt;</span> resizeAllV <span class="dv">2</span> shapes2</a>
<a class="sourceLine" id="cb10-2" title="2"></a>
<a class="sourceLine" id="cb10-3" title="3"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">3</span><span class="op">:</span><span class="dv">1</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb10-4" title="4">    • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">Resizable</span> <span class="dt">Triangle</span>)</a>
<a class="sourceLine" id="cb10-5" title="5">        arising from a use <span class="kw">of</span> ‘resizeAllV’</a>
<a class="sourceLine" id="cb10-6" title="6">    • <span class="dt">In</span> the expression<span class="op">:</span> resizeAllV <span class="dv">2</span> shapes2</a>
<a class="sourceLine" id="cb10-7" title="7">      <span class="dt">In</span> an equation for ‘it’<span class="op">:</span> it <span class="ot">=</span> resizeAllV <span class="dv">2</span> shapes2</a></code></pre></div>
<p>Indeed the type of <code>shapes2</code> indicates that it may contain triangles but <code>Triangle</code> has no <code>Resizable</code> instance!</p>
<p>Another approach is to create an instance of <code>Resizable</code> for any <code>Variant cs</code> as long as every type in <code>cs</code> has a <code>Resizable</code> instance. It is defined recursively as follows:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1"><span class="co">-- this instance is never used but it is necessary for the type-checker</span></a>
<a class="sourceLine" id="cb11-2" title="2"><span class="kw">instance</span> <span class="dt">Resizable</span> (<span class="dt">V</span> '[]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb11-3" title="3">   <span class="ot">{-# INLINE resize #-}</span></a>
<a class="sourceLine" id="cb11-4" title="4">   resize <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb11-5" title="5"></a>
<a class="sourceLine" id="cb11-6" title="6"><span class="kw">instance</span> (<span class="dt">Resizable</span> (<span class="dt">V</span> xs), <span class="dt">Resizable</span> x) <span class="ot">=&gt;</span> <span class="dt">Resizable</span> (<span class="dt">V</span> (x '<span class="op">:</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb11-7" title="7">   <span class="ot">{-# INLINE resize #-}</span></a>
<a class="sourceLine" id="cb11-8" title="8">   resize f v <span class="ot">=</span> <span class="kw">case</span> popVariantHead v <span class="kw">of</span></a>
<a class="sourceLine" id="cb11-9" title="9">      <span class="dt">Right</span> x <span class="ot">-&gt;</span> toVariantHead (resize f x)</a>
<a class="sourceLine" id="cb11-10" title="10">      <span class="dt">Left</span> xs <span class="ot">-&gt;</span> toVariantTail (resize f xs)</a></code></pre></div>
<p>We can now use the original <code>resizeAll</code> function:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" title="1"><span class="ot">resizeAll ::</span> <span class="dt">Resizable</span> a <span class="ot">=&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</a>
<a class="sourceLine" id="cb12-2" title="2">resizeAll f <span class="ot">=</span> <span class="fu">fmap</span> (resize f)</a>
<a class="sourceLine" id="cb12-3" title="3"></a>
<a class="sourceLine" id="cb12-4" title="4"><span class="op">&gt;</span> resizeAll <span class="dv">3</span> shapes</a>
<a class="sourceLine" id="cb12-5" title="5">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">15.0</span>}</a>
<a class="sourceLine" id="cb12-6" title="6">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">12.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb12-7" title="7">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">3.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}</a>
<a class="sourceLine" id="cb12-8" title="8">]</a>
<a class="sourceLine" id="cb12-9" title="9"></a>
<a class="sourceLine" id="cb12-10" title="10"><span class="op">&gt;</span> resizeAll <span class="dv">3</span> shapes2</a>
<a class="sourceLine" id="cb12-11" title="11"></a>
<a class="sourceLine" id="cb12-12" title="12"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">66</span><span class="op">:</span><span class="dv">1</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb12-13" title="13">    • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">Resizable</span> <span class="dt">Triangle</span>)</a>
<a class="sourceLine" id="cb12-14" title="14">        arising from a use <span class="kw">of</span> ‘resizeAll’</a>
<a class="sourceLine" id="cb12-15" title="15">    • <span class="dt">In</span> the expression<span class="op">:</span> resizeAll <span class="dv">3</span> shapes2</a>
<a class="sourceLine" id="cb12-16" title="16">      <span class="dt">In</span> an equation for ‘it’<span class="op">:</span> it <span class="ot">=</span> resizeAll <span class="dv">3</span> shapes2</a></code></pre></div>
<p>We use this mechanism to provide <code>Eq</code>, <code>Ord</code> and <code>Show</code> instances. That’s how GHCI shows the variant contents.</p>
<p>We can easily compose functions by “composing” the constraints on the collection types:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb13-1" title="1"><span class="kw">import</span> <span class="dt">Data.Foldable</span> (traverse_)</a>
<a class="sourceLine" id="cb13-2" title="2"></a>
<a class="sourceLine" id="cb13-3" title="3"><span class="co">-- print an heterogeneous collection</span></a>
<a class="sourceLine" id="cb13-4" title="4"><span class="ot">printAll ::</span> <span class="dt">TraverseVariant</span> <span class="dt">Show</span> cs <span class="dt">IO</span> <span class="ot">=&gt;</span> [<span class="dt">V</span> cs] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb13-5" title="5">printAll <span class="ot">=</span> traverse_ (traverseVariant_ <span class="op">@</span><span class="dt">Show</span> <span class="fu">print</span>)</a>
<a class="sourceLine" id="cb13-6" title="6"></a>
<a class="sourceLine" id="cb13-7" title="7"><span class="ot">resizeThenPrint ::</span> (<span class="dt">AlterVariant</span> <span class="dt">Resizable</span> cs, <span class="dt">TraverseVariant</span> <span class="dt">Show</span> cs <span class="dt">IO</span>)</a>
<a class="sourceLine" id="cb13-8" title="8">                  <span class="ot">=&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> [<span class="dt">V</span> cs] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb13-9" title="9">resizeThenPrint f <span class="ot">=</span> printAll <span class="op">.</span> resizeAllV f</a>
<a class="sourceLine" id="cb13-10" title="10"></a>
<a class="sourceLine" id="cb13-11" title="11"><span class="op">&gt;</span> resizeThenPrint <span class="dv">2</span> shapes</a>
<a class="sourceLine" id="cb13-12" title="12"><span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">10.0</span>}</a>
<a class="sourceLine" id="cb13-13" title="13"><span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">8.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb13-14" title="14"><span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">2.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}</a></code></pre></div>
<p>We can map a function to modify only values having some given type:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb14-1" title="1"><span class="ot">translateCircle ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">Circle</span> <span class="ot">-&gt;</span> <span class="dt">Circle</span></a>
<a class="sourceLine" id="cb14-2" title="2">translateCircle fx fy (<span class="dt">Circle</span> r (x,y)) <span class="ot">=</span> <span class="dt">Circle</span> r (fx<span class="op">+</span>x,fy<span class="op">+</span>y)</a>
<a class="sourceLine" id="cb14-3" title="3"></a>
<a class="sourceLine" id="cb14-4" title="4"><span class="op">&gt;</span> <span class="fu">fmap</span> (mapVariant (translateCircle <span class="dv">50</span> <span class="dv">70</span>)) shapes</a>
<a class="sourceLine" id="cb14-5" title="5">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}</a>
<a class="sourceLine" id="cb14-6" title="6">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">4.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">52.0</span>,<span class="fl">73.0</span>)}</a>
<a class="sourceLine" id="cb14-7" title="7">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">1.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">55.0</span>,<span class="fl">77.0</span>)}</a>
<a class="sourceLine" id="cb14-8" title="8">]</a></code></pre></div>
<p>We can also map to a <code>Variant</code> and fold the result:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb15-1" title="1"><span class="ot">transformCircle ::</span> <span class="dt">Circle</span> <span class="ot">-&gt;</span> <span class="dt">V</span> '[<span class="dt">Square</span>,<span class="dt">Triangle</span>]</a>
<a class="sourceLine" id="cb15-2" title="2">transformCircle (<span class="dt">Circle</span> r xy)</a>
<a class="sourceLine" id="cb15-3" title="3">   <span class="op">|</span> r <span class="op">&gt;</span> <span class="dv">3</span>     <span class="ot">=</span> <span class="dt">V</span> (<span class="dt">Square</span> xy r)</a>
<a class="sourceLine" id="cb15-4" title="4">   <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="dt">V</span> <span class="dt">Triangle</span></a>
<a class="sourceLine" id="cb15-5" title="5"></a>
<a class="sourceLine" id="cb15-6" title="6"><span class="op">&gt;</span> shapes</a>
<a class="sourceLine" id="cb15-7" title="7">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}</a>
<a class="sourceLine" id="cb15-8" title="8">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">4.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb15-9" title="9">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">1.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}]</a>
<a class="sourceLine" id="cb15-10" title="10"></a>
<a class="sourceLine" id="cb15-11" title="11"><span class="op">&gt;</span> <span class="fu">fmap</span> (foldMapVariant transformCircle) shapes</a>
<a class="sourceLine" id="cb15-12" title="12">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}</a>
<a class="sourceLine" id="cb15-13" title="13">,<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>), squareWidth <span class="ot">=</span> <span class="fl">4.0</span>}</a>
<a class="sourceLine" id="cb15-14" title="14">,<span class="dt">Triangle</span>]</a>
<a class="sourceLine" id="cb15-15" title="15"></a>
<a class="sourceLine" id="cb15-16" title="16"><span class="op">&gt;</span> <span class="op">:</span>t <span class="fu">fmap</span> (foldMapVariant transformCircle) shapes</a>
<a class="sourceLine" id="cb15-17" title="17"><span class="fu">fmap</span> (foldMapVariant transformCircle) shapes</a>
<a class="sourceLine" id="cb15-18" title="18"><span class="ot">  ::</span> [<span class="dt">V</span> '[<span class="dt">Square</span>, <span class="dt">Triangle</span>, <span class="dt">Square</span>]]</a></code></pre></div>
<p>As you can see, it is possible to have the same type more than once in a <code>Variant</code>. It is useful if you “select” types by index, e.g., <code>fromVariantAt @2 v</code> (cf. <code>*At</code> functions in Haddock).</p>
<p>You can also decide to keep a single entry per type with <code>nubVariant</code>:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb16-1" title="1"><span class="op">&gt;</span> <span class="op">:</span>t <span class="fu">fmap</span> (nubVariant <span class="op">.</span> foldMapVariant transformCircle) shapes</a>
<a class="sourceLine" id="cb16-2" title="2"><span class="fu">fmap</span> (nubVariant <span class="op">.</span> foldMapVariant transformCircle) shapes</a>
<a class="sourceLine" id="cb16-3" title="3"><span class="ot">  ::</span> [<span class="dt">V</span> '[<span class="dt">Square</span>, <span class="dt">Triangle</span>]]</a></code></pre></div>
<p>You can also extend or reorder the type list of a <code>Variant</code> with <code>liftVariant</code>:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb17-1" title="1"><span class="op">&gt;</span> shapes3 <span class="ot">=</span> <span class="fu">fmap</span> liftVariant<span class="ot"> shapes ::</span> [<span class="dt">V</span> '[<span class="dt">Square</span>,<span class="dt">Int</span>,<span class="dt">Circle</span>,<span class="dt">String</span>]]</a>
<a class="sourceLine" id="cb17-2" title="2"></a>
<a class="sourceLine" id="cb17-3" title="3"><span class="op">&gt;</span> shapes3 <span class="op">++</span> [<span class="dt">V</span> <span class="st">&quot;Hey!&quot;</span>, <span class="dt">V</span> (<span class="dv">10</span><span class="ot"> ::</span> <span class="dt">Int</span>)]</a>
<a class="sourceLine" id="cb17-4" title="4">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}</a>
<a class="sourceLine" id="cb17-5" title="5">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">4.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb17-6" title="6">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">1.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}</a>
<a class="sourceLine" id="cb17-7" title="7">,<span class="st">&quot;Hey!&quot;</span></a>
<a class="sourceLine" id="cb17-8" title="8">,<span class="dv">10</span></a>
<a class="sourceLine" id="cb17-9" title="9">]</a></code></pre></div>
<p>Obviously, we are not allowed to remove a type from the list (considered as a set):</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb18-1" title="1"><span class="op">&gt;</span> <span class="fu">fmap</span> liftVariant<span class="ot"> shapes ::</span> [<span class="dt">V</span> '[<span class="dt">Square</span>,<span class="dt">Int</span>,<span class="dt">String</span>]]</a>
<a class="sourceLine" id="cb18-2" title="2"></a>
<a class="sourceLine" id="cb18-3" title="3"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">112</span><span class="op">:</span><span class="dv">6</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb18-4" title="4">    • <span class="ot">`Circle' is not a member of '[Square, Int, String]</span></a>
<a class="sourceLine" id="cb18-5" title="5"><span class="ot">    • In the first argument of ‘fmap’, namely ‘liftVariant’</span></a>
<a class="sourceLine" id="cb18-6" title="6"><span class="ot">      In the expression:</span></a>
<a class="sourceLine" id="cb18-7" title="7"><span class="ot">          fmap liftVariant shapes :: [V '[Square, Int, String]]</span></a>
<a class="sourceLine" id="cb18-8" title="8"><span class="ot">      In an equation for ‘it’:</span></a>
<a class="sourceLine" id="cb18-9" title="9"><span class="ot">          it = fmap liftVariant shapes :: [V '[Square, Int, String]]</span></a>
<a class="sourceLine" id="cb18-10" title="10"></a>
<a class="sourceLine" id="cb18-11" title="11"><span class="ot">&lt;interactive&gt;:112:6: error:</span></a>
<a class="sourceLine" id="cb18-12" title="12"><span class="ot">    • '[Circle, Square]</span></a>
<a class="sourceLine" id="cb18-13" title="13"><span class="ot">      is not a subset of</span></a>
<a class="sourceLine" id="cb18-14" title="14"><span class="ot">      '[Square, Int, String]</span></a>
<a class="sourceLine" id="cb18-15" title="15"><span class="ot">    • In the first argument of ‘fmap’, namely ‘liftVariant’</span></a>
<a class="sourceLine" id="cb18-16" title="16"><span class="ot">      In the expression:</span></a>
<a class="sourceLine" id="cb18-17" title="17"><span class="ot">          fmap liftVariant shapes :: [V '[Square, Int, String]]</span></a>
<a class="sourceLine" id="cb18-18" title="18"><span class="ot">      In an equation for ‘it’:</span></a>
<a class="sourceLine" id="cb18-19" title="19"><span class="ot">          it = fmap liftVariant shapes :: [V '[Square, Int, String]]</span></a></code></pre></div>
<p>Let’s try to extract some shapes from the collection depending on their type:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb19-1" title="1"><span class="kw">import</span> <span class="dt">Data.Maybe</span> (mapMaybe)</a>
<a class="sourceLine" id="cb19-2" title="2"></a>
<a class="sourceLine" id="cb19-3" title="3"><span class="co">-- extract values having type &quot;c&quot; from the collection (&quot;cs&quot; must contain &quot;c&quot;)</span></a>
<a class="sourceLine" id="cb19-4" title="4"><span class="ot">filterColl ::</span> <span class="kw">forall</span> c cs<span class="op">.</span> <span class="dt">Popable</span> c cs <span class="ot">=&gt;</span> [<span class="dt">V</span> cs] <span class="ot">-&gt;</span> [c]</a>
<a class="sourceLine" id="cb19-5" title="5">filterColl <span class="ot">=</span> mapMaybe (fromVariant <span class="op">@</span>c)</a>
<a class="sourceLine" id="cb19-6" title="6"></a>
<a class="sourceLine" id="cb19-7" title="7"><span class="op">&gt;</span> filterColl <span class="op">@</span><span class="dt">Circle</span> shapes</a>
<a class="sourceLine" id="cb19-8" title="8">[<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">4.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb19-9" title="9">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">1.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}]</a>
<a class="sourceLine" id="cb19-10" title="10"></a>
<a class="sourceLine" id="cb19-11" title="11"><span class="op">&gt;</span> filterColl <span class="op">@</span><span class="dt">Square</span> shapes</a>
<a class="sourceLine" id="cb19-12" title="12">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}]</a>
<a class="sourceLine" id="cb19-13" title="13"></a>
<a class="sourceLine" id="cb19-14" title="14"><span class="op">&gt;</span> filterColl <span class="op">@</span><span class="dt">Triangle</span> shapes</a>
<a class="sourceLine" id="cb19-15" title="15"></a>
<a class="sourceLine" id="cb19-16" title="16"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">44</span><span class="op">:</span><span class="dv">1</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb19-17" title="17">    • <span class="ot">`Triangle' is not a member of '[Circle, Square]</span></a>
<a class="sourceLine" id="cb19-18" title="18"><span class="ot">    • In the expression: filterColl @Triangle shapes</span></a>
<a class="sourceLine" id="cb19-19" title="19"><span class="ot">      In an equation for ‘it’: it = filterColl @Triangle shapes</span></a></code></pre></div>
<p>Indeed no <code>Triangle</code> can be in the <code>shapes</code> collection as it is defined to hold only circles and squares.</p>
<p>We may want to write a generic function that filters any collection, even if we statically know that it can’t contain the given type. Let’s use <code>fromVariantMaybe</code> function and <code>MaybePopable</code> constraint for this:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb20-1" title="1"><span class="co">-- extract values having type &quot;c&quot; from the collection (&quot;cs&quot; may not contain &quot;c&quot;)</span></a>
<a class="sourceLine" id="cb20-2" title="2"><span class="ot">filterCollMaybe ::</span> <span class="kw">forall</span> c cs<span class="op">.</span> <span class="dt">MaybePopable</span> c cs <span class="ot">=&gt;</span> [<span class="dt">V</span> cs] <span class="ot">-&gt;</span> [c]</a>
<a class="sourceLine" id="cb20-3" title="3">filterCollMaybe <span class="ot">=</span> mapMaybe (fromVariantMaybe <span class="op">@</span>c)</a>
<a class="sourceLine" id="cb20-4" title="4"></a>
<a class="sourceLine" id="cb20-5" title="5"><span class="op">&gt;</span> filterCollMaybe <span class="op">@</span><span class="dt">Triangle</span> shapes</a>
<a class="sourceLine" id="cb20-6" title="6">[]</a>
<a class="sourceLine" id="cb20-7" title="7"><span class="op">&gt;</span> filterCollMaybe <span class="op">@</span><span class="dt">Triangle</span> shapes2</a>
<a class="sourceLine" id="cb20-8" title="8">[<span class="dt">Triangle</span>]</a>
<a class="sourceLine" id="cb20-9" title="9"><span class="op">&gt;</span> filterCollMaybe <span class="op">@</span><span class="dt">Int</span> shapes2</a>
<a class="sourceLine" id="cb20-10" title="10">[]</a></code></pre></div>
<p>Instead of keeping values having a given type, it may be more useful to filter out some types:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb21-1" title="1"><span class="kw">import</span> <span class="dt">Data.Either</span> (partitionEithers)</a>
<a class="sourceLine" id="cb21-2" title="2"></a>
<a class="sourceLine" id="cb21-3" title="3"><span class="ot">removeAll ::</span> <span class="kw">forall</span> c cs<span class="op">.</span> <span class="dt">MaybePopable</span> c cs <span class="ot">=&gt;</span> [<span class="dt">V</span> cs] <span class="ot">-&gt;</span> [<span class="dt">V</span> (<span class="dt">Filter</span> c cs)]</a>
<a class="sourceLine" id="cb21-4" title="4">removeAll <span class="ot">=</span> <span class="fu">fst</span> <span class="op">.</span> partitionEithers <span class="op">.</span> <span class="fu">fmap</span> (popVariantMaybe <span class="op">@</span>c)</a>
<a class="sourceLine" id="cb21-5" title="5"></a>
<a class="sourceLine" id="cb21-6" title="6"><span class="op">&gt;</span> removeAll <span class="op">@</span><span class="dt">Triangle</span> shapes</a>
<a class="sourceLine" id="cb21-7" title="7">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}</a>
<a class="sourceLine" id="cb21-8" title="8">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">4.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb21-9" title="9">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">1.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}</a>
<a class="sourceLine" id="cb21-10" title="10">]</a>
<a class="sourceLine" id="cb21-11" title="11"></a>
<a class="sourceLine" id="cb21-12" title="12"><span class="op">&gt;</span> removeAll <span class="op">@</span><span class="dt">Triangle</span> shapes2</a>
<a class="sourceLine" id="cb21-13" title="13">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}</a>
<a class="sourceLine" id="cb21-14" title="14">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">4.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">2.0</span>,<span class="fl">3.0</span>)}</a>
<a class="sourceLine" id="cb21-15" title="15">,<span class="dt">Circle</span> {circleRadius <span class="ot">=</span> <span class="fl">1.0</span>, circleCenter <span class="ot">=</span> (<span class="fl">5.0</span>,<span class="fl">7.0</span>)}</a>
<a class="sourceLine" id="cb21-16" title="16">]</a>
<a class="sourceLine" id="cb21-17" title="17"></a>
<a class="sourceLine" id="cb21-18" title="18"><span class="op">&gt;</span> <span class="op">:</span>t removeAll <span class="op">@</span><span class="dt">Triangle</span> shapes2</a>
<a class="sourceLine" id="cb21-19" title="19">removeAll <span class="op">@</span><span class="dt">Triangle</span><span class="ot"> shapes2 ::</span> [<span class="dt">V</span> '[<span class="dt">Circle</span>, <span class="dt">Square</span>]] <span class="co">-- no more Triangle</span></a>
<a class="sourceLine" id="cb21-20" title="20"></a>
<a class="sourceLine" id="cb21-21" title="21"><span class="op">&gt;</span> removeAll <span class="op">@</span><span class="dt">Circle</span> (removeAll <span class="op">@</span><span class="dt">Triangle</span> shapes2)</a>
<a class="sourceLine" id="cb21-22" title="22">[<span class="dt">Square</span> {squareTopLeft <span class="ot">=</span> (<span class="fl">1.0</span>,<span class="fl">2.0</span>), squareWidth <span class="ot">=</span> <span class="fl">5.0</span>}]</a></code></pre></div>
<p>Now let’s try some pattern-matching:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb22-1" title="1"><span class="ot">matchShapes ::</span> (<span class="dt">Popable</span> <span class="dt">Circle</span> cs</a>
<a class="sourceLine" id="cb22-2" title="2">               ,<span class="dt">Popable</span> <span class="dt">Square</span> cs</a>
<a class="sourceLine" id="cb22-3" title="3">               ,<span class="dt">MaybePopable</span> <span class="dt">Triangle</span> cs</a>
<a class="sourceLine" id="cb22-4" title="4">               ) <span class="ot">=&gt;</span> <span class="dt">V</span> cs <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb22-5" title="5">matchShapes <span class="ot">=</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb22-6" title="6">   <span class="dt">V</span> (<span class="dt">Circle</span> r _)         <span class="ot">-&gt;</span> <span class="st">&quot;circle radius: &quot;</span> <span class="op">++</span> <span class="fu">show</span> r</a>
<a class="sourceLine" id="cb22-7" title="7">   <span class="dt">V</span> (<span class="dt">Square</span> _ w)         <span class="ot">-&gt;</span> <span class="st">&quot;square width: &quot;</span> <span class="op">++</span> <span class="fu">show</span> w</a>
<a class="sourceLine" id="cb22-8" title="8">   <span class="dt">VMaybe</span> (<span class="ot">x ::</span> <span class="dt">Triangle</span>) <span class="ot">-&gt;</span> <span class="st">&quot;triangle: &quot;</span> <span class="op">++</span> <span class="fu">show</span> x</a>
<a class="sourceLine" id="cb22-9" title="9">   _                      <span class="ot">-&gt;</span> <span class="st">&quot;unknown shape&quot;</span></a>
<a class="sourceLine" id="cb22-10" title="10"></a>
<a class="sourceLine" id="cb22-11" title="11"><span class="op">&gt;</span> <span class="fu">fmap</span> matchShapes shapes</a>
<a class="sourceLine" id="cb22-12" title="12">[<span class="st">&quot;square width: 5.0&quot;</span></a>
<a class="sourceLine" id="cb22-13" title="13">,<span class="st">&quot;circle radius: 4.0&quot;</span></a>
<a class="sourceLine" id="cb22-14" title="14">,<span class="st">&quot;circle radius: 1.0&quot;</span></a>
<a class="sourceLine" id="cb22-15" title="15">]</a>
<a class="sourceLine" id="cb22-16" title="16"></a>
<a class="sourceLine" id="cb22-17" title="17"><span class="op">&gt;</span> <span class="fu">fmap</span> matchShapes shapes2</a>
<a class="sourceLine" id="cb22-18" title="18">[<span class="st">&quot;square width: 5.0&quot;</span></a>
<a class="sourceLine" id="cb22-19" title="19">,<span class="st">&quot;circle radius: 4.0&quot;</span></a>
<a class="sourceLine" id="cb22-20" title="20">,<span class="st">&quot;triangle: Triangle&quot;</span></a>
<a class="sourceLine" id="cb22-21" title="21">,<span class="st">&quot;circle radius: 1.0&quot;</span></a>
<a class="sourceLine" id="cb22-22" title="22">]</a></code></pre></div>
<ul>
<li><code>V</code> pattern synonym and <code>Popable</code> constraint are used for types that <strong>must be</strong> storable in the variant.</li>
<li><code>VMaybe</code> pattern synonym and <code>MaybePopable</code> constraint are used for types that <strong>may not be</strong> storable in the variant.</li>
</ul>
<p>Sadly when we use pattern matching on a <code>Variant</code>, the compiler can’t detect if we match all the possible types in the <code>Variant</code>. Hence we need a failover wildcard match to avoid a “non-exhaustive pattern match” warning:</p>
<div class="sourceCode" id="cb23"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb23-1" title="1"><span class="ot">matchShapes' ::</span> <span class="dt">V</span> '[<span class="dt">Circle</span>,<span class="dt">Square</span>] <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb23-2" title="2">matchShapes' <span class="ot">=</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb23-3" title="3">   <span class="dt">V</span> (<span class="dt">Circle</span> r _)         <span class="ot">-&gt;</span> <span class="st">&quot;circle radius: &quot;</span> <span class="op">++</span> <span class="fu">show</span> r</a>
<a class="sourceLine" id="cb23-4" title="4">   <span class="dt">V</span> (<span class="dt">Square</span> _ w)         <span class="ot">-&gt;</span> <span class="st">&quot;square width: &quot;</span> <span class="op">++</span> <span class="fu">show</span> w</a>
<a class="sourceLine" id="cb23-5" title="5">   _                      <span class="ot">-&gt;</span> <span class="st">&quot;unknown shape&quot;</span> <span class="co">-- required useless failover match</span></a></code></pre></div>
<p>Maybe we could circumvent this with a compiler plugin (left as an exercise for the motivated reader).</p>
<h1 id="conclusion">Conclusion</h1>
<p>I hope this introduction to the use of the <code>Haskus.Utils.Variant</code> type has been interesting. You can find it in the <code>haskus-utils</code> package either on <a href="https://github.com/haskus/haskus-utils/blob/master/src/lib/Haskus/Utils/Variant.hs">GitHub</a> or on <a href="https://hackage.haskell.org/package/haskus-utils">Hackage</a>. Feedback is welcome!</p>
<p>There was already a brief description of the use of the <code>Variant</code> data type to handle heterogeneous collections on this blog buried at the end of <a href="http://hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-2.html">this previous post</a> about control-flow. Nevertheless, after reading this <a href="https://medium.com/@concertdaw/existential-crisis-366cf6ee426a">recent post</a> about using existentials, <code>Typeable</code>, <code>Dynamic</code> and the like to manage heterogeneous collections in Haskell, I figured it deserved its own post. It led to a major API update and to a new release of <code>haskus-utils</code> package: I should write posts more often.</p>
<p>The first drafts of this post started with a presentation of the usual approaches to heterogeneous collections (i.e., the state-of-the-art). It was a bit boring and many readers would probably have left without reaching the <code>Variant</code> part, hence the state-of-the-art is now presented in the annexe of this post.</p>
<hr />
<h1 id="annexe-alternatives-and-comparison">Annexe: alternatives and comparison</h1>
<p>The <a href="https://wiki.haskell.org/Heterogenous_collections">wiki</a> lists several solutions to the “heterogeneous collections” problem:</p>
<ul>
<li>Tuples</li>
<li>Algebraic datatypes</li>
<li>Data.Dynamic</li>
<li>Existential types</li>
<li>HLists</li>
</ul>
<p>To which we should add:</p>
<ul>
<li>recursive GADT</li>
<li>Variant</li>
</ul>
<p>Let’s compare them!</p>
<h2 id="tuples">Tuples</h2>
<p>We don’t want a statically fixed length collection, hence we exclude tuples.</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length</td>
<td>NO</td>
</tr>
</tbody>
</table>
<h2 id="algebraic-datatypes">Algebraic datatypes</h2>
<p>The idea is to create a wrapper <code>Shape</code> datatype:</p>
<div class="sourceCode" id="cb24"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb24-1" title="1"><span class="kw">data</span> <span class="dt">Shape</span></a>
<a class="sourceLine" id="cb24-2" title="2">   <span class="ot">=</span> <span class="dt">ShapeCircle</span> <span class="dt">Circle</span></a>
<a class="sourceLine" id="cb24-3" title="3">   <span class="op">|</span> <span class="dt">ShapeSquare</span> <span class="dt">Square</span></a></code></pre></div>
<p>We can write an instance:</p>
<div class="sourceCode" id="cb25"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb25-1" title="1"><span class="kw">instance</span> <span class="dt">Resizable</span> <span class="dt">Shape</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb25-2" title="2">   resize f (<span class="dt">ShapeCircle</span> c) <span class="ot">=</span> <span class="dt">ShapeCircle</span> (resize f c)</a>
<a class="sourceLine" id="cb25-3" title="3">   resize f (<span class="dt">ShapeSquare</span> s) <span class="ot">=</span> <span class="dt">ShapeSquare</span> (resize f s)</a></code></pre></div>
<p>This is not easily extensible: if we want to support a new shape (e.g., a triangle), we have to modify both the <code>Shape</code> datatype and its <code>Resizable</code> instance:</p>
<div class="sourceCode" id="cb26"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb26-1" title="1"><span class="kw">data</span> <span class="dt">Shape</span></a>
<a class="sourceLine" id="cb26-2" title="2">   <span class="ot">=</span> <span class="dt">ShapeCircle</span> <span class="dt">Circle</span></a>
<a class="sourceLine" id="cb26-3" title="3">   <span class="op">|</span> <span class="dt">ShapeSquare</span> <span class="dt">Square</span></a>
<a class="sourceLine" id="cb26-4" title="4">   <span class="op">|</span> <span class="dt">ShapeTriangle</span> <span class="dt">Triangle</span></a>
<a class="sourceLine" id="cb26-5" title="5"></a>
<a class="sourceLine" id="cb26-6" title="6"><span class="kw">instance</span> <span class="dt">Resizable</span> <span class="dt">Shape</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb26-7" title="7">   <span class="op">..</span></a>
<a class="sourceLine" id="cb26-8" title="8">   resize (<span class="dt">ShapeTriangle</span> <span class="op">...</span>) <span class="ot">=</span> <span class="op">...</span></a></code></pre></div>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length</td>
<td>NO</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
</tr>
</tbody>
</table>
<p>Now suppose that for some reason we want to statically ensure that a collection only contains shapes with a central symmetry (e.g., squares and circles but not triangles). The only way is to have different shape types for the different constraints on the shapes:</p>
<div class="sourceCode" id="cb27"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb27-1" title="1"><span class="kw">data</span> <span class="dt">CentralSymShape</span></a>
<a class="sourceLine" id="cb27-2" title="2">   <span class="ot">=</span> <span class="dt">CentralSymCircle</span> <span class="dt">Circle</span></a>
<a class="sourceLine" id="cb27-3" title="3">   <span class="op">|</span> <span class="dt">CentralSymSquare</span> <span class="dt">Square</span></a>
<a class="sourceLine" id="cb27-4" title="4"></a>
<a class="sourceLine" id="cb27-5" title="5"><span class="ot">fooAll ::</span> [<span class="dt">CentralSymShape</span>] <span class="ot">-&gt;</span> [<span class="dt">CentralSymShape</span>]</a></code></pre></div>
<p>But now we can’t resize elements of this collection anymore, so we need:</p>
<div class="sourceCode" id="cb28"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb28-1" title="1"><span class="kw">instance</span> <span class="dt">Resizable</span> <span class="dt">CentralSymShape</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb28-2" title="2">   <span class="op">...</span></a></code></pre></div>
<p>Now adding a new shape is even more cumbersome because we potentially have to modify several datatypes and their instances.</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length</td>
<td>NO</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
</tr>
</tbody>
</table>
<h2 id="existential-types">Existential types</h2>
<p>We can use existential types to embed some type-classes alongside some values. For instance we could rewrite our previous datatype as follows:</p>
<div class="sourceCode" id="cb29"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb29-1" title="1"><span class="kw">data</span> <span class="dt">Shape</span> <span class="ot">=</span> <span class="kw">forall</span> a<span class="op">.</span> <span class="dt">Resizable</span> a <span class="ot">=&gt;</span> <span class="dt">Shape</span> a</a>
<a class="sourceLine" id="cb29-2" title="2"></a>
<a class="sourceLine" id="cb29-3" title="3"><span class="kw">instance</span> <span class="dt">Resizable</span> <span class="dt">Shape</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb29-4" title="4">   resize f (<span class="dt">Shape</span> a) <span class="ot">=</span> <span class="dt">Shape</span> (resize f a)</a></code></pre></div>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
<th>Existentials</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length</td>
<td>NO</td>
<td>-</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
</tr>
</tbody>
</table>
<p>The problem is that we have lost the knowledge of the actual types in the collection: we only know that they are <code>Resizable</code>. For instance we can’t easily write a function extracting the circles:</p>
<div class="sourceCode" id="cb30"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb30-1" title="1"><span class="ot">extractCircles ::</span> [<span class="dt">Shape</span>] <span class="ot">-&gt;</span> [<span class="dt">Circle</span>]</a>
<a class="sourceLine" id="cb30-2" title="2">extractCircles xs <span class="ot">=</span> <span class="op">???</span></a></code></pre></div>
<p>In addition we can’t easily reuse collections. Suppose we also have a type-class <code>Drawable</code>:</p>
<div class="sourceCode" id="cb31"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb31-1" title="1"><span class="kw">class</span> <span class="dt">Drawable</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb31-2" title="2"><span class="ot">   draw ::</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb31-3" title="3"></a>
<a class="sourceLine" id="cb31-4" title="4"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">Circle</span> <span class="kw">where</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb31-5" title="5"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">Square</span> <span class="kw">where</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb31-6" title="6"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">Triangle</span> <span class="kw">where</span> <span class="op">...</span></a></code></pre></div>
<p>We could write a <code>drawAll</code> function by using the same technique:</p>
<div class="sourceCode" id="cb32"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb32-1" title="1"><span class="kw">data</span> <span class="dt">DrawableShape</span> <span class="ot">=</span> <span class="kw">forall</span> a<span class="op">.</span> <span class="dt">Drawable</span> a <span class="ot">=&gt;</span> <span class="dt">DrawableShape</span> a</a>
<a class="sourceLine" id="cb32-2" title="2"></a>
<a class="sourceLine" id="cb32-3" title="3"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">DrawableShape</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb32-4" title="4">   draw (<span class="dt">DrawableShape</span> a) <span class="ot">=</span> draw a</a>
<a class="sourceLine" id="cb32-5" title="5"></a>
<a class="sourceLine" id="cb32-6" title="6"><span class="ot">drawAll ::</span> [<span class="dt">DrawableShape</span>] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb32-7" title="7">drawAll <span class="ot">=</span> traverse_ draw</a></code></pre></div>
<p>Now if we want to resize and then to draw a collection of shapes:</p>
<div class="sourceCode" id="cb33"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb33-1" title="1"><span class="ot">resizeAndDraw ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> [<span class="op">?</span>] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb33-2" title="2">resizeAndDraw f <span class="ot">=</span> drawAll <span class="op">.</span> resizeAll f</a></code></pre></div>
<p>We need to introduce another wrapper datatype with its boilerplate:</p>
<div class="sourceCode" id="cb34"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb34-1" title="1"><span class="kw">data</span> <span class="dt">ResizableDrawableShape</span> <span class="ot">=</span> <span class="kw">forall</span> a<span class="op">.</span> (<span class="dt">Drawable</span> a, <span class="dt">Resizable</span> a) <span class="ot">=&gt;</span> <span class="dt">ResizableDrawableShape</span> a</a>
<a class="sourceLine" id="cb34-2" title="2"></a>
<a class="sourceLine" id="cb34-3" title="3"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">ResizableDrawableShape</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb34-4" title="4">   draw (<span class="dt">ResizableDrawableShape</span> a) <span class="ot">=</span> draw a</a>
<a class="sourceLine" id="cb34-5" title="5"></a>
<a class="sourceLine" id="cb34-6" title="6"><span class="kw">instance</span> <span class="dt">Resizable</span> <span class="dt">ResizableDrawableShape</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb34-7" title="7">   resize f (<span class="dt">ResizableDrawableShape</span> a) <span class="ot">=</span> <span class="dt">ResizableDrawableShape</span> (resize f a)</a>
<a class="sourceLine" id="cb34-8" title="8"></a>
<a class="sourceLine" id="cb34-9" title="9"><span class="ot">resizeAndDraw ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> [<span class="dt">ResizableDrawableShape</span>] <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb34-10" title="10">resizeAndDraw f <span class="ot">=</span> drawAll <span class="op">.</span> resizeAll f</a></code></pre></div>
<p>Hence we want to keep the knowledge of the types of the elements in the collection at runtime instead of using a different wrapper type per collection.</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
<th>Existentials</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length</td>
<td>NO</td>
<td>-</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
</tr>
<tr class="even">
<td>Keep knowledge of element types at runtime</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
</tr>
</tbody>
</table>
<h2 id="data.dynamic">Data.Dynamic</h2>
<p><code>Data.Dynamic</code> can be used to wrap any value. It allows us to rewrite <code>resizeAll</code> as follows:</p>
<div class="sourceCode" id="cb35"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb35-1" title="1"><span class="ot">resizeAll ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> [<span class="dt">Dynamic</span>] <span class="ot">-&gt;</span> [<span class="dt">Dynamic</span>]</a>
<a class="sourceLine" id="cb35-2" title="2">resizeAll f <span class="ot">=</span> <span class="fu">fmap</span> (resizeDyn f)</a>
<a class="sourceLine" id="cb35-3" title="3"></a>
<a class="sourceLine" id="cb35-4" title="4"><span class="ot">resizeDyn ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">Dynamic</span> <span class="ot">-&gt;</span> <span class="dt">Dynamic</span></a>
<a class="sourceLine" id="cb35-5" title="5">resizeDyn f d <span class="ot">=</span></a>
<a class="sourceLine" id="cb35-6" title="6">   <span class="kw">case</span> fromDynamic<span class="ot"> d ::</span> <span class="dt">Maybe</span> <span class="dt">Circle</span> <span class="kw">of</span></a>
<a class="sourceLine" id="cb35-7" title="7">      <span class="dt">Just</span> c  <span class="ot">-&gt;</span> toDyn (resize f c)</a>
<a class="sourceLine" id="cb35-8" title="8">      <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="kw">case</span> fromDynamic<span class="ot"> d ::</span> <span class="dt">Maybe</span> <span class="dt">Square</span> <span class="kw">of</span></a>
<a class="sourceLine" id="cb35-9" title="9">         <span class="dt">Just</span> s  <span class="ot">-&gt;</span> toDyn (resize f s)</a>
<a class="sourceLine" id="cb35-10" title="10">         <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;Invalid shape&quot;</span></a></code></pre></div>
<p>The issue is that any datatype can be wrapped into a <code>Dynamic</code>, hence we lose some type safety. We want to restrict the types of the collection members using some constraints (<code>Resizable</code>, etc.).</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
<th>Existentials</th>
<th>Dynamic</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length</td>
<td>NO</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>NO</td>
</tr>
<tr class="even">
<td>Keep knowledge of element types at runtime</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
</tr>
</tbody>
</table>
<h2 id="hlist">HList</h2>
<p>Instead of wrapping the elements of the collection, we could change the collection type to one that keeps track of the element types <em>at compile time</em>. For instance, HList. However the size of the “list” is fixed at compile time.</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
<th>Existentials</th>
<th>Dynamic</th>
<th>HList</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length at runtime</td>
<td>NO</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>NO</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>NO</td>
<td>NO</td>
</tr>
<tr class="even">
<td>Keep knowledge of element types</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easy to use</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
</tr>
</tbody>
</table>
<h2 id="recursive-gadt">Recursive GADT</h2>
<p>The most basic sum type in Haskell is <code>Either a b</code>. It can be used to wrap a value whose type is either <code>a</code> or <code>b</code>.</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
<th>Existential</th>
<th>Dynamic</th>
<th>HList</th>
<th>Either</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length at runtime</td>
<td>NO</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>NO</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>NO</td>
<td>NO</td>
<td>NO</td>
</tr>
<tr class="even">
<td>Keep knowledge of element types</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easy to use</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
</tr>
<tr class="even">
<td>More than two element types</td>
<td>-</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
</tr>
</tbody>
</table>
<p>We can generalize it with a <a href="https://github.com/int-index/union">GADT</a> such as:</p>
<div class="sourceCode" id="cb36"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb36-1" title="1"><span class="kw">data</span> <span class="dt">Union</span> (<span class="ot">as ::</span> [<span class="op">*</span>]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb36-2" title="2">   <span class="dt">Union</span><span class="ot"> ::</span> <span class="dt">Either</span> (<span class="dt">Union</span> as) a <span class="ot">-&gt;</span> <span class="dt">Union</span> (a '<span class="op">:</span> as)</a>
<a class="sourceLine" id="cb36-3" title="3">   <span class="co">-- other implementations are possible...</span></a></code></pre></div>
<p>To make any union of resizable types resizable, we can write the following instances:</p>
<div class="sourceCode" id="cb37"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb37-1" title="1"><span class="co">-- required boilerplate instance</span></a>
<a class="sourceLine" id="cb37-2" title="2"><span class="kw">instance</span> <span class="dt">Resizable</span> (<span class="dt">Union</span> '[]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-3" title="3">   resize <span class="ot">=</span> <span class="fu">undefined</span></a>
<a class="sourceLine" id="cb37-4" title="4"></a>
<a class="sourceLine" id="cb37-5" title="5"><span class="kw">instance</span> (<span class="dt">Resizable</span> a, <span class="dt">Resizable</span> (<span class="dt">Union</span> as)) <span class="ot">=&gt;</span> <span class="dt">Resizable</span> (<span class="dt">Union</span> (a '<span class="op">:</span> as)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb37-6" title="6">   resize f (<span class="dt">Union</span> (<span class="dt">Right</span> a)) <span class="ot">=</span> <span class="dt">Union</span> (<span class="dt">Right</span> (resize f a))</a>
<a class="sourceLine" id="cb37-7" title="7">   resize f (<span class="dt">Union</span> (<span class="dt">Left</span> u))  <span class="ot">=</span> <span class="dt">Union</span> (<span class="dt">Left</span> (resize f u))</a></code></pre></div>
<p>The issue with this approach is that the actual type of an element is obtained by a linear traversal of the <code>Either</code> constructor nest. Moreover, we need to store this constructor nest for each element.</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
<th>Existential</th>
<th>Dynamic</th>
<th>HList</th>
<th>Either</th>
<th>GADT</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length at runtime</td>
<td>NO</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>NO</td>
<td>-</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>NO</td>
<td>NO</td>
<td>NO</td>
<td>YES</td>
</tr>
<tr class="even">
<td>Keep knowledge of element types</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easy to use</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="even">
<td>More than two element types</td>
<td>-</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Efficient tag storage/obtention</td>
<td>-</td>
<td>YES</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
</tr>
</tbody>
</table>
<h2 id="variant">Variant</h2>
<p>Could we avoid the suboptimal storage of the “tag” used to determine the actual element type with the GADT approach? It turns out we can: we just need to use a number similarly to the way ADT values are internally stored.</p>
<div class="sourceCode" id="cb38"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb38-1" title="1"><span class="kw">data</span> <span class="dt">Variant</span> (<span class="ot">types ::</span> [<span class="op">*</span>]) <span class="ot">=</span> <span class="dt">Variant</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Word</span> <span class="dt">Any</span></a>
<a class="sourceLine" id="cb38-2" title="2"></a>
<a class="sourceLine" id="cb38-3" title="3"><span class="kw">type</span> role <span class="dt">Variant</span> representational</a></code></pre></div>
<p>This is how the <code>Haskus.Utils.Variant</code> type is defined in my <a href="https://github.com/haskus/haskus-utils">haskus-utils</a> package.</p>
<p>Using a list of <code>Variant</code> as our heterogeneous collection, we finally get:</p>
<table>
<thead>
<tr class="header">
<th>Constraint</th>
<th>Tuple</th>
<th>ADT</th>
<th>Existential</th>
<th>Dynamic</th>
<th>HList</th>
<th>Either</th>
<th>GADT</th>
<th>Variant</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Non-fixed length at runtime</td>
<td>NO</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>NO</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
<tr class="even">
<td>Easily data extensible</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easily support constraints on elements</td>
<td>-</td>
<td>NO</td>
<td>YES</td>
<td>NO</td>
<td>NO</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="even">
<td>Keep knowledge of element types</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Easy to use</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="even">
<td>More than two element types</td>
<td>-</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr class="odd">
<td>Efficient tag storage/obtention</td>
<td>-</td>
<td>YES</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>YES</td>
<td>NO</td>
<td>YES</td>
</tr>
</tbody>
</table>
<p>Performance of <code>Variant</code> operations should be close to performance of ADTs with one indirection (i.e., constructors with a single (lifted) field). In a <a href="http://hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-2.html">previous post</a>, we saw that some operations such as <code>rewriteAll</code> in the example above were almost compiled to a direct pattern matching on the variant tag with GHC 8.0.1. <a href="https://ghc.haskell.org/trac/ghc/ticket/12877">My patch</a> should have made this even better in GHC 8.2.1 but sadly it isn’t the case because of <a href="https://ghc.haskell.org/trac/ghc/ticket/14170">#14170</a>… I hope to get it fixed soon.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Reducing GHC's noise: hiding source and object paths</title>
    <link href="http://www.hsyl20.fr/home/posts/2018-01-15-ghc-hiding-source-and-object-paths.html" />
    <id>http://www.hsyl20.fr/home/posts/2018-01-15-ghc-hiding-source-and-object-paths.html</id>
    <published>2018-01-15T00:00:00Z</published>
    <updated>2018-01-15T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Reducing GHC's noise: hiding source and object paths</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a></td>
               <td class="date">January 15, 2018</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>GHC 8.2 includes a new <code>-fhide-source-paths</code> command-line flag that can be used to reduce line noise (disclaimer: I’m the author of the GHC patch introducing it).</p>
<p>To use it, just add the following in your <code>stack.yaml</code> file:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode yaml"><code class="sourceCode yaml"><a class="sourceLine" id="cb1-1" title="1"><span class="fu">ghc-options:</span></a>
<a class="sourceLine" id="cb1-2" title="2">   <span class="fu">&quot;$locals&quot;:</span><span class="at"> -fhide-source-paths</span></a></code></pre></div>
<p>Here is an example with one project of mine (first without the flag, second with the flag):</p>
<p><img src="http://www.hsyl20.fr/home../images/2018_hidesourcepath/without.png" /></p>
<p><img src="http://www.hsyl20.fr/home../images/2018_hidesourcepath/with.png" /></p>
<p>If you wonder why it isn’t enabled by default or where the flag name comes from, read the related tickets (<a href="https://ghc.haskell.org/trac/ghc/ticket/12807">#12807</a> and <a href="https://ghc.haskell.org/trac/ghc/ticket/12851">#12851</a>) and the discussion on Phabricator (<a href="https://phabricator.haskell.org/D2679">Phab:D2679</a>, <a href="https://phabricator.haskell.org/D2728">Phab:D2728</a>).</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Announcing haskus-system 0.7</title>
    <link href="http://www.hsyl20.fr/home/posts/2017-06-29-announcing-haskussystem-07.html" />
    <id>http://www.hsyl20.fr/home/posts/2017-06-29-announcing-haskussystem-07.html</id>
    <published>2017-06-29T00:00:00Z</published>
    <updated>2017-06-29T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Announcing haskus-system 0.7</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/haskus-system.html">haskus-system</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">June 29, 2017</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <h1 id="what-is-haskus-system">What is haskus-system?</h1>
<p><a href="https://github.com/haskus/haskus-system">haskus-system</a> is a Haskell library for system programming on top of the Linux kernel. You can use it to build systems that only use:</p>
<ul>
<li>the Linux kernel</li>
<li>the haskus-system library</li>
<li>your code</li>
</ul>
<p>You can think of <code>haskus-system</code> as an Android-like software but in Haskell (and currently very far from being on par with Android) or as a haskus-system/Linux (similarly with GNU/Linux, but very far from being on par with GNU).</p>
<p>[For those who have been following the previous releases, it was initially called ViperVM (for the pun “Very High Performance Virtual Machine”) but this name was already used elsewhere and it was misleading (it’s not a VM).]</p>
<h1 id="whats-new-in-0.7">What’s new in 0.7?</h1>
<p><strong>Build tool</strong></p>
<p>Previous releases were hard to use (I’m not sure anyone has actually tried it) because you needed to manually install and configure Linux, SysLinux, etc. This release features a new tool ingeniously called <code>haskus-system-build</code> which performs almost all of this automatically.</p>
<p>Start by installing the tool:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb1-1" title="1"><span class="op">&gt;</span> <span class="fu">git</span> clone https://github.com/haskus/haskus-system-build.git</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="op">&gt;</span> <span class="bu">cd</span> haskus-system-build</a>
<a class="sourceLine" id="cb1-3" title="3"><span class="op">&gt;</span> <span class="ex">stack</span> install --install-ghc</a></code></pre></div>
<p>It will install the program into ~/.local/bin. Be sure to add this path to your $PATH environment variable.</p>
<p>Now to get started you just have to do:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb2-1" title="1"><span class="op">&gt;</span> <span class="fu">mkdir</span> my-project</a>
<a class="sourceLine" id="cb2-2" title="2"><span class="op">&gt;</span> <span class="bu">cd</span> my-project</a>
<a class="sourceLine" id="cb2-3" title="3"><span class="op">&gt;</span> <span class="ex">haskus-system-build</span> init</a>
<a class="sourceLine" id="cb2-4" title="4"><span class="op">&gt;</span> <span class="ex">haskus-system-build</span> test</a></code></pre></div>
<p>and it should:</p>
<ul>
<li>download the default template</li>
<li>download, configure and build Linux, SysLinux, libgmp, etc.</li>
<li>build the example from the template (creating a ramdisk)</li>
<li>start the system into QEMU</li>
</ul>
<p>The tool doesn’t detect missing programs yet (lzip, cpio, qemu, etc.) so it may fail if they aren’t installed. Please refer to <a href="http://doc.haskus.org/manual/system/volume1/automatic_building.html">the documentation</a> to know which ones are required.</p>
<p><strong>Documentation</strong></p>
<p>Speaking about the documentation, I have improved it and you can know find it here:</p>
<ul>
<li><a href="http://doc.haskus.org/manual/">http://doc.haskus.org/manual/</a></li>
</ul>
<p>Note that the programming guide (volume 2) is still a work in progress. You may think “great, we don’t know how to write systems but a least we can build them…”. I’m working on it (see below for contributing) but in the meantime you may want to look at how <a href="https://github.com/haskus/haskus-system-examples/">some examples work</a> and at the <a href="http://doc.haskus.org/haddock/haskus-system/latest/">Haddock documentation</a>.</p>
<p><strong>Examples</strong></p>
<p>Examples are now in a distinct repository (<a href="https://github.com/haskus/haskus-system-examples/">https://github.com/haskus/haskus-system-examples/</a>) and now they can be built easily with the build tool. For instance, to test the Clock example:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><a class="sourceLine" id="cb3-1" title="1"><span class="ex">haskus-system-build</span> test --init Clock</a></code></pre></div>
<p>Screenshot of the Clock example in QEMU:</p>
<p><img src="http://www.hsyl20.fr/home/images/2017_announcehs07/clock.png" alt="image" /></p>
<p>Screenshot of the Demo example in QEMU:</p>
<p><img src="http://www.hsyl20.fr/home/images/2017_announcehs07/demo.png" alt="image" /></p>
<p>Both examples use Diagrams to perform the rendering with the Rasterific backend. Then haskus-system uses Linux’s DRM interface to show the diagram on the screen.</p>
<p>This is a screencast of the terminal demo I’m working on:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Dg9KyMk2n5E" frameborder="0" allowfullscreen></iframe>
<p><strong>Other changes</strong></p>
<p><a href="https://github.com/haskus/haskus-system/commit/ec16751d3a490d12d034f6ce5b9d25d059124f95#diff-8b1c3fd0d4a6765c16dfd18509182f9d">Full changelog</a></p>
<h1 id="contributing">Contributing</h1>
<p>If you want to contribute to this project, don’t hesitate to:</p>
<ul>
<li><p><a href="https://www.tipeee.com/vipervm">subscribe on Tipeee</a></p>
<p>I would like to thank the first subscriber again (that I didn’t know beforehand) who has been supporting this project for a few months already. Thank you!</p></li>
<li>submit issues or pull requests on <a href="https://github.com/haskus/haskus-system">GitHub</a></li>
</ul>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Control Flow in Haskell (3) - Flow with Variant</title>
    <link href="http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-3.html" />
    <id>http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-3.html</id>
    <published>2016-12-12T00:00:00Z</published>
    <updated>2016-12-12T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Control Flow in Haskell (3) - Flow with Variant</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Control%20Flow.html">Control Flow</a>, <a href="http://www.hsyl20.fr/home/tags/Variant.html">Variant</a></td>
               <td class="date">December 12, 2016</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This post is part of a <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-0.html">series</a>.</p>
<h3 id="control-flow-with-variant">Control flow with Variant</h3>
<p>We can use the <code>Variant</code> data type <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-2.html">described in the previous part</a> to help with control flow. Basically we can write functions that return a <code>Variant</code> to indicate their different possible output types. To make the code easier to read (fewer brackets), we use the following type alias:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">type</span> <span class="dt">Flow</span> m l <span class="ot">=</span> m (<span class="dt">Variant</span> l)</a></code></pre></div>
<p>Here is our previous example from <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-1.html">part 1</a> rewritten to use <code>Flow</code>:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="kw">data</span> <span class="dt">XY</span>   <span class="ot">=</span> <span class="dt">XY</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="kw">data</span> <span class="dt">UV</span>   <span class="ot">=</span> <span class="dt">UV</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-3" title="3"><span class="kw">data</span> <span class="dt">ErrA</span> <span class="ot">=</span> <span class="dt">ErrA</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-4" title="4"><span class="kw">data</span> <span class="dt">ErrB</span> <span class="ot">=</span> <span class="dt">ErrB</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-5" title="5"><span class="kw">data</span> <span class="dt">ErrC</span> <span class="ot">=</span> <span class="dt">ErrC</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-6" title="6"><span class="kw">data</span> <span class="dt">ErrD</span> <span class="ot">=</span> <span class="dt">ErrD</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-7" title="7"><span class="kw">data</span> <span class="dt">ErrE</span> <span class="ot">=</span> <span class="dt">ErrE</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-8" title="8"></a>
<a class="sourceLine" id="cb2-9" title="9"><span class="ot">doXY ::</span> <span class="dt">Flow</span> <span class="dt">IO</span> '[<span class="dt">XY</span>,<span class="dt">ErrA</span>,<span class="dt">ErrB</span>,<span class="dt">ErrC</span>]</a>
<a class="sourceLine" id="cb2-10" title="10">doXY <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-11" title="11"></a>
<a class="sourceLine" id="cb2-12" title="12"><span class="ot">doUV ::</span> <span class="dt">XY</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> <span class="dt">IO</span> '[<span class="dt">UV</span>,<span class="dt">ErrA</span>,<span class="dt">ErrD</span>,<span class="dt">ErrE</span>]</a>
<a class="sourceLine" id="cb2-13" title="13">doUV <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-14" title="14"></a>
<a class="sourceLine" id="cb2-15" title="15"><span class="ot">doXYUV ::</span> <span class="dt">Flow</span> <span class="dt">IO</span> '[<span class="dt">UV</span>,<span class="dt">ErrA</span>,<span class="dt">ErrB</span>,<span class="dt">ErrC</span>,<span class="dt">ErrD</span>,<span class="dt">ErrE</span>]</a>
<a class="sourceLine" id="cb2-16" title="16">doXYUV <span class="ot">=</span> doXY <span class="op">&gt;.~^^&gt;</span> doUV</a></code></pre></div>
<p>Notice how the same error types (such as <code>ErrA</code>) can be returned by different functions without being wrapped with different constructors each time.</p>
<p>Another thing to notice is that all the return types are at the same level: there is no difference between “success” types and “error” types. Compared to using <code>Either Errors UV</code>, we avoid the indirection caused by the <code>Errors</code> sum type.</p>
<p>Similarly to <code>Either</code>, however, we can have a convention about the most expected returned type. With <code>Either a b</code> we most expect the type associated to the <code>Right</code> constructor (i.e., <code>b</code>); with <code>Variant (x ': xs)</code> we most expect the first type in the list (i.e., <code>x</code>). This is useful to define composition operators on variants such as <code>&gt;.~^^&gt;</code> in the code above (operators are presented in the next section).</p>
<h3 id="flow-operators">Flow operators</h3>
<p>There are many ways to compose flows. Say we have the following function:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="ot">f ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a></code></pre></div>
<p>There are many potential <code>g</code> functions that we would like to compose with <code>f</code> to get the <code>h</code> functions.</p>
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/operators.png" /></p>
<p><em>(It’s the first time I use a graphics tablet: it is much faster to draw things but I’m not very good at it)</em></p>
<p>Moreover, we need to make the types unambiguous without having to add type annotations everywhere, especially for intermediate values. So we have different operators with different type dependencies: <code>f -&gt; g h</code>, <code>f g -&gt; h</code>, <code>h f -&gt; g</code>, etc.</p>
<h3 id="returning-a-value">Returning a value</h3>
<p>Let’s start with the value returning “operators”:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="co">-- return a value by index</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="ot">f ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb4-3" title="3">f <span class="ot">=</span> <span class="op">...</span> flowSetN <span class="op">@</span><span class="dv">2</span> a</a>
<a class="sourceLine" id="cb4-4" title="4"></a>
<a class="sourceLine" id="cb4-5" title="5"><span class="co">-- return a value by type (first matching type)</span></a>
<a class="sourceLine" id="cb4-6" title="6"><span class="ot">f ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb4-7" title="7">f <span class="ot">=</span> <span class="op">...</span> flowSet b</a>
<a class="sourceLine" id="cb4-8" title="8"></a>
<a class="sourceLine" id="cb4-9" title="9"><span class="co">-- return a single value, the type list can be inferred from the type of 'x'</span></a>
<a class="sourceLine" id="cb4-10" title="10"><span class="co">-- u :: Monad m =&gt; Flow m '[X]</span></a>
<a class="sourceLine" id="cb4-11" title="11">u <span class="ot">=</span> <span class="op">...</span> flowSingle x</a></code></pre></div>
<h3 id="first-output-biased-operators">First output biased operators</h3>
<p>We have said that by convention the first output type in the type list is the most expected one (equivalent to the <code>Right</code> constructor for <code>Either</code>). So we have a bunch of operators biased for this case.</p>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow1.png" /></p>
<p>First, the equivalent of <code>fmap</code> for Flows (<code>g</code> is pure):</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="ot">g ::</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">R</span></a>
<a class="sourceLine" id="cb5-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb5-3" title="3"></a>
<a class="sourceLine" id="cb5-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">R</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb5-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.-.&gt;</span> g</a></code></pre></div>
<p>The equivalent of <code>forM</code>/<code>traverse</code> for Flows (<code>g</code> is monadic in the same Monad as f):</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> m <span class="dt">R</span></a>
<a class="sourceLine" id="cb6-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb6-3" title="3"></a>
<a class="sourceLine" id="cb6-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">R</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb6-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~.&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow2.png" /></p>
<p>When <code>g</code> has several output types and output types are concatenated:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">Y</span>,<span class="dt">Z</span>]</a>
<a class="sourceLine" id="cb7-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb7-3" title="3"></a>
<a class="sourceLine" id="cb7-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">Y</span>,<span class="dt">Z</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb7-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~+&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow3.png" /></p>
<p>When <code>g</code> has several output types, <code>f</code> and <code>g</code> determine the output types of <code>h</code> (by union):</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">Y</span>]</a>
<a class="sourceLine" id="cb8-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb8-3" title="3"></a>
<a class="sourceLine" id="cb8-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">Y</span>,<span class="dt">B</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb8-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~|&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow4.png" /></p>
<p>When <code>g</code> has several output types (the same as <code>f</code> except for the first one):</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb9-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb9-3" title="3"></a>
<a class="sourceLine" id="cb9-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb9-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~$&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow5.png" /></p>
<p>When <code>g</code> has several output types, <code>g</code> determines the output types of <code>h</code>:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">E</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb10-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb10-3" title="3"></a>
<a class="sourceLine" id="cb10-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">E</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb10-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~^&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow6.png" /></p>
<p>When <code>g</code> has several output types, <code>h</code> determines its own output types:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">Y</span>,<span class="dt">Z</span>]</a>
<a class="sourceLine" id="cb11-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb11-3" title="3"></a>
<a class="sourceLine" id="cb11-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">X</span>,<span class="dt">A</span>,<span class="dt">Y</span>,<span class="dt">C</span>,<span class="dt">W</span>,<span class="dt">D</span>,<span class="dt">Z</span>,<span class="dt">B</span>]</a>
<a class="sourceLine" id="cb11-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~^^&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow7.png" /></p>
<p>When <code>g</code> only performs some effects:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> m ()</a>
<a class="sourceLine" id="cb12-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb12-3" title="3"></a>
<a class="sourceLine" id="cb12-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb12-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~=&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow8.png" /></p>
<p>When <code>g</code> only performs some effects: this one is a little bit more suspicious (hence the <code>!</code>) because some output paths are not explicitly handled:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb13-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> m ()</a>
<a class="sourceLine" id="cb13-2" title="2">g <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb13-3" title="3"></a>
<a class="sourceLine" id="cb13-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> m ()</a>
<a class="sourceLine" id="cb13-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~!&gt;</span> g</a></code></pre></div>
<hr />
<p><img src="http://www.hsyl20.fr/home../images/2016_controlflow/flow9.png" /></p>
<p>When <code>g</code> only performs some effects: this case is even more dangerous because you assert that the first output path mustn’t be followed. <code>g</code> mustn’t return (i.e., it should call <code>error</code> for instance).</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb14-1" title="1"><span class="ot">g ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">A</span> <span class="ot">-&gt;</span> m ()</a>
<a class="sourceLine" id="cb14-2" title="2">g <span class="ot">=</span> <span class="op">...</span> <span class="co">-- error &quot;...&quot;</span></a>
<a class="sourceLine" id="cb14-3" title="3"></a>
<a class="sourceLine" id="cb14-4" title="4"><span class="ot">h ::</span> <span class="dt">Monad</span> m <span class="ot">=&gt;</span> <span class="dt">Flow</span> m '[<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb14-5" title="5">h <span class="ot">=</span> f <span class="op">&gt;.~!!&gt;</span> g</a></code></pre></div>
<h3 id="other-operators">Other operators</h3>
<p>The operators presented in the previous sections are biased towards the first output but we also have other operators for other cases! To avoid having to learn each operator, here is the logic I have followed to build them. Operators are decomposed in three parts:</p>
<ul>
<li>what we select in the Variant:
<ul>
<li><code>.</code> the head</li>
<li><code>..</code> the tail</li>
<li><code>%</code> a mandatory type</li>
<li><code>?</code> an optional type</li>
<li><code>..%</code> a mandatory type in the tail</li>
<li><code>..?</code> an optional type in the tail</li>
</ul></li>
<li>what kind of function we apply to it:
<ul>
<li><code>-</code> pure function</li>
<li><code>~</code> monadic function</li>
<li><code>~~</code> constant monadic function (doesn’t use its parameter)</li>
</ul></li>
<li>how we combine the result <code>p</code> with the remaining part <code>q</code> to get the result <code>r</code>:
<ul>
<li><code>+</code> r = concatenate p and q</li>
<li><code>.</code> set the head of the result (p isn’t a Variant in this case)</li>
<li><code>|</code> r = union of p and q</li>
<li><code>^</code> lift q into p, r = p</li>
<li><code>^^</code> lift p and q into r</li>
<li><code>$</code> tail r = tail p = tail q</li>
<li><code>=</code> perform an effet and passthrough the Variant</li>
<li><code>!</code> perform an effect and return <code>()</code></li>
<li><code>!!</code> perform a bottom effect or return q</li>
</ul></li>
</ul>
<p>By combining these three parts, we have operators such as: <code>&gt;..~.&gt;</code>, <code>&gt;..~^&gt;</code>, <code>&gt;..~!!&gt;</code>, <code>&gt;%~.&gt;</code>, <code>&gt;%~^&gt;</code>, <code>&gt;%~!!&gt;</code> <code>&gt;..%~.&gt;</code>, <code>&gt;..%~^&gt;</code>, <code>&gt;..%~!!&gt;</code>, <code>&gt;?~!&gt;</code>, <code>&gt;..?~!!</code>, etc. The full list is in the <a href="https://github.com/hsyl20/haskus-system/blob/master/src/lib/Haskus/Utils/Flow.hs">Flow module</a> in my haskus-system package.</p>
<p>Note that in some cases, the combination of the parts doesn’t make sense. Also in some cases I have replaced <code>Flow m '[x]</code> with <code>m x</code> as it is easier to work with.</p>
<h3 id="examples">Examples</h3>
<p>Consider the following example where we have a function <code>f</code> that may return either an <code>A</code>, a <code>B</code> or a <code>C</code>.</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb15-1" title="1"><span class="ot">{-# LANGUAGE ScopedTypeVariables #-}</span></a>
<a class="sourceLine" id="cb15-2" title="2"><span class="ot">{-# LANGUAGE DataKinds #-}</span></a>
<a class="sourceLine" id="cb15-3" title="3"></a>
<a class="sourceLine" id="cb15-4" title="4"><span class="kw">import</span> <span class="dt">Haskus.Utils.Flow</span></a>
<a class="sourceLine" id="cb15-5" title="5"></a>
<a class="sourceLine" id="cb15-6" title="6"><span class="kw">data</span> <span class="dt">A</span> <span class="ot">=</span> <span class="dt">A</span></a>
<a class="sourceLine" id="cb15-7" title="7"><span class="kw">data</span> <span class="dt">B</span> <span class="ot">=</span> <span class="dt">B</span></a>
<a class="sourceLine" id="cb15-8" title="8"><span class="kw">data</span> <span class="dt">C</span> <span class="ot">=</span> <span class="dt">C</span></a>
<a class="sourceLine" id="cb15-9" title="9"><span class="kw">data</span> <span class="dt">D</span> <span class="ot">=</span> <span class="dt">D</span></a>
<a class="sourceLine" id="cb15-10" title="10"></a>
<a class="sourceLine" id="cb15-11" title="11"><span class="ot">f ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Flow</span> <span class="dt">IO</span> '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">C</span>]</a>
<a class="sourceLine" id="cb15-12" title="12">f x <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb15-13" title="13">   <span class="fu">putStrLn</span> (<span class="st">&quot;f &quot;</span> <span class="op">++</span> <span class="fu">show</span> x)</a>
<a class="sourceLine" id="cb15-14" title="14">   <span class="kw">case</span> x <span class="kw">of</span></a>
<a class="sourceLine" id="cb15-15" title="15">      <span class="dv">0</span> <span class="ot">-&gt;</span> flowSet <span class="dt">A</span></a>
<a class="sourceLine" id="cb15-16" title="16">      <span class="dv">1</span> <span class="ot">-&gt;</span> flowSet <span class="dt">B</span></a>
<a class="sourceLine" id="cb15-17" title="17">      _ <span class="ot">-&gt;</span> flowSet <span class="dt">C</span></a></code></pre></div>
<p>Now, if we want to do something if a <code>C</code> is returned, we can use the <code>&gt;%~!&gt;</code> operator as follows.</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb16-1" title="1"><span class="ot">test ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb16-2" title="2">test <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb16-3" title="3">   f <span class="dv">0</span> <span class="op">&gt;%~!&gt;</span> \(<span class="ot">_ ::</span> <span class="dt">C</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;  -&gt; C returned!&quot;</span> <span class="co">-- &quot;&quot;</span></a>
<a class="sourceLine" id="cb16-4" title="4">   f <span class="dv">1</span> <span class="op">&gt;%~!&gt;</span> \(<span class="ot">_ ::</span> <span class="dt">C</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;  -&gt; C returned!&quot;</span> <span class="co">-- &quot;&quot;</span></a>
<a class="sourceLine" id="cb16-5" title="5">   f <span class="dv">2</span> <span class="op">&gt;%~!&gt;</span> \(<span class="ot">_ ::</span> <span class="dt">C</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;  -&gt; C returned!&quot;</span> <span class="co">-- &quot;  -&gt; C returned!&quot;</span></a></code></pre></div>
<p>Now suppose that we want to do something if a <code>D</code> is returned:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb17-1" title="1">   f <span class="dv">2</span> <span class="op">&gt;%~!&gt;</span> \(<span class="ot">d ::</span> <span class="dt">D</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;  -&gt; D returned!&quot;</span></a></code></pre></div>
<p>Oops, we get the following error:</p>
<pre><code>scripts/Flow.hs:27:4: error:
    • `D' is not a member of '[A, B, C]
    • In a stmt of a 'do' block:
        f 2 &gt;%~!&gt; \ (d :: D) -&gt; putStrLn &quot;  -&gt; D returned!&quot;</code></pre>
<p>Indeed <code>f</code> never returns a <code>D</code> and the compiler checks that.</p>
<p>Note that it is possible to write generic functions that take as parameters functions that may or may not return some types. For instance by using the <code>&gt;?~!!&gt;</code> operator as the <code>handleD</code> function does in the following code:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb19-1" title="1"><span class="ot">{-# LANGUAGE FlexibleContexts #-}</span></a>
<a class="sourceLine" id="cb19-2" title="2"><span class="ot">{-# LANGUAGE TypeFamilies #-}</span></a>
<a class="sourceLine" id="cb19-3" title="3"></a>
<a class="sourceLine" id="cb19-4" title="4"><span class="kw">import</span> <span class="dt">Haskus.Utils.Types.List</span></a>
<a class="sourceLine" id="cb19-5" title="5"></a>
<a class="sourceLine" id="cb19-6" title="6"><span class="ot">handleD ::</span> <span class="dt">MaybeCatchable</span> <span class="dt">D</span> xs <span class="ot">=&gt;</span> <span class="dt">Flow</span> <span class="dt">IO</span> xs <span class="ot">-&gt;</span> <span class="dt">Flow</span> <span class="dt">IO</span> (<span class="dt">Filter</span> <span class="dt">D</span> xs)</a>
<a class="sourceLine" id="cb19-7" title="7">handleD u <span class="ot">=</span> u <span class="op">&gt;?~!!&gt;</span> \(<span class="ot">_ ::</span> <span class="dt">D</span>) <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;D returned!&quot;</span></a>
<a class="sourceLine" id="cb19-8" title="8"></a>
<a class="sourceLine" id="cb19-9" title="9"><span class="ot">test ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb19-10" title="10">test <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb19-11" title="11">   r <span class="ot">&lt;-</span> handleD (f <span class="dv">2</span>) <span class="co">-- handleD does nothing, f can't return a D (r :: Variant '[A,B,C])</span></a>
<a class="sourceLine" id="cb19-12" title="12">   _ <span class="ot">&lt;-</span> handleD g     <span class="co">-- handleD fails because 'g' returns a D</span></a>
<a class="sourceLine" id="cb19-13" title="13">   b <span class="ot">&lt;-</span> handleD h     <span class="co">-- handleD filters the possible output type D (b :: Variant '[B])</span></a>
<a class="sourceLine" id="cb19-14" title="14"></a>
<a class="sourceLine" id="cb19-15" title="15"><span class="ot">g ::</span> <span class="dt">Flow</span> <span class="dt">IO</span> '[<span class="dt">B</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb19-16" title="16">g <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb19-17" title="17">   <span class="fu">putStrLn</span> <span class="st">&quot;g&quot;</span></a>
<a class="sourceLine" id="cb19-18" title="18">   flowSet <span class="dt">D</span></a>
<a class="sourceLine" id="cb19-19" title="19"></a>
<a class="sourceLine" id="cb19-20" title="20"><span class="ot">h ::</span> <span class="dt">Flow</span> <span class="dt">IO</span> '[<span class="dt">B</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb19-21" title="21">h <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb19-22" title="22">   <span class="fu">putStrLn</span> <span class="st">&quot;h&quot;</span></a>
<a class="sourceLine" id="cb19-23" title="23">   flowSet <span class="dt">B</span></a></code></pre></div>
<h3 id="pattern-matching-and-flows">Pattern-matching and Flows</h3>
<p>Sometimes we would like to use pattern matching instead of using a sequence of fish operators like the following one:</p>
<div class="sourceCode" id="cb20"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb20-1" title="1">test <span class="ot">=</span> f <span class="dv">5</span> <span class="op">&gt;%~=&gt;</span> (\(<span class="ot">a ::</span> <span class="dt">A</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;An A has been returned&quot;</span>)</a>
<a class="sourceLine" id="cb20-2" title="2">           <span class="op">&gt;%~=&gt;</span> (\(<span class="ot">b ::</span> <span class="dt">B</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;A B has been returned&quot;</span>)</a>
<a class="sourceLine" id="cb20-3" title="3">           <span class="op">&gt;%~=&gt;</span> (\(<span class="ot">c ::</span> <span class="dt">C</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;A C has been returned&quot;</span>)</a></code></pre></div>
<p>We can do something similar with <code>flowToCont</code> and the <code>&gt;::&gt;</code> operator. In this case the continuations are matched by position in the tuple:</p>
<div class="sourceCode" id="cb21"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb21-1" title="1"><span class="ot">test ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb21-2" title="2">test <span class="ot">=</span> flowToCont (f <span class="dv">5</span>) <span class="op">&gt;::&gt;</span></a>
<a class="sourceLine" id="cb21-3" title="3">   ( \a <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;An A has been returned&quot;</span></a>
<a class="sourceLine" id="cb21-4" title="4">   , \b <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;A B has been returned&quot;</span></a>
<a class="sourceLine" id="cb21-5" title="5">   , \c <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;A C has been returned&quot;</span></a>
<a class="sourceLine" id="cb21-6" title="6">   )</a></code></pre></div>
<p>We can also match them by type if there is no ambiguity with the <code>&gt;:%:&gt;</code> operator:</p>
<div class="sourceCode" id="cb22"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb22-1" title="1"><span class="ot">test ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb22-2" title="2">test <span class="ot">=</span> flowToCont (f <span class="dv">5</span>) <span class="op">&gt;:%:&gt;</span></a>
<a class="sourceLine" id="cb22-3" title="3">   ( \(<span class="ot">a ::</span> <span class="dt">A</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;An A has been returned&quot;</span></a>
<a class="sourceLine" id="cb22-4" title="4">   , \(<span class="ot">c ::</span> <span class="dt">C</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;A C has been returned&quot;</span> <span class="co">-- notice that C comes before B</span></a>
<a class="sourceLine" id="cb22-5" title="5">   , \(<span class="ot">b ::</span> <span class="dt">B</span>) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> <span class="st">&quot;A B has been returned&quot;</span> <span class="co">-- but it still works</span></a>
<a class="sourceLine" id="cb22-6" title="6">   )</a></code></pre></div>
<p>Continuations like this will be the topic of a planned next part. <!--- the [next part](2016-12-12-control-flow-in-haskell-part-4.html). --></p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Control Flow in Haskell (2) - Variant</title>
    <link href="http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-2.html" />
    <id>http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-2.html</id>
    <published>2016-12-12T00:00:00Z</published>
    <updated>2016-12-12T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Control Flow in Haskell (2) - Variant</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Variant.html">Variant</a></td>
               <td class="date">December 12, 2016</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This post is part of a <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-0.html">series</a>.</p>
<h3 id="open-sum-type">Open sum type</h3>
<p>With some type-level hackery, we can define an open sum type in GHC which has the same internal representation as other sum types such as <code>Either</code>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">data</span> <span class="dt">Variant</span> (<span class="ot">types ::</span> [<span class="op">*</span>]) <span class="ot">=</span> <span class="dt">Variant</span> <span class="ot">{-# UNPACK #-}</span> <span class="op">!</span><span class="dt">Word</span> <span class="dt">Any</span></a>
<a class="sourceLine" id="cb1-2" title="2"></a>
<a class="sourceLine" id="cb1-3" title="3"><span class="kw">type</span> role <span class="dt">Variant</span> representational</a></code></pre></div>
<p>The Word value is a tag (similar to a constructor tag) that indicates the actual type of the <code>Any</code> value by indexing into the <code>types</code> list. Given a type-level index <code>n</code>, we can get or set the value with the appropriate type:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="co">-- | Set the value with the given indexed type</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="ot">setVariantN ::</span> <span class="kw">forall</span> (<span class="ot">n ::</span> <span class="dt">Nat</span>) (<span class="ot">l ::</span> [<span class="op">*</span>])<span class="op">.</span>  <span class="dt">KnownNat</span> n <span class="ot">=&gt;</span> <span class="dt">Index</span> n l <span class="ot">-&gt;</span> <span class="dt">Variant</span> l</a>
<a class="sourceLine" id="cb2-3" title="3">setVariantN a <span class="ot">=</span> <span class="dt">Variant</span> (natValue <span class="op">@</span>n) (unsafeCoerce a)</a>
<a class="sourceLine" id="cb2-4" title="4"></a>
<a class="sourceLine" id="cb2-5" title="5"><span class="co">-- | Get the value if it has the indexed type</span></a>
<a class="sourceLine" id="cb2-6" title="6"><span class="ot">getVariantN ::</span> <span class="kw">forall</span> (<span class="ot">n ::</span> <span class="dt">Nat</span>) (<span class="ot">l ::</span> [<span class="op">*</span>])<span class="op">.</span> <span class="dt">KnownNat</span> n <span class="ot">=&gt;</span> <span class="dt">Variant</span> l <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">Index</span> n l)</a>
<a class="sourceLine" id="cb2-7" title="7">getVariantN (<span class="dt">Variant</span> t a) <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb2-8" title="8">   guard (t <span class="op">==</span> natValue <span class="op">@</span>n)</a>
<a class="sourceLine" id="cb2-9" title="9">   <span class="fu">return</span> (unsafeCoerce a)</a></code></pre></div>
<p>It means that where we would have written:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">data</span> <span class="dt">A</span> <span class="ot">=</span> <span class="dt">A</span></a>
<a class="sourceLine" id="cb3-2" title="2"><span class="kw">data</span> <span class="dt">B</span> <span class="ot">=</span> <span class="dt">B</span></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="kw">data</span> <span class="dt">C</span> <span class="ot">=</span> <span class="dt">C</span></a>
<a class="sourceLine" id="cb3-4" title="4"><span class="kw">data</span> <span class="dt">Error</span> <span class="ot">=</span> <span class="dt">ErrA</span> <span class="dt">A</span> <span class="op">|</span> <span class="dt">ErrB</span> <span class="dt">B</span> <span class="op">|</span> <span class="dt">ErrC</span> <span class="dt">C</span></a>
<a class="sourceLine" id="cb3-5" title="5"></a>
<a class="sourceLine" id="cb3-6" title="6"><span class="ot">err ::</span> <span class="dt">Error</span></a>
<a class="sourceLine" id="cb3-7" title="7">err <span class="ot">=</span> <span class="dt">ErrB</span> <span class="dt">B</span></a>
<a class="sourceLine" id="cb3-8" title="8"></a>
<a class="sourceLine" id="cb3-9" title="9">main <span class="ot">=</span> <span class="kw">case</span> err <span class="kw">of</span></a>
<a class="sourceLine" id="cb3-10" title="10">   <span class="dt">ErrC</span> c <span class="ot">-&gt;</span> doSomething c</a>
<a class="sourceLine" id="cb3-11" title="11">   _      <span class="ot">-&gt;</span> doSomethingElse</a>
<a class="sourceLine" id="cb3-12" title="12"></a>
<a class="sourceLine" id="cb3-13" title="13"><span class="ot">doSomething ::</span> <span class="dt">C</span> <span class="ot">-&gt;</span> <span class="op">...</span></a></code></pre></div>
<p>we can now write:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="kw">data</span> <span class="dt">A</span> <span class="ot">=</span> <span class="dt">A</span></a>
<a class="sourceLine" id="cb4-2" title="2"><span class="kw">data</span> <span class="dt">B</span> <span class="ot">=</span> <span class="dt">B</span></a>
<a class="sourceLine" id="cb4-3" title="3"><span class="kw">data</span> <span class="dt">C</span> <span class="ot">=</span> <span class="dt">C</span></a>
<a class="sourceLine" id="cb4-4" title="4"></a>
<a class="sourceLine" id="cb4-5" title="5"><span class="ot">err ::</span> <span class="dt">Variant</span> '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">C</span>]</a>
<a class="sourceLine" id="cb4-6" title="6">err <span class="ot">=</span> setVariantN <span class="op">@</span><span class="dv">1</span> <span class="dt">B</span>            <span class="co">-- or better (see below): err = setVariant B</span></a>
<a class="sourceLine" id="cb4-7" title="7"></a>
<a class="sourceLine" id="cb4-8" title="8">main <span class="ot">=</span> <span class="kw">case</span> getVariantN <span class="op">@</span><span class="dv">2</span> err <span class="kw">of</span> <span class="co">-- or better: getVariant err</span></a>
<a class="sourceLine" id="cb4-9" title="9">   <span class="dt">Just</span> c  <span class="ot">-&gt;</span> doSomething c</a>
<a class="sourceLine" id="cb4-10" title="10">   <span class="dt">Nothing</span> <span class="ot">-&gt;</span> doSomethingElse</a>
<a class="sourceLine" id="cb4-11" title="11"></a>
<a class="sourceLine" id="cb4-12" title="12"><span class="ot">doSomething ::</span> <span class="dt">C</span> <span class="ot">-&gt;</span> <span class="op">...</span></a></code></pre></div>
<p>Notice how we don’t have to declare a new data type to multiplex <code>A</code>, <code>B</code> and <code>C</code> into a single type.</p>
<h3 id="open-sum-type-operations">Open sum type operations</h3>
<p><code>setVariantN</code> and <code>getVariantN</code> are the most basic operations, but we have many more of them:</p>
<ul>
<li>set/get a variant value without specifying its index (the first matching type in the list is used):</li>
</ul>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">String</span>,<span class="dt">Double</span>]</a>
<a class="sourceLine" id="cb5-2" title="2">v <span class="ot">=</span> setVariant <span class="st">&quot;Hi!&quot;</span></a>
<a class="sourceLine" id="cb5-3" title="3"></a>
<a class="sourceLine" id="cb5-4" title="4"><span class="ot">s ::</span> <span class="dt">Maybe</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb5-5" title="5">s <span class="ot">=</span> getVariant v</a></code></pre></div>
<ul>
<li>prepend or append possible types to the variant type list:</li>
</ul>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">String</span>,<span class="dt">Double</span>]</a>
<a class="sourceLine" id="cb6-2" title="2"></a>
<a class="sourceLine" id="cb6-3" title="3"><span class="ot">v2 ::</span> <span class="dt">Variant</span> '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">Int</span>,<span class="dt">String</span>,<span class="dt">Double</span>]</a>
<a class="sourceLine" id="cb6-4" title="4">v2 <span class="ot">=</span> prependVariant <span class="op">@</span>'[<span class="dt">A</span>,<span class="dt">B</span>] v</a>
<a class="sourceLine" id="cb6-5" title="5"></a>
<a class="sourceLine" id="cb6-6" title="6"><span class="ot">v3 ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">String</span>,<span class="dt">Double</span>,<span class="dt">A</span>,<span class="dt">B</span>]</a>
<a class="sourceLine" id="cb6-7" title="7">v3 <span class="ot">=</span> appendVariant <span class="op">@</span>'[<span class="dt">A</span>,<span class="dt">B</span>] v</a></code></pre></div>
<ul>
<li>lift a variant into another whose type list is a superset (in any order):</li>
</ul>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">String</span>]</a>
<a class="sourceLine" id="cb7-2" title="2">v <span class="ot">=</span> setVariant <span class="st">&quot;Hi!&quot;</span></a>
<a class="sourceLine" id="cb7-3" title="3"></a>
<a class="sourceLine" id="cb7-4" title="4"><span class="ot">v2 ::</span> <span class="dt">Variant</span> '[<span class="dt">String</span>,<span class="dt">Double</span>,<span class="dt">Int</span>]</a>
<a class="sourceLine" id="cb7-5" title="5">v2 <span class="ot">=</span> liftVariant v</a></code></pre></div>
<ul>
<li>pick a value by index and get either a new variant or the picked value with the appropriate type:</li>
</ul>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Double</span>,<span class="dt">String</span>,<span class="dt">Double</span>,<span class="dt">Float</span>]</a>
<a class="sourceLine" id="cb8-2" title="2">v <span class="ot">=</span> setVariant <span class="st">&quot;Hi!&quot;</span></a>
<a class="sourceLine" id="cb8-3" title="3"></a>
<a class="sourceLine" id="cb8-4" title="4"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> pickVariant <span class="op">@</span><span class="dv">1</span> v</a>
<a class="sourceLine" id="cb8-5" title="5">pickVariant <span class="op">@</span><span class="dv">1</span><span class="ot"> v ::</span> <span class="dt">Either</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">String</span>, <span class="dt">Double</span>, <span class="dt">Float</span>]) <span class="dt">Double</span></a></code></pre></div>
<ul>
<li>catch any value of a given type and get either a new variant or the value with the appropriate type:</li>
</ul>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Double</span>,<span class="dt">String</span>,<span class="dt">Double</span>,<span class="dt">Float</span>]</a>
<a class="sourceLine" id="cb9-2" title="2">v <span class="ot">=</span> setVariant <span class="st">&quot;Hi!&quot;</span></a>
<a class="sourceLine" id="cb9-3" title="3"></a>
<a class="sourceLine" id="cb9-4" title="4"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> catchVariant <span class="op">@</span><span class="dt">Double</span> v</a>
<a class="sourceLine" id="cb9-5" title="5">catchVariant <span class="op">@</span><span class="dt">Double</span><span class="ot"> v ::</span> <span class="dt">Either</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">String</span>, <span class="dt">Float</span>]) <span class="dt">Double</span></a></code></pre></div>
<ul>
<li>update a variant:</li>
</ul>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Double</span>,<span class="dt">String</span>]</a>
<a class="sourceLine" id="cb10-2" title="2">v <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb10-3" title="3"></a>
<a class="sourceLine" id="cb10-4" title="4"><span class="ot">f ::</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb10-5" title="5">f <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb10-6" title="6"></a>
<a class="sourceLine" id="cb10-7" title="7"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> updateVariantN <span class="op">@</span><span class="dv">1</span> f v</a>
<a class="sourceLine" id="cb10-8" title="8">updateVariantN <span class="op">@</span><span class="dv">1</span> f<span class="ot"> v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Float</span>,<span class="dt">String</span>]</a>
<a class="sourceLine" id="cb10-9" title="9"></a>
<a class="sourceLine" id="cb10-10" title="10"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> updateVariant f v</a>
<a class="sourceLine" id="cb10-11" title="11">updateVariant f<span class="ot"> v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Float</span>,<span class="dt">String</span>]</a></code></pre></div>
<ul>
<li>update a variant by inserting a variant:</li>
</ul>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Double</span>,<span class="dt">String</span>]</a>
<a class="sourceLine" id="cb11-2" title="2">v <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb11-3" title="3"></a>
<a class="sourceLine" id="cb11-4" title="4"><span class="ot">f ::</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Variant</span> '[<span class="dt">Float</span>,<span class="dt">Char</span>]</a>
<a class="sourceLine" id="cb11-5" title="5">f <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb11-6" title="6"></a>
<a class="sourceLine" id="cb11-7" title="7"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> updateVariantFoldN <span class="op">@</span><span class="dv">1</span> f v</a>
<a class="sourceLine" id="cb11-8" title="8">updateVariantFoldN <span class="op">@</span><span class="dv">1</span> f<span class="ot"> v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Float</span>,<span class="dt">Char</span>,<span class="dt">String</span>]</a>
<a class="sourceLine" id="cb11-9" title="9"></a>
<a class="sourceLine" id="cb11-10" title="10"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> updateVariantFold f v</a>
<a class="sourceLine" id="cb11-11" title="11">updateVariantFold f<span class="ot"> v ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">Float</span>,<span class="dt">Char</span>,<span class="dt">String</span>]</a></code></pre></div>
<h3 id="various-uses-of-variant">Various uses of Variant</h3>
<p>In the <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-3.html">following part</a> we will see how to use <code>Variant</code> to solve control flow issues. But <code>Variant</code> proves to be also very useful in other contexts. For instance to handle heterogeneous collections of items:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" title="1"><span class="kw">data</span> <span class="dt">A</span> <span class="ot">=</span> <span class="dt">A</span> <span class="kw">deriving</span> (<span class="dt">Show</span>,<span class="dt">Eq</span>,<span class="dt">Ord</span>)</a>
<a class="sourceLine" id="cb12-2" title="2"><span class="kw">data</span> <span class="dt">B</span> <span class="ot">=</span> <span class="dt">B</span> <span class="kw">deriving</span> (<span class="dt">Show</span>,<span class="dt">Eq</span>,<span class="dt">Ord</span>)</a>
<a class="sourceLine" id="cb12-3" title="3"><span class="kw">data</span> <span class="dt">C</span> <span class="ot">=</span> <span class="dt">C</span> <span class="kw">deriving</span> (<span class="dt">Show</span>,<span class="dt">Eq</span>,<span class="dt">Ord</span>)</a>
<a class="sourceLine" id="cb12-4" title="4"><span class="kw">data</span> <span class="dt">D</span> <span class="ot">=</span> <span class="dt">D</span> <span class="kw">deriving</span> (<span class="dt">Show</span>,<span class="dt">Eq</span>,<span class="dt">Ord</span>)</a>
<a class="sourceLine" id="cb12-5" title="5"></a>
<a class="sourceLine" id="cb12-6" title="6"><span class="kw">type</span> <span class="dt">T</span> <span class="ot">=</span> <span class="dt">Variant</span> '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb12-7" title="7"></a>
<a class="sourceLine" id="cb12-8" title="8"><span class="ot">vs ::</span> [<span class="dt">T</span>]</a>
<a class="sourceLine" id="cb12-9" title="9">vs <span class="ot">=</span> [setVariant <span class="dt">B</span>, setVariant <span class="dt">A</span>, setVariant <span class="dt">B</span>, setVariant <span class="dt">C</span>]</a></code></pre></div>
<p>In addition, a <code>Variant</code> can easily make use of the type class instances of its members. For instance, <code>Show</code>, <code>Eq</code> and <code>Ord</code> are supported by default:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb13-1" title="1"><span class="op">&gt;</span> <span class="fu">print</span> vs</a>
<a class="sourceLine" id="cb13-2" title="2">[<span class="dt">B</span>,<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">C</span>]</a>
<a class="sourceLine" id="cb13-3" title="3"></a>
<a class="sourceLine" id="cb13-4" title="4"><span class="op">&gt;</span> vs <span class="op">==</span> vs</a>
<a class="sourceLine" id="cb13-5" title="5"><span class="dt">True</span></a>
<a class="sourceLine" id="cb13-6" title="6"><span class="op">&gt;</span> vs <span class="op">==</span> <span class="fu">reverse</span> vs</a>
<a class="sourceLine" id="cb13-7" title="7"><span class="dt">False</span></a>
<a class="sourceLine" id="cb13-8" title="8"></a>
<a class="sourceLine" id="cb13-9" title="9"><span class="op">&gt;</span> <span class="fu">sort</span> vs</a>
<a class="sourceLine" id="cb13-10" title="10">[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">B</span>,<span class="dt">C</span>]</a></code></pre></div>
<p>Defining new instances for <code>Variant</code> is easy and quite efficient:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb14-1" title="1"><span class="ot">{-# LANGUAGE UndecidableInstances #-}</span></a>
<a class="sourceLine" id="cb14-2" title="2"><span class="ot">{-# LANGUAGE TypeOperators #-}</span></a>
<a class="sourceLine" id="cb14-3" title="3"><span class="ot">{-# LANGUAGE DataKinds #-}</span></a>
<a class="sourceLine" id="cb14-4" title="4"><span class="ot">{-# LANGUAGE FlexibleInstances #-}</span></a>
<a class="sourceLine" id="cb14-5" title="5"></a>
<a class="sourceLine" id="cb14-6" title="6"><span class="kw">class</span> <span class="dt">MyClass</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb14-7" title="7"><span class="ot">   doSomething ::</span> a <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb14-8" title="8"></a>
<a class="sourceLine" id="cb14-9" title="9"><span class="kw">instance</span> <span class="dt">MyClass</span> (<span class="dt">Variant</span> '[]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb14-10" title="10">   <span class="ot">{-# INLINE doSomething #-}</span></a>
<a class="sourceLine" id="cb14-11" title="11">   doSomething <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;Empty variant&quot;</span></a>
<a class="sourceLine" id="cb14-12" title="12">   <span class="co">-- this instance is never used but is necessary for the type-checker</span></a>
<a class="sourceLine" id="cb14-13" title="13"></a>
<a class="sourceLine" id="cb14-14" title="14"><span class="kw">instance</span> (<span class="dt">MyClass</span> (<span class="dt">Variant</span> xs), <span class="dt">MyClass</span> x) <span class="ot">=&gt;</span> <span class="dt">MyClass</span> (<span class="dt">Variant</span> (x '<span class="op">:</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb14-15" title="15">   <span class="ot">{-# INLINE doSomething #-}</span></a>
<a class="sourceLine" id="cb14-16" title="16">   doSomething v <span class="ot">=</span> <span class="kw">case</span> headVariant v <span class="kw">of</span></a>
<a class="sourceLine" id="cb14-17" title="17">      <span class="dt">Right</span> x <span class="ot">-&gt;</span> doSomething x</a>
<a class="sourceLine" id="cb14-18" title="18">      <span class="dt">Left</span> xs <span class="ot">-&gt;</span> doSomething xs</a></code></pre></div>
<p>With the <code>INLINE</code> pragmas and <code>-O2</code>, GHC 8.0.1 compiles the following code:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb15-1" title="1"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">A</span>,<span class="dt">B</span>,<span class="dt">C</span>,<span class="dt">D</span>]</a>
<a class="sourceLine" id="cb15-2" title="2">v <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb15-3" title="3"></a>
<a class="sourceLine" id="cb15-4" title="4">main <span class="ot">=</span> doSomething v</a></code></pre></div>
<p>into the following core (in pseudo-code):</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb16-1" title="1">main <span class="ot">=</span> <span class="kw">case</span> tag_of_v <span class="kw">of</span></a>
<a class="sourceLine" id="cb16-2" title="2">   <span class="dv">0</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">A</span>)</a>
<a class="sourceLine" id="cb16-3" title="3">   t   <span class="ot">-&gt;</span> <span class="kw">case</span> t <span class="op">-#</span> <span class="dv">1</span><span class="op">##</span> <span class="kw">of</span></a>
<a class="sourceLine" id="cb16-4" title="4">      <span class="dv">0</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">B</span>)</a>
<a class="sourceLine" id="cb16-5" title="5">      t   <span class="ot">-&gt;</span> <span class="kw">case</span> t <span class="op">-#</span> <span class="dv">1</span><span class="op">##</span> <span class="kw">of</span></a>
<a class="sourceLine" id="cb16-6" title="6">         <span class="dv">0</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">C</span>)</a>
<a class="sourceLine" id="cb16-7" title="7">         t   <span class="ot">-&gt;</span> <span class="kw">case</span> t <span class="op">-#</span> <span class="dv">1</span><span class="op">##</span> <span class="kw">of</span></a>
<a class="sourceLine" id="cb16-8" title="8">            <span class="dv">0</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">D</span>)</a>
<a class="sourceLine" id="cb16-9" title="9">            _   <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;Empty variant&quot;</span></a></code></pre></div>
<p>with my <a href="https://ghc.haskell.org/trac/ghc/ticket/12877">patch (see Trac #12877)</a>, GHC now produces the expected:</p>
<div class="sourceCode" id="cb17"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb17-1" title="1">main <span class="ot">=</span> <span class="kw">case</span> tag_of_v <span class="kw">of</span></a>
<a class="sourceLine" id="cb17-2" title="2">   <span class="dv">0</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">A</span>)</a>
<a class="sourceLine" id="cb17-3" title="3">   <span class="dv">1</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">B</span>)</a>
<a class="sourceLine" id="cb17-4" title="4">   <span class="dv">2</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">C</span>)</a>
<a class="sourceLine" id="cb17-5" title="5">   <span class="dv">3</span><span class="op">##</span> <span class="ot">-&gt;</span> doSomething (unsafeCoerce<span class="ot"> value_of_v ::</span> <span class="dt">D</span>)</a>
<a class="sourceLine" id="cb17-6" title="6">   _   <span class="ot">-&gt;</span> <span class="fu">error</span> <span class="st">&quot;Empty variant&quot;</span></a></code></pre></div>
<p>I have started to use this approach for a renderer which uses a <code>Scene</code> data type parameterized by the types of the objects it can contain:</p>
<div class="sourceCode" id="cb18"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb18-1" title="1"><span class="kw">data</span> <span class="dt">Scene</span> xs <span class="ot">=</span> <span class="dt">Scene</span></a>
<a class="sourceLine" id="cb18-2" title="2">   {<span class="ot"> sceneObjects ::</span> [<span class="dt">Variant</span> xs]</a>
<a class="sourceLine" id="cb18-3" title="3">   }</a>
<a class="sourceLine" id="cb18-4" title="4"></a>
<a class="sourceLine" id="cb18-5" title="5"><span class="kw">class</span> <span class="dt">Drawable</span> t <span class="kw">where</span></a>
<a class="sourceLine" id="cb18-6" title="6"><span class="ot">   draw ::</span> <span class="dt">Screen</span> <span class="ot">-&gt;</span> t <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb18-7" title="7"></a>
<a class="sourceLine" id="cb18-8" title="8"><span class="kw">instance</span> <span class="dt">Drawable</span> (<span class="dt">Variant</span> '[]) <span class="kw">where</span></a>
<a class="sourceLine" id="cb18-9" title="9">   draw <span class="ot">=</span> <span class="fu">error</span> <span class="st">&quot;Empty variant&quot;</span></a>
<a class="sourceLine" id="cb18-10" title="10"></a>
<a class="sourceLine" id="cb18-11" title="11"><span class="kw">instance</span> (<span class="dt">Drawable</span> (<span class="dt">Variant</span> xs), <span class="dt">Drawable</span> x) <span class="ot">=&gt;</span> <span class="dt">Drawable</span> (<span class="dt">Variant</span> (x '<span class="op">:</span> xs)) <span class="kw">where</span></a>
<a class="sourceLine" id="cb18-12" title="12">   draw s v <span class="ot">=</span> <span class="kw">case</span> headVariant v <span class="kw">of</span></a>
<a class="sourceLine" id="cb18-13" title="13">      <span class="dt">Right</span> x <span class="ot">-&gt;</span> draw s x</a>
<a class="sourceLine" id="cb18-14" title="14">      <span class="dt">Left</span> xs <span class="ot">-&gt;</span> draw s xs</a>
<a class="sourceLine" id="cb18-15" title="15"></a>
<a class="sourceLine" id="cb18-16" title="16"><span class="ot">drawScene ::</span> <span class="dt">Drawable</span> xs <span class="ot">=&gt;</span> <span class="dt">Screen</span> <span class="ot">-&gt;</span> <span class="dt">Scene</span> xs <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb18-17" title="17">drawScene screen scene <span class="ot">=</span> traverse_ (draw screen) (sceneObjects scene)</a></code></pre></div>
<p>The scene is abstract in the types of objects it can contain. We can use it as follows:</p>
<div class="sourceCode" id="cb19"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb19-1" title="1"><span class="kw">data</span> <span class="dt">Circle</span>    <span class="ot">=</span> <span class="dt">Circle</span> <span class="dt">Point</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb19-2" title="2"><span class="kw">data</span> <span class="dt">Rectangle</span> <span class="ot">=</span> <span class="dt">Rectangle</span> <span class="dt">Point</span> <span class="dt">Point</span></a>
<a class="sourceLine" id="cb19-3" title="3"><span class="kw">data</span> <span class="dt">Image</span>     <span class="ot">=</span> <span class="dt">Image</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb19-4" title="4"></a>
<a class="sourceLine" id="cb19-5" title="5"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">Circle</span>    <span class="kw">where</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb19-6" title="6"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">Rectangle</span> <span class="kw">where</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb19-7" title="7"><span class="kw">instance</span> <span class="dt">Drawable</span> <span class="dt">Image</span>     <span class="kw">where</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb19-8" title="8"></a>
<a class="sourceLine" id="cb19-9" title="9"><span class="ot">scene ::</span> <span class="dt">Scene</span> '[<span class="dt">Rectangle</span>,<span class="dt">Circle</span>,<span class="dt">Image</span>]</a>
<a class="sourceLine" id="cb19-10" title="10">scene <span class="ot">=</span> <span class="dt">Scene</span></a>
<a class="sourceLine" id="cb19-11" title="11">   { sceneObjects <span class="ot">=</span> [<span class="op">...</span>]</a>
<a class="sourceLine" id="cb19-12" title="12">   }</a>
<a class="sourceLine" id="cb19-13" title="13"></a>
<a class="sourceLine" id="cb19-14" title="14">main <span class="ot">=</span> drawScene screen scene</a></code></pre></div>
<p>Compared to approaches with collections such as <code>[forall a. Drawable a =&gt; a]</code>, we can get the objects out of the collection in a type-safe manner!</p>
<p>In <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-3.html">the next part</a> we see how to use <code>Variant</code> for control-flow.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Control Flow in Haskell (1) - State of the art</title>
    <link href="http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-1.html" />
    <id>http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-1.html</id>
    <published>2016-12-12T00:00:00Z</published>
    <updated>2016-12-12T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Control Flow in Haskell (1) - State of the art</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Control%20Flow.html">Control Flow</a></td>
               <td class="date">December 12, 2016</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>This post is part of a <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-0.html">series</a>.</p>
<h3 id="unchecked-exceptions">Unchecked Exceptions</h3>
<p>One of the good things in Haskell is that function signatures don’t lie in general. Nevertheless they do when we use unchecked exceptions. This is the prototype of <a href="https://www.stackage.org/haddock/lts-7.9/base-4.9.0.0/Control-Exception.html#v:catch">the simplest of the exception-catching</a> function <code>catch</code>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="fu">catch</span><span class="ot"> ::</span> <span class="dt">Exception</span> e <span class="ot">=&gt;</span> <span class="dt">IO</span> a <span class="ot">-&gt;</span> (e <span class="ot">-&gt;</span> <span class="dt">IO</span> a) <span class="ot">-&gt;</span> <span class="dt">IO</span> a</a></code></pre></div>
<p>Where does <code>e</code> come from? We can use this function as follows:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1">doSomething <span class="ot">`catch`</span> \(<span class="ot">e ::</span> <span class="dt">ArithException</span>) <span class="ot">-&gt;</span> handleArith e</a>
<a class="sourceLine" id="cb2-2" title="2">            <span class="ot">`catch`</span> \(<span class="ot">e ::</span> <span class="dt">IOException</span>)    <span class="ot">-&gt;</span> handleIO e</a></code></pre></div>
<p>Does <code>catch</code> perform some kind of pattern matching depending on the dynamic type of a value (a.k.a. introspection)?</p>
<p>Indeed the <a href="https://www.stackage.org/haddock/lts-7.9/base-4.9.0.0/Control-Exception.html#t:Exception">Exception type-class</a> has a default <a href="https://www.stackage.org/haddock/lts-7.9/base-4.9.0.0/Control-Exception.html#v:fromException">fromException</a> method that uses the <a href="https://www.stackage.org/haddock/lts-7.9/base-4.9.0.0/Data-Typeable.html#v:cast">type-safe cast</a> method that relies on the <a href="https://www.stackage.org/haddock/lts-7.9/base-4.9.0.0/Data-Typeable.html#t:Typeable">Typeable type-class</a>. Since <a href="https://git.haskell.org/ghc.git/commitdiff/91c6b1f54aea658b0056caec45655475897f1972">this commit</a>, GHC generates a Typeable instance for every data type, hence any data type with a <code>Show</code> instance can have an <code>Exception</code> instance.</p>
<p>From an implementation point of view, <code>catch</code> invokes a GHC primitive (<code>catch#</code>) that pushes a “catch frame” on the STG stack containing a reference to the handler function. When an exception is raised with one of the <code>raise#</code> or <code>raiseIO#</code> primitives, the stack is unwinded down to the topmost “catch frame” (included). Then <code>fromException</code> is used to check that the exception type is valid for the exception handler associated with the “catch frame”: if it is, it is executed, otherwise the exception is raised again. (See <a href="https://www.researchgate.net/publication/2530941_Handling_Exceptions_in_Haskell">Handling Exceptions in Haskell (Alastair Reid)</a> and <a href="https://www.classes.cs.uchicago.edu/archive/2007/spring/32102-1/papers/p274-marlow.pdf">Asynchronous Exceptions in Haskell (Simon Marlow et al.)</a>).</p>
<p>It means that there is always an exception handler floating around when Haskell code is executed, the first handler being GHC’s “unhandled exception” handler, and that the correct handler is found in O(n) (where n is the number of nested <code>catch</code>).</p>
<p>I think this mechanism is good to have to handle asynchronous exceptions/errors or to implement runtime system level features (e.g., interruptible computations). But I don’t think it is appropriate to use this mechanism to hide “normal”, non-exceptional, control flow paths:</p>
<ul>
<li><p>There are many <a href="https://www.stackage.org/haddock/lts-7.9/base-4.9.0.0/src/GHC-IO-Exception.html#IOErrorType">possible IO errors</a> that I consider to be non-exceptional and we have to check the documentation of each IO function (if such a thing exists) to see which exceptions may be raised. See for instance the <a href="https://www.stackage.org/haddock/lts-7.9/directory-1.2.6.2/System-Directory.html#v:createDirectory">documentation for createDirectory</a>.</p>
<p>Note that this is another example of abuse of <a href="http://www.hsyl20.fr/home2016-04-05-predefined-shared-error-sets-considered-harmful.html">predefined error sets</a> where the set of POSIX errors is mapped with a surjective function into the smaller set of Haskell IO errors.</p></li>
<li><p>The compiler doesn’t help us if we don’t handle an exception while we should (e.g., the documentation is missing or wrong or if the function has been modified to return a new exception) or if we handle an exception that will never be triggered (dead code).</p></li>
</ul>
<h3 id="sum-types">Sum types</h3>
<p>A typical approach to avoid exceptions (or for languages which lack exception mechanism) is to make functions return values indicating which control path to follow. It is the responsibility of the caller function to check this value and to call the appropriate handler code accordingly or to return an error value itself.</p>
<p>For instance, most <a href="http://www.hsyl20.fr/home2014-04-01-libc-considered-harmful.html">Linux system calls</a> return negative integral values when an error occurs and a positive value otherwise. We have potentially 2^32 error values to consider on 64-bit architectures and we have to read the documentation to know the potential valid error codes (e.g., see the Errors section in the <a href="https://linux.die.net/man/2/mkdir">manual page of mkdir</a>).</p>
<h3 id="ad-hoc-return-sum-types">Ad-hoc return sum types</h3>
<p>In Haskell, we can use a sum type instead of a number and use pattern matching on the returned value, as in the following code:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">data</span> <span class="dt">Error</span> <span class="ot">=</span> <span class="dt">NotAllowed</span> <span class="op">|</span> <span class="dt">NotFound</span> <span class="op">|</span> <span class="dt">Success</span> <span class="dt">XY</span></a>
<a class="sourceLine" id="cb3-2" title="2"></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="ot">doSomething ::</span> <span class="dt">IO</span> <span class="dt">Error</span></a>
<a class="sourceLine" id="cb3-4" title="4">doSomething <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb3-5" title="5"></a>
<a class="sourceLine" id="cb3-6" title="6"><span class="ot">caller ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb3-7" title="7">caller <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb3-8" title="8">   r <span class="ot">&lt;-</span> doSomething</a>
<a class="sourceLine" id="cb3-9" title="9">   <span class="kw">case</span> r <span class="kw">of</span></a>
<a class="sourceLine" id="cb3-10" title="10">      <span class="dt">NotAllowed</span> <span class="ot">-&gt;</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb3-11" title="11">      <span class="dt">NotFound</span>   <span class="ot">-&gt;</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb3-12" title="12">      <span class="dt">Success</span> xy <span class="ot">-&gt;</span> <span class="op">...</span></a></code></pre></div>
<p>The pattern match is compiled into a check of the constructor tag (a number) of the <code>r</code> value to know what to do with it. The compiler tells us if we forget to handle a case.</p>
<p>The drawback of this approach is that it doesn’t compose well. Suppose we have two functions <code>doXY</code> and <code>doUV</code> returning values in different “sets” except for the “Error A” and a function <code>doXYUV</code> composing them.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="ot">doXY   ::</span> () <span class="op">|-&gt;</span> {<span class="dt">Error</span> <span class="dt">A</span>, <span class="dt">Error</span> <span class="dt">B</span>, <span class="dt">Error</span> <span class="dt">C</span>, <span class="dt">XY</span>}</a>
<a class="sourceLine" id="cb4-2" title="2"><span class="ot">doUV   ::</span> <span class="dt">XY</span> <span class="op">|-&gt;</span> {<span class="dt">Error</span> <span class="dt">A</span>, <span class="dt">Error</span> <span class="dt">D</span>, <span class="dt">Error</span> <span class="dt">E</span>, <span class="dt">UV</span>}</a>
<a class="sourceLine" id="cb4-3" title="3"><span class="ot">doXYUV ::</span> () <span class="op">|-&gt;</span> {<span class="dt">Error</span> <span class="dt">A</span>, <span class="dt">Error</span> <span class="dt">B</span>, <span class="dt">Error</span> <span class="dt">C</span>, <span class="dt">Error</span> <span class="dt">D</span>, <span class="dt">Error</span> <span class="dt">E</span>, <span class="dt">UV</span>}</a></code></pre></div>
<p>We could use the following code and sum types to encode this:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">data</span> <span class="dt">ReturnXY</span>   <span class="ot">=</span> <span class="dt">ErrA</span>   <span class="op">|</span> <span class="dt">ErrB</span>  <span class="op">|</span> <span class="dt">ErrC</span>  <span class="op">|</span> <span class="dt">SuccessXY</span> <span class="dt">XY</span></a>
<a class="sourceLine" id="cb5-2" title="2"><span class="kw">data</span> <span class="dt">ReturnUV</span>   <span class="ot">=</span> <span class="dt">ErrA'</span>  <span class="op">|</span> <span class="dt">ErrD</span>  <span class="op">|</span> <span class="dt">ErrE</span>  <span class="op">|</span> <span class="dt">SuccessUV</span> <span class="dt">UV</span></a>
<a class="sourceLine" id="cb5-3" title="3"><span class="kw">data</span> <span class="dt">ReturnXYUV</span> <span class="ot">=</span> <span class="dt">ErrA''</span> <span class="op">|</span> <span class="dt">ErrB'</span> <span class="op">|</span> <span class="dt">ErrC'</span> <span class="op">|</span> <span class="dt">ErrD'</span> <span class="op">|</span> <span class="dt">ErrE'</span> <span class="op">|</span> <span class="dt">SuccessXYUV</span> <span class="dt">UV</span></a>
<a class="sourceLine" id="cb5-4" title="4"></a>
<a class="sourceLine" id="cb5-5" title="5"><span class="ot">doXY ::</span> <span class="dt">IO</span> <span class="dt">ReturnXY</span></a>
<a class="sourceLine" id="cb5-6" title="6">doXY <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb5-7" title="7"></a>
<a class="sourceLine" id="cb5-8" title="8"><span class="ot">doUV ::</span> <span class="dt">XY</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> <span class="dt">ReturnUV</span></a>
<a class="sourceLine" id="cb5-9" title="9">doUV <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb5-10" title="10"></a>
<a class="sourceLine" id="cb5-11" title="11"><span class="ot">doXYUV ::</span> <span class="dt">IO</span> <span class="dt">ReturnXYUV</span></a>
<a class="sourceLine" id="cb5-12" title="12">doXYUV <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb5-13" title="13">   mxy <span class="ot">&lt;-</span> doXY</a>
<a class="sourceLine" id="cb5-14" title="14">   <span class="kw">case</span> mxy <span class="kw">of</span></a>
<a class="sourceLine" id="cb5-15" title="15">      <span class="dt">ErrA</span>         <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="dt">ErrA''</span></a>
<a class="sourceLine" id="cb5-16" title="16">      <span class="dt">ErrB</span>         <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="dt">ErrB'</span></a>
<a class="sourceLine" id="cb5-17" title="17">      <span class="dt">ErrC</span>         <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="dt">ErrC'</span></a>
<a class="sourceLine" id="cb5-18" title="18">      <span class="dt">SuccessXY</span> xy <span class="ot">-&gt;</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb5-19" title="19">         muv <span class="ot">&lt;-</span> doUV xy</a>
<a class="sourceLine" id="cb5-20" title="20">         <span class="kw">case</span> muv <span class="kw">of</span></a>
<a class="sourceLine" id="cb5-21" title="21">            <span class="dt">ErrA'</span>        <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="dt">ErrA''</span></a>
<a class="sourceLine" id="cb5-22" title="22">            <span class="dt">ErrD</span>         <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="dt">ErrD'</span></a>
<a class="sourceLine" id="cb5-23" title="23">            <span class="dt">ErrE</span>         <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="dt">ErrE'</span></a>
<a class="sourceLine" id="cb5-24" title="24">            <span class="dt">SuccessUV</span> uv <span class="ot">-&gt;</span> <span class="fu">return</span> <span class="dt">SuccessXYUV</span> uv</a></code></pre></div>
<p>As a return value cannot be in two different error sets (sum types), we have to alias constructor names, leading to a lot of boilerplate code.</p>
<h3 id="ad-hoc-error-sum-types">Ad-hoc error sum types</h3>
<p>A first step to reduce the boilerplate code is to separate error types from successful types with <code>Either</code>: a single successful value type is assumed per function.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">data</span> <span class="dt">ErrorXY</span>   <span class="ot">=</span> <span class="dt">ErrA</span>   <span class="op">|</span> <span class="dt">ErrB</span>  <span class="op">|</span> <span class="dt">ErrC</span></a>
<a class="sourceLine" id="cb6-2" title="2"><span class="kw">data</span> <span class="dt">ErrorUV</span>   <span class="ot">=</span> <span class="dt">ErrA'</span>  <span class="op">|</span> <span class="dt">ErrD</span>  <span class="op">|</span> <span class="dt">ErrE</span></a>
<a class="sourceLine" id="cb6-3" title="3"><span class="kw">data</span> <span class="dt">ErrorXYUV</span> <span class="ot">=</span> <span class="dt">ErrA''</span> <span class="op">|</span> <span class="dt">ErrB'</span> <span class="op">|</span> <span class="dt">ErrC'</span> <span class="op">|</span> <span class="dt">ErrD'</span> <span class="op">|</span> <span class="dt">ErrE'</span></a>
<a class="sourceLine" id="cb6-4" title="4"></a>
<a class="sourceLine" id="cb6-5" title="5"><span class="ot">doXY ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">ErrorXY</span> <span class="dt">XY</span>)</a>
<a class="sourceLine" id="cb6-6" title="6">doXY <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb6-7" title="7"></a>
<a class="sourceLine" id="cb6-8" title="8"><span class="ot">doUV ::</span> <span class="dt">XY</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">ErrorUV</span> <span class="dt">UV</span>)</a>
<a class="sourceLine" id="cb6-9" title="9">doUV <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb6-10" title="10"></a>
<a class="sourceLine" id="cb6-11" title="11"><span class="ot">doXYUV ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">ErrorXYUV</span> <span class="dt">UV</span>)</a>
<a class="sourceLine" id="cb6-12" title="12">doXYUV <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb6-13" title="13">   mxy <span class="ot">&lt;-</span> doXY</a>
<a class="sourceLine" id="cb6-14" title="14">   <span class="kw">case</span> mxy <span class="kw">of</span></a>
<a class="sourceLine" id="cb6-15" title="15">      <span class="dt">Left</span> <span class="dt">ErrA</span> <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">ErrA''</span>)</a>
<a class="sourceLine" id="cb6-16" title="16">      <span class="dt">Left</span> <span class="dt">ErrB</span> <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">ErrB'</span>)</a>
<a class="sourceLine" id="cb6-17" title="17">      <span class="dt">Left</span> <span class="dt">ErrC</span> <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">ErrC'</span>)</a>
<a class="sourceLine" id="cb6-18" title="18">      <span class="dt">Right</span> xy  <span class="ot">-&gt;</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb6-19" title="19">         muv <span class="ot">&lt;-</span> doUV xy</a>
<a class="sourceLine" id="cb6-20" title="20">         <span class="kw">case</span> muv <span class="kw">of</span></a>
<a class="sourceLine" id="cb6-21" title="21">            <span class="dt">Left</span> <span class="dt">ErrA'</span> <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">ErrA''</span>)</a>
<a class="sourceLine" id="cb6-22" title="22">            <span class="dt">Left</span> <span class="dt">ErrD</span>  <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">ErrD'</span>)</a>
<a class="sourceLine" id="cb6-23" title="23">            <span class="dt">Left</span> <span class="dt">ErrE</span>  <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">ErrE'</span>)</a>
<a class="sourceLine" id="cb6-24" title="24">            <span class="dt">Right</span> uv   <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Right</span> uv)</a></code></pre></div>
<p>In the special case where several functions have the same set of error values, we can easily compose them. For instance with <a href="https://www.stackage.org/haddock/lts-7.9/either-4.4.1.1/Control-Monad-Trans-Either.html">EitherT</a>:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="kw">data</span> <span class="dt">Errors</span> <span class="ot">=</span> <span class="dt">ErrA</span> <span class="op">|</span> <span class="dt">ErrB</span> <span class="op">|</span> <span class="dt">ErrC</span></a>
<a class="sourceLine" id="cb7-2" title="2"></a>
<a class="sourceLine" id="cb7-3" title="3"><span class="ot">doXY ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Errors</span> <span class="dt">XY</span>)</a>
<a class="sourceLine" id="cb7-4" title="4">doXY <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb7-5" title="5"></a>
<a class="sourceLine" id="cb7-6" title="6"><span class="ot">doUV ::</span> <span class="dt">XY</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Errors</span> <span class="dt">UV</span>)</a>
<a class="sourceLine" id="cb7-7" title="7">doUV <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb7-8" title="8"></a>
<a class="sourceLine" id="cb7-9" title="9"><span class="ot">doXYUV ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Errors</span> <span class="dt">UV</span>)</a>
<a class="sourceLine" id="cb7-10" title="10">doXYUV <span class="ot">=</span> runEitherT <span class="op">$</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb7-11" title="11">   xy <span class="ot">&lt;-</span> doXY</a>
<a class="sourceLine" id="cb7-12" title="12">   doUV xy</a></code></pre></div>
<p>However it is hard to define an <code>Errors</code> sum type that is both small enough to avoid having to handle error cases that cannot happen and large enough to allow the composition of various functions throwing different kinds of errors.</p>
<p>Moreover fixing an <code>Errors</code> sum type makes it hard to refine errors. For instance the following code may be what we would like to write but we can’t:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="kw">data</span> <span class="dt">IOErrors</span> <span class="ot">=</span> <span class="dt">FileNotFound</span> <span class="op">|</span> <span class="dt">DiskError</span> <span class="op">|</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb8-2" title="2"></a>
<a class="sourceLine" id="cb8-3" title="3"><span class="fu">readFile</span><span class="ot"> ::</span> <span class="dt">FilePath</span> <span class="ot">-&gt;</span> <span class="dt">Either</span> <span class="dt">IOErrors</span> <span class="dt">Text</span></a>
<a class="sourceLine" id="cb8-4" title="4"><span class="op">...</span></a>
<a class="sourceLine" id="cb8-5" title="5"></a>
<a class="sourceLine" id="cb8-6" title="6">readInterfaceFile path <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb8-7" title="7">   <span class="fu">readFile</span> path <span class="op">&gt;&gt;=</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb8-8" title="8">      <span class="dt">Left</span> <span class="dt">FileNotFound</span> <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">InterfaceFileNotFound</span>)</a>
<a class="sourceLine" id="cb8-9" title="9">      e                 <span class="ot">-&gt;</span> <span class="fu">return</span> e</a>
<a class="sourceLine" id="cb8-10" title="10"></a>
<a class="sourceLine" id="cb8-11" title="11">readSourceFile path <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb8-12" title="12">   <span class="fu">readFile</span> path <span class="op">&gt;&gt;=</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb8-13" title="13">      <span class="dt">Left</span> <span class="dt">FileNotFound</span> <span class="ot">-&gt;</span> <span class="fu">return</span> (<span class="dt">Left</span> <span class="dt">SourceFileNotFound</span>)</a>
<a class="sourceLine" id="cb8-14" title="14">      e                 <span class="ot">-&gt;</span> <span class="fu">return</span> e</a></code></pre></div>
<p><strong>Teaser</strong>: the next posts of the series show how to write valid similar codes.</p>
<h3 id="parametric-error-sum-type">Parametric error sum type</h3>
<p>A partial solution to avoid fixing the error sum type is to keep it parametric with type classes constraints and to instanciate it only when needed:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">class</span> <span class="dt">TErrA</span> e <span class="kw">where</span><span class="ot"> throwErrA ::</span> <span class="dt">ErrA</span> <span class="ot">-&gt;</span> e</a>
<a class="sourceLine" id="cb9-2" title="2"><span class="kw">class</span> <span class="dt">TErrB</span> e <span class="kw">where</span><span class="ot"> throwErrB ::</span> <span class="dt">ErrB</span> <span class="ot">-&gt;</span> e</a>
<a class="sourceLine" id="cb9-3" title="3"><span class="kw">class</span> <span class="dt">TErrC</span> e <span class="kw">where</span><span class="ot"> throwErrC ::</span> <span class="dt">ErrC</span> <span class="ot">-&gt;</span> e</a>
<a class="sourceLine" id="cb9-4" title="4"><span class="kw">class</span> <span class="dt">TErrD</span> e <span class="kw">where</span><span class="ot"> throwErrD ::</span> <span class="dt">ErrD</span> <span class="ot">-&gt;</span> e</a>
<a class="sourceLine" id="cb9-5" title="5"><span class="kw">class</span> <span class="dt">TErrE</span> e <span class="kw">where</span><span class="ot"> throwErrE ::</span> <span class="dt">ErrE</span> <span class="ot">-&gt;</span> e</a>
<a class="sourceLine" id="cb9-6" title="6"></a>
<a class="sourceLine" id="cb9-7" title="7"><span class="ot">doXY ::</span> (<span class="dt">TErrA</span> e, <span class="dt">TErrB</span> e, <span class="dt">TErrC</span> e) <span class="ot">=&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> e <span class="dt">XY</span>)</a>
<a class="sourceLine" id="cb9-8" title="8">doXY <span class="ot">=</span> <span class="op">...</span> <span class="co">-- use throwErrA, throwErrB and throwErrC</span></a>
<a class="sourceLine" id="cb9-9" title="9"></a>
<a class="sourceLine" id="cb9-10" title="10"><span class="ot">doUV ::</span> (<span class="dt">TErrA</span> e, <span class="dt">TErrD</span> e, <span class="dt">TErrE</span> e) <span class="ot">=&gt;</span> <span class="dt">XY</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> e <span class="dt">UV</span>)</a>
<a class="sourceLine" id="cb9-11" title="11">doUV <span class="ot">=</span> <span class="op">...</span> <span class="co">-- use throwErrA, throwErrD and throwErrE</span></a>
<a class="sourceLine" id="cb9-12" title="12"></a>
<a class="sourceLine" id="cb9-13" title="13"><span class="co">-- the union of the constraints is automatically inferred by GHC</span></a>
<a class="sourceLine" id="cb9-14" title="14"><span class="ot">doXYUV ::</span> (<span class="dt">TErrA</span> e, <span class="dt">TErrB</span> e, <span class="dt">TErrC</span> e, <span class="dt">TErrD</span> e, <span class="dt">TErrE</span>) <span class="ot">=&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> e <span class="dt">UV</span>)</a>
<a class="sourceLine" id="cb9-15" title="15">doXYUV <span class="ot">=</span> runEitherT <span class="op">$</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb9-16" title="16">   xy <span class="ot">&lt;-</span> doXY</a>
<a class="sourceLine" id="cb9-17" title="17">   doUV xy</a></code></pre></div>
<p>The <code>TErr*</code> constraints indicate the required field types for the error sum type. GHC automatically infers and merges these constraints.</p>
<p>A data type declaration with its <code>TErr*</code> type class instances is only needed when we need to match on the error value:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="kw">data</span> <span class="dt">MyError</span> <span class="ot">=</span> <span class="dt">MyErrA</span> <span class="dt">ErrA</span></a>
<a class="sourceLine" id="cb10-2" title="2">             <span class="op">|</span> <span class="dt">MyErrB</span> <span class="dt">ErrB</span></a>
<a class="sourceLine" id="cb10-3" title="3">             <span class="op">|</span> <span class="dt">MyErrC</span> <span class="dt">ErrC</span></a>
<a class="sourceLine" id="cb10-4" title="4">             <span class="op">|</span> <span class="dt">MyErrD</span> <span class="dt">ErrD</span></a>
<a class="sourceLine" id="cb10-5" title="5">             <span class="op">|</span> <span class="dt">MyErrE</span> <span class="dt">ErrE</span></a>
<a class="sourceLine" id="cb10-6" title="6"><span class="kw">instance</span> <span class="dt">TErrA</span> <span class="dt">MyError</span> <span class="kw">where</span> throwErrA <span class="ot">=</span> <span class="dt">MyErrA</span></a>
<a class="sourceLine" id="cb10-7" title="7"><span class="kw">instance</span> <span class="dt">TErrB</span> <span class="dt">MyError</span> <span class="kw">where</span> throwErrB <span class="ot">=</span> <span class="dt">MyErrB</span></a>
<a class="sourceLine" id="cb10-8" title="8"><span class="kw">instance</span> <span class="dt">TErrC</span> <span class="dt">MyError</span> <span class="kw">where</span> throwErrC <span class="ot">=</span> <span class="dt">MyErrC</span></a>
<a class="sourceLine" id="cb10-9" title="9"><span class="kw">instance</span> <span class="dt">TErrD</span> <span class="dt">MyError</span> <span class="kw">where</span> throwErrD <span class="ot">=</span> <span class="dt">MyErrD</span></a>
<a class="sourceLine" id="cb10-10" title="10"><span class="kw">instance</span> <span class="dt">TErrE</span> <span class="dt">MyError</span> <span class="kw">where</span> throwErrE <span class="ot">=</span> <span class="dt">MyErrE</span></a>
<a class="sourceLine" id="cb10-11" title="11"></a>
<a class="sourceLine" id="cb10-12" title="12"><span class="ot">main ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb10-13" title="13">main <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb10-14" title="14">   muv <span class="ot">&lt;-</span> doXYUV</a>
<a class="sourceLine" id="cb10-15" title="15">   <span class="kw">case</span> muv <span class="kw">of</span></a>
<a class="sourceLine" id="cb10-16" title="16">      <span class="dt">Right</span> uv           <span class="ot">-&gt;</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb10-17" title="17">      <span class="dt">Left</span> (<span class="dt">MyErrA</span> <span class="dt">ErrA</span>) <span class="ot">-&gt;</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb10-18" title="18">      <span class="dt">Left</span> (<span class="dt">MyErrB</span> <span class="dt">ErrB</span>) <span class="ot">-&gt;</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb10-19" title="19">      <span class="dt">Left</span> (<span class="dt">MyErrC</span> <span class="dt">ErrC</span>) <span class="ot">-&gt;</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb10-20" title="20">      <span class="op">...</span></a></code></pre></div>
<p>The inconvenient of this method is that it still requires a lot of boilerplate code for type classes and for ad-hoc sum types.</p>
<p>In <a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-2.html">the next part</a> we see how to define an open sum type that allows us to deal with this issue without any boilerplate code.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Control Flow in Haskell (0) - Introduction</title>
    <link href="http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-0.html" />
    <id>http://www.hsyl20.fr/home/posts/2016-12-12-control-flow-in-haskell-part-0.html</id>
    <published>2016-12-12T00:00:00Z</published>
    <updated>2016-12-12T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Control Flow in Haskell (0) - Introduction</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/Control%20Flow.html">Control Flow</a></td>
               <td class="date">December 12, 2016</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>I have been working on improving the way we describe the control flow of Haskell programs. As the post is rather long, it is split in several parts:</p>
<ol type="1">
<li><a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-1.html">State of the art</a>: briefly survey the state of the art (unchecked exceptions, Either, EitherT, etc.) and the issues I am trying to solve.</li>
<li><a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-2.html">Variant</a>: describe a new <code>Variant</code> data type (a parameterized open sum type). Basically a value of type <code>Variant '[X,Y,Z]</code> can contain any value whose type is <code>X</code>, <code>Y</code> or <code>Z</code>.</li>
<li><a href="http://www.hsyl20.fr/home2016-12-12-control-flow-in-haskell-part-3.html">Flow with Variant</a>: describe how we can use the <code>Variant</code> data type to solve control flow issues.</li>
</ol>
<!--
4. [Multi-continuations](2016-12-12-control-flow-in-haskell-part-4.html):
  propose a complementary multi-continuation based approach that avoids sum
  types for return values altogether.
-->
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Haskell type system from the ground up (1)</title>
    <link href="http://www.hsyl20.fr/home/posts/2016-10-04-haskell-type-system-from-the-ground-up.html" />
    <id>http://www.hsyl20.fr/home/posts/2016-10-04-haskell-type-system-from-the-ground-up.html</id>
    <published>2016-10-04T00:00:00Z</published>
    <updated>2016-10-04T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Haskell type system from the ground up (1)</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a></td>
               <td class="date">October  4, 2016</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>I was thinking about how difficult it would be to explain GHC’s advanced type system features to non-Haskell programmers. I give it a go in this series of posts.</p>
<blockquote>
<p>Avant donc que d’écrire, apprenez à penser. Selon que notre idée est plus ou moins obscure, L’expression la suit, ou moins nette, ou plus pure. <strong>Ce que l’on conçoit bien s’énonce clairement, Et les mots pour le dire arrivent aisément.</strong></p>
<p>Hâtez-vous lentement, et sans perdre courage, Vingt fois sur le métier remettez votre ouvrage, Polissez-le sans cesse, et le repolissez, Ajoutez quelquefois, et souvent effacez.</p>
<p>– <cite>Nicolas Boileau, “L’Art Poétique”, 1674</cite></p>
</blockquote>
<h3 id="data-types-and-functions">Data types and functions</h3>
<p>In Haskell we use <strong>functions</strong> to transform <strong>data</strong>:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">data</span> <span class="dt">A</span> <span class="ot">=</span> <span class="op">...</span> <span class="co">-- A, B and C are data</span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw">data</span> <span class="dt">B</span> <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb1-3" title="3"><span class="kw">data</span> <span class="dt">C</span> <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb1-4" title="4"></a>
<a class="sourceLine" id="cb1-5" title="5"><span class="co">-- f is a function</span></a>
<a class="sourceLine" id="cb1-6" title="6"><span class="ot">f ::</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">B</span> <span class="ot">-&gt;</span> <span class="dt">C</span></a>
<a class="sourceLine" id="cb1-7" title="7">f <span class="ot">=</span> <span class="op">...</span></a></code></pre></div>
<p>Here we don’t care about what the function does and what the data represent. We just need to know that we can define functions that take some data as input and return some data.</p>
<h3 id="the-problem">The problem</h3>
<p>Suppose we define the addition functions <code>plusInt</code> and <code>plusFloat</code> for <code>Int</code> and <code>Float</code> data types respectively:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="kw">data</span> <span class="dt">Float</span> <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-2" title="2"><span class="kw">data</span> <span class="dt">Int</span>   <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-3" title="3"></a>
<a class="sourceLine" id="cb2-4" title="4"><span class="ot">plusInt   ::</span> <span class="dt">Int</span>   <span class="ot">-&gt;</span> <span class="dt">Int</span>   <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb2-5" title="5">plusInt <span class="ot">=</span> <span class="op">...</span></a>
<a class="sourceLine" id="cb2-6" title="6"></a>
<a class="sourceLine" id="cb2-7" title="7"><span class="ot">plusFloat ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb2-8" title="8">plusFloat <span class="op">...</span></a></code></pre></div>
<p>We would like to use the same <code>+</code> operator for both operations instead of the longer distinct names <code>plusFloat</code> and <code>plusInt</code>. However we can’t have two functions with the same name. Intuitionistically we would like <code>+</code> to select the correct function depending on the type of its parameters.</p>
<h3 id="solution-predicates-and-proofs">Solution: predicates and proofs</h3>
<p>We would like a function such as:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="ot">(+) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a></code></pre></div>
<p>But we need a predicate to restrict <code>a</code> to data types that support addition. Currently we only have functions and data types: let’s use a parametric data type as a predicate and its instances as proofs.</p>
<p>In the following code, we use the data type <code>Plus a</code> as a predicate for the ability to use addition of data with type <code>a</code>. We create two proofs/instances of this predicate/data type: <code>plusForInt</code> and <code>plusForFloat</code> with the functions defined previously.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="kw">data</span> <span class="dt">Plus</span> a <span class="ot">=</span> <span class="dt">PlusOp</span></a>
<a class="sourceLine" id="cb4-2" title="2">   {<span class="ot"> (+) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb4-3" title="3">   }</a>
<a class="sourceLine" id="cb4-4" title="4"></a>
<a class="sourceLine" id="cb4-5" title="5"><span class="ot">plusForInt ::</span> <span class="dt">Plus</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb4-6" title="6">plusForInt <span class="ot">=</span> <span class="dt">PlusOp</span> { (<span class="op">+</span>) <span class="ot">=</span> plusInt }</a>
<a class="sourceLine" id="cb4-7" title="7"></a>
<a class="sourceLine" id="cb4-8" title="8"><span class="ot">plusForFloat ::</span> <span class="dt">Plus</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb4-9" title="9">plusForFloat <span class="ot">=</span> <span class="dt">PlusOp</span> { (<span class="op">+</span>) <span class="ot">=</span> plusFloat }</a>
<a class="sourceLine" id="cb4-10" title="10"></a>
<a class="sourceLine" id="cb4-11" title="11"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> (<span class="op">+</span>)</a>
<a class="sourceLine" id="cb4-12" title="12"><span class="ot">(+) ::</span> <span class="dt">Plus</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb4-13" title="13"><span class="co">-- equivalent to</span></a>
<a class="sourceLine" id="cb4-14" title="14"><span class="ot">(+) ::</span> <span class="dt">Plus</span> a <span class="ot">-&gt;</span> (a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a)</a></code></pre></div>
<p>We can see that if we give to the <code>+</code> function a proof <code>Plus a</code> that <code>a</code> types can be added, it returns a function to add numbers of this type. It is completely trivial because <code>+</code> only extracts the function in the <code>Plus a</code> data type and returns it.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> ((<span class="op">+</span>) plusForInt)</a>
<a class="sourceLine" id="cb5-2" title="2">((<span class="op">+</span>) plusForInt)<span class="ot"> ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb5-3" title="3"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> ((<span class="op">+</span>) plusForFloat)</a>
<a class="sourceLine" id="cb5-4" title="4">((<span class="op">+</span>) plusForFloat)<span class="ot"> ::</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">Float</span> <span class="ot">-&gt;</span> <span class="dt">Float</span></a></code></pre></div>
<p>At this point we would like the compiler to automatically pass the correct proof to the <code>+</code> function depending on the type of the data we pass to it. Let’s use the <code>=&gt;</code> arrow to separate automatically passed proofs and normal parameters:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="ot">(+) ::</span> <span class="dt">Plus</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a></code></pre></div>
<p>When the compiler sees such expression, it knows it has to implicitly pass an additional parameter that depends on the actual <code>a</code> type. If it can’t find it, it reports an error at compile time.</p>
<p>Given a few minor syntactic differences in actual Haskell code (cf next section), we can now write:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="ot">testInt ::</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb7-2" title="2">testInt <span class="ot">=</span> <span class="dv">8</span> <span class="op">+</span> <span class="dv">3</span></a>
<a class="sourceLine" id="cb7-3" title="3"></a>
<a class="sourceLine" id="cb7-4" title="4"><span class="ot">testFloat ::</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb7-5" title="5">testFloat <span class="ot">=</span> <span class="fl">2.0</span> <span class="op">+</span> <span class="fl">5.0</span></a></code></pre></div>
<h3 id="type-classes">Type-classes</h3>
<p>If you have followed down to this point, you should have understood the basics of Haskell type-classes (predicates/data types) and type-class instances (proofs/data instances). Let’s check the actual type of <code>+</code> in Haskell:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="op">&gt;</span> <span class="op">:</span><span class="kw">type</span> (<span class="op">+</span>)</a>
<a class="sourceLine" id="cb8-2" title="2"><span class="ot">(+) ::</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb8-3" title="3"></a>
<a class="sourceLine" id="cb8-4" title="4"><span class="op">&gt;</span> <span class="op">:</span>info <span class="dt">Num</span></a>
<a class="sourceLine" id="cb8-5" title="5"><span class="kw">class</span> <span class="dt">Num</span> a <span class="kw">where</span>       <span class="co">-- equivalent to: data Num a = NumOp</span></a>
<a class="sourceLine" id="cb8-6" title="6"><span class="ot">  (+) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a    <span class="co">--                               { (+) :: a -&gt; a -&gt; a</span></a>
<a class="sourceLine" id="cb8-7" title="7"><span class="ot">  (-) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a    <span class="co">--                               , (-) :: a -&gt; a -&gt; a</span></a>
<a class="sourceLine" id="cb8-8" title="8"><span class="ot">  (*) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a    <span class="co">--                               , ...</span></a>
<a class="sourceLine" id="cb8-9" title="9"><span class="ot">  negate ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb8-10" title="10"><span class="ot">  abs ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb8-11" title="11"><span class="ot">  signum ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb8-12" title="12"><span class="ot">  fromInteger ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> a</a></code></pre></div>
<p>The predicate is called <code>Num</code> instead of our <code>Plus</code> as it is used as a predicate for more functions: <code>+</code>, <code>-</code>, <code>*</code>, <code>negate</code>, <code>abs</code>, <code>signum</code> and <code>fromInteger</code>.</p>
<p>The syntax <code>class Num a where</code> is just a fancy way of declaring a predicate/data type/type class <code>Num</code> with a single implicit <code>NumOp</code> constructor. Anonymous data instances/type class instances of this data type can be defined with:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Int</span> <span class="kw">where</span>  <span class="co">-- equivalent to: numForInt :: Num Int</span></a>
<a class="sourceLine" id="cb9-2" title="2">   (<span class="op">+</span>) <span class="ot">=</span> plusInt        <span class="co">--                numForInt = NumOp { (+) = plusInt</span></a>
<a class="sourceLine" id="cb9-3" title="3">   (<span class="op">-</span>) <span class="ot">=</span> minusInt       <span class="co">--                                  , (-) = minusInt</span></a>
<a class="sourceLine" id="cb9-4" title="4">   <span class="op">...</span>                  <span class="co">--                                  , ...</span></a></code></pre></div>
<p><code>Num</code> can be seen as a function from a type <code>a</code> to a data with type <code>Num a</code> if it exists, otherwise the compiler reports an error:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="op">&gt;</span> <span class="st">&quot;test&quot;</span> <span class="op">+</span> <span class="st">&quot;test&quot;</span></a>
<a class="sourceLine" id="cb10-2" title="2"></a>
<a class="sourceLine" id="cb10-3" title="3"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">34</span><span class="op">:</span><span class="dv">1</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb10-4" title="4">    • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">Num</span> [<span class="dt">Char</span>]) arising from a use <span class="kw">of</span> ‘<span class="op">+</span>’</a>
<a class="sourceLine" id="cb10-5" title="5">    <span class="op">...</span></a></code></pre></div>
<p>Similarily, the compiler checks for the uniqueness of the proofs for a given type:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1">test<span class="op">.</span>hs<span class="op">:</span><span class="dv">22</span><span class="op">:</span><span class="dv">10</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb11-2" title="2">    <span class="dt">Duplicate</span> <span class="kw">instance</span> declarations<span class="op">:</span></a>
<a class="sourceLine" id="cb11-3" title="3">         <span class="kw">instance</span> <span class="dt">Plus</span> <span class="dt">Int</span> <span class="co">-- Defined at test.hs:22:10</span></a>
<a class="sourceLine" id="cb11-4" title="4">         <span class="kw">instance</span> <span class="dt">Plus</span> <span class="dt">Int</span> <span class="co">-- Defined at test.hs:25:10</span></a></code></pre></div>
<h3 id="conclusion">Conclusion</h3>
<p>We have seen that the type-class mecanism allows us to implicitly select a data instance (a value) from a type. We can make it even clearer with the following example. <code>getData</code> is really a function from a type to a String value.</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" title="1"><span class="ot">{-# LANGUAGE TypeApplications #-}</span></a>
<a class="sourceLine" id="cb12-2" title="2"><span class="ot">{-# LANGUAGE AllowAmbiguousTypes  #-}</span></a>
<a class="sourceLine" id="cb12-3" title="3"></a>
<a class="sourceLine" id="cb12-4" title="4"><span class="kw">class</span> <span class="dt">TypeToData</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb12-5" title="5"><span class="ot">   getData ::</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb12-6" title="6"></a>
<a class="sourceLine" id="cb12-7" title="7"><span class="kw">instance</span> <span class="dt">TypeToData</span> <span class="dt">Int</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb12-8" title="8">   getData <span class="ot">=</span> <span class="st">&quot;An Int&quot;</span></a>
<a class="sourceLine" id="cb12-9" title="9"></a>
<a class="sourceLine" id="cb12-10" title="10"><span class="kw">instance</span> <span class="dt">TypeToData</span> <span class="dt">Float</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb12-11" title="11">   getData <span class="ot">=</span> <span class="st">&quot;A Float&quot;</span></a>
<a class="sourceLine" id="cb12-12" title="12"></a>
<a class="sourceLine" id="cb12-13" title="13"><span class="op">&gt;</span> getData <span class="op">@</span><span class="dt">Int</span>    </a>
<a class="sourceLine" id="cb12-14" title="14"><span class="st">&quot;An Int&quot;</span>          </a>
<a class="sourceLine" id="cb12-15" title="15"><span class="op">&gt;</span> getData <span class="op">@</span><span class="dt">Float</span>  </a>
<a class="sourceLine" id="cb12-16" title="16"><span class="st">&quot;A Float&quot;</span></a>
<a class="sourceLine" id="cb12-17" title="17"><span class="op">&gt;</span> getData <span class="op">@</span><span class="dt">String</span></a>
<a class="sourceLine" id="cb12-18" title="18"></a>
<a class="sourceLine" id="cb12-19" title="19"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">91</span><span class="op">:</span><span class="dv">1</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></a>
<a class="sourceLine" id="cb12-20" title="20">    • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">TypeToData</span> <span class="dt">String</span>) arising from a use <span class="kw">of</span> ‘getData’</a></code></pre></div>
<p>We can check the type of <code>getData</code> with the GHC flag <code>-ddump-tc</code>:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb13-1" title="1"><span class="ot">getData ::</span> <span class="kw">forall</span> a<span class="op">.</span> <span class="dt">TypeToData</span> a <span class="ot">=&gt;</span> <span class="dt">String</span></a></code></pre></div>
<p>The type application <code>getData @Int</code> sets the type <code>a</code> to <code>Int</code> in the <code>getData</code> declaration. Hence it requires an implicit <code>TypeToData Int</code> proof from the compiler</p>
<h3 id="annexes">Annexes</h3>
<h4 id="non-solution-1-keep-using-different-names">Non-solution 1: keep using different names</h4>
<p>If we only have data types and functions, we could say that <code>+</code> is for the integer addition and <code>+.</code> is for float addition:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb14-1" title="1">(<span class="op">+</span>)  <span class="ot">=</span> plusInt</a>
<a class="sourceLine" id="cb14-2" title="2">(<span class="op">+.</span>) <span class="ot">=</span> plusFloat</a></code></pre></div>
<p>If it hasn’t changed since the last time I have used it 12 years ago, it is the solution chosen by the OCaml language. It becomes an issue if you add several other data types and functions accordingly (e.g., Double, Word, etc.). You have to find a different operator for each case.</p>
<h4 id="non-solution-2-use-modules">Non-solution 2: use modules</h4>
<p>If we have modules, we could put each function in its own module:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb15-1" title="1"><span class="kw">module</span> <span class="dt">Int</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb15-2" title="2"></a>
<a class="sourceLine" id="cb15-3" title="3">(<span class="op">+</span>) <span class="ot">=</span> plusInt</a>
<a class="sourceLine" id="cb15-4" title="4"></a>
<a class="sourceLine" id="cb15-5" title="5"></a>
<a class="sourceLine" id="cb15-6" title="6"><span class="kw">module</span> <span class="dt">Float</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb15-7" title="7"></a>
<a class="sourceLine" id="cb15-8" title="8">(<span class="op">+</span>) <span class="ot">=</span> plusFloat</a></code></pre></div>
<p>But then we can’t use both functions in the same module without resolving the ambiguity (prefixing with the module name, renaming the function during the import, etc.). Some Haskell libraries use this approach (Text vs String, etc.).</p>
<h4 id="non-solution-3-sum-types">Non-solution 3: sum types</h4>
<p>Haskell doesn’t support sub-typing. The closer we can get given what we currently have (data types and functions) is by using a sum type:</p>
<div class="sourceCode" id="cb16"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb16-1" title="1"><span class="kw">data</span> <span class="dt">IntFloat</span> <span class="ot">=</span> <span class="dt">A</span> <span class="dt">Int</span> </a>
<a class="sourceLine" id="cb16-2" title="2">              <span class="op">|</span> <span class="dt">B</span> <span class="dt">Float</span></a>
<a class="sourceLine" id="cb16-3" title="3"></a>
<a class="sourceLine" id="cb16-4" title="4"><span class="ot">(+) ::</span> <span class="dt">IntFloat</span> <span class="ot">-&gt;</span> <span class="dt">IntFloat</span> <span class="ot">-&gt;</span> <span class="dt">IntFloat</span></a></code></pre></div>
<p>Here <code>IntFloat</code> can either contain an <code>Int</code> or a <code>Float</code>. Hence <code>+</code> supports both integer addition and float addition. Additionally it has to support mixed up integer/float addition (i.e., the first argument may contain an integer and the second one a float, or vice-versa). In this case the result may either be an integer or a float: it is chosen by convention and the compiler doesn’t check nor enforce it.</p>
<p>Programming languages with <a href="https://en.wikipedia.org/wiki/Subtyping">subtyping</a>, operator overloading or automatic coercion use such kinds of mecanisms. For instance, C would <a href="https://en.wikipedia.org/wiki/Type_conversion#C-like_languages">automatically coerce the integer into a float</a>; Scala <a href="https://github.com/scala/scala/blob/v2.11.8/src/library/scala/Float.scala#L128">uses operator/function overloading</a>.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Predefined shared error sets considered harmful</title>
    <link href="http://www.hsyl20.fr/home/posts/2016-04-05-predefined-shared-error-sets-considered-harmful.html" />
    <id>http://www.hsyl20.fr/home/posts/2016-04-05-predefined-shared-error-sets-considered-harmful.html</id>
    <published>2016-04-05T00:00:00Z</published>
    <updated>2016-04-05T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Predefined shared error sets considered harmful</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Linux.html">Linux</a>, <a href="http://www.hsyl20.fr/home/tags/UNIX.html">UNIX</a>, <a href="http://www.hsyl20.fr/home/tags/OS.html">OS</a></td>
               <td class="date">April  5, 2016</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p><strong>Changelog</strong></p>
<ul>
<li>2016-11-17: title change; paragraph added about manual pages</li>
</ul>
<hr />
<p>When we will design the next OS, we should definitely avoid having <a href="http://www.hsyl20.fr/home2014-04-01-libc-considered-harmful.html">a static errno variable</a> in user-space. In addition, we should also avoid having a limited predefined set of error codes. Consider the following example (from the Linux DRM subsystem):</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb1-1" title="1">plane = drm_plane_find(dev, plane_req-&gt;plane_id);</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="cf">if</span> (!plane) {</a>
<a class="sourceLine" id="cb1-3" title="3">        DRM_DEBUG_KMS(<span class="st">&quot;Unknown plane ID %d</span><span class="sc">\n</span><span class="st">&quot;</span>,</a>
<a class="sourceLine" id="cb1-4" title="4">                      plane_req-&gt;plane_id);</a>
<a class="sourceLine" id="cb1-5" title="5">        <span class="cf">return</span> -ENOENT;</a>
<a class="sourceLine" id="cb1-6" title="6">}</a>
<a class="sourceLine" id="cb1-7" title="7"></a>
<a class="sourceLine" id="cb1-8" title="8"><span class="cf">if</span> (plane_req-&gt;fb_id) {</a>
<a class="sourceLine" id="cb1-9" title="9">        fb = drm_framebuffer_lookup(dev, plane_req-&gt;fb_id);</a>
<a class="sourceLine" id="cb1-10" title="10">        <span class="cf">if</span> (!fb) {</a>
<a class="sourceLine" id="cb1-11" title="11">                DRM_DEBUG_KMS(<span class="st">&quot;Unknown framebuffer ID %d</span><span class="sc">\n</span><span class="st">&quot;</span>,</a>
<a class="sourceLine" id="cb1-12" title="12">                              plane_req-&gt;fb_id);</a>
<a class="sourceLine" id="cb1-13" title="13">                <span class="cf">return</span> -ENOENT;</a>
<a class="sourceLine" id="cb1-14" title="14">        }</a>
<a class="sourceLine" id="cb1-15" title="15"></a>
<a class="sourceLine" id="cb1-16" title="16">        crtc = drm_crtc_find(dev, plane_req-&gt;crtc_id);</a>
<a class="sourceLine" id="cb1-17" title="17">        <span class="cf">if</span> (!crtc) {</a>
<a class="sourceLine" id="cb1-18" title="18">                DRM_DEBUG_KMS(<span class="st">&quot;Unknown crtc ID %d</span><span class="sc">\n</span><span class="st">&quot;</span>,</a>
<a class="sourceLine" id="cb1-19" title="19">                              plane_req-&gt;crtc_id);</a>
<a class="sourceLine" id="cb1-20" title="20">                <span class="cf">return</span> -ENOENT;</a>
<a class="sourceLine" id="cb1-21" title="21">        }</a>
<a class="sourceLine" id="cb1-22" title="22">        <span class="co">// ...</span></a>
<a class="sourceLine" id="cb1-23" title="23">}</a></code></pre></div>
<p>The bad practice of using predefined error codes (here <code>ENOENT</code>) makes impossible for the user code to know what is the exact error (here, which kind of entity is not found). We could have returned different error codes for the different errors instead.</p>
<p>When we use a function that uses <code>errno</code> to return its error codes, we <em>already have to read its manual page</em> to know which error codes may be returned. It wouldn’t be more difficult to deal with per-function error codes and it would make error handling much easier. In the given example above, the user-space code has to find the invalid entity by itself, wasting time and programmer’s sanity. Moreover the kernel code locks the entities while it uses them but the user-space code has to deal with potential race conditions.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>First Experiments With Dependent Types In GHC</title>
    <link href="http://www.hsyl20.fr/home/posts/2016-03-18-first-experiments-with-dependent-types.html" />
    <id>http://www.hsyl20.fr/home/posts/2016-03-18-first-experiments-with-dependent-types.html</id>
    <published>2016-03-18T00:00:00Z</published>
    <updated>2016-03-18T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">First Experiments With Dependent Types In GHC</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/GHC.html">GHC</a>, <a href="http://www.hsyl20.fr/home/tags/Dependent%20Types.html">Dependent Types</a>, <a href="http://www.hsyl20.fr/home/tags/FFI.html">FFI</a>, <a href="http://www.hsyl20.fr/home/tags/haskus-system.html">haskus-system</a></td>
               <td class="date">March 18, 2016</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>Update 2016-12-28: rename ViperVM into Haskus system and fix links accordingly</p>
<p>For two weeks I have been getting my feet wet with GHC’s type extensions: DataKinds, TypeFamilies, TypeOperators, etc.</p>
<p>I rely a lot on the Foreign Function Interface (FFI) in my Haskus system project (formerly ViperVM) and I wanted to easily and efficiently map Haskell data types to C data types (unions, arrays, bitsets, bitfields, etc.). Last week I have put together a coherent set of modules to do it, heavily based on GHC’s type extensions. It is not yet documented on this blog, but you can read about it here: <a href="https://github.com/hsyl20/haskus-system/blob/master/WritingBindings.md">Writing bindings</a></p>
<p>Playing with type extensions gave me a lot of food for thought, hence this article about using them to enhance the way we do error checking and other control-flow stuff.</p>
<h3 id="control-flow">Control-flow</h3>
<p>I am now trying to solve another issue: <strong>control-flow in the IO monad with error handling.</strong> For instance, if you have read <a href="http://www.hsyl20.fr/home2014-04-01-libc-considered-harmful.html">this page</a>, you know that most Linux’s syscalls can either fail and return an error, or succeed and return a value. E.g.:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" title="1"><span class="ot">pipe ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> (<span class="dt">FileDescriptor</span>, <span class="dt">FileDescriptor</span>))</a></code></pre></div>
<p>I will use the following simpler functions to illustrate this article:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><span class="ot">f ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> <span class="dt">A</span>)</a>
<a class="sourceLine" id="cb2-2" title="2"><span class="ot">g ::</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> <span class="dt">B</span>)</a>
<a class="sourceLine" id="cb2-3" title="3"><span class="ot">h ::</span> <span class="dt">B</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> <span class="dt">C</span>)</a></code></pre></div>
<h4 id="eithert">EitherT</h4>
<p>To compose these calls, it is common to use the <a href="https://hackage.haskell.org/package/either">EitherT monad transformer</a>.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="kw">import</span> <span class="dt">Control.Monad.Trans.Either</span></a>
<a class="sourceLine" id="cb3-2" title="2"></a>
<a class="sourceLine" id="cb3-3" title="3"><span class="ot">result ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> <span class="dt">C</span>)</a>
<a class="sourceLine" id="cb3-4" title="4">result <span class="ot">=</span> runEitherT <span class="op">$</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb3-5" title="5">   a <span class="ot">&lt;-</span> <span class="dt">EitherT</span> f</a>
<a class="sourceLine" id="cb3-6" title="6">   b <span class="ot">&lt;-</span> <span class="dt">EitherT</span> (g a)</a>
<a class="sourceLine" id="cb3-7" title="7">   c <span class="ot">&lt;-</span> <span class="dt">EitherT</span> (h b)</a>
<a class="sourceLine" id="cb3-8" title="8">   <span class="fu">return</span> c</a>
<a class="sourceLine" id="cb3-9" title="9"></a>
<a class="sourceLine" id="cb3-10" title="10"><span class="co">-- or</span></a>
<a class="sourceLine" id="cb3-11" title="11"><span class="ot">result ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> <span class="dt">C</span>)</a>
<a class="sourceLine" id="cb3-12" title="12">result <span class="ot">=</span> runEitherT (<span class="dt">EitherT</span> f <span class="op">&gt;&gt;=</span> (<span class="dt">EitherT</span> <span class="op">.</span> g) <span class="op">&gt;&gt;=</span> (<span class="dt">EitherT</span> <span class="op">.</span> h))</a></code></pre></div>
<p>The corresponding data-flow diagram is then:</p>
<p><img src="http://www.hsyl20.fr/home../images/2016_deptypes/eithert.png" /></p>
<h4 id="drawbacks">Drawbacks</h4>
<p>I think that this composition approach, however, is quite limiting:</p>
<ul>
<li>all the functions must share the same <code>Error</code> type</li>
<li>when we get an <code>Error</code>, we don’t know which of the function has failed</li>
</ul>
<p>Suppose we have instead a different error type per function:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="ot">f ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">ErrorF</span> <span class="dt">A</span>)</a>
<a class="sourceLine" id="cb4-2" title="2"><span class="ot">g ::</span> <span class="dt">A</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">ErrorG</span> <span class="dt">B</span>)</a>
<a class="sourceLine" id="cb4-3" title="3"><span class="ot">h ::</span> <span class="dt">B</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">ErrorH</span> <span class="dt">C</span>)</a></code></pre></div>
<p>We can somehow circumvent the issues mentionned above by enhancing the <code>Error</code> data type so that it can contain the different kinds of error. We could also add an identifier indicating the function which has triggered the error (I haven’t done it here to keep things simple).</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" title="1"><span class="kw">data</span> <span class="dt">Error</span></a>
<a class="sourceLine" id="cb5-2" title="2">   <span class="ot">=</span> <span class="dt">ErrF</span> <span class="dt">ErrorF</span></a>
<a class="sourceLine" id="cb5-3" title="3">   <span class="op">|</span> <span class="dt">ErrG</span> <span class="dt">ErrorG</span></a>
<a class="sourceLine" id="cb5-4" title="4">   <span class="op">|</span> <span class="dt">ErrH</span> <span class="dt">ErrorH</span></a>
<a class="sourceLine" id="cb5-5" title="5">   <span class="op">|</span> <span class="op">....</span></a></code></pre></div>
<p>This method doesn’t scale well. When we use <code>Error</code> in different places, we never know the real subset of errors that can happen in practice. For instance, in the following example, the type of <code>result2</code> doesn’t tell us that the <code>ErrorH</code> error will never happen while it may happen in <code>result</code>.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" title="1"><span class="ot">result ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> <span class="dt">C</span>)</a>
<a class="sourceLine" id="cb6-2" title="2">result <span class="ot">=</span> runEitherT <span class="op">$</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb6-3" title="3">   a <span class="ot">&lt;-</span> <span class="dt">EitherT</span> (mapLeft <span class="dt">ErrF</span> <span class="op">&lt;$&gt;</span> f)</a>
<a class="sourceLine" id="cb6-4" title="4">   b <span class="ot">&lt;-</span> <span class="dt">EitherT</span> (mapLeft <span class="dt">ErrG</span> <span class="op">&lt;$&gt;</span> g a)</a>
<a class="sourceLine" id="cb6-5" title="5">   c <span class="ot">&lt;-</span> <span class="dt">EitherT</span> (mapLeft <span class="dt">ErrH</span> <span class="op">&lt;$&gt;</span> h b)</a>
<a class="sourceLine" id="cb6-6" title="6">   <span class="fu">return</span> c</a>
<a class="sourceLine" id="cb6-7" title="7"></a>
<a class="sourceLine" id="cb6-8" title="8"><span class="ot">result2 ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> <span class="dt">B</span>)</a>
<a class="sourceLine" id="cb6-9" title="9">result2 <span class="ot">=</span> runEitherT <span class="op">$</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb6-10" title="10">   a <span class="ot">&lt;-</span> <span class="dt">EitherT</span> (mapLeft <span class="dt">ErrF</span> <span class="op">&lt;$&gt;</span> f)</a>
<a class="sourceLine" id="cb6-11" title="11">   b <span class="ot">&lt;-</span> <span class="dt">EitherT</span> (mapLeft <span class="dt">ErrG</span> <span class="op">&lt;$&gt;</span> g a)</a>
<a class="sourceLine" id="cb6-12" title="12">   <span class="fu">return</span> b</a></code></pre></div>
<p>(It is similar to <code>errno</code> in C: it can be any <code>int</code> value so we never know if we have tested all the possible error cases for a given syscall).</p>
<p>Handling errors is already very boring, we don’t want to handle errors that will never happen and we don’t want to create new <code>ErrorXXX</code> data types for each error subset due to composition. Instead, we would like to compose the functions to get:</p>
<p><img src="http://www.hsyl20.fr/home../images/2016_deptypes/eithert_enhanced.png" /></p>
<p>That is, <code>result</code> should have an extended <code>Either</code> type that can contain an arbitrary number of different types: here <code>C</code>, <code>ErrorF</code>, <code>ErrorG</code> and <code>ErrorH</code>. And we want the help of the compiler to ensure that we don’t forget to handle some errors: we want to pattern match on <code>result</code> so that the compiler signals missing cases.</p>
<h3 id="variant">Variant</h3>
<p>I have implemented a <a href="https://github.com/hsyl20/haskus-system/blob/master/src/lib/Haskus/Utils/Variant.hs"><code>Variant</code></a> type that supports an arbitrary number of content types. Similarly to data types (as implemented in GHC as far as I know), a hidden tag number identifies the actual type of the contained value. The value can be obtained/set with a type index (a <code>Nat</code>) that is used both to index into the content types and to check/set the tag value. It is much more simple to understand with a few examples:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" title="1"><span class="ot">{-# LANGUAGE DataKinds #-}</span></a>
<a class="sourceLine" id="cb7-2" title="2"></a>
<a class="sourceLine" id="cb7-3" title="3"><span class="co">-- creating a new variant: using an Int (index 1)</span></a>
<a class="sourceLine" id="cb7-4" title="4"><span class="ot">v ::</span> <span class="dt">Variant</span> '[<span class="dt">String</span>,<span class="dt">Int</span>,<span class="dt">Float</span>]</a>
<a class="sourceLine" id="cb7-5" title="5">v <span class="ot">=</span> setVariant (<span class="dt">Proxy</span><span class="ot"> ::</span> <span class="dt">Proxy</span> <span class="dv">1</span>) <span class="dv">10</span></a>
<a class="sourceLine" id="cb7-6" title="6"><span class="co">-- or simply</span></a>
<a class="sourceLine" id="cb7-7" title="7">v <span class="ot">=</span> setVariant1 <span class="dv">10</span></a>
<a class="sourceLine" id="cb7-8" title="8"></a>
<a class="sourceLine" id="cb7-9" title="9"><span class="co">-- trying to get a String from the variant (index 0)</span></a>
<a class="sourceLine" id="cb7-10" title="10"><span class="op">&gt;</span> getVariant0 v</a>
<a class="sourceLine" id="cb7-11" title="11"><span class="dt">Nothing</span></a>
<a class="sourceLine" id="cb7-12" title="12"></a>
<a class="sourceLine" id="cb7-13" title="13"><span class="co">-- trying to get an Int from the variant (index 1)</span></a>
<a class="sourceLine" id="cb7-14" title="14"><span class="op">&gt;</span> getVariant1 v</a>
<a class="sourceLine" id="cb7-15" title="15"><span class="dt">Just</span> <span class="dv">10</span></a>
<a class="sourceLine" id="cb7-16" title="16"></a>
<a class="sourceLine" id="cb7-17" title="17"><span class="co">-- trying to get a Float from the variant (index 2)</span></a>
<a class="sourceLine" id="cb7-18" title="18"><span class="op">&gt;</span> getVariant2 v</a>
<a class="sourceLine" id="cb7-19" title="19"><span class="dt">Nothing</span></a>
<a class="sourceLine" id="cb7-20" title="20"></a>
<a class="sourceLine" id="cb7-21" title="21"><span class="co">-- trying with an out-of-bound index</span></a>
<a class="sourceLine" id="cb7-22" title="22"><span class="op">&gt;</span> getVariant3 v <span class="co">-- doesn't compile!</span></a>
<a class="sourceLine" id="cb7-23" title="23"></a>
<a class="sourceLine" id="cb7-24" title="24"><span class="co">-- Creating a variant from a String</span></a>
<a class="sourceLine" id="cb7-25" title="25"><span class="ot">w ::</span> <span class="dt">Variant</span> '[<span class="dt">String</span>,<span class="dt">Int</span>,<span class="dt">Float</span>]</a>
<a class="sourceLine" id="cb7-26" title="26">w <span class="ot">=</span> setVariant0 <span class="st">&quot;Hello&quot;</span></a>
<a class="sourceLine" id="cb7-27" title="27"></a>
<a class="sourceLine" id="cb7-28" title="28"><span class="co">-- Updating a variant value (if it has the correct tag of course)</span></a>
<a class="sourceLine" id="cb7-29" title="29"><span class="ot">w' ::</span> <span class="dt">Variant</span> '[<span class="dt">String</span>,<span class="dt">Int</span>,<span class="dt">Float</span>]</a>
<a class="sourceLine" id="cb7-30" title="30">w' <span class="ot">=</span> updateVariant0 (<span class="op">++</span> <span class="st">&quot; World!&quot;</span>) w</a>
<a class="sourceLine" id="cb7-31" title="31"></a>
<a class="sourceLine" id="cb7-32" title="32"><span class="co">-- Updating a value and changing the type</span></a>
<a class="sourceLine" id="cb7-33" title="33"><span class="ot">v' ::</span> <span class="dt">Variant</span> '[<span class="dt">String</span>,<span class="dt">String</span>,<span class="dt">Float</span>]</a>
<a class="sourceLine" id="cb7-34" title="34">v' <span class="ot">=</span> updateVariant1 (\x <span class="ot">-&gt;</span> <span class="st">&quot;Value: &quot;</span> <span class="op">++</span> <span class="fu">show</span> x) v</a>
<a class="sourceLine" id="cb7-35" title="35"></a>
<a class="sourceLine" id="cb7-36" title="36"><span class="co">-- Converting a Variant into a Tuple</span></a>
<a class="sourceLine" id="cb7-37" title="37"><span class="op">&gt;</span> matchVariant w'</a>
<a class="sourceLine" id="cb7-38" title="38">(<span class="dt">Just</span> <span class="st">&quot;Hello World!&quot;</span>,<span class="dt">Nothing</span>,<span class="dt">Nothing</span>)</a>
<a class="sourceLine" id="cb7-39" title="39"></a>
<a class="sourceLine" id="cb7-40" title="40"><span class="op">&gt;</span> matchVariant v'</a>
<a class="sourceLine" id="cb7-41" title="41">(<span class="dt">Nothing</span>,<span class="dt">Just</span> <span class="st">&quot;Value: 10&quot;</span>,<span class="dt">Nothing</span>)</a>
<a class="sourceLine" id="cb7-42" title="42"></a>
<a class="sourceLine" id="cb7-43" title="43"><span class="co">-- We can also store functions, etc.</span></a>
<a class="sourceLine" id="cb7-44" title="44"><span class="ot">z ::</span> <span class="dt">Variant</span> '[<span class="dt">String</span>,<span class="dt">Int</span>,<span class="dt">Float</span>,<span class="dt">Int</span><span class="ot">-&gt;</span><span class="dt">Int</span>]</a>
<a class="sourceLine" id="cb7-45" title="45">z <span class="ot">=</span> setVariant3 (<span class="op">+</span><span class="dv">1</span>)</a>
<a class="sourceLine" id="cb7-46" title="46"></a>
<a class="sourceLine" id="cb7-47" title="47"><span class="op">&gt;</span> <span class="fu">fmap</span> (<span class="op">$</span> <span class="dv">2</span>) (getVariant3 z)</a>
<a class="sourceLine" id="cb7-48" title="48"><span class="dt">Just</span> <span class="dv">3</span></a></code></pre></div>
<h3 id="flow">Flow</h3>
<p>I have made a little <a href="https://github.com/hsyl20/haskus-system/blob/master/src/lib/Haskus/Utils/Flow.hs">control-flow module</a> that deals with functions returning <code>Variant</code>s. Now instead of returning <code>Either Error a</code>, we can make our functions return a <code>Variant '[a,Error]</code> and we can compose them with <code>flowSeq</code> as in the following example:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" title="1"><span class="ot">{-# LANGUAGE DataKinds #-}</span></a>
<a class="sourceLine" id="cb8-2" title="2"></a>
<a class="sourceLine" id="cb8-3" title="3"><span class="kw">import</span> <span class="dt">Haskus.Utils.Variant</span></a>
<a class="sourceLine" id="cb8-4" title="4"><span class="kw">import</span> <span class="dt">Haskus.Utils.Flow</span></a>
<a class="sourceLine" id="cb8-5" title="5"></a>
<a class="sourceLine" id="cb8-6" title="6"><span class="kw">data</span> <span class="dt">ErrorF</span> <span class="ot">=</span> <span class="dt">ErrorF</span> <span class="kw">deriving</span> (<span class="dt">Show</span>)</a>
<a class="sourceLine" id="cb8-7" title="7"><span class="kw">data</span> <span class="dt">ErrorG</span> <span class="ot">=</span> <span class="dt">ErrorG</span> <span class="kw">deriving</span> (<span class="dt">Show</span>)</a>
<a class="sourceLine" id="cb8-8" title="8"><span class="kw">data</span> <span class="dt">ErrorH</span> <span class="ot">=</span> <span class="dt">ErrorH</span> <span class="kw">deriving</span> (<span class="dt">Show</span>)</a>
<a class="sourceLine" id="cb8-9" title="9"></a>
<a class="sourceLine" id="cb8-10" title="10"><span class="ot">f ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">ErrorF</span>])</a>
<a class="sourceLine" id="cb8-11" title="11">f <span class="ot">=</span> <span class="fu">return</span> (setVariant0 <span class="dv">10</span>)</a>
<a class="sourceLine" id="cb8-12" title="12"></a>
<a class="sourceLine" id="cb8-13" title="13"><span class="ot">g ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">ErrorG</span>])</a>
<a class="sourceLine" id="cb8-14" title="14">g x <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb8-15" title="15">   <span class="fu">print</span> x</a>
<a class="sourceLine" id="cb8-16" title="16">   <span class="co">--fail!</span></a>
<a class="sourceLine" id="cb8-17" title="17">   <span class="fu">return</span> (setVariant1 <span class="dt">ErrorG</span>)</a>
<a class="sourceLine" id="cb8-18" title="18"></a>
<a class="sourceLine" id="cb8-19" title="19"><span class="ot">h ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">ErrorH</span>])</a>
<a class="sourceLine" id="cb8-20" title="20">h x <span class="ot">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb8-21" title="21">   <span class="fu">print</span> x</a>
<a class="sourceLine" id="cb8-22" title="22">   <span class="fu">return</span> (setVariant0 (x<span class="op">+</span><span class="dv">20</span>))</a>
<a class="sourceLine" id="cb8-23" title="23"></a>
<a class="sourceLine" id="cb8-24" title="24">result <span class="ot">=</span></a>
<a class="sourceLine" id="cb8-25" title="25">   f</a>
<a class="sourceLine" id="cb8-26" title="26">   <span class="ot">`flowSeq`</span> g</a>
<a class="sourceLine" id="cb8-27" title="27">   <span class="ot">`flowSeq`</span> h</a>
<a class="sourceLine" id="cb8-28" title="28"></a>
<a class="sourceLine" id="cb8-29" title="29"><span class="op">&gt;</span> <span class="op">:</span>t result</a>
<a class="sourceLine" id="cb8-30" title="30"><span class="ot">result ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorH</span>, <span class="dt">ErrorG</span>, <span class="dt">ErrorF</span>])</a>
<a class="sourceLine" id="cb8-31" title="31"></a>
<a class="sourceLine" id="cb8-32" title="32"><span class="op">&gt;</span> matchVariant <span class="op">&lt;$&gt;</span> result</a>
<a class="sourceLine" id="cb8-33" title="33"><span class="dv">10</span></a>
<a class="sourceLine" id="cb8-34" title="34">(<span class="dt">Nothing</span>,<span class="dt">Nothing</span>,<span class="dt">Just</span> <span class="dt">ErrorG</span>,<span class="dt">Nothing</span>)</a></code></pre></div>
<p>Notice that by convention, the first value type in the variant is the type of the “correct” value: it is the type of the value that is potentially passed to the next function.</p>
<p>We can easily lift functions returning <code>Either</code> with <code>flowSeqE</code>:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">data</span> <span class="dt">ErrorE</span> <span class="ot">=</span> <span class="dt">ErrorE</span> <span class="kw">deriving</span> (<span class="dt">Show</span>)</a>
<a class="sourceLine" id="cb9-2" title="2"></a>
<a class="sourceLine" id="cb9-3" title="3"><span class="ot">e ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">ErrorE</span> <span class="dt">Int</span>)</a>
<a class="sourceLine" id="cb9-4" title="4">e x <span class="ot">=</span> <span class="fu">return</span> (<span class="dt">Right</span> (x<span class="op">*</span><span class="dv">100</span>))</a>
<a class="sourceLine" id="cb9-5" title="5"></a>
<a class="sourceLine" id="cb9-6" title="6">result2 <span class="ot">=</span> f <span class="ot">`flowSeqE`</span> e</a>
<a class="sourceLine" id="cb9-7" title="7"></a>
<a class="sourceLine" id="cb9-8" title="8"><span class="op">&gt;</span> <span class="op">:</span>t result2</a>
<a class="sourceLine" id="cb9-9" title="9"><span class="ot">result2 ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorE</span>, <span class="dt">ErrorF</span>])</a>
<a class="sourceLine" id="cb9-10" title="10"></a>
<a class="sourceLine" id="cb9-11" title="11"><span class="op">&gt;</span> matchVariant <span class="op">&lt;$&gt;</span> result2</a>
<a class="sourceLine" id="cb9-12" title="12">(<span class="dt">Just</span> <span class="dv">1000</span>,<span class="dt">Nothing</span>,<span class="dt">Nothing</span>)</a></code></pre></div>
<p>Similarly, we can lift functions that do not fail with <code>flowSeqM</code>:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" title="1"><span class="ot">square ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb10-2" title="2">square x <span class="ot">=</span> <span class="fu">return</span> (x<span class="op">*</span>x)</a>
<a class="sourceLine" id="cb10-3" title="3"></a>
<a class="sourceLine" id="cb10-4" title="4">result3 <span class="ot">=</span> f <span class="ot">`flowSeqM`</span> square <span class="ot">`flowSeq`</span> h</a>
<a class="sourceLine" id="cb10-5" title="5"></a>
<a class="sourceLine" id="cb10-6" title="6"><span class="op">&gt;</span> <span class="op">:</span>t result3</a>
<a class="sourceLine" id="cb10-7" title="7"><span class="ot">result3 ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorH</span>, <span class="dt">ErrorF</span>])</a>
<a class="sourceLine" id="cb10-8" title="8"></a>
<a class="sourceLine" id="cb10-9" title="9"><span class="op">&gt;</span> matchVariant <span class="op">&lt;$&gt;</span> result3</a>
<a class="sourceLine" id="cb10-10" title="10"><span class="dv">100</span></a>
<a class="sourceLine" id="cb10-11" title="11">(<span class="dt">Just</span> <span class="dv">120</span>,<span class="dt">Nothing</span>,<span class="dt">Nothing</span>)</a></code></pre></div>
<p>Note that a function may return several kinds of errors:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" title="1"><span class="ot">err ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">ErrorF</span>,<span class="dt">ErrorG</span>])</a>
<a class="sourceLine" id="cb11-2" title="2">err x</a>
<a class="sourceLine" id="cb11-3" title="3">   <span class="op">|</span> x <span class="op">&gt;</span> <span class="dv">10</span>    <span class="ot">=</span> <span class="fu">return</span> (setVariant1 <span class="dt">ErrorF</span>)</a>
<a class="sourceLine" id="cb11-4" title="4">   <span class="op">|</span> x <span class="op">&lt;</span> <span class="dv">10</span>    <span class="ot">=</span> <span class="fu">return</span> (setVariant2 <span class="dt">ErrorG</span>)</a>
<a class="sourceLine" id="cb11-5" title="5">   <span class="op">|</span> <span class="fu">otherwise</span> <span class="ot">=</span> <span class="fu">return</span> (setVariant0 <span class="dv">123</span>)</a>
<a class="sourceLine" id="cb11-6" title="6"></a>
<a class="sourceLine" id="cb11-7" title="7">result4 <span class="ot">=</span> f <span class="ot">`flowSeq`</span> err <span class="ot">`flowSeq`</span> h</a>
<a class="sourceLine" id="cb11-8" title="8"></a>
<a class="sourceLine" id="cb11-9" title="9"><span class="op">&gt;</span> <span class="op">:</span>t result4</a>
<a class="sourceLine" id="cb11-10" title="10"><span class="ot">result4 ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorH</span>, <span class="dt">ErrorF</span>, <span class="dt">ErrorG</span>, <span class="dt">ErrorF</span>])</a>
<a class="sourceLine" id="cb11-11" title="11"></a>
<a class="sourceLine" id="cb11-12" title="12"><span class="op">&gt;</span> matchVariant <span class="op">&lt;$&gt;</span> result4</a>
<a class="sourceLine" id="cb11-13" title="13"><span class="dv">123</span></a>
<a class="sourceLine" id="cb11-14" title="14">(<span class="dt">Just</span> <span class="dv">143</span>,<span class="dt">Nothing</span>,<span class="dt">Nothing</span>,<span class="dt">Nothing</span>,<span class="dt">Nothing</span>)</a></code></pre></div>
<p>Most flow functions are biased in favor of the first element of the variant (the “correct” one). Nevertheless it is totally possible to perform custom operations during a flow:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb12-1" title="1"><span class="kw">import</span> <span class="dt">Control.Monad</span> ((&gt;=&gt;))</a>
<a class="sourceLine" id="cb12-2" title="2"></a>
<a class="sourceLine" id="cb12-3" title="3"><span class="co">-- | We suppose that if &quot;g&quot; fails, we can use the default value 18</span></a>
<a class="sourceLine" id="cb12-4" title="4"><span class="ot">fixG ::</span> <span class="dt">Variant</span> '[<span class="dt">Int</span>,<span class="dt">ErrorG</span>] <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>])</a>
<a class="sourceLine" id="cb12-5" title="5">fixG v <span class="ot">=</span> <span class="fu">return</span> <span class="op">$</span> <span class="kw">case</span> matchVariant v <span class="kw">of</span></a>
<a class="sourceLine" id="cb12-6" title="6">   (<span class="dt">Just</span> r,_) <span class="ot">-&gt;</span> setVariant0 r</a>
<a class="sourceLine" id="cb12-7" title="7">   _          <span class="ot">-&gt;</span> setVariant0 <span class="dv">18</span></a>
<a class="sourceLine" id="cb12-8" title="8"></a>
<a class="sourceLine" id="cb12-9" title="9">result5 <span class="ot">=</span></a>
<a class="sourceLine" id="cb12-10" title="10">   f</a>
<a class="sourceLine" id="cb12-11" title="11">   <span class="ot">`flowSeq`</span> (g <span class="op">&gt;=&gt;</span> fixG)</a>
<a class="sourceLine" id="cb12-12" title="12">   <span class="ot">`flowSeq`</span> h</a>
<a class="sourceLine" id="cb12-13" title="13"></a>
<a class="sourceLine" id="cb12-14" title="14"><span class="op">&gt;</span> <span class="op">:</span>t result5</a>
<a class="sourceLine" id="cb12-15" title="15"><span class="ot">result5 ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorH</span>, <span class="dt">ErrorF</span>])  <span class="co">-- no ErrorG!</span></a>
<a class="sourceLine" id="cb12-16" title="16"></a>
<a class="sourceLine" id="cb12-17" title="17"><span class="op">&gt;</span> matchVariant <span class="op">&lt;$&gt;</span> result5</a>
<a class="sourceLine" id="cb12-18" title="18"><span class="dv">10</span></a>
<a class="sourceLine" id="cb12-19" title="19"><span class="dv">18</span></a>
<a class="sourceLine" id="cb12-20" title="20">(<span class="dt">Just</span> <span class="dv">38</span>,<span class="dt">Nothing</span>,<span class="dt">Nothing</span>)</a></code></pre></div>
<p>We can also directly match in the flow with <code>flowMatch</code>:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb13-1" title="1"><span class="ot">{-# LANGUAGE LambdaCase #-}</span></a>
<a class="sourceLine" id="cb13-2" title="2"></a>
<a class="sourceLine" id="cb13-3" title="3">result6 <span class="ot">=</span></a>
<a class="sourceLine" id="cb13-4" title="4">   f</a>
<a class="sourceLine" id="cb13-5" title="5">   <span class="ot">`flowSeq`</span> g</a>
<a class="sourceLine" id="cb13-6" title="6">   <span class="ot">`flowSeq`</span> h</a>
<a class="sourceLine" id="cb13-7" title="7">   <span class="ot">`flowMatch`</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb13-8" title="8">      (<span class="dt">Just</span> r,_,_,_) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> (<span class="st">&quot;Success! &quot;</span><span class="op">++</span> <span class="fu">show</span> r)</a>
<a class="sourceLine" id="cb13-9" title="9">      (_,<span class="dt">Just</span> r,_,_) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> (<span class="st">&quot;Error in h: &quot;</span><span class="op">++</span> <span class="fu">show</span> r)</a>
<a class="sourceLine" id="cb13-10" title="10">      (_,_,<span class="dt">Just</span> r,_) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> (<span class="st">&quot;Error in g: &quot;</span><span class="op">++</span> <span class="fu">show</span> r)</a>
<a class="sourceLine" id="cb13-11" title="11">      (_,_,_,<span class="dt">Just</span> r) <span class="ot">-&gt;</span> <span class="fu">putStrLn</span> (<span class="st">&quot;Error in f: &quot;</span><span class="op">++</span> <span class="fu">show</span> r)</a>
<a class="sourceLine" id="cb13-12" title="12"></a>
<a class="sourceLine" id="cb13-13" title="13"><span class="op">&gt;</span> <span class="op">:</span>t result6</a>
<a class="sourceLine" id="cb13-14" title="14"><span class="ot">result6 ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb13-15" title="15"></a>
<a class="sourceLine" id="cb13-16" title="16"><span class="op">&gt;</span> result6</a>
<a class="sourceLine" id="cb13-17" title="17"><span class="dv">10</span></a>
<a class="sourceLine" id="cb13-18" title="18"><span class="dt">Error</span> <span class="kw">in</span> g<span class="op">:</span> <span class="dt">ErrorG</span></a></code></pre></div>
<p>Finally, if we want to catch all the errors with a given type, we can use <code>flowCatch</code>:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb14-1" title="1">ff <span class="ot">=</span> </a>
<a class="sourceLine" id="cb14-2" title="2">   f</a>
<a class="sourceLine" id="cb14-3" title="3">   <span class="ot">`flowSeq`</span> g</a>
<a class="sourceLine" id="cb14-4" title="4">   <span class="ot">`flowSeq`</span> h</a>
<a class="sourceLine" id="cb14-5" title="5">   <span class="ot">`flowSeq`</span> g</a>
<a class="sourceLine" id="cb14-6" title="6"></a>
<a class="sourceLine" id="cb14-7" title="7"><span class="op">&gt;</span> <span class="op">:</span>t ff</a>
<a class="sourceLine" id="cb14-8" title="8"><span class="ot">ff ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorG</span>, <span class="dt">ErrorH</span>, <span class="dt">ErrorG</span>, <span class="dt">ErrorF</span>])</a>
<a class="sourceLine" id="cb14-9" title="9"></a>
<a class="sourceLine" id="cb14-10" title="10">result7 <span class="ot">=</span></a>
<a class="sourceLine" id="cb14-11" title="11">   ff</a>
<a class="sourceLine" id="cb14-12" title="12">   <span class="ot">`flowCatch`</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb14-13" title="13">      (<span class="dt">Left</span> <span class="dt">ErrorG</span>) <span class="ot">-&gt;</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb14-14" title="14">         <span class="fu">putStrLn</span> <span class="st">&quot;Handling error in g&quot;</span></a>
<a class="sourceLine" id="cb14-15" title="15">         <span class="fu">return</span> (setVariant0 <span class="dv">18</span>)</a>
<a class="sourceLine" id="cb14-16" title="16">      (<span class="dt">Right</span> a)     <span class="ot">-&gt;</span> <span class="fu">return</span> a</a>
<a class="sourceLine" id="cb14-17" title="17"></a>
<a class="sourceLine" id="cb14-18" title="18"><span class="op">&gt;</span> <span class="op">:</span>t result7</a>
<a class="sourceLine" id="cb14-19" title="19"><span class="ot">result7 ::</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorH</span>, <span class="dt">ErrorF</span>])  <span class="co">-- not any ErrorG anymore!</span></a>
<a class="sourceLine" id="cb14-20" title="20"></a>
<a class="sourceLine" id="cb14-21" title="21"><span class="op">&gt;</span> result7 <span class="ot">`flowSeqM`</span> <span class="fu">print</span></a>
<a class="sourceLine" id="cb14-22" title="22"><span class="dv">10</span></a>
<a class="sourceLine" id="cb14-23" title="23"><span class="dt">Handling</span> <span class="fu">error</span> <span class="kw">in</span> g</a>
<a class="sourceLine" id="cb14-24" title="24"><span class="dv">18</span></a></code></pre></div>
<p>If we catch all the error types, we must be able to match the result with <code>singleVariant</code>, otherwise it doesn’t compile:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb15-1" title="1"><span class="op">&gt;</span> singleVariant <span class="op">&lt;$&gt;</span> result7 <span class="co">-- doesn't compile</span></a>
<a class="sourceLine" id="cb15-2" title="2"></a>
<a class="sourceLine" id="cb15-3" title="3"><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">275</span><span class="op">:</span><span class="dv">19</span><span class="op">:</span></a>
<a class="sourceLine" id="cb15-4" title="4">    <span class="dt">Couldn't</span> match <span class="kw">type</span> ‘'[<span class="dt">ErrorH</span>, <span class="dt">ErrorF</span>]’ with ‘'[]’   <span class="co">-- we know the error to catch</span></a>
<a class="sourceLine" id="cb15-5" title="5">    <span class="dt">Expected</span> <span class="kw">type</span><span class="op">:</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>])</a>
<a class="sourceLine" id="cb15-6" title="6">      <span class="dt">Actual</span> <span class="kw">type</span><span class="op">:</span> <span class="dt">IO</span> (<span class="dt">Variant</span> '[<span class="dt">Int</span>, <span class="dt">ErrorH</span>, <span class="dt">ErrorF</span>])</a>
<a class="sourceLine" id="cb15-7" title="7">    <span class="dt">In</span> the second argument <span class="kw">of</span> ‘(<span class="op">&lt;$&gt;</span>)’, namely ‘result7’</a>
<a class="sourceLine" id="cb15-8" title="8">    <span class="dt">In</span> the expression<span class="op">:</span> singleVariant <span class="op">&lt;$&gt;</span> result7</a>
<a class="sourceLine" id="cb15-9" title="9"></a>
<a class="sourceLine" id="cb15-10" title="10"></a>
<a class="sourceLine" id="cb15-11" title="11">result8 <span class="ot">=</span></a>
<a class="sourceLine" id="cb15-12" title="12">   ff</a>
<a class="sourceLine" id="cb15-13" title="13">   <span class="ot">`flowCatch`</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb15-14" title="14">      (<span class="dt">Left</span> <span class="dt">ErrorG</span>) <span class="ot">-&gt;</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb15-15" title="15">         <span class="fu">putStrLn</span> <span class="st">&quot;Handling error in g&quot;</span></a>
<a class="sourceLine" id="cb15-16" title="16">         <span class="fu">return</span> (setVariant0 <span class="dv">18</span>)</a>
<a class="sourceLine" id="cb15-17" title="17">      (<span class="dt">Right</span> a)     <span class="ot">-&gt;</span> <span class="fu">return</span> a</a>
<a class="sourceLine" id="cb15-18" title="18">   <span class="ot">`flowCatch`</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb15-19" title="19">      (<span class="dt">Left</span> <span class="dt">ErrorF</span>) <span class="ot">-&gt;</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb15-20" title="20">         <span class="fu">putStrLn</span> <span class="st">&quot;Handling error in f&quot;</span></a>
<a class="sourceLine" id="cb15-21" title="21">         <span class="fu">return</span> (setVariant0 <span class="dv">10</span>)</a>
<a class="sourceLine" id="cb15-22" title="22">      (<span class="dt">Right</span> a)     <span class="ot">-&gt;</span> <span class="fu">return</span> a</a>
<a class="sourceLine" id="cb15-23" title="23">   <span class="ot">`flowCatch`</span> \<span class="kw">case</span></a>
<a class="sourceLine" id="cb15-24" title="24">      (<span class="dt">Left</span> <span class="dt">ErrorH</span>) <span class="ot">-&gt;</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb15-25" title="25">         <span class="fu">putStrLn</span> <span class="st">&quot;Handling error in h&quot;</span></a>
<a class="sourceLine" id="cb15-26" title="26">         <span class="fu">return</span> (setVariant0 <span class="dv">42</span>)</a>
<a class="sourceLine" id="cb15-27" title="27">      (<span class="dt">Right</span> a)     <span class="ot">-&gt;</span> <span class="fu">return</span> a</a>
<a class="sourceLine" id="cb15-28" title="28"></a>
<a class="sourceLine" id="cb15-29" title="29"><span class="op">&gt;</span> <span class="op">:</span>t singleVariant <span class="op">&lt;$&gt;</span> result8</a>
<a class="sourceLine" id="cb15-30" title="30">singleVariant <span class="op">&lt;$&gt;</span><span class="ot"> result8 ::</span> <span class="dt">IO</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb15-31" title="31"></a>
<a class="sourceLine" id="cb15-32" title="32"><span class="op">&gt;</span> singleVariant <span class="op">&lt;$&gt;</span> result8</a>
<a class="sourceLine" id="cb15-33" title="33"><span class="dv">10</span></a>
<a class="sourceLine" id="cb15-34" title="34"><span class="dt">Handling</span> <span class="fu">error</span> <span class="kw">in</span> g</a>
<a class="sourceLine" id="cb15-35" title="35"><span class="dv">18</span></a></code></pre></div>
<h3 id="conclusion">Conclusion</h3>
<p>Finally, we now have a control-flow framework that seems easy to work with (I still need to use it in production). It looks a little bit like checked-exceptions in Java, but first-class (we can manipulate them, etc.). I should add combinators usually found in Exception frameworks (<code>finally</code>, <code>bracket</code>, etc.).</p>
<p>If you have other ideas, do not hesitate to <a href="http://www.hsyl20.fr/homemailto:sylvain@haskus.fr">contact me</a>!</p>
<p>All of this code is part of a larger project now called <a href="https://github.com/haskus/haskus-system/">Haskus system</a></p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>libc considered harmful</title>
    <link href="http://www.hsyl20.fr/home/posts/2014-04-01-libc-considered-harmful.html" />
    <id>http://www.hsyl20.fr/home/posts/2014-04-01-libc-considered-harmful.html</id>
    <published>2014-04-01T00:00:00Z</published>
    <updated>2014-04-01T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">libc considered harmful</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/haskus-system.html">haskus-system</a>, <a href="http://www.hsyl20.fr/home/tags/C.html">C</a>, <a href="http://www.hsyl20.fr/home/tags/libc.html">libc</a>, <a href="http://www.hsyl20.fr/home/tags/Haskell.html">Haskell</a>, <a href="http://www.hsyl20.fr/home/tags/FFI.html">FFI</a></td>
               <td class="date">April  1, 2014</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>Update 2016-12-28: rename ViperVM into Haskus system and fix links accordingly</p>
<p>For my Haskus system project, I want to be able to manage memory at a very low-level (pinning pages into RAM, using custom allocator instead of malloc, allocating huge pages, setting execution flag, etc.). However using system calls through the legacy libc interface from Haskell is not appealing and imposes some constraints because the libc is unnecessarily stateful (cf errno). In this post I present the module I am working on that performs system calls directly.</p>
<p>I am aware that as we bypass the libc, we lose a lot of portability, at least until someone does the same work for other architectures and OS. Currently only Linux on x86-64 is beginning to be supported. Anyway, we have to start somewhere in order to build user space applications on safer software layers.</p>
<h2 id="background">Background</h2>
<p>A few decades ago, computer programs were written specifically for each architecture and applications had to deal with devices explicitly as there were only a few of them (remember sound card configuration in old games where the whole list of existing/supported sound cards were listed). Nevertheless, the BIOS has been used to offer a standard interface for the most common ones, for instance to manage the display (cf VESA), keyboards, etc. To call a “function” provided by the BIOS, programs had to put appropriate parameters into registers and use an instruction triggering a software interruption. The appropriate BIOS interrupt handler then performed the requested operation and returned some values into registers to indicate results to the application. Operating systems such as DOS provided custom interrupt handlers to add more high-level functionalities (access to the file system, etc.). <strong>Modern operating systems still use the same mechanism</strong>. OS and their hardware drivers are now used by applications instead of BIOS but the same “trap” mechanism is used, either with software interruptions or explicit syscall instruction (cf x86-64).</p>
<p>Most applications do not call syscalls explicitly but use the wrappers provided by libc implementations alongside other “standard” libraries (libpthread, etc.). These standard libraries have been designed a long time ago and still bear the stigma of the long gone time when multicore computers were not widespread.</p>
<h2 id="i-cant-get-errno-satisfaction">I can’t get errno satisfaction</h2>
<p>A good example to show how bad it can get is error management in libc: a global variable “errno” is used to indicate if the libc call executed last has produced an error. This approach is bad in at least three ways: (1) it has weak multithreading support, (2) it does not encourage systematic error checking, (3) it produces additional overhead (memory access).</p>
<ol type="1">
<li>To support multithreading, that is several threads calling into the libc concurrently, and to avoid mixing up “errno” values for different calls, the global variable is in fact aliased and stored in each thread local storage (TLS). User-space threads (also called green threads) implementations also have to deal with this mandatory global variable at the core of all Posix C programs. For instance, if we look into the sources of the runtime system for GHC (Glasgow Haskell Compiler), we can see that errno has special treatment. In “schedule” function in rts/Schedule.c we even have the following comment:</li>
</ol>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><a class="sourceLine" id="cb1-1" title="1"><span class="co">// And save the current errno in this thread.</span></a>
<a class="sourceLine" id="cb1-2" title="2"><span class="co">// XXX: possibly bogus for SMP because this thread might already</span></a>
<a class="sourceLine" id="cb1-3" title="3"><span class="co">// be running again, see code below.</span></a></code></pre></div>
<ol start="2" type="1">
<li>Checking for errors returned by libc functions is cumbersome because error codes are not directly returned by functions. In general, if a libc function returns -1 or NULL, then it signals that an error occured whose code is stored in “errno”. However this is not an unbreakable rule. From the manual of “errno”:</li>
</ol>
<blockquote>
<p>“For some system calls and library functions (e.g., getpriority(2)), -1 is a valid return on success. In such cases, a successful return can be distinguished from an error return by setting errno to zero before the call, and then, if the call returns a status that indicates that an error may have occurred, checking to see if errno has a nonzero value.”</p>
</blockquote>
<p>A language is not considered good for what it allows but for what it makes easy to do. C and its standard library make error checking laborious and error-prone.</p>
<ol start="3" type="1">
<li>“errno” is stored in memory which is notoriously slower than registers (even if it is presumably cached and maybe even forwarded in the instruction pipeline). It makes no sense for such a volatile value that is used once before being discarded.</li>
</ol>
<p>Note: the whole “errno” issue is very similar to the flag register EFLAG in x86 architectures containing carry-flag, overflow-flag, etc. This register is likely to be aliased to support out-of-order or concurrent instruction executions just like “errno”. Notice how in Itanium ISA (IA-64), Intel avoided this issue by using several flag registers (“predicate” registers).</p>
<h2 id="what-can-we-do-about-it">What can we do about it?</h2>
<p>Exceptions aside, the most common way to indicate that an error has occured during the execution of a function is to use a sum type. In Haskell we can use the following types:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb2-1" title="1"><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</a>
<a class="sourceLine" id="cb2-2" title="2"><span class="kw">data</span> <span class="dt">Either</span> a b <span class="ot">=</span> <span class="dt">Left</span> a <span class="op">|</span> <span class="dt">Right</span> b</a></code></pre></div>
<p>In particular, if the function only indicates if it fails or succeeds without returning a value, we will use “Maybe Error” as a return type: Nothing will indicate that no error occured, “Just err” will indicate that the error “err” occured. For instance, we could have this prototype for “close” system call (used to close a file descriptor):</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb3-1" title="1"><span class="ot">close ::</span> <span class="dt">FileDescriptor</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> (<span class="dt">Maybe</span> <span class="dt">Error</span>)</a></code></pre></div>
<p>Similarily, we can use Either sum type to return a value or an error. By convention we use “Right” constructor to return the “right” value (i.e. not an error) and “Left” constructor to return an error. So the return type used by most system calls will be “Either Error a” where “a” depends on the syscall return value type. For instance, for “pipe” syscall that returns the two ends (file descriptors) of a newly created channel:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" title="1"><span class="ot">pipe ::</span> <span class="dt">IO</span> (<span class="dt">Either</span> <span class="dt">Error</span> (<span class="dt">FileDescriptor</span>,<span class="dt">FileDescriptor</span>))</a></code></pre></div>
<h2 id="wrapping-system-calls-using-ffi">Wrapping system calls using FFI</h2>
<p>Now that we know how we want to access system calls, we have to wrap them into functions with appropriate prototypes. My first idea was to wrap “syscall” libc function that allows to call any system call. However the only thing it does is what we want to avoid: setting errno…</p>
<p>So we have to use the (not so) hard way, that is to use the OS syscall convention directly. With Linux on x86-64 architectures, the syscall number is to be found in RAX register and parameters (up to 6) in RDI, RSI, RDX, R10, R8 and R9 registers (see: man 2 syscall).</p>
<p>The first approach is to write a function that converts between the convention used by C and the syscall convention. Using Haskell FFI, we can easily call the C function.</p>
<h2 id="wrapping-system-calls-using-primops">Wrapping system calls using PrimOps</h2>
<p>In order to bypass the FFI that is known to be a little bit slow, we can directly use the calling convention used internally by GHC and provide a new “primop” for system calls.</p>
<p>Internally, GHC uses the following (virtual) registers for the STG calling convention: Base, Sp, Hp, R1, R2, R3, R4, R5, R6 and SpLim. Function parameters (up to 6) are passed in R1-R6 virtual registers and if there are more than 6 parameters, they are stored in the stack accessible through Sp (“stack pointer”). The first additional parameter is stored in Sp[1] and so on upwards for other parameters. There is no return convention because every function performs a tail-call (a jump) to the next one whose address is stored on the top of the stack (Sp[0]).</p>
<p>On x86-64 architectures, virtual registers are respectively mapped on R13, RBP, R12, RBX, R14, RSI, RDI, R8, R9 and R15. After the syscall, we need to put RAX value (the value returned by the syscall) into RBX and to jump to SP[0], that is [RBP].</p>
<h2 id="implementation">Implementation</h2>
<p>I have implemented the two approaches in my haskus-system package. The most interesting files for the subject at stake are :</p>
<ul>
<li><a href="https://github.com/haskus/haskus-system/blob/master/src/lib/Haskus/Arch/X86_64/Linux/syscall.c">syscall.c</a> for assembly part</li>
<li><a href="https://github.com/haskus/haskus-system/blob/master/src/lib/Haskus/Arch/X86_64/Linux/Syscall.hs">Syscall.hs</a> for the FFI and foreign primops part</li>
</ul>
<p>The other files in Haskus.Arch.X86_64.Linux.* are syscalls wrapped as presented in introduction (returning either Maybe or Either). At the time of writing, I still have a lot of them to wrap.</p>
<h2 id="future-work">Future work</h2>
<p>This implementation is only for Linux on x86-64 architectures. We could easily do the same thing for other architectures and OS. It may allow us to define a more up to date common interface to operating systems (instead of Posix one). In addition, we are no longer tied to C language and C libraries for the interaction with the OS. This is one step towards a full Haskell software stack.</p>
<p>It could be fun and useful to support inline assembly directly into Haskell files. Even more if custom calling conventions could be defined so that Haskell compiler register allocator can optimize register use and so that we could delete the useless calling convention convertion functions written in assembly language.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>UNIX philosophy: a praise for functional programming</title>
    <link href="http://www.hsyl20.fr/home/posts/2014-02-14-unix-philosophy-a-praise-for-functional-programming.html" />
    <id>http://www.hsyl20.fr/home/posts/2014-02-14-unix-philosophy-a-praise-for-functional-programming.html</id>
    <published>2014-02-14T00:00:00Z</published>
    <updated>2014-02-14T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">UNIX philosophy: a praise for functional programming</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Functional%20programming.html">Functional programming</a>, <a href="http://www.hsyl20.fr/home/tags/UNIX.html">UNIX</a></td>
               <td class="date">February 14, 2014</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>It is often stated that UNIX philosophy consists in writing small programs that do a single thing right and that are composable. For instance, Douglas McIlroy describes it as follows:</p>
<blockquote>
<p>This is the Unix philosophy: Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.</p>
</blockquote>
<p>Except for the last part of the quotation about text streams being universal (he meant ASCII text streams, before the encoding hell era), it is exactly the approach followed in functional programming. Indeed, we write small composable/modular functions with clear interfaces (statically typed, indicating whether side-effects occur, etc.).</p>
<p>So what does it mean? We could imagine a kind of shell where the separation between programs and functions is blurred. Oh wait! This is called a read-eval-print-loop (REPL) and we already have GHCi for instance (interactive interpreter of the Glasgow Haskell Compiler (GHC)).</p>
<p>So what could be the next steps?</p>
<ul>
<li>Blur even more the difference between scripting and programming</li>
<li>Get rid of crappy shell scripts (bash syntax anyone?) and use modules such as <a href="https://github.com/yesodweb/Shelly.hs">Shelly</a></li>
<li>Build an enhanced shell/repl with integrated completion, enhanced output, etc.
<ul>
<li>For instance, <a href="http://www.enlightenment.org/p.php?p=about/terminology">Terminology</a> is able to display pictures and videos directly in the “console”</li>
<li><a href="https://github.com/mzero/plush">Plush</a> aims to provide enhanced HTML console output</li>
</ul></li>
</ul>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Continuations avec Scala</title>
    <link href="http://www.hsyl20.fr/home/posts/2010-07-16-continuations-avec-scala.html" />
    <id>http://www.hsyl20.fr/home/posts/2010-07-16-continuations-avec-scala.html</id>
    <published>2010-07-16T00:00:00Z</published>
    <updated>2010-07-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Continuations avec Scala</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/Scala.html">Scala</a>, <a href="http://www.hsyl20.fr/home/tags/CPS.html">CPS</a></td>
               <td class="date">July 16, 2010</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>Une des nouveautés de Scala 2.8 est le plugin qui ajoute le support des continuations. Je vous présente un exemple dans la suite de ce post.</p>
<p>L’exemple qui suit est repris depuis <a href="http://scala-programming-language.1934581.n4.nabble.com/Delimited-continuations-and-Scala-td1947779.html#a1947779">ici</a></p>
<div class="sourceCode" id="cb1"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">import</span> scala.<span class="fu">continuations</span>._ </a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw">import</span> scala.<span class="fu">continuations</span>.<span class="fu">ControlContext</span>._ </a>
<a class="sourceLine" id="cb1-3" title="3"></a>
<a class="sourceLine" id="cb1-4" title="4"><span class="kw">object</span> Test { </a>
<a class="sourceLine" id="cb1-5" title="5"></a>
<a class="sourceLine" id="cb1-6" title="6">  <span class="kw">var</span> producerCont : (Unit =&gt; Unit) = <span class="kw">null</span> </a>
<a class="sourceLine" id="cb1-7" title="7">  <span class="kw">var</span> consumerCont : (Int =&gt; Unit) = <span class="kw">null</span> </a>
<a class="sourceLine" id="cb1-8" title="8"></a>
<a class="sourceLine" id="cb1-9" title="9">  <span class="kw">def</span> <span class="fu">produce</span>(i : Int) : Unit @suspendable = </a>
<a class="sourceLine" id="cb1-10" title="10">    shift { </a>
<a class="sourceLine" id="cb1-11" title="11">      (k : Unit =&gt; Unit) =&gt; { </a>
<a class="sourceLine" id="cb1-12" title="12">        producerCont = k </a>
<a class="sourceLine" id="cb1-13" title="13">        <span class="fu">consumerCont</span>(i) </a>
<a class="sourceLine" id="cb1-14" title="14">      } </a>
<a class="sourceLine" id="cb1-15" title="15">    } </a>
<a class="sourceLine" id="cb1-16" title="16"></a>
<a class="sourceLine" id="cb1-17" title="17">  <span class="kw">def</span> consume : Int @ suspendable = </a>
<a class="sourceLine" id="cb1-18" title="18">    shift { </a>
<a class="sourceLine" id="cb1-19" title="19">      (k : Int =&gt; Unit) =&gt; { </a>
<a class="sourceLine" id="cb1-20" title="20">        consumerCont = k </a>
<a class="sourceLine" id="cb1-21" title="21">        <span class="kw">if</span> (producerCont != <span class="kw">null</span>) </a>
<a class="sourceLine" id="cb1-22" title="22">          <span class="fu">producerCont</span>() </a>
<a class="sourceLine" id="cb1-23" title="23">      } </a>
<a class="sourceLine" id="cb1-24" title="24">    } </a>
<a class="sourceLine" id="cb1-25" title="25"></a>
<a class="sourceLine" id="cb1-26" title="26">  <span class="kw">def</span> <span class="fu">main</span>(args: Array[String]) { </a>
<a class="sourceLine" id="cb1-27" title="27">    reset { </a>
<a class="sourceLine" id="cb1-28" title="28">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb1-29" title="29">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb1-30" title="30">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb1-31" title="31">    } </a>
<a class="sourceLine" id="cb1-32" title="32"></a>
<a class="sourceLine" id="cb1-33" title="33">    reset { </a>
<a class="sourceLine" id="cb1-34" title="34">      <span class="fu">println</span>(<span class="st">&quot;Producing: 1&quot;</span>) </a>
<a class="sourceLine" id="cb1-35" title="35">      <span class="fu">produce</span>(<span class="dv">1</span>) </a>
<a class="sourceLine" id="cb1-36" title="36">      <span class="fu">println</span>(<span class="st">&quot;Producing: 2&quot;</span>) </a>
<a class="sourceLine" id="cb1-37" title="37">      <span class="fu">produce</span>(<span class="dv">2</span>) </a>
<a class="sourceLine" id="cb1-38" title="38">      <span class="fu">println</span>(<span class="st">&quot;Producing: 3&quot;</span>) </a>
<a class="sourceLine" id="cb1-39" title="39">      <span class="fu">produce</span>(<span class="dv">3</span>) </a>
<a class="sourceLine" id="cb1-40" title="40">    } </a>
<a class="sourceLine" id="cb1-41" title="41">  } </a>
<a class="sourceLine" id="cb1-42" title="42">} </a></code></pre></div>
<p>Ce code affiche</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb2-1" title="1">Producing: <span class="dv">1</span> </a>
<a class="sourceLine" id="cb2-2" title="2">Consuming: <span class="dv">1</span> </a>
<a class="sourceLine" id="cb2-3" title="3">Producing: <span class="dv">2</span> </a>
<a class="sourceLine" id="cb2-4" title="4">Consuming: <span class="dv">2</span> </a>
<a class="sourceLine" id="cb2-5" title="5">Producing: <span class="dv">3</span> </a>
<a class="sourceLine" id="cb2-6" title="6">Consuming: <span class="dv">3</span> </a></code></pre></div>
<p>Essayons de comprendre pourquoi. Le premier code exécuté (la fonction “main”) est :</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb3-1" title="1">reset { </a>
<a class="sourceLine" id="cb3-2" title="2">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb3-3" title="3">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb3-4" title="4">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb3-5" title="5">    } </a></code></pre></div>
<p>Ce qui est équivalent à :</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb4-1" title="1">reset { </a>
<a class="sourceLine" id="cb4-2" title="2">      <span class="kw">val</span> a = consume</a>
<a class="sourceLine" id="cb4-3" title="3">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+a) </a>
<a class="sourceLine" id="cb4-4" title="4">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb4-5" title="5">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb4-6" title="6">    } </a></code></pre></div>
<p>Ce qui est équivalent à :</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb5-1" title="1">reset { </a>
<a class="sourceLine" id="cb5-2" title="2">      <span class="kw">val</span> a = shift { </a>
<a class="sourceLine" id="cb5-3" title="3">           (k : Int =&gt; Unit) =&gt; { </a>
<a class="sourceLine" id="cb5-4" title="4">               consumerCont = k </a>
<a class="sourceLine" id="cb5-5" title="5">               <span class="kw">if</span> (producerCont != <span class="kw">null</span>) </a>
<a class="sourceLine" id="cb5-6" title="6">               <span class="fu">producerCont</span>() </a>
<a class="sourceLine" id="cb5-7" title="7">           } </a>
<a class="sourceLine" id="cb5-8" title="8">      } </a>
<a class="sourceLine" id="cb5-9" title="9">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+a) </a>
<a class="sourceLine" id="cb5-10" title="10">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb5-11" title="11">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb5-12" title="12">    } </a></code></pre></div>
<p>Rappelons qu’un “shift” ne peut être rencontré que dans le contexte d’un “reset”. Lorsqu’un shift est rencontré, une fonction est créée de façon à ce qu’un argument remplace l’appel à “shift” :</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb6-1" title="1"><span class="kw">def</span> <span class="fu">myCont1</span>(arg: ?): Unit = {</a>
<a class="sourceLine" id="cb6-2" title="2">      <span class="kw">val</span> a = arg</a>
<a class="sourceLine" id="cb6-3" title="3">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+a) </a>
<a class="sourceLine" id="cb6-4" title="4">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb6-5" title="5">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb6-6" title="6">    } </a></code></pre></div>
<p>Si le type de retour de la fonction peut être inféré de façon classique (“println” donc “Unit”), c’est plus compliqué pour le type de l’argument “arg”. Or cette fonction que j’ai appelée “myCont1” va être passée comme argument à la fonction contenue dans le “shift” qui prend en argument “k : Int =&gt; Unit”. Donc le type de “arg” est “Int”.</p>
<p>Maintenant ce qui se passe est simple. La fonction contenue dans “shift” est appelée avec en argument la fonction “myCont1”. Si on regarde le code :</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb7-1" title="1">consumerCont = k </a>
<a class="sourceLine" id="cb7-2" title="2"><span class="kw">if</span> (producerCont != <span class="kw">null</span>) </a>
<a class="sourceLine" id="cb7-3" title="3">    <span class="fu">producerCont</span>() </a></code></pre></div>
<p>On s’aperçoit que l’argument “k” qui référence “myCont1” est sauvegardé mais jamais utilisé. Comme “producerCont” est null, il ne se passe rien d’autre. Après ça, le code exécuté est celui situé après le “reset”, c’est-à-dire l’autre “reset” :</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb8-1" title="1">reset { </a>
<a class="sourceLine" id="cb8-2" title="2">      <span class="fu">println</span>(<span class="st">&quot;Producing: 1&quot;</span>) </a>
<a class="sourceLine" id="cb8-3" title="3">      <span class="fu">produce</span>(<span class="dv">1</span>) </a>
<a class="sourceLine" id="cb8-4" title="4">      <span class="fu">println</span>(<span class="st">&quot;Producing: 2&quot;</span>) </a>
<a class="sourceLine" id="cb8-5" title="5">      <span class="fu">produce</span>(<span class="dv">2</span>) </a>
<a class="sourceLine" id="cb8-6" title="6">      <span class="fu">println</span>(<span class="st">&quot;Producing: 3&quot;</span>) </a>
<a class="sourceLine" id="cb8-7" title="7">      <span class="fu">produce</span>(<span class="dv">3</span>) </a>
<a class="sourceLine" id="cb8-8" title="8">    } </a></code></pre></div>
<p>Le premier “println” affiche “Producing: 1”. Ensuite, la fonction “produce” est appelée. Si on la remplace, comme précédemment, par sa définition, on obtient la fonction suivante :</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb9-1" title="1"><span class="kw">def</span> <span class="fu">myCont2</span>(arg: Unit) : Unit = {</a>
<a class="sourceLine" id="cb9-2" title="2">      <span class="co">// Déjà fait : println(&quot;Producing: 1&quot;) </span></a>
<a class="sourceLine" id="cb9-3" title="3">      arg <span class="co">// Cet argument ne sert à rien car il ne fait rien (type Unit)</span></a>
<a class="sourceLine" id="cb9-4" title="4">      <span class="fu">println</span>(<span class="st">&quot;Producing: 2&quot;</span>) </a>
<a class="sourceLine" id="cb9-5" title="5">      <span class="fu">produce</span>(<span class="dv">2</span>) </a>
<a class="sourceLine" id="cb9-6" title="6">      <span class="fu">println</span>(<span class="st">&quot;Producing: 3&quot;</span>) </a>
<a class="sourceLine" id="cb9-7" title="7">      <span class="fu">produce</span>(<span class="dv">3</span>) </a>
<a class="sourceLine" id="cb9-8" title="8">}</a></code></pre></div>
<p>Cette fonction est passée à la fonction contenue dans le “shift” défini dans la fonction “produce”. Si on regarde le code :</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb10-1" title="1">producerCont = k </a>
<a class="sourceLine" id="cb10-2" title="2"><span class="fu">consumerCont</span>(i) </a></code></pre></div>
<p>On constate que la fonction “myCont2” est sauvegardée dans “producerCont”. Puis on appelle la fonction “consumerCont”. Rappelez-vous, nous avions sauvegardé dans “consumerCont” la fonction “myCont1”. C’est donc cette dernière qui est exécutée avec pour argument “i” qui est égal à 1. Si on regarde le code de “myCont1”, on voit que “println” est appelé pour afficher “Consuming: 1”.</p>
<p>Le reste de “myCont1” s’exécute et un nouvel appel à “consume” est effectué. Comme précédemment, une fonction “myCont3” sera créée. Elle contiendra la suite de “myCont1”, c’est-à-dire :</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb11-1" title="1"><span class="kw">def</span> <span class="fu">myCont3</span>(arg: Int): Unit = {</a>
<a class="sourceLine" id="cb11-2" title="2">      <span class="co">// Déjà fait : println(&quot;Consuming: &quot;+consume)</span></a>
<a class="sourceLine" id="cb11-3" title="3">      <span class="kw">val</span> a = arg</a>
<a class="sourceLine" id="cb11-4" title="4">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+a) </a>
<a class="sourceLine" id="cb11-5" title="5">      <span class="fu">println</span>(<span class="st">&quot;Consuming: &quot;</span>+consume) </a>
<a class="sourceLine" id="cb11-6" title="6">    } </a></code></pre></div>
<p>Cette fois-ci cependant, “producerCont” ne sera pas “null” puisqu’elle référence “myCont2”. “myCont2” sera donc appelée, permettant ainsi la production d’une nouvelle valeur (“produce(2)”) qui elle-même appellera “consumerCont” qui consommera une valeur (“consume”) et qui elle-même appellera “producerCont”, permettant ainsi la production d’une nouvelle valeur, etc. La condition d’arrêt est quand “producerCont” est appelée alors que toutes les valeurs ont été produites :</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb12-1" title="1"><span class="kw">def</span> <span class="fu">myContN</span>() : Unit = {</a>
<a class="sourceLine" id="cb12-2" title="2">      <span class="co">// Déjà fait : println(&quot;Producing: 1&quot;) </span></a>
<a class="sourceLine" id="cb12-3" title="3">      <span class="co">// Déjà fait : produce(1) </span></a>
<a class="sourceLine" id="cb12-4" title="4">      <span class="co">// Déjà fait : println(&quot;Producing: 2&quot;) </span></a>
<a class="sourceLine" id="cb12-5" title="5">      <span class="co">// Déjà fait : produce(2) </span></a>
<a class="sourceLine" id="cb12-6" title="6">      <span class="co">// Déjà fait : println(&quot;Producing: 3&quot;) </span></a>
<a class="sourceLine" id="cb12-7" title="7">      <span class="co">// Déjà fait : produce(3) </span></a>
<a class="sourceLine" id="cb12-8" title="8">}</a></code></pre></div>
<p>Arrivé à ce stade, la suite de la fonction “main” est exécutée et le programme se termine.</p>
<p>Voilà, j’espère que ce petit aperçu vous a montré la puissance de cette construction syntaxique. On a ainsi implémenté des co-routines très facilement.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Encadrer des geeks</title>
    <link href="http://www.hsyl20.fr/home/posts/2010-05-19-encadrer-des-geeks.html" />
    <id>http://www.hsyl20.fr/home/posts/2010-05-19-encadrer-des-geeks.html</id>
    <published>2010-05-19T00:00:00Z</published>
    <updated>2010-05-19T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Encadrer des geeks</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: </td>
               <td class="date">May 19, 2010</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>Un article très intéressant sur le management des geeks : <a href="http://www.computerworld.com/s/article/9137708/Opinion_The_unspoken_truth_about_managing_geeks">http://www.computerworld.com/s/article/9137708/Opinion_The_unspoken_truth_about_managing_geeks</a></p>
<p>“Gaining respect is not a matter of being the boss and has nothing to do with being likeable or sociable; whether you talk, eat or smell right; or any measure that isn’t directly related to the work.”</p>
<p>“While everyone would like to work for a nice person who is always right, IT pros will prefer a jerk who is always right over a nice person who is always wrong.”</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>SunBurn : DSL</title>
    <link href="http://www.hsyl20.fr/home/posts/2009-06-19-sunburn-dsl.html" />
    <id>http://www.hsyl20.fr/home/posts/2009-06-19-sunburn-dsl.html</id>
    <published>2009-06-19T00:00:00Z</published>
    <updated>2009-06-19T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">SunBurn : DSL</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/SunBurn.html">SunBurn</a>, <a href="http://www.hsyl20.fr/home/tags/Raytracing.html">Raytracing</a>, <a href="http://www.hsyl20.fr/home/tags/DSL.html">DSL</a>, <a href="http://www.hsyl20.fr/home/tags/Scala.html">Scala</a></td>
               <td class="date">June 19, 2009</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>J’ai commencé à créer un début de DSL (Domain Specific Language) pour SunBurn. Scala permet en effet de créer des structures qui ressemblent à d’autres langages alors qu’il s’agit de Scala normal. J’ai donc essayé de me rapprocher d’un langage de type POV-ray. Lorsque la version 2.8 de Scala sera sortie, il sera peut-être possible de l’améliorer avec des paramètres nommés et des valeurs par défaut. Enfin on n’en est pas encore là !</p>
<p>Voici une capture d’écran d’un rendu suivi du code qui a permis de le créer :</p>
<p><img src="http://www.hsyl20.fr/home../images/sunburn/sunburn_04.png" /></p>
<div class="sourceCode" id="cb1"><pre class="sourceCode scala"><code class="sourceCode scala"><a class="sourceLine" id="cb1-1" title="1"><span class="kw">import</span> sunburn.<span class="fu">geometry</span>._</a>
<a class="sourceLine" id="cb1-2" title="2"><span class="kw">import</span> sunburn.<span class="fu">geometry</span>.<span class="fu">Vector3D</span>._</a>
<a class="sourceLine" id="cb1-3" title="3"><span class="kw">import</span> sunburn.<span class="fu">core</span>._</a>
<a class="sourceLine" id="cb1-4" title="4"><span class="kw">import</span> sunburn.<span class="fu">samplers</span>._</a>
<a class="sourceLine" id="cb1-5" title="5"><span class="kw">import</span> sunburn.<span class="fu">colors</span>._</a>
<a class="sourceLine" id="cb1-6" title="6"><span class="kw">import</span> sunburn.<span class="fu">colors</span>.<span class="fu">RGBColor</span>._</a>
<a class="sourceLine" id="cb1-7" title="7"><span class="kw">import</span> sunburn.<span class="fu">materials</span>._</a>
<a class="sourceLine" id="cb1-8" title="8"><span class="kw">import</span> sunburn.<span class="fu">cameras</span>._</a>
<a class="sourceLine" id="cb1-9" title="9"><span class="kw">import</span> sunburn.<span class="fu">lights</span>._</a>
<a class="sourceLine" id="cb1-10" title="10"></a>
<a class="sourceLine" id="cb1-11" title="11"><span class="kw">object</span> Main {</a>
<a class="sourceLine" id="cb1-12" title="12">   <span class="kw">def</span> <span class="fu">main</span>(args: Array[String]) = {     </a>
<a class="sourceLine" id="cb1-13" title="13">      <span class="kw">val</span> myworld = <span class="kw">new</span> World {</a>
<a class="sourceLine" id="cb1-14" title="14">         <span class="fu">objects</span> (</a>
<a class="sourceLine" id="cb1-15" title="15">            <span class="kw">new</span> Sphere {</a>
<a class="sourceLine" id="cb1-16" title="16">               center = (<span class="fl">0.0</span>, <span class="fl">12.0</span>, <span class="fl">0.0</span>)                </a>
<a class="sourceLine" id="cb1-17" title="17">               radius = <span class="fl">10.0</span>                </a>
<a class="sourceLine" id="cb1-18" title="18">               material = <span class="kw">new</span> MatteMaterial {                    </a>
<a class="sourceLine" id="cb1-19" title="19">                  color = Yellow                    </a>
<a class="sourceLine" id="cb1-20" title="20">                  diffuse = <span class="fl">0.5</span>                    </a>
<a class="sourceLine" id="cb1-21" title="21">                  ambient = <span class="fl">0.5</span>                </a>
<a class="sourceLine" id="cb1-22" title="22">               }            </a>
<a class="sourceLine" id="cb1-23" title="23">            },            </a>
<a class="sourceLine" id="cb1-24" title="24">            <span class="kw">new</span> Sphere {                </a>
<a class="sourceLine" id="cb1-25" title="25">               center = (<span class="fl">20.0</span>, <span class="fl">10.0</span>, <span class="fl">0.0</span>)                </a>
<a class="sourceLine" id="cb1-26" title="26">               radius = <span class="fl">5.0</span>                </a>
<a class="sourceLine" id="cb1-27" title="27">               material = <span class="kw">new</span> MatteMaterial {                    </a>
<a class="sourceLine" id="cb1-28" title="28">                  color = Red                    </a>
<a class="sourceLine" id="cb1-29" title="29">                  diffuse = 1                    </a>
<a class="sourceLine" id="cb1-30" title="30">                  ambient = 1                </a>
<a class="sourceLine" id="cb1-31" title="31">               }            </a>
<a class="sourceLine" id="cb1-32" title="32">            },            </a>
<a class="sourceLine" id="cb1-33" title="33">            <span class="kw">new</span> Plane {                </a>
<a class="sourceLine" id="cb1-34" title="34">               point = (<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">0</span>)                </a>
<a class="sourceLine" id="cb1-35" title="35">               normal = (<span class="fl">0.0</span>, <span class="fl">1.0</span>, <span class="dv">0</span>)                </a>
<a class="sourceLine" id="cb1-36" title="36">               material = <span class="kw">new</span> MatteMaterial {                    </a>
<a class="sourceLine" id="cb1-37" title="37">                  color = <span class="fu">RGBColor</span>(<span class="fl">0.2</span>,<span class="fl">0.2</span>,<span class="fl">0.2</span>)                    </a>
<a class="sourceLine" id="cb1-38" title="38">                  diffuse = <span class="fl">2.2</span>                    </a>
<a class="sourceLine" id="cb1-39" title="39">                  ambient = <span class="fl">2.2</span>                </a>
<a class="sourceLine" id="cb1-40" title="40">               }            </a>
<a class="sourceLine" id="cb1-41" title="41">            }        </a>
<a class="sourceLine" id="cb1-42" title="42">         )            </a>
<a class="sourceLine" id="cb1-43" title="43">         </a>
<a class="sourceLine" id="cb1-44" title="44">         backgroundColor = Green                </a>
<a class="sourceLine" id="cb1-45" title="45">         ambientLight = <span class="kw">new</span> SimpleAmbientLight {            </a>
<a class="sourceLine" id="cb1-46" title="46">            intensity = <span class="fl">0.2</span>            </a>
<a class="sourceLine" id="cb1-47" title="47">            color = Blue        </a>
<a class="sourceLine" id="cb1-48" title="48">         }        </a>
<a class="sourceLine" id="cb1-49" title="49">         </a>
<a class="sourceLine" id="cb1-50" title="50">         <span class="fu">lights</span> (            </a>
<a class="sourceLine" id="cb1-51" title="51">            <span class="kw">new</span> PointLight {                </a>
<a class="sourceLine" id="cb1-52" title="52">               intensity = <span class="fl">8.0</span>                </a>
<a class="sourceLine" id="cb1-53" title="53">               color = White                </a>
<a class="sourceLine" id="cb1-54" title="54">               location =  (<span class="dv">10</span>,<span class="dv">30</span>,<span class="dv">10</span>)            </a>
<a class="sourceLine" id="cb1-55" title="55">            }        </a>
<a class="sourceLine" id="cb1-56" title="56">         )     </a>
<a class="sourceLine" id="cb1-57" title="57">      }        </a>
<a class="sourceLine" id="cb1-58" title="58">      </a>
<a class="sourceLine" id="cb1-59" title="59">      <span class="kw">val</span> vp = <span class="kw">new</span> ViewPlane {        </a>
<a class="sourceLine" id="cb1-60" title="60">         size = (<span class="dv">800</span>,<span class="dv">600</span>)        </a>
<a class="sourceLine" id="cb1-61" title="61">         resolution = <span class="fl">0.2</span>        </a>
<a class="sourceLine" id="cb1-62" title="62">         sampler = <span class="kw">new</span> <span class="fu">BufferedSampler</span>( <span class="kw">new</span> <span class="fu">ShuffledSampler</span>(</a>
<a class="sourceLine" id="cb1-63" title="63">                     <span class="kw">new</span> <span class="fu">MultiJitteredSampler</span>(<span class="dv">100</span>)))    </a>
<a class="sourceLine" id="cb1-64" title="64">      }    </a>
<a class="sourceLine" id="cb1-65" title="65">      </a>
<a class="sourceLine" id="cb1-66" title="66">      <span class="kw">val</span> c = <span class="kw">new</span> <span class="fu">ThinLensCamera</span>(myworld, vp) {        </a>
<a class="sourceLine" id="cb1-67" title="67">         eye =  <span class="fu">Point3D</span>(<span class="dv">0</span>,<span class="dv">40</span>,<span class="dv">40</span>)        </a>
<a class="sourceLine" id="cb1-68" title="68">         lookat = <span class="fu">Point3D</span>(<span class="dv">0</span>,<span class="dv">0</span>,<span class="dv">0</span>)        </a>
<a class="sourceLine" id="cb1-69" title="69">         viewDistance = <span class="fl">50.0</span>        </a>
<a class="sourceLine" id="cb1-70" title="70">         focalDistance = <span class="fl">40.0</span>        </a>
<a class="sourceLine" id="cb1-71" title="71">         lensRadius = <span class="fl">2.0</span>    </a>
<a class="sourceLine" id="cb1-72" title="72">      }        </a>
<a class="sourceLine" id="cb1-73" title="73">      </a>
<a class="sourceLine" id="cb1-74" title="74">      <span class="kw">val</span> r = <span class="kw">new</span> <span class="fu">Displayer</span>(c)    </a>
<a class="sourceLine" id="cb1-75" title="75">      </a>
<a class="sourceLine" id="cb1-76" title="76">      c.<span class="fu">render</span>  </a>
<a class="sourceLine" id="cb1-77" title="77">   }</a>
<a class="sourceLine" id="cb1-78" title="78">}</a></code></pre></div>
<p>Le code est assez explicite. Au début on a les différents “imports”. Ensuite on a la définition du monde (“World”) avec les objets qui le composent, les lumières (dont la lumière ambiente) ainsi que la couleur à l’infini.</p>
<p>On crée ensuite un ViewPlane. Le ViewPlane définit :</p>
<ul>
<li>la taille de l’image finale (ici 800x600 pixels).</li>
<li>la résolution, c’est-à-dire la taille d’un pixel de l’image finale en unité du monde. Ici avec une résolution de 0.2, 1 unité dans le monde occupe 5 pixels (5 * 0.2)</li>
<li>l’échantillonneur (sampler). Pour chaque pixel de l’image finale, on envoie plusieurs rayons répartis sur le carré de taille 0.2x0.2. La répartition de ces rayons dépend de l’échantillonneur. Ici on a 100 rayons par pixel avec une répartition MultiJittered. On fait ensuite la moyenne des différentes couleurs renvoyées par les rayons.</li>
</ul>
<p>Ensuite on définit une caméra utilisant une lentille mince (ThinLens) que l’on règle pour que la distance focale soit sur la sphère jaune.</p>
<p>Enfin on crée un Displayer sur cette caméra. Il s’agit en fait d’une fenêtre affichant l’image au fur et à mesure que le rendu s’effectue (ainsi que l’image finale bien sûr). On lance ensuite le rendu de la caméra avec la méthode “render”.</p>
<p>Vous pouvez trouver le code (sous Licence GPL v3) <a href="http://github.com/hsyl20/SunBurn/">ici</a></p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>SunBurn : ajouts de caméras, de lumières et de matériaux</title>
    <link href="http://www.hsyl20.fr/home/posts/2009-06-11-sunburn-ajouts-de-cameras-de-lumieres-et-de-materiaux.html" />
    <id>http://www.hsyl20.fr/home/posts/2009-06-11-sunburn-ajouts-de-cameras-de-lumieres-et-de-materiaux.html</id>
    <published>2009-06-11T00:00:00Z</published>
    <updated>2009-06-11T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">SunBurn : ajouts de caméras, de lumières et de matériaux</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/SunBurn.html">SunBurn</a>, <a href="http://www.hsyl20.fr/home/tags/Raytracing.html">Raytracing</a>, <a href="http://www.hsyl20.fr/home/tags/Scala.html">Scala</a></td>
               <td class="date">June 11, 2009</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>J’ai eu un peu de temps pour ajouter de nouveaux éléments à mon RayTracer en Scala. Tout d’abord deux nouvelles caméras (PinHole et ThinLens). Quelques sources de lumière (Directional, PointLight et Ambient). Et enfin le matériau Matte.</p>
<p>Sur la capture on peut voir deux sphères et un plan (gris) avec un matériau Matte éclairés par une PointLight. Le tout dans un monde vert. Les sphères sont coupées par le plan.</p>
<p><img src="http://www.hsyl20.fr/home../images/sunburn/sunburn_03.png" /></p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>SunBurn Ray Tracer - Premières images</title>
    <link href="http://www.hsyl20.fr/home/posts/2009-05-27-sunburn-ray-tracer-premieres-images.html" />
    <id>http://www.hsyl20.fr/home/posts/2009-05-27-sunburn-ray-tracer-premieres-images.html</id>
    <published>2009-05-27T00:00:00Z</published>
    <updated>2009-05-27T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">SunBurn Ray Tracer - Premières images</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/SunBurn.html">SunBurn</a>, <a href="http://www.hsyl20.fr/home/tags/Raytracing.html">Raytracing</a>, <a href="http://www.hsyl20.fr/home/tags/Scala.html">Scala</a></td>
               <td class="date">May 27, 2009</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>J’ai commencé à développer un Ray Tracer en Scala. Pourquoi un Ray Tracer me direz-vous ? Et bien parce que je suis en train de lire le livre Ray Tracing From The Ground Up de Kevin Suffern et parce que j’avais envie ! ;)</p>
<p>Voici donc une première capture d’écran où l’on peut voir 2 sphères (rouge et jaune) et un plan (vert) qui coupe la sphère jaune.</p>
<p><img src="http://www.hsyl20.fr/home../images/sunburn/sunburn_01.png" /></p>
<p>Évidemment sans les ombres et tout le reste, ça ne rend pas très bien ! Néanmoins si vous zoomez vous pourrez voir qu’il y a de l’anti-aliasing :</p>
<p><img src="http://www.hsyl20.fr/home../images/sunburn/sunburn_02.png" /></p>
<p>J’ai en fait implémenté les différentes méthodes d’échantillonnage présentées dans le livre. C’est à dire (je ne connais pas les noms en français) : Regular, Random, Jittered, N-Rooks, Multi-Jittered et Hammersley. Sur l’image ci-dessus il s’agit d’un échantillonnage multi-jittering avec 36 échantillons par pixel.</p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Hackers</title>
    <link href="http://www.hsyl20.fr/home/posts/2008-12-02-hackers.html" />
    <id>http://www.hsyl20.fr/home/posts/2008-12-02-hackers.html</id>
    <published>2008-12-02T00:00:00Z</published>
    <updated>2008-12-02T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Hackers</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: </td>
               <td class="date">December  2, 2008</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>Je viens de tomber sur un texte intéressant à propos de nous, les “hackers” (au sens original du terme).</p>
<p>The most obvious common ‘personality’ characteristics of hackers are high intelligence, consuming curiosity, and facility with intellectual abstractions. Also, most hackers are ‘neophiles’, stimulated by and appreciative of novelty (especially intellectual novelty). Most are also relatively individualistic and anti-conformist.[…]</p>
<p>Ça se passe <a href="http://catb.org/jargon/html/personality.html">ici</a></p>
    </section>

</article>
]]></summary>
</entry>
<entry>
    <title>Ruby-EFL tutorial</title>
    <link href="http://www.hsyl20.fr/home/posts/2007-11-02-rubyefl-tutorial.html" />
    <id>http://www.hsyl20.fr/home/posts/2007-11-02-rubyefl-tutorial.html</id>
    <published>2007-11-02T00:00:00Z</published>
    <updated>2007-11-02T00:00:00Z</updated>
    <summary type="html"><![CDATA[<article>
    <header>
       <div class="title">Ruby-EFL tutorial</div>
       <table class="tags_date">
           <tr>
               <td class="tags">Tags: <a href="http://www.hsyl20.fr/home/tags/EFL.html">EFL</a></td>
               <td class="date">November  2, 2007</td>
           </tr>
        </table>
        <hr />
    </header>

    <section>
    <p>I am writing a tutorial about using EFL (Enlightenment Foundations Libraries) with RUBY using bindings provided <a href="http://code-monkey.de/pages/ruby-efl">here</a>.</p>
<p>Even if it is not finished, I publish it: <a href="http://www.hsyl20.fr/home../files/2007-ruby-efl-tutorial.pdf">Tutorial</a></p>
    </section>

</article>
]]></summary>
</entry>

</feed>
