<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Mike Limansky blog</title>
    <subtitle><![CDATA[Latest blog posts]]></subtitle>
    <link href="http://www.limansky.me/atom.xml" rel="self" />
    <link href="http://www.limansky.me" />
    <id>http://www.limansky.me/atom.xml</id>
    <author>
        <name>Mike Limansky</name>
        
        <email>mike.limansky@gmail.com</email>
        
    </author>
    <updated>2024-02-23T00:00:00Z</updated>
    <entry>
    <title>32рдле</title>
    <link href="http://limansky.me/posts/2024-02-23-32rdle.html" />
    <id>http://limansky.me/posts/2024-02-23-32rdle.html</id>
    <published>2024-02-23T00:00:00Z</published>
    <updated>2024-02-23T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Almost all my career I’ve been mostly a backend guy. Even when I was working with mobile platforms
it usually was related to different background services. And I’m ok with that. Well, sometimes
it might be difficult to explain people what are you actually doing, but I still prefer this things just
because it’s more interesting for me, and, to be honest, I’m pretty bad in drawing, choosing colors,
etc.</p>
<p>However, some time ago I played <a href="https://duotrigordle.com">Duotrigordle</a> and I thought what it would
be great to have it in Russian. And that lead me to another pet project in a very uncommon
environment for me. It’s a pure client word guessing game. Of course, I could use Scala.js for that,
but I wanted to keep it light, and also, to have a little bit practice in the common frontend tools.
It took couple of months for me to create it from scratch. It still have a
nasty hard to reproduce bug, but it’s available at <a href="https://32.limansky.me">32.limansky.me</a>, so you can
play it. Here I’d like to share some details and thoughts about this project development.</p>
<!--more-->
<p>I decide to use pure React because, to be honest, I have a little experience with it already. While
we developed <a href="https://xn--80ahhi0afh.xn--p1ai">Продажи.рф</a> at 1-OFD, we all participated in frontend development
a little bit. But, since 32rdle is a pure client side game, I decided not to use any
React based frameworks. I chose <a href="https://github.com/molefrog/wouter">wouter</a> for routing and
<a href="https://github.com/pmndrs/zustand">zustand</a> for state management, because both of them are simple
and lightweight libraries. Also I used <a href="https://vitejs.dev/">Vite</a> and <a href="https://vitest.dev/">Vitest</a>
because it’s easy to setup and fast. Of course, I used TypeScript for coding, because I have no
idea how and why people write any code without of types.</p>
<p>Fortunately I already had Neovim setup (<a href="https://github.com/limansky/dotfiles">my dotfiles</a>) with
LSP, so I’ve been kind of ready to start.</p>
<p>Here is a list of top 5 problems I faced with from hard to easy:</p>
<ol type="1">
<li>CSS.</li>
<li>More CSS.</li>
<li>Algorithms.</li>
<li>React itself.</li>
<li>Components organization.</li>
</ol>
<p>This list is not that I initially expected. Well, I knew what CSS is hard, but I didn’t expect it
to be that hard. Secondly, I expected React to be a bigger problem for me. I still have some
problems with understanding hooks, and what and when, should I use, but it is not the major problem.
The two last points are related. At some point I’ve found that I put to much business logic into
the components. In my case that lead to the calculation duplication. For example boards can
calculate their state themselves according to the entered words and the guessed word. However,
these states are also required for the status bar component. So I had to change the interface of the
components several times to avoid unnecessary calculation repetitions.</p>
<p>Some pieces of code I wrote still looks weird for me, and I feel like I do something wrong way. For
example I need a path parameter to be a number.</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode typescript"><code class="sourceCode typescript"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">const</span> gameParser <span class="op">=</span> (path<span class="op">:</span> <span class="dt">string</span><span class="op">,</span> loose<span class="op">?:</span> <span class="dt">boolean</span>)<span class="op">:</span> { pattern<span class="op">:</span> <span class="bu">RegExp</span><span class="op">,</span> keys<span class="op">:</span> <span class="dt">string</span>[] } <span class="kw">=&gt;</span> {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">if</span> (path <span class="op">===</span> <span class="st">&quot;/daily/:id&quot;</span>) {</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">const</span> named <span class="op">=</span> <span class="fu">parse</span>(<span class="ss">/</span><span class="sc">^\/</span><span class="ss">daily</span><span class="sc">\/(?</span><span class="ss">&lt;id&gt;</span><span class="sc">[0-9]+)$</span><span class="ss">/</span>)<span class="op">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> { pattern<span class="op">:</span> named<span class="op">.</span><span class="at">pattern</span><span class="op">,</span> keys<span class="op">:</span> [<span class="st">&#39;id&#39;</span>] }<span class="op">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  }</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="cf">return</span> <span class="fu">parse</span>(path<span class="op">,</span> loose)<span class="op">;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>}<span class="op">;</span></span></code></pre></div>
<p>This condition is looks ugly for me, but it works, and I have no idea how to make it better.</p>
<p>The whole code is available at <a href="https://github.com/limansky/32rdle">github</a>.</p>]]></summary>
</entry>
<entry>
    <title>Superstition is Perdition</title>
    <link href="http://limansky.me/posts/2023-10-06-Orange-Noise.html" />
    <id>http://limansky.me/posts/2023-10-06-Orange-Noise.html</id>
    <published>2023-10-06T00:00:00Z</published>
    <updated>2023-10-06T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Just a little bit about my free time. I haven’t been here for a while, but it was for a good reason.
This year my band finished a debut album and it available for a while on the most of the streaming services.</p>
<iframe allowfullscreen="true" height="400" width="370" src="https://band.link/on_sip/iframe?youtube_enabled=1&amp;header=1&amp;title=1&amp;theme=dark&amp;player_enabled=1&amp;picture=1&amp;footer=1" frameborder="0" scrolling="no">
</iframe>]]></summary>
</entry>
<entry>
    <title>From Scala 2 shapeless to Scala 3</title>
    <link href="http://limansky.me/posts/2021-07-26-from-scala-2-shapeless-to-scala-3.html" />
    <id>http://limansky.me/posts/2021-07-26-from-scala-2-shapeless-to-scala-3.html</id>
    <published>2021-07-26T00:00:00Z</published>
    <updated>2021-07-26T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>In this post I’d like to discover Scala 3 generic programming abilities. Scala 3 provides a lot of new features, and
generic programming is the one of the areas where we have a lot of changes. I assume that you have used
<a href="https://github.com/milessabin/shapeless">shapeless</a> with Scala 2, but if not, I’ll try to explain things in this post.
However I’d recommend to read <a href="/posts/2016-11-24-getting-started-with-shapeless.html">this post</a> before if you don’t even know what shapeless is.</p>
<!--more-->
<h3 id="tuples-in-scala-3">Tuples in Scala 3</h3>
<p>Let’s take a look at tuples in Scala 3. In previous versions of Scala we had the famous <code>Tuple1</code> .. <code>Tuple22</code> classes
defined like:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">final</span> <span class="cf">case</span> <span class="kw">class</span> Tuple2<span class="op">[+</span>T1<span class="op">,</span> <span class="op">+</span>T2<span class="op">](</span>_1<span class="op">:</span> T1<span class="op">,</span> _2<span class="op">:</span> T2<span class="op">)</span> </span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">extends</span> Product2<span class="op">[</span>T1<span class="op">,</span> T2<span class="op">]</span> </span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">with</span> Product </span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">with</span> <span class="ex">Serializable</span></span></code></pre></div>
<p>These classes are available in Scala 3 too, but there are another classes for tuples:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">sealed</span> <span class="kw">trait</span> Tuple <span class="kw">extends</span> Product</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> EmptyTuple <span class="kw">extends</span> Tuple</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> NonEmptyTuple <span class="kw">extends</span> Tuple</span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="kw">class</span> <span class="op">[+</span>H<span class="op">,</span> <span class="op">+</span>T <span class="op">&lt;:</span> Tuple<span class="op">]</span> <span class="op">*:(</span>head<span class="op">:</span> H<span class="op">,</span> tail<span class="op">:</span> T<span class="op">)</span> <span class="kw">extends</span> NonEmptyTuple</span></code></pre></div>
<p>I simplified the code a little bit, but the idea is the same. This is something new in the Scala library, but it looks
very familiar. Actually it’s a list with different types of its’ elements. This called the <em>Heterogeneous list</em>, or <code>HList</code>!
In Scala 2 we had <code>HList</code>s in shapeless, and also in some other libraries. Having heterogeneous lists in the standard library
makes a lot of sense, and now we don’t need any other HList implementation. Scala 3 tuples has a lot of useful functions, for
example they can be converted to <code>List</code>, be concatenated, zipped, etc.:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">val</span> t <span class="op">=</span> <span class="op">(</span><span class="dv">5</span><span class="op">,</span> <span class="st">&quot;String&quot;</span><span class="op">,</span> <span class="dv">3</span>d<span class="op">,</span> <span class="kw">false</span><span class="op">)</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> t<span class="op">:</span> <span class="op">(</span><span class="bu">Int</span><span class="op">,</span> <span class="ex">String</span><span class="op">,</span> <span class="ex">Double</span><span class="op">,</span> <span class="ex">Boolean</span><span class="op">)</span> <span class="op">=</span> <span class="op">(</span><span class="dv">5</span><span class="op">,</span><span class="ex">String</span><span class="op">,</span><span class="fl">3.0</span><span class="op">,</span><span class="kw">false</span><span class="op">)</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> t<span class="op">.</span>toList</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> res0<span class="op">:</span> <span class="ex">List</span><span class="op">[</span>Tuple<span class="op">.</span>Union<span class="op">[</span>t<span class="op">.</span><span class="kw">type</span><span class="op">]]</span> <span class="op">=</span> <span class="ex">List</span><span class="op">(</span><span class="dv">5</span><span class="op">,</span> <span class="ex">String</span><span class="op">,</span> <span class="fl">3.0</span><span class="op">,</span> <span class="kw">false</span><span class="op">)</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">val</span> x <span class="op">=</span> t<span class="op">.</span><span class="fu">drop</span><span class="op">(</span><span class="dv">2</span><span class="op">)</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> x<span class="op">:</span> <span class="op">(</span><span class="ex">Double</span><span class="op">,</span> <span class="ex">Boolean</span><span class="op">)</span> <span class="op">=</span> <span class="op">(</span><span class="fl">3.0</span><span class="op">,</span><span class="kw">false</span><span class="op">)</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> t <span class="op">++</span> x</span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> res1<span class="op">:</span> <span class="bu">Int</span> <span class="op">*:</span> <span class="ex">String</span> <span class="op">*:</span> <span class="ex">Double</span> <span class="op">*:</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a>  scala<span class="op">.</span>Tuple<span class="op">.</span>Concat<span class="op">[</span><span class="ex">Boolean</span> <span class="op">*:</span> scala<span class="op">.</span>Tuple$package<span class="op">.</span>EmptyTuple<span class="op">.</span><span class="kw">type</span><span class="op">,</span> x<span class="op">.</span><span class="kw">type</span><span class="op">]</span></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="op">=</span> <span class="op">(</span><span class="dv">5</span><span class="op">,</span><span class="ex">String</span><span class="op">,</span><span class="fl">3.0</span><span class="op">,</span><span class="kw">false</span><span class="op">,</span><span class="fl">3.0</span><span class="op">,</span><span class="kw">false</span><span class="op">)</span></span></code></pre></div>
<p>Moreover, Scala 3 provides mechanisms similar to shapeless <code>Generic</code>s making possible to convert from algebraic data types
(if you are not familiar with algebraic data types, to understand further examples you might think that it’s just case classes)
to tuples and back. Let’s take a look at these features.</p>
<h3 id="tuples-from-case-classes">Tuples from case classes</h3>
<p>The <code>Tuple</code> companion object contains method <code>fromProductTyped</code> which allows us to construct tuple from a case class:</p>
<pre><code>scala&gt; case class Foo(a: String, b: Int)
// defined case class Foo

scala&gt; Tuple.fromProductTyped(Foo(&quot;test&quot;, 5))
val res2: (String, Int) = (test,5)</code></pre>
<p>With this knowledge we can try to implement <code>SqlSaver</code> from <a href="/posts/2016-11-24-getting-started-with-shapeless.html">“Getting started with shapeless”</a> post for Scala 3. So, let’s do it.
The type class definition itself is unchanged:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> SqlSaver<span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> <span class="fu">save</span><span class="op">(</span>statement<span class="op">:</span> <span class="ex">PreparedStatement</span><span class="op">,</span> idx<span class="op">:</span> <span class="bu">Int</span><span class="op">)(</span>a<span class="op">:</span> A<span class="op">):</span> <span class="bu">Int</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>However, there is a new syntax for implicits in Scala 3. When we need to use an implicit instance we use <code>using</code> keyword. So,
now the summoner method will look like:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> SqlSaver <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> apply<span class="op">[</span>T<span class="op">](</span>using ss<span class="op">:</span> SqlSaver<span class="op">[</span>T<span class="op">]):</span> SqlSaver<span class="op">[</span>T<span class="op">]</span> <span class="op">=</span> ss</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>When we need to declare an instance of type class (or any other implicit), we use <code>given</code> keyword. With this new syntax instances of <code>SqlSaver</code> for
primitive types become:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> SqlSaver <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="co">// ...</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>  given SqlSaver<span class="op">[</span><span class="bu">Int</span><span class="op">]</span> <span class="op">=</span> <span class="fu">createSimpleSaver</span><span class="op">((</span>a<span class="op">,</span> s<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> s<span class="op">.</span><span class="fu">setInt</span><span class="op">(</span>i<span class="op">,</span> a<span class="op">))</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  given SqlSaver<span class="op">[</span><span class="ex">String</span><span class="op">]</span> <span class="op">=</span> <span class="fu">createSimpleSaver</span><span class="op">((</span>a<span class="op">,</span> s<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> s<span class="op">.</span><span class="fu">setString</span><span class="op">(</span>i<span class="op">,</span> a<span class="op">))</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  given SqlSaver<span class="op">[</span><span class="ex">Double</span><span class="op">]</span> <span class="op">=</span> <span class="fu">createSimpleSaver</span><span class="op">((</span>a<span class="op">,</span> s<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> s<span class="op">.</span><span class="fu">setDouble</span><span class="op">(</span>i<span class="op">,</span> a<span class="op">))</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>  given SqlSaver<span class="op">[</span><span class="ex">BigDecimal</span><span class="op">]</span> <span class="op">=</span> <span class="fu">createSimpleSaver</span><span class="op">((</span>a<span class="op">,</span> s<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> s<span class="op">.</span><span class="fu">setBigDecimal</span><span class="op">(</span>i<span class="op">,</span> a<span class="op">.</span>underlying<span class="op">))</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  given SqlSaver<span class="op">[</span>LocalDateTime<span class="op">]</span> <span class="op">=</span> </span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>    <span class="fu">createSimpleSaver</span><span class="op">((</span>a<span class="op">,</span> s<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> s<span class="op">.</span><span class="fu">setTimestamp</span><span class="op">(</span>i<span class="op">,</span> <span class="ex">Timestamp</span><span class="op">.</span><span class="fu">valueOf</span><span class="op">(</span>a<span class="op">)))</span></span></code></pre></div>
<p>In this example we created anonymous instances, but it’s also possible to give names to the type class instances, e.g.:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>  given intSaver<span class="op">:</span> SqlSaver<span class="op">[</span><span class="bu">Int</span><span class="op">]</span> <span class="op">=</span> <span class="fu">createSimpleSaver</span><span class="op">((</span>a<span class="op">,</span> s<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> s<span class="op">.</span><span class="fu">setString</span><span class="op">(</span>i<span class="op">,</span> a<span class="op">))</span></span></code></pre></div>
<p>Now, let’s implement <code>SqlSaver</code> instances for tuples. As it was before for <code>HNil</code> (empty <code>HList</code>), for the empty tuple it just does nothing:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a>  given SqlSaver<span class="op">[</span>EmptyTuple<span class="op">]</span> <span class="op">=</span> <span class="fu">createSaver</span><span class="op">((</span>_<span class="op">,</span> _<span class="op">,</span> i<span class="op">)</span> <span class="op">=&gt;</span> i<span class="op">)</span></span></code></pre></div>
<p>For non-empty tuple we need <code>SqlSaver</code> for head, to save left tuple member and <code>SqlSaver</code> for the tail, like we did before
for <code>::</code> (non-empty <code>HList</code>):</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>  given <span class="op">[</span>H<span class="op">,</span> T <span class="op">&lt;:</span> Tuple<span class="op">](</span>using hSaver<span class="op">:</span> SqlSaver<span class="op">[</span>H<span class="op">],</span> tSaver<span class="op">:</span> SqlSaver<span class="op">[</span>T<span class="op">]):</span> SqlSaver<span class="op">[</span>H <span class="op">*:</span> T<span class="op">]</span> <span class="op">=</span> </span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">new</span> SqlSaver<span class="op">[</span>H <span class="op">*:</span> T<span class="op">]</span> <span class="op">{</span></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a>      <span class="kw">override</span> <span class="kw">def</span> <span class="fu">save</span><span class="op">(</span>statement<span class="op">:</span> <span class="ex">PreparedStatement</span><span class="op">,</span> idx<span class="op">:</span> <span class="bu">Int</span><span class="op">)(</span>t<span class="op">:</span> H <span class="op">*:</span> T<span class="op">):</span> <span class="bu">Int</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>        <span class="kw">val</span> next <span class="op">=</span> hSaver<span class="op">.</span><span class="fu">save</span><span class="op">(</span>statement<span class="op">,</span> idx<span class="op">)(</span>t<span class="op">.</span>head<span class="op">)</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>        tSaver<span class="op">.</span><span class="fu">save</span><span class="op">(</span>statement<span class="op">,</span> next<span class="op">)(</span>t<span class="op">.</span>tail<span class="op">)</span></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a>      <span class="op">}</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span></code></pre></div>
<p>Here, we created instance for tuple dependent on the instances for the <code>H</code> and <code>T</code> via <code>using</code> keyword.</p>
<p>Finally, we can create instance for <code>Product</code>s, which will convert a case class to tuple, and then call <code>SqlSaver</code>
for the tuple to really save the data. However, to do it we need to know the exact tuple type. For example, if the product is
<code>case class Foo(a: String, b: Int)</code> then the tuple type will be <code>(String, Int)</code>, or that’s the same <code>String *: Int *: EmptyTuple</code>.
In shapeless for Scala 2, we used <code>Generic</code> to convert ADTs to and from <code>HList</code>s. It also was a type link between ADTs and their
HList representations. In Scala 3, we have class <code>Mirror</code> to connect products and coproducts with tuples both on the type and the value level.</p>
<p>To achieve that <code>Mirror</code> trait contains several type members. The <code>MirroredElemTypes</code> is a tuple type we are looking for. Bearing this
in mind, we can connect the mirror with the <code>SqlSaver</code> in the <code>using</code> part of the type class instance declaration:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> scala<span class="op">.</span>deriving<span class="op">.</span>Mirror</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="co">// ...</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>  given <span class="op">[</span>P <span class="op">&lt;:</span> Product<span class="op">](</span>using m<span class="op">:</span> Mirror<span class="op">.</span>ProductOf<span class="op">[</span>P<span class="op">],</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>                            ts<span class="op">:</span> SqlSaver<span class="op">[</span>m<span class="op">.</span>MirroredElemTypes<span class="op">]</span></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>                      <span class="op">):</span> SqlSaver<span class="op">[</span>P<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> SqlSaver<span class="op">[</span>P<span class="op">]</span> <span class="op">{</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">def</span> <span class="fu">save</span><span class="op">(</span>statement<span class="op">:</span> <span class="ex">PreparedStatement</span><span class="op">,</span> idx<span class="op">:</span> <span class="bu">Int</span><span class="op">)(</span>t<span class="op">:</span> P<span class="op">):</span> <span class="bu">Int</span> <span class="op">=</span></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>      ts<span class="op">.</span><span class="fu">save</span><span class="op">(</span>statement<span class="op">,</span> idx<span class="op">)(</span>Tuple<span class="op">.</span><span class="fu">fromProductTyped</span><span class="op">(</span>t<span class="op">))</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span></code></pre></div>
<p>Here you can see another new cool feature of Scala 3. Previously we had to use Aux pattern to make types depend on each other.
Now, we can just use type members in other function parameters or even as a result type.</p>
<h3 id="summary">Summary</h3>
<p>Scala 3 brings us a lot of new features. Personally I like the way the language is evolving. Even if some things a bit
controversial most of the stuff makes Scala more readable, and gives us tools to build standard solutions for standard problems.
Typelevel programming in general is a complex topic, but the new code looks a bit simpler, and also it doesn’t require external
dependencies.</p>]]></summary>
</entry>
<entry>
    <title>sbt-git-flow-version announcement</title>
    <link href="http://limansky.me/posts/2018-11-13-sbt-git-flow-version-announce.html" />
    <id>http://limansky.me/posts/2018-11-13-sbt-git-flow-version-announce.html</id>
    <published>2018-11-13T00:00:00Z</published>
    <updated>2018-11-13T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’d like to announce my new project called <a href="https://github.com/limansky/sbt-git-flow-version">sbt-git-flow-version</a>.
As you might guess it’s a plugin for sbt. The goal of the project is set your
sbt build version according to <a href="https://leanpub.com/git-flow/read">git flow</a> rules.</p>
<p>I found that for big or medium size teams git flow is quite practical. What I didn’t
like about it, is that it requires to change the version all the time you change the branch
in your repository. At some point I took responsibilities of release engineer in our team.
Since I’m very lazy to do all of this styff I came up with some Scala code in the <code>project</code> catalog
of my current working project. Later I rewrote it as an sbt plugin.</p>
<p>So, what can it do for you?</p>
<!--more-->
<p>Let’s start with git flow. The typical git flow process have following branches:</p>
<ul>
<li><code>master</code> - contains stable releases. Only tested releases are merged here, and only
stable artifacts are build from this branch (no snapshots allowed).</li>
<li><code>develop</code> - current development release. Features for the next release are going here.
We can define the version as a next minor version: “(last version + 0.1)-SNAPSHOT”.</li>
<li><code>release/x.y.z</code> - release branches. These branches are for upcoming releases during
stabilization. In our team we do not have <code>develop</code> branch, but several <code>release</code>
branches. For me, it’s more clear. The versions on this branch is <code>x.y.z-SNAPSHOT</code>.</li>
<li><code>feature/xxx</code>, and also <code>bugfix/yyy</code>, <code>hotfix/zzz</code> - branches for a specific task
development. The version for such build</li>
</ul>
<p>You might see that we need three components to compose the version:</p>
<ul>
<li>previous version</li>
<li>current tags</li>
<li>current branch name</li>
</ul>
<p>The main setting of sbt-git-flow-version is <code>versionPolicy</code> which has type
<code>Seq[(BranchMatcher =&gt; VersionCalculator)]</code>. So it tries to find matching rule for
a branch and calculate a version.</p>
<p>What is a <code>BranchMatcher</code>? It’s a function <code>String =&gt; Option[Matching]</code> where matching
is a case class containing branch name and some additional optional extracted string. There are several
predefined branch matchers:</p>
<ul>
<li><code>exact(name: String)</code> - branch name is equals to <code>name</code>, extraction is empty.</li>
<li><code>prefix(prefix: String)</code> - branch name starts with <code>prefix</code>. The part after prefix is extraction.</li>
<li><code>prefixes(prefixes: String*)</code> - same as prefix but supports a number of prefixes.</li>
<li><code>regex(r: String)</code> - branch name matches regular expression <code>r</code>. If the expression contains
groups, the first group will be returned as extraction.</li>
<li><code>any</code> - matches any branch (might be used to define default behaviour).</li>
</ul>
<p>The <code>VersionCalculator</code> converts previous version, current version, and matching either
to the version number or error message. The predefined version calculators are:</p>
<ul>
<li><code>currentTag</code> - take a version from a current tag. If there are several current tags it will take the
one with a maximal version.</li>
<li><code>nextMajor</code>, <code>nextMinor</code>, <code>nextBuild</code>, <code>nextN</code> - increment major, minor, build or n-th number of
a last version. The version is snapshot by default.</li>
<li><code>matching</code> - take a version from matching returned by <code>BranchMatcher</code>. The version is snapshot by default.</li>
<li><code>lastVersion</code> - previous version. Version value is taken from last tag or <code>initialVersion</code> setting.
The version is not snapshot by default.</li>
<li><code>lastVersionWithMatching</code> - takes last version and append matching returned by <code>BranchMatcher</code>. By default
new version is snapshot.</li>
<li><code>unknownVersion</code> - fails with unknown version message.</li>
</ul>
<p>The default policy is defined as:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="bu">Seq</span><span class="op">(</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>  <span class="fu">exact</span><span class="op">(</span><span class="st">&quot;master&quot;</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="fu">currentTag</span><span class="op">(),</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>  <span class="fu">exact</span><span class="op">(</span><span class="st">&quot;develop&quot;</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="fu">nextMinor</span><span class="op">(),</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="fu">prefix</span><span class="op">(</span><span class="st">&quot;release/&quot;</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="fu">matching</span><span class="op">(),</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  <span class="fu">prefixes</span><span class="op">(</span><span class="st">&quot;feature/&quot;</span><span class="op">,</span> <span class="st">&quot;bugfix/&quot;</span><span class="op">,</span> <span class="st">&quot;hotfix/&quot;</span><span class="op">)</span> <span class="op">-&gt;</span> <span class="fu">lastVersionWithMatching</span><span class="op">(),</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>  any <span class="op">-&gt;</span> unknownVersion</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div>
<p>What literally means following:</p>
<ul>
<li>If branch name is “master” then the branch name is a current commit tag</li>
<li>If branch name is “develop” then the branch name is a next minor version.
E.g. if last version was <code>1.4.2</code>, the current version is <code>1.5.0-SNAPSHOT</code>.</li>
<li>If the branch name starts with “release/” then the version is taken from the
branch name. E.g. for the branch <code>release/2.12.85</code> the version is <code>2.12.85-SNAPSHOT</code>.</li>
<li>For the branches started with “feature/”, “bugfix/”, and “hotfix/” the version is
a combination of the last version and matching. E.g. for the branch <code>feature/123-new-ui</code>
and the prevous version “1.0.1” the current version is <code>1.0.1-123-new-ui-SNAPSHOT</code>.</li>
<li>Finally, if the branch name doesn’t follow any of these rules, the build fails,
because version is unknown.</li>
</ul>
<p>You can define your own rules in you <code>build.sbt</code> in the following way:</p>
<pre><code>import sbtgitflowversion.BranchMatcher._
import sbtgitflowversion.VersionCalculator._

versionPolicy := (exact(&quot;big-release&quot;) -&gt; next-major()) +: versionPolicy.value</code></pre>
<p>This will set the next major version for the “big-release” branch.</p>
<p>Current verion of the plugin is <code>0.1</code>. So, to add to your <code>project/plugins.sbt</code> the line:</p>
<pre><code>addSbtPlugin(&quot;me.limansky&quot; % &quot;sbt-git-flow-version&quot; % &quot;0.1&quot;)</code></pre>]]></summary>
</entry>
<entry>
    <title>BeanPurée 0.2 release announcement</title>
    <link href="http://limansky.me/posts/2017-08-09-beanpuree-0.2-announcement.html" />
    <id>http://limansky.me/posts/2017-08-09-beanpuree-0.2-announcement.html</id>
    <published>2017-08-09T00:00:00Z</published>
    <updated>2017-08-09T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’m happy to announce the second release of
<a href="https://github.com/limansky/beanpuree">BeanPurée</a> library.</p>
<p>The main goal of this release is to make <code>BeanConverter</code> more intelligent.
Previously, it required you to have the same type for the corresponding fields in a
bean and a product. If there are Java number classes in your beans, it’s possible you
don’t want to use it in your Scala code. Instead, you would like to use Options,
or you may know that these values are never null.</p>
<p>Now <code>BeanConverter</code> can do these kinds of transformations for you.</p>
<p><code>JavaTypeMapper</code> type class was introduced to acheive that. It provides
two-way conversions for the following cases:</p>
<ul>
<li>Java number class to Scala type. E.g. Integer to Int, or <code>java.math.BigDecimal</code>
to <code>scala.math.BigDecimal</code>. If Java value is null it throws
NullPointerException.</li>
<li>A class <code>T</code> to an <code>Option[T]</code>. Wraps nullable to Option.</li>
<li>A class <code>T</code> for which an instance of <code>JavaTypeMapper</code> to class <code>U</code> is
available to an <code>Option[U]</code>. For example it is used to convert <code>Integer</code> to
<code>Option[Int]</code>.</li>
<li><code>HList</code> of the elements which can be mapped with <code>JavaTypeMapper</code>s, to HList
of mapped values.</li>
</ul>
<p>If you want to have a previous behavior from <code>BeanConverter</code> use
<code>StrictBeanConverter</code> class.</p>]]></summary>
</entry>
<entry>
    <title>Introducing BeanPurée</title>
    <link href="http://limansky.me/posts/2017-04-05-introducing-beanpuree.html" />
    <id>http://limansky.me/posts/2017-04-05-introducing-beanpuree.html</id>
    <published>2017-04-05T00:00:00Z</published>
    <updated>2017-04-05T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>As a Scala developer I prefer to use Scala libraries rather than Java ones for my
code. However, it is not always possible. Sometimes I might not find a required library,
or I just have to use some legacy code I already have. Even though Scala
runs on a JVM and is fully compatible with Java, the languages have different
ideologies, different code styles and sometimes different API’s. Thus, in Scala it is
preferable to use immutable case classes for the data modeling. However, in Java
the common building blocks are JavaBeans, which are mutable. Another problem
is that a lot of Scala libraries expect case classes. Even if they work with
JavaBeans, usually you have to write some boilerplate code.</p>
<p>So, quite often it is easier to have a separate model in your Scala code, and
converters between Java model classes and Scala ones.</p>
<p><a href="https://github.com/limansky/beanpuree">BeanPurée</a> is a library that helps you
to automate this process. And it helps you to do even more, because it’s a
bridge from JavaBeans to shapeless.</p>
<!--more-->
<p>Let’s take this Java class as an example:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode java"><code class="sourceCode java"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">public</span> <span class="kw">class</span> Dog <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="bu">String</span> name<span class="op">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">int</span> age<span class="op">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    <span class="kw">private</span> <span class="dt">boolean</span> chaseCats<span class="op">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="bu">String</span> <span class="fu">getName</span><span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> name<span class="op">;</span> <span class="op">}</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">setName</span><span class="op">(</span><span class="bu">String</span> name<span class="op">)</span> <span class="op">{</span> <span class="kw">this</span><span class="op">.</span><span class="fu">name</span> <span class="op">=</span> name<span class="op">;</span> <span class="op">}</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">int</span> <span class="fu">getAge</span><span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> age<span class="op">;</span> <span class="op">}</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">setAge</span><span class="op">(</span><span class="dt">int</span> age<span class="op">)</span> <span class="op">{</span> <span class="kw">this</span><span class="op">.</span><span class="fu">age</span> <span class="op">=</span> age<span class="op">;</span> <span class="op">}</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">boolean</span> <span class="fu">isChaseCats</span><span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> chaseCats<span class="op">;</span> <span class="op">}</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="dt">void</span> <span class="fu">setChaseCats</span><span class="op">(</span><span class="dt">boolean</span> chaseCats<span class="op">)</span> <span class="op">{</span> <span class="kw">this</span><span class="op">.</span><span class="fu">chaseCats</span> <span class="op">=</span> chaseCats<span class="op">;</span> <span class="op">}</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    <span class="kw">public</span> <span class="bu">String</span> <span class="fu">toString</span><span class="op">()</span> <span class="op">{</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> <span class="st">&quot;Dog &quot;</span> <span class="op">+</span> name <span class="op">+</span> <span class="st">&quot;, &quot;</span> <span class="op">+</span> age <span class="op">+</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>            <span class="op">(</span>chaseCats <span class="op">?</span> <span class="st">&quot; is looking for cats&quot;</span> <span class="op">:</span> <span class="st">&quot; is sleeping&quot;</span><span class="op">);</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>BeanPurée provides <code>BeanGeneric</code> class, which has the same function with
shapeless’s <code>Generic</code>:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">import</span> me<span class="op">.</span>limansky<span class="op">.</span>beanpuree<span class="op">.</span>_</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> me<span class="op">.</span>limansky<span class="op">.</span>beanpuree<span class="op">.</span>_</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">val</span> gen <span class="op">=</span> BeanGeneric<span class="op">[</span>Dog<span class="op">]</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>gen<span class="op">:</span> me<span class="op">.</span>limansky<span class="op">.</span>beanpuree<span class="op">.</span>BeanGeneric<span class="op">[</span>Dog<span class="op">]{</span><span class="kw">type</span> Repr <span class="op">=</span> shapeless<span class="op">.::[</span><span class="ex">String</span><span class="op">,</span>shapeless<span class="op">.::[</span><span class="bu">Int</span><span class="op">,</span>shapeless<span class="op">.::[</span><span class="ex">Boolean</span><span class="op">,</span>shapeless<span class="op">.</span>HNil<span class="op">]]]}</span> <span class="op">=</span> $anon$<span class="dv">1</span>@<span class="dv">56</span>f5a8b7</span></code></pre></div>
<p>We just get a <code>BeanGeneric</code> instance with representation type <code>String :: Int :: Boolean :: HNil</code>. Internally, <code>BeanGeneric</code> uses the getters order to build the
Repr type. Let’s try to use it:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">val</span> fima <span class="op">=</span> gen<span class="op">.</span><span class="fu">from</span><span class="op">(</span><span class="st">&quot;Fima&quot;</span> <span class="op">::</span> <span class="dv">12</span> <span class="op">::</span> <span class="kw">false</span> <span class="op">::</span> HNil<span class="op">)</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>fima<span class="op">:</span> Dog <span class="op">=</span> Dog Fima<span class="op">,</span> <span class="dv">12</span> is sleeping</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> fima<span class="op">.</span><span class="fu">setChaseCats</span><span class="op">(</span><span class="kw">true</span><span class="op">)</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> gen<span class="op">.</span><span class="fu">to</span><span class="op">(</span>fima<span class="op">)</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>res3<span class="op">:</span> gen<span class="op">.</span>Repr <span class="op">=</span> Fima <span class="op">::</span> <span class="dv">12</span> <span class="op">::</span> <span class="kw">true</span> <span class="op">::</span> HNi</span></code></pre></div>
<p>So far, so good, let’s combine it with shapeless:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="cf">case</span> <span class="kw">class</span> <span class="fu">ScalaDog</span><span class="op">(</span>name<span class="op">:</span> <span class="ex">String</span><span class="op">,</span> age<span class="op">:</span> <span class="bu">Int</span><span class="op">,</span> chaseCats<span class="op">:</span> <span class="ex">Boolean</span><span class="op">)</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>defined <span class="kw">class</span> ScalaDog</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">val</span> sgen <span class="op">=</span> Generic<span class="op">[</span>ScalaDog<span class="op">]</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>sgen<span class="op">:</span> shapeless<span class="op">.</span>Generic<span class="op">[</span>ScalaDog<span class="op">]{</span><span class="kw">type</span> Repr <span class="op">=</span> shapeless<span class="op">.::[</span><span class="ex">String</span><span class="op">,</span>shapeless<span class="op">.::[</span><span class="bu">Int</span><span class="op">,</span>shapeless<span class="op">.::[</span><span class="ex">Boolean</span><span class="op">,</span>shapeless<span class="op">.</span>HNil<span class="op">]]]}</span> <span class="op">=</span> anon$macro$<span class="dv">8</span>$<span class="dv">1</span>@<span class="fl">45e06950</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> sgen<span class="op">.</span><span class="fu">from</span><span class="op">(</span>gen<span class="op">.</span><span class="fu">to</span><span class="op">(</span>fima<span class="op">))</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>res4<span class="op">:</span> ScalaDog <span class="op">=</span> <span class="fu">ScalaDog</span><span class="op">(</span>Fima<span class="op">,</span><span class="dv">12</span><span class="op">,</span><span class="kw">true</span><span class="op">)</span></span></code></pre></div>
<p>Since the shape of <code>Dog</code> and <code>ScalaDog</code> is the same we can convert from one
class to another using a combination of <code>Generic</code> and <code>BeanGeneric</code>.</p>
<p>Just as shapeless provides <code>LabelledGeneric</code> with field names information in the
<code>Repr</code> type, BeanPurée provides <code>LabelledBeanGeneric</code>, which adds property
names to the generic representation.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">val</span> lgen <span class="op">=</span> LabelledBeanGeneric<span class="op">[</span>Dog<span class="op">]</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>lgen<span class="op">:</span> me<span class="op">.</span>limansky<span class="op">.</span>beanpuree<span class="op">.</span>LabelledBeanGeneric<span class="op">[</span>Dog<span class="op">]{</span><span class="kw">type</span> Repr <span class="op">=</span> shapeless<span class="op">.::[</span><span class="ex">String</span> <span class="kw">with</span> shapeless<span class="op">.</span>labelled<span class="op">.</span>KeyTag<span class="op">[</span><span class="bu">Symbol</span> <span class="kw">with</span> shapeless<span class="op">.</span>tag<span class="op">.</span>Tagged<span class="op">[</span><span class="ex">String</span><span class="op">(</span><span class="st">&quot;name&quot;</span><span class="op">)],</span><span class="ex">String</span><span class="op">],</span>shapeless<span class="op">.::[</span><span class="bu">Int</span> <span class="kw">with</span> shapeless<span class="op">.</span>labelled<span class="op">.</span>KeyTag<span class="op">[</span><span class="bu">Symbol</span> <span class="kw">with</span> shapeless<span class="op">.</span>tag<span class="op">.</span>Tagged<span class="op">[</span><span class="ex">String</span><span class="op">(</span><span class="st">&quot;age&quot;</span><span class="op">)],</span><span class="bu">Int</span><span class="op">],</span>shapeless<span class="op">.::[</span><span class="ex">Boolean</span> <span class="kw">with</span> shapeless<span class="op">.</span>labelled<span class="op">.</span>KeyTag<span class="op">[</span><span class="bu">Symbol</span> <span class="kw">with</span> shapeless<span class="op">.</span>tag<span class="op">.</span>Tagged<span class="op">[</span><span class="ex">String</span><span class="op">(</span><span class="st">&quot;chaseCats&quot;</span><span class="op">)],</span><span class="ex">Boolean</span><span class="op">],</span>shapeless<span class="op">.</span>HNil<span class="op">]]]}</span> <span class="op">=</span> me<span class="op">.</span>limansky<span class="op">.</span>beanpuree<span class="op">.</span>LabelledBeanGeneric$$anon$<span class="dv">1</span>@<span class="dv">412</span>d56b4</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> lgen<span class="op">.</span><span class="fu">from</span><span class="op">(</span><span class="er">&#39;</span>name <span class="op">-&gt;&gt;</span> <span class="st">&quot;Rex&quot;</span> <span class="op">::</span> <span class="er">&#39;</span>age <span class="op">-&gt;&gt;</span> <span class="dv">5</span> <span class="op">::</span> <span class="er">&#39;</span>chaseCats <span class="op">-&gt;&gt;</span> <span class="kw">true</span> <span class="op">::</span> HNil<span class="op">)</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>res7<span class="op">:</span> Dog <span class="op">=</span> Dog Rex<span class="op">,</span> <span class="dv">5</span> is looking <span class="cf">for</span> cats</span></code></pre></div>
<p>Having this stuff allows me to implement a more intelligent (but not too much)
converter between case classes and beans. This class is called <code>BeanConverter</code>.
It doesn’t rely on a definition order of properties . Instead, it uses names.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="cf">case</span> <span class="kw">class</span> <span class="fu">ScalaDog</span><span class="op">(</span>name<span class="op">:</span> <span class="ex">String</span><span class="op">,</span> chaseCats<span class="op">:</span> <span class="ex">Boolean</span><span class="op">,</span> age<span class="op">:</span> <span class="bu">Int</span><span class="op">)</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>defined <span class="kw">class</span> ScalaDog</span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">val</span> conv <span class="op">=</span> BeanConverter<span class="op">[</span>Dog<span class="op">,</span> ScalaDog<span class="op">]</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>conv<span class="op">:</span> me<span class="op">.</span>limansky<span class="op">.</span>beanpuree<span class="op">.</span>BeanConverter<span class="op">[</span>Dog<span class="op">,</span>ScalaDog<span class="op">]</span> <span class="op">=</span> me<span class="op">.</span>limansky<span class="op">.</span>beanpuree<span class="op">.</span>BeanConverter$$anon$<span class="dv">1</span>@<span class="dv">5</span>dd7b913</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> conv<span class="op">.</span><span class="fu">productToBean</span><span class="op">(</span><span class="fu">ScalaDog</span><span class="op">(</span><span class="st">&quot;Lassie&quot;</span><span class="op">,</span> <span class="kw">false</span><span class="op">,</span> <span class="dv">5</span><span class="op">))</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>res0<span class="op">:</span> Dog <span class="op">=</span> Dog Lassie<span class="op">,</span> <span class="dv">5</span> is sleeping</span></code></pre></div>
<p>That’s all the features of the release 0.1, which is available in the Sonatype
Maven repository. I have several ideas for the next releases, e.g automatic
Java types to Scala types conversion, and partial converters.</p>]]></summary>
</entry>
<entry>
    <title>Generating SQL queries with shapeless</title>
    <link href="http://limansky.me/posts/2017-02-02-generating-sql-queries-with-shapeless.html" />
    <id>http://limansky.me/posts/2017-02-02-generating-sql-queries-with-shapeless.html</id>
    <published>2017-02-02T00:00:00Z</published>
    <updated>2017-02-02T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>In the <a href="/posts/2016-11-24-getting-started-with-shapeless.html">previous</a>
<a href="http://limansky.me/posts/2016-12-22-fixing-bugs-in-sql-saver.html">posts</a> we
created the <code>SqlSaver</code> class which can set values into the prepared
statement. It assumes that the SQL request is correct and the parameters are in the
required order (in the order they are defined in the model). What if the model class
is changed? If the query is not updated we’ll get a runtime error, since the
fields order in the query and the order of calls performed by <code>SqlSaver</code> are not the same
anymore. So, it would be nice to generate SQL queries as well. Something like:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> query <span class="op">=</span> StatementGenerator<span class="op">[</span>Sale<span class="op">].</span><span class="fu">insert</span><span class="op">(</span>tableName<span class="op">)</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="kw">val</span> statement <span class="op">=</span> connection<span class="op">.</span><span class="fu">prepareStatement</span><span class="op">(</span>query<span class="op">)</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>SqlSaver<span class="op">[</span>Sale<span class="op">](</span>statement<span class="op">,</span> <span class="dv">1</span><span class="op">)(</span>sale<span class="op">)</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>statement<span class="op">.</span><span class="fu">execute</span><span class="op">()</span></span></code></pre></div>
<p>Let’s try to implement it with shapeless.</p>
<!--more-->
<p>First, let’s define our type class for statement generators:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> <span class="fu">select</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> <span class="fu">insert</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Then we can create a companion object with summoner function and
implementation for case classes. Since we need not only values, but also field names,
we need to use <code>LabelledGeneric</code> class instead of <code>Generic</code>.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> StatementGenerator <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> apply<span class="op">[</span>A<span class="op">](</span><span class="kw">implicit</span> sg<span class="op">:</span> StatementGenerator<span class="op">[</span>A<span class="op">]):</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">=</span> sg</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> genericGenerator<span class="op">[</span>A<span class="op">,</span> R<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    gen<span class="op">:</span> LabelledGeneric<span class="op">.</span>Aux<span class="op">[</span>A<span class="op">,</span> R<span class="op">]</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">def</span> <span class="fu">select</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span> <span class="op">=</span> <span class="op">???</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">def</span> <span class="fu">insert</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span> <span class="op">=</span> <span class="op">???</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Ok, we have an instance of <code>LabelledGeneric</code> for type <code>A</code> which can convert an
instance of type <code>A</code> to <code>HList</code> <code>R</code>. But we don’t have an <code>A</code> instance, because we
don’t need values. All we need are the field names. Shapeless contains package
<code>ops</code> which provides utilities for different cases. We need to get keys of the
key-value records. The necessary class called <code>Keys</code> is available in package
<code>ops.record</code>. It takes an <code>HList</code> of records and provides an <code>HList</code> of keys. The next
thing we need to do is to materialize <code>HList</code> of keys into a Scala List of Symbols
(because key in our case is <code>Symbol</code>). The utility class we need is called <code>hlist.ToList</code>.
We also have to set the constraints for the types we use: a type passed to Keys
shall be an <code>HList</code>, as well as a type passed to <code>ToList</code>. Let’s code:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> StatementGenerator <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> apply<span class="op">[</span>A<span class="op">](</span><span class="kw">implicit</span> sg<span class="op">:</span> StatementGenerator<span class="op">[</span>A<span class="op">]):</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">=</span> sg</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> genericGenerator<span class="op">[</span>A<span class="op">,</span> R <span class="op">&lt;:</span> HList<span class="op">,</span> K <span class="op">&lt;:</span> HList<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb4-5"><a href="#cb4-5" aria-hidden="true" tabindex="-1"></a>    gen<span class="op">:</span> LabelledGeneric<span class="op">.</span>Aux<span class="op">[</span>A<span class="op">,</span> R<span class="op">],</span></span>
<span id="cb4-6"><a href="#cb4-6" aria-hidden="true" tabindex="-1"></a>    keys<span class="op">:</span> record<span class="op">.</span>Keys<span class="op">.</span>Aux<span class="op">[</span>R<span class="op">,</span> K<span class="op">],</span></span>
<span id="cb4-7"><a href="#cb4-7" aria-hidden="true" tabindex="-1"></a>    ktl<span class="op">:</span> hlist<span class="op">.</span>ToList<span class="op">[</span>K<span class="op">,</span> <span class="bu">Symbol</span><span class="op">]</span></span>
<span id="cb4-8"><a href="#cb4-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb4-9"><a href="#cb4-9" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">def</span> <span class="fu">select</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span> <span class="op">=</span> <span class="op">???</span></span>
<span id="cb4-10"><a href="#cb4-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">def</span> <span class="fu">insert</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span> <span class="op">=</span> <span class="op">???</span></span>
<span id="cb4-11"><a href="#cb4-11" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb4-12"><a href="#cb4-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Once we have all the required components we can implement the select and insert
methods:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">override</span> <span class="kw">def</span> <span class="fu">select</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">val</span> fields <span class="op">=</span> <span class="fu">keys</span><span class="op">().</span>toList<span class="op">.</span><span class="fu">map</span><span class="op">(</span>_<span class="op">.</span>name<span class="op">).</span><span class="fu">mkString</span><span class="op">(</span><span class="st">&quot;,&quot;</span><span class="op">)</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>  <span class="ss">s&quot;</span><span class="st">SELECT </span><span class="ss">$fields</span><span class="st"> FROM </span><span class="ss">$table&quot;</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a><span class="kw">override</span> <span class="kw">def</span> <span class="fu">insert</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>  <span class="kw">val</span> fieldNames <span class="op">=</span> <span class="fu">keys</span><span class="op">().</span>toList<span class="op">.</span><span class="fu">map</span><span class="op">(</span>_<span class="op">.</span>name<span class="op">)</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  <span class="kw">val</span> fields <span class="op">=</span> fieldNames<span class="op">.</span><span class="fu">mkString</span><span class="op">(</span><span class="st">&quot;,&quot;</span><span class="op">)</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">val</span> placeholders <span class="op">=</span> <span class="ex">List</span><span class="op">.</span><span class="fu">fill</span><span class="op">(</span>fieldNames<span class="op">.</span>size<span class="op">)(</span><span class="st">&quot;?&quot;</span><span class="op">).</span><span class="fu">mkString</span><span class="op">(</span><span class="st">&quot;,&quot;</span><span class="op">)</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>  <span class="ss">s&quot;</span><span class="st">INSERT INTO </span><span class="ss">$table</span><span class="st"> (</span><span class="ss">$fields</span><span class="st">) VALUES(</span><span class="ss">$placeholders</span><span class="st">)</span><span class="ss">&quot;</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This code is quite straightforward and it works for most cases. But it doesn’t cover all
the features of <code>SqlSaver</code>. In the last post we added the ability to save nested case
classes. So, we need to recursively handle all of the fields and make a flat
list of primitive ones. E.g. if we have classes <code>A(a: String, b: Int)</code> and
<code>B(c: String, d: A, e: Int)</code> we should get <code>c :: a :: b :: e :: Nil</code>.</p>
<p>I think it’s better to create a separate type class <code>FieldLister</code>, which will
provide a list of fields. Let’s start with our type class:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> FieldLister<span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">val</span> list<span class="op">:</span> <span class="ex">List</span><span class="op">[</span><span class="ex">String</span><span class="op">]</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>We want to create instances of <code>FieldLister</code> for any class, so we need
<code>LabelledGeneric</code> to convert a class to <code>HList</code>:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> FieldLister <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">def</span> genericLister<span class="op">[</span>A<span class="op">,</span> R<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>    gen<span class="op">:</span> LabelledGeneric<span class="op">.</span>Aux<span class="op">[</span>A<span class="op">,</span> R<span class="op">],</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>    lister<span class="op">:</span> Lazy<span class="op">[</span>FieldLister<span class="op">[</span>R<span class="op">]]</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> FieldLister<span class="op">[</span>A<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> FieldLister<span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">val</span> list <span class="op">=</span> lister<span class="op">.</span>value<span class="op">.</span>list</span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span></code></pre></div>
<p>You might notice, that we don’t need the value of <code>LabelledGeneric</code>. But we
need it on the type level, to link types <code>A</code> and <code>R</code>, because type <code>R</code> <em>depends</em> on
type <code>A</code>.</p>
<p>Next, we can create instances for <code>HList</code>. It’s obvious that the result list
for <code>HNil</code> is <code>Nil</code>:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">val</span> hnilLister<span class="op">:</span> FieldLister<span class="op">[</span>HNil<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> FieldLister<span class="op">[</span>HNil<span class="op">]</span> <span class="op">{</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">override</span> <span class="kw">val</span> list <span class="op">=</span> Nil</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>The instance for a non-empty list is more tricky. We need to separate the primitive
types from the nested classes. For the nested classes the implementation is quite
simple. We obtain instances for the tail and head and concatenating the result lists:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">def</span> hconsLister<span class="op">[</span>K<span class="op">,</span> H<span class="op">,</span> T <span class="op">&lt;:</span> HList<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>  hLister<span class="op">:</span> Lazy<span class="op">[</span>FieldLister<span class="op">[</span>H<span class="op">]],</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>  tLister<span class="op">:</span> FieldLister<span class="op">[</span>T<span class="op">]</span></span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a><span class="op">):</span> FieldLister<span class="op">[</span>FieldType<span class="op">[</span>K<span class="op">,</span> H<span class="op">]</span> <span class="op">::</span> T<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> FieldLister<span class="op">[</span>FieldType<span class="op">[</span>K<span class="op">,</span> H<span class="op">]</span> <span class="op">::</span> T<span class="op">]</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">override</span> <span class="kw">val</span> list <span class="op">=</span> hLister<span class="op">.</span>value<span class="op">.</span>list <span class="op">++</span> tLister<span class="op">.</span>list</span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Let’s take a closer look at this function. To understand what’s going on we
need to understand what the <code>LabelledGeneric</code> produces. We can check it in
REPL:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="kw">import</span> shapeless<span class="op">.</span>_</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> shapeless<span class="op">.</span>_</span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> <span class="cf">case</span> <span class="kw">class</span> <span class="fu">Test</span><span class="op">(</span>first<span class="op">:</span> <span class="ex">String</span><span class="op">,</span> second<span class="op">:</span> <span class="bu">Int</span><span class="op">)</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a>defined <span class="kw">class</span> Test</span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a>scala<span class="op">&gt;</span> LabelledGeneric<span class="op">[</span>Test<span class="op">]</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a>res0<span class="op">:</span> LabelledGeneric<span class="op">[</span>Test<span class="op">]{</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> Repr <span class="op">=</span> <span class="ex">String</span> <span class="kw">with</span> KeyTag<span class="op">[</span><span class="bu">Symbol</span> <span class="kw">with</span> Tagged<span class="op">[</span><span class="ex">String</span><span class="op">(</span><span class="st">&quot;first&quot;</span><span class="op">)],</span><span class="ex">String</span><span class="op">]</span> <span class="op">::</span></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true" tabindex="-1"></a>              <span class="bu">Int</span> <span class="kw">with</span> KeyTag<span class="op">[</span><span class="bu">Symbol</span> <span class="kw">with</span> Tagged<span class="op">[</span><span class="ex">String</span><span class="op">(</span><span class="st">&quot;second&quot;</span><span class="op">)],</span><span class="bu">Int</span><span class="op">]</span> <span class="op">::</span></span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true" tabindex="-1"></a>              HNil</span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span> <span class="op">=</span></span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true" tabindex="-1"></a>LabelledGeneric$$anon$<span class="dv">1</span>@<span class="dv">1</span>b09215f</span></code></pre></div>
<p>I rewrote the result type in the infix form and removed package names for readability.
What is important here is that the <code>Repr</code> type is not just <code>String :: Int :: HNil</code>,
but each type element contains additional type level information.</p>
<p>If we check the shapeless sources, we find that <code>FieldType</code> is just a type alias:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> FieldType<span class="op">[</span>K<span class="op">,</span> <span class="op">+</span>V<span class="op">]</span> <span class="op">=</span> V <span class="kw">with</span> KeyTag<span class="op">[</span>K<span class="op">,</span> V<span class="op">]</span></span></code></pre></div>
<p>That’s exactly what we saw inside <code>Repr</code>. With this knowledge we can rewrite <code>Repr</code> type as:</p>
<div class="sourceCode" id="cb12"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>LabelledGeneric<span class="op">[</span>Test<span class="op">]{</span></span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">type</span> Repr <span class="op">=</span> FieldType<span class="op">[</span><span class="bu">Symbol</span> <span class="kw">with</span> Tagged<span class="op">[</span><span class="ex">String</span><span class="op">(</span><span class="st">&quot;first&quot;</span><span class="op">)],</span><span class="ex">String</span><span class="op">]</span> <span class="op">::</span></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true" tabindex="-1"></a>              FieldType<span class="op">[</span><span class="bu">Symbol</span> <span class="kw">with</span> Tagged<span class="op">[</span><span class="ex">String</span><span class="op">(</span><span class="st">&quot;second&quot;</span><span class="op">)],</span><span class="bu">Int</span><span class="op">]</span> <span class="op">::</span></span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true" tabindex="-1"></a>              HNil</span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And this is the reason we need to define the result type of <code>hconsLister</code> as
<code>FieldLister[FieldType[K, H] :: T]</code>. On the value level we just need to concatenate the lists
produced for the head and for the tail of the <code>HList</code>.</p>
<p>At this point our code can work with case classes and <code>HLists</code> of elements for which we have instances of
<code>FieldLister</code>, i.e. the other HLists and case classes. But what about the
primitive types? If we have a head element of <code>HList</code> which does not have an
instance of <code>FieldLister</code>, we need to get this field name and set it as a head
element of the result list. We need to somehow get the instance of type <code>K</code> on the value
level to get the field name. Shapeless provides type class <code>Witness</code>
for this purpose. With all of these blocks we can build our function:</p>
<div class="sourceCode" id="cb13"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">def</span> primitiveFieldLister<span class="op">[</span>K <span class="op">&lt;:</span> <span class="bu">Symbol</span><span class="op">,</span> H<span class="op">,</span> T <span class="op">&lt;:</span> HList<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb13-2"><a href="#cb13-2" aria-hidden="true" tabindex="-1"></a>  witness<span class="op">:</span> Witness<span class="op">.</span>Aux<span class="op">[</span>K<span class="op">],</span></span>
<span id="cb13-3"><a href="#cb13-3" aria-hidden="true" tabindex="-1"></a>  tLister<span class="op">:</span> FieldLister<span class="op">[</span>T<span class="op">]</span></span>
<span id="cb13-4"><a href="#cb13-4" aria-hidden="true" tabindex="-1"></a><span class="op">):</span> FieldLister<span class="op">[</span>FieldType<span class="op">[</span>K<span class="op">,</span> H<span class="op">]</span> <span class="op">::</span> T<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> FieldLister<span class="op">[</span>FieldType<span class="op">[</span>K<span class="op">,</span> H<span class="op">]</span> <span class="op">::</span>T<span class="op">]</span> <span class="op">{</span></span>
<span id="cb13-5"><a href="#cb13-5" aria-hidden="true" tabindex="-1"></a>  <span class="kw">override</span> <span class="kw">val</span> list <span class="op">=</span> witness<span class="op">.</span>value<span class="op">.</span>name <span class="op">::</span> tLister<span class="op">.</span>list</span>
<span id="cb13-6"><a href="#cb13-6" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Even though it looks nice, we’ve got a new kind of problem here. Our implicits are
ambiguous. Both <code>hconsLister</code> and <code>primitiveFieldLister</code> can be applied to
<code>HList</code>. The Scala compiler cannot choose which one is more applicable (even
though one of these declarations requires an instance of <code>FieldLister[H]</code>, both
of the instances have the same weight). So, the compiler
requires that you avoid conflicts in the implicit resolution. To manage the
implicit resolution order we can use “Low priority” pattern. The idea is to
move the implicits with lower precedence to the parent class. Once the
compiler can find an implicit instance in the child class it will use it (it
will not search all possible implicits in the class parents). But if it is not
able to find an implicit in the inherited class, it will search in the parent
classes. So we can rewrite it in the following way:</p>
<div class="sourceCode" id="cb14"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">trait</span> FieldListerLowPriority <span class="op">{</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">implicit</span> <span class="kw">def</span> primitiveFieldLister<span class="op">[</span>K <span class="op">&lt;:</span> <span class="bu">Symbol</span><span class="op">,</span> H<span class="op">,</span> T <span class="op">&lt;:</span> HList<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true" tabindex="-1"></a>    witness<span class="op">:</span> Witness<span class="op">.</span>Aux<span class="op">[</span>K<span class="op">],</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true" tabindex="-1"></a>    tLister<span class="op">:</span> FieldLister<span class="op">[</span>T<span class="op">]</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> FieldLister<span class="op">[</span>FieldType<span class="op">[</span>K<span class="op">,</span> H<span class="op">]</span> <span class="op">::</span> T<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> FieldLister<span class="op">[</span>FieldType<span class="op">[</span>K<span class="op">,</span> H<span class="op">]</span> <span class="op">::</span>T<span class="op">]</span> <span class="op">{</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">val</span> list <span class="op">=</span> witness<span class="op">.</span>value<span class="op">.</span>name <span class="op">::</span> tLister<span class="op">.</span>list</span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb14-10"><a href="#cb14-10" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> FieldLister <span class="kw">extends</span> FieldListerLowPriority <span class="op">{</span></span>
<span id="cb14-11"><a href="#cb14-11" aria-hidden="true" tabindex="-1"></a>  <span class="co">// all other instances are here</span></span>
<span id="cb14-12"><a href="#cb14-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Now, when we have the <code>FieldLister</code> we can easily implement <code>StatementGenerator</code>.
All we need to do is to wrap the <code>FieldLister</code> result into the SQL statements:</p>
<div class="sourceCode" id="cb15"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="kw">object</span> StatementGenerator <span class="op">{</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a>  <span class="kw">implicit</span> <span class="kw">def</span> genericGenerator<span class="op">[</span>A<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true" tabindex="-1"></a>    fieldLister<span class="op">:</span> FieldLister<span class="op">[</span>A<span class="op">]</span></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">=</span> <span class="kw">new</span> StatementGenerator<span class="op">[</span>A<span class="op">]</span> <span class="op">{</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">def</span> <span class="fu">select</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">):</span> <span class="ex">String</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">val</span> fields <span class="op">=</span> fieldLister<span class="op">.</span>list<span class="op">.</span><span class="fu">mkString</span><span class="op">(</span><span class="st">&quot;,&quot;</span><span class="op">)</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true" tabindex="-1"></a>      <span class="ss">s&quot;</span><span class="st">SELECT </span><span class="ss">$fields</span><span class="st"> FROM </span><span class="ss">$table&quot;</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true" tabindex="-1"></a>    <span class="kw">override</span> <span class="kw">def</span> <span class="fu">insert</span><span class="op">(</span>table<span class="op">:</span> <span class="ex">String</span><span class="op">)</span> <span class="op">=</span> <span class="op">{</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true" tabindex="-1"></a>      <span class="kw">val</span> fieldNames <span class="op">=</span> fieldLister<span class="op">.</span>list</span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true" tabindex="-1"></a>      <span class="kw">val</span> fields <span class="op">=</span> fieldNames<span class="op">.</span><span class="fu">mkString</span><span class="op">(</span><span class="st">&quot;,&quot;</span><span class="op">)</span></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true" tabindex="-1"></a>      <span class="kw">val</span> placeholders <span class="op">=</span> <span class="ex">List</span><span class="op">.</span><span class="fu">fill</span><span class="op">(</span>fieldNames<span class="op">.</span>size<span class="op">)(</span><span class="st">&quot;?&quot;</span><span class="op">).</span><span class="fu">mkString</span><span class="op">(</span><span class="st">&quot;,&quot;</span><span class="op">)</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true" tabindex="-1"></a>      <span class="ss">s&quot;</span><span class="st">INSERT INTO </span><span class="ss">$table</span><span class="st"> (</span><span class="ss">$fields</span><span class="st">) VALUES (</span><span class="ss">$placeholders</span><span class="st">)</span><span class="ss">&quot;</span></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>And that’s all folks.</p>]]></summary>
</entry>
<entry>
    <title>Firefox ESR and XMonad</title>
    <link href="http://limansky.me/posts/2017-01-28-firefox-esr-and-xmonad.html" />
    <id>http://limansky.me/posts/2017-01-28-firefox-esr-and-xmonad.html</id>
    <published>2017-01-28T00:00:00Z</published>
    <updated>2017-01-28T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>If you are XMonad and Firefox ESR user, just like me, you might know that there
is a problem with full screen videos playback. A video hangs and you cannot close
it. All you can do is just to kill Firefox. It’s already fixed in the main line,
but it looks like they <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1189622">don’t want</a>
to port the patch to ESR version.</p>
<p>Fortunately the patch is not too big and I adopted it for the ESR version. Here is
it:</p>
<!--more-->
<div class="sourceCode" id="cb1"><pre class="sourceCode diff"><code class="sourceCode diff"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="dt">--- a/dom/base/nsGlobalWindow.h</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="dt">+++ b/dom/base/nsGlobalWindow.h</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -473,7 +473,7 @@</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>     FullscreenReason aReason, bool aIsFullscreen,</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>     mozilla::gfx::VRHMDInfo *aHMD = nullptr) override final;</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>   virtual void FinishFullscreenChange(bool aIsFullscreen) override final;</span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a><span class="st">-  void SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a><span class="va">+  bool SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>                            nsIWidget* aWidget, nsIScreen* aScreen);</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>   bool FullScreen() const;</span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a><span class="kw">diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="dt">--- a/dom/base/nsGlobalWindow.cpp.orig</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a><span class="dt">+++ b/dom/base/nsGlobalWindow.cpp	</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -5905,8 +5905,12 @@</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>       mWindow-&gt;mFullScreen = mFullscreen;</span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>     }</span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>     // Toggle the fullscreen state on the widget</span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a><span class="st">-    mWindow-&gt;SetWidgetFullscreen(nsPIDOMWindow::eForFullscreenAPI,</span></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a><span class="st">-                                 mFullscreen, mWidget, mScreen);</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a><span class="va">+    if (!mWindow-&gt;SetWidgetFullscreen(nsPIDOMWindow::eForFullscreenAPI,</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a><span class="va">+                                      mFullscreen, mWidget, mScreen)) {</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a><span class="va">+      // Fail to setup the widget, call FinishFullscreenChange to</span></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a><span class="va">+      // complete fullscreen change directly.</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a><span class="va">+      mWindow-&gt;FinishFullscreenChange(mFullscreen);</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a><span class="va">+    }</span></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>     // Set observer for the next content paint.</span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>     nsCOMPtr&lt;nsIObserver&gt; observer = new Observer(this);</span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>     nsCOMPtr&lt;nsIObserverService&gt; obs = mozilla::services::GetObserverService();</span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -5985,14 +5989,14 @@</span></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a>   }</span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>   nsCOMPtr&lt;nsIScreen&gt; screen = aHMD ? aHMD-&gt;GetScreen() : nullptr;</span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>   if (!performTransition) {</span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a><span class="st">-    aWindow-&gt;SetWidgetFullscreen(aReason, aFullscreen, widget, screen);</span></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a><span class="va">+    return aWindow-&gt;SetWidgetFullscreen(aReason, aFullscreen, widget, screen);</span></span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>   } else {</span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a>     nsCOMPtr&lt;nsIRunnable&gt; task =</span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>       new FullscreenTransitionTask(duration, aWindow, aFullscreen,</span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a>                                    widget, screen, transitionData);</span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>     task-&gt;Run();</span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a><span class="va">+    return true;</span></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a>   }</span>
<span id="cb1-44"><a href="#cb1-44" aria-hidden="true" tabindex="-1"></a><span class="st">-  return true;</span></span>
<span id="cb1-45"><a href="#cb1-45" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb1-46"><a href="#cb1-46" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-47"><a href="#cb1-47" aria-hidden="true" tabindex="-1"></a> nsresult</span>
<span id="cb1-48"><a href="#cb1-48" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -6096,7 +6100,7 @@</span></span>
<span id="cb1-49"><a href="#cb1-49" aria-hidden="true" tabindex="-1"></a>   return NS_OK;</span>
<span id="cb1-50"><a href="#cb1-50" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb1-51"><a href="#cb1-51" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-52"><a href="#cb1-52" aria-hidden="true" tabindex="-1"></a><span class="st">-void</span></span>
<span id="cb1-53"><a href="#cb1-53" aria-hidden="true" tabindex="-1"></a><span class="va">+bool</span></span>
<span id="cb1-54"><a href="#cb1-54" aria-hidden="true" tabindex="-1"></a> nsGlobalWindow::SetWidgetFullscreen(FullscreenReason aReason, bool aIsFullscreen,</span>
<span id="cb1-55"><a href="#cb1-55" aria-hidden="true" tabindex="-1"></a>                                     nsIWidget* aWidget, nsIScreen* aScreen)</span>
<span id="cb1-56"><a href="#cb1-56" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb1-57"><a href="#cb1-57" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -6108,13 +6112,12 @@</span></span>
<span id="cb1-58"><a href="#cb1-58" aria-hidden="true" tabindex="-1"></a>   if (nsCOMPtr&lt;nsIPresShell&gt; presShell = mDocShell-&gt;GetPresShell()) {</span>
<span id="cb1-59"><a href="#cb1-59" aria-hidden="true" tabindex="-1"></a>     presShell-&gt;SetIsInFullscreenChange(true);</span>
<span id="cb1-60"><a href="#cb1-60" aria-hidden="true" tabindex="-1"></a>   }</span>
<span id="cb1-61"><a href="#cb1-61" aria-hidden="true" tabindex="-1"></a><span class="st">-  if (aReason == nsPIDOMWindow::eForFullscreenMode) {</span></span>
<span id="cb1-62"><a href="#cb1-62" aria-hidden="true" tabindex="-1"></a><span class="va">+  nsresult rv = aReason == nsPIDOMWindow::eForFullscreenMode ?</span></span>
<span id="cb1-63"><a href="#cb1-63" aria-hidden="true" tabindex="-1"></a>     // If we enter fullscreen for fullscreen mode, we want</span>
<span id="cb1-64"><a href="#cb1-64" aria-hidden="true" tabindex="-1"></a>     // the native system behavior.</span>
<span id="cb1-65"><a href="#cb1-65" aria-hidden="true" tabindex="-1"></a><span class="st">-    aWidget-&gt;MakeFullScreenWithNativeTransition(aIsFullscreen, aScreen);</span></span>
<span id="cb1-66"><a href="#cb1-66" aria-hidden="true" tabindex="-1"></a><span class="st">-  } else {</span></span>
<span id="cb1-67"><a href="#cb1-67" aria-hidden="true" tabindex="-1"></a><span class="va">+    aWidget-&gt;MakeFullScreenWithNativeTransition(aIsFullscreen, aScreen) :</span></span>
<span id="cb1-68"><a href="#cb1-68" aria-hidden="true" tabindex="-1"></a>     aWidget-&gt;MakeFullScreen(aIsFullscreen, aScreen);</span>
<span id="cb1-69"><a href="#cb1-69" aria-hidden="true" tabindex="-1"></a><span class="st">-  }</span></span>
<span id="cb1-70"><a href="#cb1-70" aria-hidden="true" tabindex="-1"></a><span class="va">+  return NS_SUCCEEDED(rv);</span></span>
<span id="cb1-71"><a href="#cb1-71" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb1-72"><a href="#cb1-72" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-73"><a href="#cb1-73" aria-hidden="true" tabindex="-1"></a> /* virtual */ void</span>
<span id="cb1-74"><a href="#cb1-74" aria-hidden="true" tabindex="-1"></a><span class="kw">diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h</span></span>
<span id="cb1-75"><a href="#cb1-75" aria-hidden="true" tabindex="-1"></a><span class="dt">--- a/widget/nsIWidget.h</span></span>
<span id="cb1-76"><a href="#cb1-76" aria-hidden="true" tabindex="-1"></a><span class="dt">+++ b/widget/nsIWidget.h</span></span>
<span id="cb1-77"><a href="#cb1-77" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -1137,16 +1137,20 @@ class nsIWidget : public nsISupports {</span></span>
<span id="cb1-78"><a href="#cb1-78" aria-hidden="true" tabindex="-1"></a>                                              nsIRunnable* aCallback) = 0;</span>
<span id="cb1-79"><a href="#cb1-79" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-80"><a href="#cb1-80" aria-hidden="true" tabindex="-1"></a>     /**</span>
<span id="cb1-81"><a href="#cb1-81" aria-hidden="true" tabindex="-1"></a>      * Put the toplevel window into or out of fullscreen mode.</span>
<span id="cb1-82"><a href="#cb1-82" aria-hidden="true" tabindex="-1"></a>      * If aTargetScreen is given, attempt to go fullscreen on that screen,</span>
<span id="cb1-83"><a href="#cb1-83" aria-hidden="true" tabindex="-1"></a>      * if possible.  (If not, it behaves as if aTargetScreen is null.)</span>
<span id="cb1-84"><a href="#cb1-84" aria-hidden="true" tabindex="-1"></a>      * If !aFullScreen, aTargetScreen is ignored.</span>
<span id="cb1-85"><a href="#cb1-85" aria-hidden="true" tabindex="-1"></a>      * aTargetScreen support is currently only implemented on Windows.</span>
<span id="cb1-86"><a href="#cb1-86" aria-hidden="true" tabindex="-1"></a><span class="va">+     *</span></span>
<span id="cb1-87"><a href="#cb1-87" aria-hidden="true" tabindex="-1"></a><span class="va">+     * @return NS_OK if the widget is setup properly for fullscreen and</span></span>
<span id="cb1-88"><a href="#cb1-88" aria-hidden="true" tabindex="-1"></a><span class="va">+     * FullscreenChanged callback has been or will be called. If other</span></span>
<span id="cb1-89"><a href="#cb1-89" aria-hidden="true" tabindex="-1"></a><span class="va">+     * value is returned, the caller should continue the change itself.</span></span>
<span id="cb1-90"><a href="#cb1-90" aria-hidden="true" tabindex="-1"></a>      */</span>
<span id="cb1-91"><a href="#cb1-91" aria-hidden="true" tabindex="-1"></a>     NS_IMETHOD MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen = nullptr) = 0;</span>
<span id="cb1-92"><a href="#cb1-92" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-93"><a href="#cb1-93" aria-hidden="true" tabindex="-1"></a>     /**</span>
<span id="cb1-94"><a href="#cb1-94" aria-hidden="true" tabindex="-1"></a>      * Same as MakeFullScreen, except that, on systems which natively</span>
<span id="cb1-95"><a href="#cb1-95" aria-hidden="true" tabindex="-1"></a>      * support fullscreen transition, calling this method explicitly</span>
<span id="cb1-96"><a href="#cb1-96" aria-hidden="true" tabindex="-1"></a>      * requests that behavior.</span>
<span id="cb1-97"><a href="#cb1-97" aria-hidden="true" tabindex="-1"></a>      * It is currently only supported on OS X 10.7+.</span>
<span id="cb1-98"><a href="#cb1-98" aria-hidden="true" tabindex="-1"></a><span class="kw">diff --git a/widget/gtk/mozgtk/mozgtk.c b/widget/gtk/mozgtk/mozgtk.c</span></span>
<span id="cb1-99"><a href="#cb1-99" aria-hidden="true" tabindex="-1"></a><span class="dt">--- a/widget/gtk/mozgtk/mozgtk.c</span></span>
<span id="cb1-100"><a href="#cb1-100" aria-hidden="true" tabindex="-1"></a><span class="dt">+++ b/widget/gtk/mozgtk/mozgtk.c</span></span>
<span id="cb1-101"><a href="#cb1-101" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -122,16 +122,17 @@ STUB(gdk_x11_display_get_user_time)</span></span>
<span id="cb1-102"><a href="#cb1-102" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_display_get_xdisplay)</span>
<span id="cb1-103"><a href="#cb1-103" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_get_default_root_xwindow)</span>
<span id="cb1-104"><a href="#cb1-104" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_get_default_xdisplay)</span>
<span id="cb1-105"><a href="#cb1-105" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_get_server_time)</span>
<span id="cb1-106"><a href="#cb1-106" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_get_xatom_by_name)</span>
<span id="cb1-107"><a href="#cb1-107" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_get_xatom_by_name_for_display)</span>
<span id="cb1-108"><a href="#cb1-108" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_lookup_xdisplay)</span>
<span id="cb1-109"><a href="#cb1-109" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_screen_get_xscreen)</span>
<span id="cb1-110"><a href="#cb1-110" aria-hidden="true" tabindex="-1"></a><span class="va">+STUB(gdk_x11_screen_supports_net_wm_hint)</span></span>
<span id="cb1-111"><a href="#cb1-111" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_visual_get_xvisual)</span>
<span id="cb1-112"><a href="#cb1-112" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_window_foreign_new_for_display)</span>
<span id="cb1-113"><a href="#cb1-113" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_window_lookup_for_display)</span>
<span id="cb1-114"><a href="#cb1-114" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_window_set_user_time)</span>
<span id="cb1-115"><a href="#cb1-115" aria-hidden="true" tabindex="-1"></a> STUB(gdk_x11_xatom_to_atom)</span>
<span id="cb1-116"><a href="#cb1-116" aria-hidden="true" tabindex="-1"></a> STUB(gtk_accel_label_new)</span>
<span id="cb1-117"><a href="#cb1-117" aria-hidden="true" tabindex="-1"></a> STUB(gtk_alignment_get_type)</span>
<span id="cb1-118"><a href="#cb1-118" aria-hidden="true" tabindex="-1"></a> STUB(gtk_alignment_new)</span>
<span id="cb1-119"><a href="#cb1-119" aria-hidden="true" tabindex="-1"></a><span class="kw">diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp</span></span>
<span id="cb1-120"><a href="#cb1-120" aria-hidden="true" tabindex="-1"></a><span class="dt">--- a/widget/gtk/nsWindow.cpp</span></span>
<span id="cb1-121"><a href="#cb1-121" aria-hidden="true" tabindex="-1"></a><span class="dt">+++ b/widget/gtk/nsWindow.cpp</span></span>
<span id="cb1-122"><a href="#cb1-122" aria-hidden="true" tabindex="-1"></a><span class="dt">@@ -4972,22 +4972,39 @@ nsWindow::PerformFullscreenTransition(Fu</span></span>
<span id="cb1-123"><a href="#cb1-123" aria-hidden="true" tabindex="-1"></a>     auto transitionData = new FullscreenTransitionData(aStage, aDuration,</span>
<span id="cb1-124"><a href="#cb1-124" aria-hidden="true" tabindex="-1"></a>                                                        aCallback, data);</span>
<span id="cb1-125"><a href="#cb1-125" aria-hidden="true" tabindex="-1"></a>     g_timeout_add_full(G_PRIORITY_HIGH,</span>
<span id="cb1-126"><a href="#cb1-126" aria-hidden="true" tabindex="-1"></a>                        FullscreenTransitionData::sInterval,</span>
<span id="cb1-127"><a href="#cb1-127" aria-hidden="true" tabindex="-1"></a>                        FullscreenTransitionData::TimeoutCallback,</span>
<span id="cb1-128"><a href="#cb1-128" aria-hidden="true" tabindex="-1"></a>                        transitionData, nullptr);</span>
<span id="cb1-129"><a href="#cb1-129" aria-hidden="true" tabindex="-1"></a> }</span>
<span id="cb1-130"><a href="#cb1-130" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-131"><a href="#cb1-131" aria-hidden="true" tabindex="-1"></a><span class="va">+static bool</span></span>
<span id="cb1-132"><a href="#cb1-132" aria-hidden="true" tabindex="-1"></a><span class="va">+IsFullscreenSupported(GtkWidget* aShell)</span></span>
<span id="cb1-133"><a href="#cb1-133" aria-hidden="true" tabindex="-1"></a><span class="va">+{</span></span>
<span id="cb1-134"><a href="#cb1-134" aria-hidden="true" tabindex="-1"></a><span class="va">+#ifdef MOZ_X11</span></span>
<span id="cb1-135"><a href="#cb1-135" aria-hidden="true" tabindex="-1"></a><span class="va">+    GdkScreen* screen = gtk_widget_get_screen(aShell);</span></span>
<span id="cb1-136"><a href="#cb1-136" aria-hidden="true" tabindex="-1"></a><span class="va">+    GdkAtom atom = gdk_atom_intern(&quot;_NET_WM_STATE_FULLSCREEN&quot;, FALSE);</span></span>
<span id="cb1-137"><a href="#cb1-137" aria-hidden="true" tabindex="-1"></a><span class="va">+    if (!gdk_x11_screen_supports_net_wm_hint(screen, atom)) {</span></span>
<span id="cb1-138"><a href="#cb1-138" aria-hidden="true" tabindex="-1"></a><span class="va">+        return false;</span></span>
<span id="cb1-139"><a href="#cb1-139" aria-hidden="true" tabindex="-1"></a><span class="va">+    }</span></span>
<span id="cb1-140"><a href="#cb1-140" aria-hidden="true" tabindex="-1"></a><span class="va">+#endif</span></span>
<span id="cb1-141"><a href="#cb1-141" aria-hidden="true" tabindex="-1"></a><span class="va">+    return true;</span></span>
<span id="cb1-142"><a href="#cb1-142" aria-hidden="true" tabindex="-1"></a><span class="va">+}</span></span>
<span id="cb1-143"><a href="#cb1-143" aria-hidden="true" tabindex="-1"></a><span class="va">+</span></span>
<span id="cb1-144"><a href="#cb1-144" aria-hidden="true" tabindex="-1"></a> NS_IMETHODIMP</span>
<span id="cb1-145"><a href="#cb1-145" aria-hidden="true" tabindex="-1"></a> nsWindow::MakeFullScreen(bool aFullScreen, nsIScreen* aTargetScreen)</span>
<span id="cb1-146"><a href="#cb1-146" aria-hidden="true" tabindex="-1"></a> {</span>
<span id="cb1-147"><a href="#cb1-147" aria-hidden="true" tabindex="-1"></a>     LOG((&quot;nsWindow::MakeFullScreen [%p] aFullScreen %d\n&quot;,</span>
<span id="cb1-148"><a href="#cb1-148" aria-hidden="true" tabindex="-1"></a>          (void *)this, aFullScreen));</span>
<span id="cb1-149"><a href="#cb1-149" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-150"><a href="#cb1-150" aria-hidden="true" tabindex="-1"></a><span class="va">+    if (!IsFullscreenSupported(mShell)) {</span></span>
<span id="cb1-151"><a href="#cb1-151" aria-hidden="true" tabindex="-1"></a><span class="va">+        return NS_ERROR_NOT_AVAILABLE;</span></span>
<span id="cb1-152"><a href="#cb1-152" aria-hidden="true" tabindex="-1"></a><span class="va">+    }</span></span>
<span id="cb1-153"><a href="#cb1-153" aria-hidden="true" tabindex="-1"></a><span class="va">+</span></span>
<span id="cb1-154"><a href="#cb1-154" aria-hidden="true" tabindex="-1"></a>     if (aFullScreen) {</span>
<span id="cb1-155"><a href="#cb1-155" aria-hidden="true" tabindex="-1"></a>         if (mSizeMode != nsSizeMode_Fullscreen)</span>
<span id="cb1-156"><a href="#cb1-156" aria-hidden="true" tabindex="-1"></a>             mLastSizeMode = mSizeMode;</span>
<span id="cb1-157"><a href="#cb1-157" aria-hidden="true" tabindex="-1"></a> </span>
<span id="cb1-158"><a href="#cb1-158" aria-hidden="true" tabindex="-1"></a>         mSizeMode = nsSizeMode_Fullscreen;</span>
<span id="cb1-159"><a href="#cb1-159" aria-hidden="true" tabindex="-1"></a>         gtk_window_fullscreen(GTK_WINDOW(mShell));</span>
<span id="cb1-160"><a href="#cb1-160" aria-hidden="true" tabindex="-1"></a>     }</span>
<span id="cb1-161"><a href="#cb1-161" aria-hidden="true" tabindex="-1"></a>     else {</span></code></pre></div>
<p>If you use Gentoo you can just put the patch in
<code>/etc/portage/patches/www-client/firefox/firefox-45.7.0/patch.diff</code> file and
reemerge Firefox.</p>]]></summary>
</entry>
<entry>
    <title>Pagination with Hakyll</title>
    <link href="http://limansky.me/posts/2016-12-28-pagination-with-hakyll.html" />
    <id>http://limansky.me/posts/2016-12-28-pagination-with-hakyll.html</id>
    <published>2016-12-28T00:00:00Z</published>
    <updated>2016-12-28T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Yesterday I realized that there are more than ten posts in my blog. Not so many
for more than a year, but quite a lot for the index page. The simplest solution
is to just limit amount of posts with <code>take</code> function, and write something like
“more posts in the <a href="/archive.html">archives</a>”. But I prefer to have pagination
for the index page. Hakyll has built-in support for pagination in the module
<a href="https://jaspervdj.be/hakyll/reference/Hakyll-Web-Paginate.html">Hakyll.Web.Paginate</a>.
There is a very nice manual about how to use it in this <a href="https://dannysu.com/2015/10/29/hakyll-pagination/">blog
post</a>.</p>
<p>Unfortunately, Paginate provides only first/previous/current/next/last functionality.
It’s quite common to have only “Older posts” and “Newer posts” buttons for
blogs, but I’d like to have a list of all pages in the Bootstrap pagination
component. So, it’s time to write some Haskell code (of course you need to
write code to add the standard Paginate, but I’m going to write a little bit more).</p>
<!--more-->
<h2 id="generating-paginated-pages">Generating paginated pages</h2>
<p>Let’s set up basic Paginate and then extend it. If you are already familiar
with Paginate, you can skip this section.</p>
<p>The data type <code>Paginate</code> holds mapping from page numbers to <code>Identifier</code>s. The
<code>buildPaginateWith</code> function is used to create <code>Paginate</code> instances. This
function has three parameters:</p>
<ul>
<li>grouper – a function to group a list of <code>Identifier</code>s into chunks</li>
<li>pattern – a <code>Pattern</code> instance to get required items</li>
<li>makeId – a function to map page numbers to <code>Identifier</code>s</li>
</ul>
<p>Let start with <code>makeId</code> as the simplest one:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ot">postsPageId ::</span> <span class="dt">PageNumber</span> <span class="ot">-&gt;</span> <span class="dt">Identifier</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>postsPageId n <span class="ot">=</span> fromFilePath <span class="op">$</span> <span class="kw">if</span> (n <span class="op">==</span> <span class="dv">1</span>) <span class="kw">then</span> <span class="st">&quot;index.html&quot;</span> <span class="kw">else</span> <span class="fu">show</span> n <span class="op">++</span> <span class="st">&quot;/index.html&quot;</span></span></code></pre></div>
<p>Pretty straightforward, right? It creates an <code>Identifier</code> from the file path. If it’s
the first page, the path is just “index.html”, otherwise it should take
“index.html” file from the folder named with a page number, e.g. “2/index.html”.</p>
<p>The grouper has the following signature:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">postsGrouper ::</span> <span class="dt">MonadMetadata</span> m <span class="ot">=&gt;</span> [<span class="dt">Identifier</span>] <span class="ot">-&gt;</span> m [[<span class="dt">Identifier</span>]]</span></code></pre></div>
<p>Hakyll provides the <code>paginateEvery</code> function which takes a list and groups it into
chunks of a specified number of elements. Another useful function is
<code>sortRecentFirst</code>, which sorts a list of <code>Identifier</code>s. So, we need to sort a
list of identifiers and then paginate it. To do that, we need to lift the
<code>paginateEvery</code> function to the <code>MonadMetadata</code> monad.</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="dt">Control.Monad</span> (liftM)</span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a><span class="ot">postsGrouper ::</span> <span class="dt">MonadMetadata</span> m <span class="ot">=&gt;</span> [<span class="dt">Identifier</span>] <span class="ot">-&gt;</span> m [[<span class="dt">Identifier</span>]]</span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>postsGrouper <span class="ot">=</span> liftM (paginateEvery <span class="dv">10</span>) <span class="op">.</span> sortRecentFirst </span></code></pre></div>
<p>Now we can build a <code>Paginate</code> instance:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>main <span class="ot">=</span> checkArgs <span class="op">&lt;$&gt;</span> getArgs <span class="op">&gt;&gt;=</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>        \(postsPattern, conf, args) <span class="ot">-&gt;</span> withArgs args <span class="op">$</span> hakyllWith conf <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>    paginate <span class="ot">&lt;-</span> buildPaginateWith postsGrouper postsPattern postsPageId</span></code></pre></div>
<p>In a simple case <code>postsPattern</code> can be just a string <code>"posts/*"</code>, but I use different
configurations depending on the command line parameters (see <a href="/posts/2015-10-31-Draft-posts-with-Hakyll.html">Draft posts with
Hakyll</a> post).</p>
<p>Once we obtain a <code>Paginate</code> instance we can generate content using the
<code>paginateRules</code> function. This function takes an instance of <code>Paginate</code> as a
parameter and a function with the following signature <code>PageNumber -&gt; Pattern -&gt; Rules()</code> as a second parameter.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a>    paginateRules paginate <span class="op">$</span> \page <span class="kw">pattern</span> <span class="ot">-&gt;</span> <span class="kw">do</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>        route idRoute</span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>        compile <span class="op">$</span> <span class="kw">do</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>            posts <span class="ot">&lt;-</span> recentFirst <span class="op">=&lt;&lt;</span> loadAllSnapshots <span class="kw">pattern</span> <span class="st">&quot;content&quot;</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>            <span class="kw">let</span> indexCtx <span class="ot">=</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>                    constField <span class="st">&quot;title&quot;</span> (<span class="kw">if</span> page <span class="op">==</span> <span class="dv">1</span> <span class="kw">then</span> <span class="st">&quot;Latest blog posts&quot;</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>                                                     <span class="kw">else</span> <span class="st">&quot;Blog posts, page &quot;</span> <span class="op">++</span> <span class="fu">show</span> page) <span class="op">&lt;&gt;</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>                    listField <span class="st">&quot;posts&quot;</span> (previewCtx tags) (<span class="fu">return</span> posts) <span class="op">&lt;&gt;</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>                    paginateContextPlus paginate page <span class="op">&lt;&gt;</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a>                    mainCtx tags postsPattern</span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a>            makeItem <span class="st">&quot;&quot;</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true" tabindex="-1"></a>                <span class="op">&gt;&gt;=</span> applyAsTemplate indexCtx</span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true" tabindex="-1"></a>                <span class="op">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;templates/posts-preview-list.html&quot;</span> indexCtx</span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true" tabindex="-1"></a>                <span class="op">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;templates/page-right-column.html&quot;</span> indexCtx</span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true" tabindex="-1"></a>                <span class="op">&gt;&gt;=</span> loadAndApplyTemplate <span class="st">&quot;templates/default.html&quot;</span> indexCtx</span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true" tabindex="-1"></a>                <span class="op">&gt;&gt;=</span> relativizeUrls</span></code></pre></div>
<p>Hakyll has the <code>paginateContext</code> function which returns a context with a
number of fields for the specific page. As I said before, this is not enough for
me, so I’m using <code>paginateContextPlus</code>, which is defined in the next section.</p>
<h2 id="extending-paginate-context">Extending paginate context</h2>
<p>To create the paginator I need a list of all the pages, and a current page. Since it is
not possible to perform an equality check inside the template, I decided to split
the list of pages into two parts: pages before the current one, and pages after it.
Let’s write a function which will create a context with these fields:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">import</span> <span class="kw">qualified</span> <span class="dt">Data.Map</span> <span class="kw">as</span> <span class="dt">M</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a><span class="ot">paginateContextPlus ::</span> <span class="dt">Paginate</span> <span class="ot">-&gt;</span> <span class="dt">PageNumber</span> <span class="ot">-&gt;</span> <span class="dt">Context</span> a</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>paginateContextPlus pag currentPage <span class="ot">=</span> paginateContext pag currentPage <span class="op">&lt;&gt;</span> <span class="fu">mconcat</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    [ listField <span class="st">&quot;pagesBefore&quot;</span> linkCtx <span class="op">$</span> wrapPages pagesBefore</span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true" tabindex="-1"></a>    , listField <span class="st">&quot;pagesAfter&quot;</span>  linkCtx <span class="op">$</span> wrapPages pagesAfter</span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true" tabindex="-1"></a>    ]</span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true" tabindex="-1"></a>    <span class="kw">where</span></span></code></pre></div>
<p>I included <code>paginateContext</code> into the result of this function. Since
we need a lists of pages, we need to use the <code>listField</code> function to create
contexts. We need to create nested contexts for the list elements:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ot">        linkCtx ::</span> <span class="dt">Context</span> (<span class="dt">String</span>, <span class="dt">String</span>)</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>        linkCtx <span class="ot">=</span> field <span class="st">&quot;pageNum&quot;</span> (<span class="fu">return</span> <span class="op">.</span> <span class="fu">fst</span> <span class="op">.</span> itemBody) <span class="op">&lt;&gt;</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>                  field <span class="st">&quot;pageUrl&quot;</span> (<span class="fu">return</span> <span class="op">.</span> <span class="fu">snd</span> <span class="op">.</span> itemBody)</span></code></pre></div>
<p>The next step is to get the information about each page except the current one and split the
list of the pages into two parts:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a>        pages <span class="ot">=</span> [pageInfo n <span class="op">|</span> n <span class="ot">&lt;-</span> [<span class="dv">1</span><span class="op">..</span>lastPage], n <span class="op">/=</span> currentPage]</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>        lastPage <span class="ot">=</span> M.size <span class="op">.</span> paginateMap <span class="op">$</span> pag</span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a>        pageInfo n <span class="ot">=</span> (n, paginateMakeId pag n)</span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>        (pagesBefore, pagesAfter) <span class="ot">=</span> <span class="fu">span</span> ((<span class="op">&lt;</span> currentPage) <span class="op">.</span> <span class="fu">fst</span>) pages</span></code></pre></div>
<p>And the last required part is a <code>wrapPages</code> function, which converts
<code>[(PageNumber, Identifier)]</code> into <code>Compiler [Item (String, String)]</code>. Let’s
start with a helper function to convert a single list item into <code>Compiler (Item (String, String))</code>.</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="ot">        makeInfoItem ::</span> (<span class="dt">PageNumber</span>, <span class="dt">Identifier</span>) <span class="ot">-&gt;</span> <span class="dt">Compiler</span> (<span class="dt">Item</span> (<span class="dt">String</span>, <span class="dt">String</span>))</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a>        makeInfoItem (n, i) <span class="ot">=</span> getRoute i <span class="op">&gt;&gt;=</span> \mbR <span class="ot">-&gt;</span> <span class="kw">case</span> mbR <span class="kw">of</span></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Just</span> r  <span class="ot">-&gt;</span> makeItem (<span class="fu">show</span> n, toUrl r)</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true" tabindex="-1"></a>            <span class="dt">Nothing</span> <span class="ot">-&gt;</span> <span class="fu">fail</span> <span class="op">$</span> <span class="st">&quot;No URL for page: &quot;</span> <span class="op">++</span> <span class="fu">show</span> n</span></code></pre></div>
<p>Now, we can map a list with <code>makeInfoItem</code>:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="ot">        wrapPages ::</span> [(<span class="dt">PageNumber</span>, <span class="dt">Identifier</span>)] <span class="ot">-&gt;</span> <span class="dt">Compiler</span> [<span class="dt">Item</span> (<span class="dt">String</span>, <span class="dt">String</span>)]</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a>        wrapPages <span class="ot">=</span> <span class="fu">sequence</span> <span class="op">.</span> <span class="fu">map</span> makeInfoItem</span></code></pre></div>
<p>Since <code>Compiler</code> is a monad, we can convert a list of <code>Compiler</code>s to the
<code>Compiler</code> of the list with the <code>sequence</code> function.</p>
<h2 id="template">Template</h2>
<p>Now, when we have all the required variables in the context, it is simple to add the
paginator to the template:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode html"><code class="sourceCode html"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;</span><span class="kw">nav</span><span class="ot"> aria-label</span><span class="op">=</span><span class="st">&quot;Page navigation&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a>  <span class="dt">&lt;</span><span class="kw">ul</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;pagination&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true" tabindex="-1"></a>    $if(previousPageNum)$</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;</span><span class="kw">li</span><span class="dt">&gt;</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true" tabindex="-1"></a>    $else$</span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;</span><span class="kw">li</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;disabled&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true" tabindex="-1"></a>    $endif$</span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true" tabindex="-1"></a>    $if(previousPageNum)$</span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;$previousPageUrl$&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true" tabindex="-1"></a>    $else$</span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;#&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true" tabindex="-1"></a>    $endif$</span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true" tabindex="-1"></a>        <span class="dt">&lt;</span><span class="kw">span</span><span class="ot"> aria-hidden</span><span class="op">=</span><span class="st">&quot;true&quot;</span><span class="dt">&gt;</span><span class="dv">&amp;laquo;</span><span class="dt">&lt;/</span><span class="kw">span</span><span class="dt">&gt;</span></span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&lt;/</span><span class="kw">a</span><span class="dt">&gt;</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;/</span><span class="kw">li</span><span class="dt">&gt;</span></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true" tabindex="-1"></a>    $for(pagesBefore)$</span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;</span><span class="kw">li</span><span class="dt">&gt;&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;$pageUrl$&quot;</span><span class="dt">&gt;</span>$pageNum$<span class="dt">&lt;/</span><span class="kw">a</span><span class="dt">&gt;&lt;/</span><span class="kw">li</span><span class="dt">&gt;</span></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true" tabindex="-1"></a>    $endfor$</span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;</span><span class="kw">li</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;active&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;#&quot;</span><span class="dt">&gt;</span>$currentPageNum$<span class="dt">&lt;</span><span class="kw">span</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;sr-only&quot;</span><span class="dt">&gt;</span>current<span class="dt">&lt;/</span><span class="kw">span</span><span class="dt">&gt;&lt;/</span><span class="kw">a</span><span class="dt">&gt;</span></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;/</span><span class="kw">li</span><span class="dt">&gt;</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true" tabindex="-1"></a>    $for(pagesAfter)$</span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;</span><span class="kw">li</span><span class="dt">&gt;&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;$pageUrl$&quot;</span><span class="dt">&gt;</span>$pageNum$<span class="dt">&lt;/</span><span class="kw">a</span><span class="dt">&gt;&lt;/</span><span class="kw">li</span><span class="dt">&gt;</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true" tabindex="-1"></a>    $endfor$</span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true" tabindex="-1"></a>    $if(nextPageNum)$</span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;</span><span class="kw">li</span><span class="dt">&gt;</span></span>
<span id="cb11-27"><a href="#cb11-27" aria-hidden="true" tabindex="-1"></a>    $else$</span>
<span id="cb11-28"><a href="#cb11-28" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;</span><span class="kw">li</span><span class="ot"> class</span><span class="op">=</span><span class="st">&quot;disabled&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-29"><a href="#cb11-29" aria-hidden="true" tabindex="-1"></a>    $endif$</span>
<span id="cb11-30"><a href="#cb11-30" aria-hidden="true" tabindex="-1"></a>    $if(nextPageNum)$</span>
<span id="cb11-31"><a href="#cb11-31" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;$nextPageUrl$&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-32"><a href="#cb11-32" aria-hidden="true" tabindex="-1"></a>    $else$</span>
<span id="cb11-33"><a href="#cb11-33" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&lt;</span><span class="kw">a</span><span class="ot"> href</span><span class="op">=</span><span class="st">&quot;#&quot;</span><span class="dt">&gt;</span></span>
<span id="cb11-34"><a href="#cb11-34" aria-hidden="true" tabindex="-1"></a>    $endif$</span>
<span id="cb11-35"><a href="#cb11-35" aria-hidden="true" tabindex="-1"></a>        <span class="dt">&lt;</span><span class="kw">span</span><span class="ot"> aria-hidden</span><span class="op">=</span><span class="st">&quot;true&quot;</span><span class="dt">&gt;</span><span class="dv">&amp;raquo;</span><span class="dt">&lt;/</span><span class="kw">span</span><span class="dt">&gt;</span></span>
<span id="cb11-36"><a href="#cb11-36" aria-hidden="true" tabindex="-1"></a>      <span class="dt">&lt;/</span><span class="kw">a</span><span class="dt">&gt;</span></span>
<span id="cb11-37"><a href="#cb11-37" aria-hidden="true" tabindex="-1"></a>    <span class="dt">&lt;/</span><span class="kw">li</span><span class="dt">&gt;</span></span>
<span id="cb11-38"><a href="#cb11-38" aria-hidden="true" tabindex="-1"></a>  <span class="dt">&lt;/</span><span class="kw">ui</span><span class="dt">&gt;</span></span>
<span id="cb11-39"><a href="#cb11-39" aria-hidden="true" tabindex="-1"></a><span class="dt">&lt;/</span><span class="kw">nav</span><span class="dt">&gt;</span></span></code></pre></div>
<p>Hakyll requires you to check if the previous/next page variables are defined,
because they are not defined on the first/last page.</p>
<p>And that’s all.</p>]]></summary>
</entry>
<entry>
    <title>Fixing bugs in SqlSaver</title>
    <link href="http://limansky.me/posts/2016-12-22-fixing-bugs-in-sql-saver.html" />
    <id>http://limansky.me/posts/2016-12-22-fixing-bugs-in-sql-saver.html</id>
    <published>2016-12-22T00:00:00Z</published>
    <updated>2016-12-22T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>In the <a href="/posts/2016-11-24-getting-started-with-shapeless.html">previous post</a>
I created <code>SqlSaver</code> class. Later, playing with it, I found that it has
several bugs.</p>
<p>First of all, it doesn’t work properly with nested
classes. Let’s start with a test:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="kw">class</span> <span class="fu">SaleRecord</span><span class="op">(</span>id<span class="op">:</span> <span class="bu">Int</span><span class="op">,</span> sale<span class="op">:</span> Sale<span class="op">,</span> seller<span class="op">:</span> <span class="ex">String</span><span class="op">)</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>it should <span class="st">&quot;save nested case classes&quot;</span> in <span class="op">{</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>  <span class="kw">val</span> date <span class="op">=</span> LocalDateTime<span class="op">.</span>now</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>  SqlSaver<span class="op">[</span>SaleRecord<span class="op">].</span><span class="fu">save</span><span class="op">(</span>stm<span class="op">,</span> <span class="dv">6</span><span class="op">)(</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="fu">SaleRecord</span><span class="op">(</span><span class="dv">1</span><span class="op">,</span> <span class="fu">Sale</span><span class="op">(</span><span class="st">&quot;bar&quot;</span><span class="op">,</span> date<span class="op">,</span> <span class="dv">42</span><span class="op">),</span> <span class="st">&quot;Shop&quot;</span><span class="op">)</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">)</span> should <span class="fu">equal</span><span class="op">(</span><span class="dv">11</span><span class="op">)</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>  <span class="fu">verify</span><span class="op">(</span>stm<span class="op">).</span><span class="fu">setInt</span><span class="op">(</span><span class="dv">6</span><span class="op">,</span> <span class="dv">1</span><span class="op">)</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>  <span class="fu">verify</span><span class="op">(</span>stm<span class="op">).</span><span class="fu">setString</span><span class="op">(</span><span class="dv">7</span><span class="op">,</span> <span class="st">&quot;bar&quot;</span><span class="op">)</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>  <span class="fu">verify</span><span class="op">(</span>stm<span class="op">).</span><span class="fu">setTimestamp</span><span class="op">(</span><span class="dv">8</span><span class="op">,</span> <span class="ex">Timestamp</span><span class="op">.</span><span class="fu">valueOf</span><span class="op">(</span>date<span class="op">))</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>  <span class="fu">verify</span><span class="op">(</span>stm<span class="op">).</span><span class="fu">setBigDecimal</span><span class="op">(</span><span class="dv">9</span><span class="op">,</span> java<span class="op">.</span>math<span class="op">.</span><span class="ex">BigDecimal</span><span class="op">.</span><span class="fu">valueOf</span><span class="op">(</span><span class="dv">42</span><span class="op">))</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>  <span class="fu">verify</span><span class="op">(</span>stm<span class="op">).</span><span class="fu">setString</span><span class="op">(</span><span class="dv">10</span><span class="op">,</span> <span class="st">&quot;Shop&quot;</span><span class="op">)</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Unfortunately it doesn’t compile:</p>
<pre><code>[error] SqlSaverTest.scala:38: diverging implicit expansion for type SqlSaver[LocalDateTime :: BigDecimal :: HNil]
[error] starting with method hlistSaver in object SqlSaver
[error]    SqlSaver[SaleRecord].save(stm, 6)(
[error]            ^</code></pre>
<pre><code>Note: here and later I rewrote HLists into the infix form, for readability.</code></pre>
<!--more-->
<p>That’s strange. We know that SqlSaver for <code>Sale</code> can be instantiated, because
<code>Sale</code> contains only fields of supported types. Maybe shapeless cannot
construct <code>Generic</code> for our nested classes? If we try to do it in REPL we get
the following result:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>Generic<span class="op">[</span>SaleRecord<span class="op">]{</span><span class="kw">type</span> Repr <span class="op">=</span> <span class="bu">Int</span> <span class="op">::</span> Sale <span class="op">::</span> <span class="ex">String</span> <span class="op">::</span> HNil <span class="op">}</span></span></code></pre></div>
<p>But if we try to evaluate <code>SqlSaver[Int :: Sale :: String :: HNil]</code> we get an
error. The problem we are faced with is related to how Scala implicit resolution
works. This topic is described in “The Type Astronaut’s Guide to Shapeless”. The
main idea is that the Scala compiler tries to avoid infinite loops during implicit
resolution. To do that, it has several heuristics. One of them is to stop
searching if it meets the same step twice. Another one is to stop if the
complexity of type parameters is increasing for the type constructor it met
before. In shapeless one of the type constructors is <code>::[H, T]</code> – the
constructor of HList. In our case we get a more complex HList for Sale than for
SaleRecord, so it cannot find an implicit instance of <code>SqlSaver[Sale]</code> and doesn’t compile.
Fortunately shapeless has special type <code>Lazy</code> to solve this problem (else shapeless
would be a quite useless thing). Let’s fix the last error case:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">def</span> hlistSaver<span class="op">[</span>H<span class="op">,</span> T <span class="op">&lt;:</span> HList<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>     hSaver<span class="op">:</span> Lazy<span class="op">[</span>SqlSaver<span class="op">[</span>H<span class="op">]],</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a>     tSaver<span class="op">:</span> SqlSaver<span class="op">[</span>T<span class="op">]</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> SqlSaver<span class="op">[</span>H <span class="op">::</span> T<span class="op">]</span> <span class="op">=</span> createSaver <span class="op">{</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">(</span>h <span class="op">::</span> t<span class="op">,</span> stm<span class="op">,</span> idx<span class="op">)</span> <span class="op">=&gt;</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>      hSaver<span class="op">.</span>value<span class="op">.</span><span class="fu">save</span><span class="op">(</span>stm<span class="op">,</span> idx<span class="op">)(</span>h<span class="op">)</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a>      tSaver<span class="op">.</span><span class="fu">save</span><span class="op">(</span>stm<span class="op">,</span> idx <span class="op">+</span> <span class="dv">1</span><span class="op">)(</span>t<span class="op">)</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span></code></pre></div>
<p>Once we wrapped the <code>hSaver</code> in <code>Lazy</code> it prevents the compiler from being too
clever, and postpones the implicit parameters evaluation to runtime. Now the
<code>SqlSaver</code> for HList works properly. We can fix the <code>genericSaver</code> in the
same way, wrapping <code>saver</code> into <code>Lazy</code>:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">def</span> genericSaver<span class="op">[</span>A<span class="op">,</span> R<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a>     gen<span class="op">:</span> Generic<span class="op">.</span>Aux<span class="op">[</span>A<span class="op">,</span> R<span class="op">],</span></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true" tabindex="-1"></a>     saver<span class="op">:</span> Lazy<span class="op">[</span>SqlSaver<span class="op">[</span>R<span class="op">]]</span></span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> SqlSaver<span class="op">[</span>A<span class="op">]</span> <span class="op">=</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true" tabindex="-1"></a>    <span class="fu">createSaver</span><span class="op">((</span>v<span class="op">,</span> stm<span class="op">,</span> idx<span class="op">)</span> <span class="op">=&gt;</span> saver<span class="op">.</span>value<span class="op">.</span><span class="fu">save</span><span class="op">(</span>stm<span class="op">,</span> idx<span class="op">)(</span>gen<span class="op">.</span><span class="fu">to</span><span class="op">(</span>v<span class="op">)))</span></span></code></pre></div>
<p>Now the test compiles successfully but fails on runtime with “9 did not equal
11” message. What happened? The current implementation of HList saver assumes that the head
saver takes only one element. This worked for primitive types, but of course
doesn’t work for classes. To fix that we need to use the next index returned by
<code>hSaver</code>:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">def</span> hlistSaver<span class="op">[</span>H<span class="op">,</span> T <span class="op">&lt;:</span> HList<span class="op">](</span><span class="kw">implicit</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>     hSaver<span class="op">:</span> Lazy<span class="op">[</span>SqlSaver<span class="op">[</span>H<span class="op">]],</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a>     tSaver<span class="op">:</span> SqlSaver<span class="op">[</span>T<span class="op">]</span></span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true" tabindex="-1"></a>  <span class="op">):</span> SqlSaver<span class="op">[</span>H <span class="op">::</span> T<span class="op">]</span> <span class="op">=</span> createSaver <span class="op">{</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true" tabindex="-1"></a>    <span class="cf">case</span> <span class="op">(</span>h <span class="op">::</span> t<span class="op">,</span> stm<span class="op">,</span> idx<span class="op">)</span> <span class="op">=&gt;</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true" tabindex="-1"></a>      <span class="kw">val</span> next <span class="op">=</span> hSaver<span class="op">.</span>value<span class="op">.</span><span class="fu">save</span><span class="op">(</span>stm<span class="op">,</span> idx<span class="op">)(</span>h<span class="op">)</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true" tabindex="-1"></a>      tSaver<span class="op">.</span><span class="fu">save</span><span class="op">(</span>stm<span class="op">,</span> next<span class="op">)(</span>t<span class="op">)</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span></span></code></pre></div>
<p>Now it works fine for nested classes.</p>]]></summary>
</entry>

</feed>
