Jekyll2016-10-23T10:16:11+01:00/Practical ScalaWebsite about Scala programming.Josef Vlachvlach.josef@gmail.comhttp://www.vlachjosef.comAux Pattern Evolution2016-10-23T09:51:20+01:002016-10-23T09:51:20+01:00/aux-pattern-evolution<p>When learning <a href="https://github.com/milessabin/shapeless">Shapeless</a> you will sooner or later encounter the so called <em>Aux Pattern</em>. There exists nice tutorial by Luigi Antonini - <a href="http://gigiigig.github.io/posts/2015/09/13/aux-pattern.html">The Aux Pattern - A short introduction to the <code class="highlighter-rouge">Aux Pattern</code></a> which explains this pattern quite well and you will gain good understanding what problem this pattern is solving. I recommend you to go and read that blog post first and come back if you would feel that you are still missing something in a complete understanding of a said pattern. That was exactly my feeling and motivation to write this article.</p>
<p>In this article I’m going to take step back into the past and I’m going to show how <code class="highlighter-rouge">Aux Pattern</code> was initially implemented before the contemporary implementation made it into Shapeless 2.x.x.</p>
<p>As a driving example we will use following type class (in order to avoid any external dependecies):</p>
<p><a name="unwrap-typeclass"></a></p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">trait</span> <span class="nc">Unwrap</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span><span class="o">]</span> <span class="o">{</span>
<span class="k">type</span> <span class="kt">Out</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])</span><span class="k">:</span> <span class="kt">Out</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Purpose of this type class is following: given some type constructor <code class="highlighter-rouge">T[_]</code> (let’s call it container) with arbitrary type <code class="highlighter-rouge">R</code> inside of this container, it will produce some output value of type <code class="highlighter-rouge">Out</code> as a result.</p>
<h3 id="aux-pattern---why">Aux Pattern - why</h3>
<p>Let’s suppose we have some values of type <code class="highlighter-rouge">List[String]</code> and <code class="highlighter-rouge">List[Int]</code> in our program (but we are not limited to <code class="highlighter-rouge">List</code> we can use any type constructor, for example <code class="highlighter-rouge">Option</code>), then we can write generic method <code class="highlighter-rouge">extractor</code> to process these values by use of type class <code class="highlighter-rouge">Unwrap[T, R]</code> like this:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">extractor</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span><span class="o">](</span><span class="n">in</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])(</span>
<span class="k">implicit</span>
<span class="n">unwrap</span><span class="k">:</span> <span class="kt">Unwrap</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span><span class="o">]</span>
<span class="o">)</span><span class="k">:</span> <span class="kt">unwrap.Out</span> <span class="o">=</span> <span class="o">{</span>
<span class="n">unwrap</span><span class="o">(</span><span class="n">in</span><span class="o">)</span>
<span class="o">}</span>
</code></pre>
</div>
<p>It is worth noting how this method is implemented.</p>
<ol>
<li>It takes generic input parameter <code class="highlighter-rouge">in: T[R]</code> (our <code class="highlighter-rouge">List[String]</code> or <code class="highlighter-rouge">List[Int]</code>)</li>
<li>Implicit parameter <code class="highlighter-rouge">unwrap: Unwrap[T, R]</code> is instance of our type class, which will be looked up in an implicit scope depending on the type parameters <code class="highlighter-rouge">T</code> and <code class="highlighter-rouge">R</code> of input value <code class="highlighter-rouge">in</code> (in our case <code class="highlighter-rouge">T</code> will be a <code class="highlighter-rouge">List</code> and <code class="highlighter-rouge">R</code> will be either a <code class="highlighter-rouge">String</code> or an <code class="highlighter-rouge">Int</code>).</li>
<li>Return type of the method is <strong>path dependent</strong> type <code class="highlighter-rouge">unwrap.Out</code> (it depends solely on what implicit <code class="highlighter-rouge">unwrap: Unwrap[T, R]</code> value will be chosen by implicit search mechanism in point 2.).</li>
</ol>
<p>We can provide instances of type class <code class="highlighter-rouge">Unwrap[T, R]</code> for <code class="highlighter-rouge">List[String]</code> and <code class="highlighter-rouge">List[Int]</code> in its companion object:</p>
<p><a name="unwrap-typeclass-instances"></a></p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Unwrap</span> <span class="o">{</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">listStringSize</span> <span class="k">extends</span> <span class="nc">Unwrap</span><span class="o">[</span><span class="kt">List</span>, <span class="kt">String</span><span class="o">]</span> <span class="o">{</span>
<span class="k">type</span> <span class="kt">Out</span> <span class="o">=</span> <span class="nc">Int</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="n">tr</span><span class="o">.</span><span class="n">size</span>
<span class="o">}</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">listIntMax</span> <span class="k">extends</span> <span class="nc">Unwrap</span><span class="o">[</span><span class="kt">List</span>, <span class="kt">Int</span><span class="o">]</span> <span class="o">{</span>
<span class="k">type</span> <span class="kt">Out</span> <span class="o">=</span> <span class="nc">Int</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Int</span><span class="o">])</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="n">tr</span><span class="o">.</span><span class="n">max</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Given these implicit values we can now use our <code class="highlighter-rouge">extractor</code> method. Given <code class="highlighter-rouge">List</code> of <code class="highlighter-rouge">Int</code>s, it returns maximal value, but given <code class="highlighter-rouge">List</code> of <code class="highlighter-rouge">String</code>s it returns size of the list itself.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>scala> extractor(List(1,2,10,9))
res0: Unwrap.listIntMax.Out = 10
scala> extractor(List("1","2","10","9"))
res1: Unwrap.listStringSize.Out = 4
</code></pre>
</div>
<p>In both cases <code class="highlighter-rouge">Out</code> type is an <code class="highlighter-rouge">Int</code> but it can be an arbitrary type.</p>
<p>Up until now everything were working fine without any problems. Let’s now add another feature to our <code class="highlighter-rouge">extractor</code> method. Let’s say that aside from <code class="highlighter-rouge">unwrap.Out</code> return value itself we want also return <code class="highlighter-rouge">String</code> representation of this value. Let’s define another type class for that purpose named <code class="highlighter-rouge">Printer[T]</code>.</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">trait</span> <span class="nc">Printer</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">T</span><span class="o">)</span><span class="k">:</span> <span class="o">(</span><span class="kt">String</span><span class="o">,</span> <span class="kt">T</span><span class="o">)</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Definition of <code class="highlighter-rouge">Printer[T]</code> type class is trivial. It takes value of type <code class="highlighter-rouge">T</code> as a parameter and return <code class="highlighter-rouge">String</code> representation of a <code class="highlighter-rouge">T</code> together with <code class="highlighter-rouge">T</code> itself. We will define two instance of this type class. One for <code class="highlighter-rouge">T</code> being a <code class="highlighter-rouge">String</code> and one for <code class="highlighter-rouge">T</code> being an <code class="highlighter-rouge">Int</code>:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Printer</span> <span class="o">{</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">stringPrinter</span> <span class="k">extends</span> <span class="nc">Printer</span><span class="o">[</span><span class="kt">String</span><span class="o">]</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">s</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span><span class="k">:</span> <span class="o">(</span><span class="kt">String</span><span class="o">,</span> <span class="kt">String</span><span class="o">)</span> <span class="k">=</span> <span class="o">(</span><span class="s">"String: "</span> <span class="o">+</span> <span class="n">s</span><span class="o">,</span> <span class="n">s</span><span class="o">)</span>
<span class="o">}</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">intPrinter</span> <span class="k">extends</span> <span class="nc">Printer</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">i</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span><span class="k">:</span> <span class="o">(</span><span class="kt">String</span><span class="o">,</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">=</span> <span class="o">(</span><span class="s">"Int: "</span> <span class="o">+</span> <span class="n">i</span><span class="o">,</span> <span class="n">i</span><span class="o">)</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Let’s now use <code class="highlighter-rouge">Printer</code> type class in our <code class="highlighter-rouge">extractor</code> method:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">extractor</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span><span class="o">](</span><span class="n">in</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])(</span>
<span class="k">implicit</span>
<span class="n">unwrap</span><span class="k">:</span> <span class="kt">Unwrap</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span><span class="o">],</span>
<span class="n">withPrinter</span><span class="k">:</span> <span class="kt">Printer</span><span class="o">[</span><span class="kt">unwrap.Out</span><span class="o">]</span>
<span class="o">)</span><span class="k">:</span> <span class="o">(</span><span class="kt">String</span><span class="o">,</span> <span class="kt">unwrap.Out</span><span class="o">)</span> <span class="k">=</span> <span class="o">{</span>
<span class="n">withPrinter</span><span class="o">(</span><span class="n">unwrap</span><span class="o">(</span><span class="n">in</span><span class="o">))</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Note that we are now using <code class="highlighter-rouge">unwrap.Out</code> not only as a return type, but also as a type parameter to our <code class="highlighter-rouge">Printer</code> type class in <code class="highlighter-rouge">withPrinter: Printer[unwrap.Out]</code>. We need to do that since we want compiler to provide us proper instance of a <code class="highlighter-rouge">Printer</code> type class in dependence on types <code class="highlighter-rouge">T</code> and <code class="highlighter-rouge">R</code> of an input parameter <code class="highlighter-rouge">in</code>.</p>
<p>This looks promising, unfortunately it won’t compile.</p>
<div class="highlighter-rouge"><pre class="highlight"><code><console>:17: error: illegal dependent method type: parameter may only be referenced in a subsequent parameter section
unwrap: Unwrap[T, R],
^
</code></pre>
</div>
<p>We’ve got some cryptic message from a compiler, but in an essence we hit a limitation in a Scala compiler how path dependent types and implicit values can interact. We need to came up with some workaround to overcome this limitation and this workaround is called <code class="highlighter-rouge">Aux pattern</code>.</p>
<h2 id="aux-pattern-to-the-rescue">Aux Pattern to the rescue</h2>
<p>We are going to look at two different implementation of an <code class="highlighter-rouge">Aux Pattern</code>. Let’s give them names for purpose of this article:</p>
<ul>
<li><em>Explicit</em> - this is implementation of <code class="highlighter-rouge">Aux Pattern</code> used in Shapeless version 1.x.x. It is more verbose in comparison with version from Shapeless 2.x.x.</li>
<li><em>Concise</em> - this is contemporary version of <code class="highlighter-rouge">Aux Pattern</code> you can find in Shapeless 2.x.x. It is more concise in comparison with Explicit version.</li>
</ul>
<h3 id="aux-pattern---explicit-implementation">Aux Pattern - Explicit implementation</h3>
<p>As a first step of Explicit implementation we are going to define auxiliary type class called <code class="highlighter-rouge">UnwrapAux</code> which will be the same as the <a href="#unwrap-typeclass"><code class="highlighter-rouge">Unwrap</code> type class</a> with the exception that the abstract type member <code class="highlighter-rouge">Out</code> will be removed and replaced by type parameter <code class="highlighter-rouge">Out</code> instead:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">trait</span> <span class="nc">UnwrapAux</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span>, <span class="kt">Out</span><span class="o">]</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])</span><span class="k">:</span> <span class="kt">Out</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Given this auxiliary type class <code class="highlighter-rouge">UnwrapAux</code> we can define implicit instances for it in companion object, similarly as we done before:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">object</span> <span class="nc">UnwrapAux</span> <span class="o">{</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">listStringSize</span> <span class="k">extends</span> <span class="nc">UnwrapAux</span><span class="o">[</span><span class="kt">List</span>, <span class="kt">String</span>, <span class="kt">Int</span><span class="o">]</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="n">tr</span><span class="o">.</span><span class="n">size</span>
<span class="o">}</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">listIntMax</span> <span class="k">extends</span> <span class="nc">UnwrapAux</span><span class="o">[</span><span class="kt">List</span>, <span class="kt">Int</span>, <span class="kt">Int</span><span class="o">]</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Int</span><span class="o">])</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="n">tr</span><span class="o">.</span><span class="n">max</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>And surprisingly this is all we need to make <code class="highlighter-rouge">extractor</code> method work. We just use <code class="highlighter-rouge">UnwrapAux</code> in place of <code class="highlighter-rouge">Unwrap</code> and we add third type parameter <code class="highlighter-rouge">Out</code> to <code class="highlighter-rouge">extractor</code> method:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">extractor</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span>, <span class="kt">Out</span><span class="o">](</span><span class="n">in</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])(</span>
<span class="k">implicit</span>
<span class="n">unwrap</span><span class="k">:</span> <span class="kt">UnwrapAux</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span>, <span class="kt">Out</span><span class="o">],</span>
<span class="n">withPrinter</span><span class="k">:</span> <span class="kt">Printer</span><span class="o">[</span><span class="kt">Out</span><span class="o">]</span>
<span class="o">)</span><span class="k">:</span> <span class="o">(</span><span class="kt">String</span><span class="o">,</span> <span class="kt">Out</span><span class="o">)</span> <span class="k">=</span> <span class="o">{</span>
<span class="n">withPrinter</span><span class="o">(</span><span class="n">unwrap</span><span class="o">(</span><span class="n">in</span><span class="o">))</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Notice that in this implementation type <code class="highlighter-rouge">Out</code> is known beforehand so compiler knows what instance of <code class="highlighter-rouge">Printer</code> type class to search for.</p>
<p>But we are not done yet. Remember that in case of <code class="highlighter-rouge">extractor</code> implementation without <code class="highlighter-rouge">Printer</code> we returned path dependent type directly. Here is that implementation repeated once more:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">extractor</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span><span class="o">](</span><span class="n">in</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])(</span>
<span class="k">implicit</span>
<span class="n">unwrap</span><span class="k">:</span> <span class="kt">Unwrap</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span><span class="o">]</span>
<span class="o">)</span><span class="k">:</span> <span class="kt">unwrap.Out</span> <span class="o">=</span> <span class="o">{</span>
<span class="n">unwrap</span><span class="o">(</span><span class="n">in</span><span class="o">)</span>
<span class="o">}</span>
</code></pre>
</div>
<p>We don’t need our auxiliary <code class="highlighter-rouge">UnwrapAux</code> type class here as <code class="highlighter-rouge">Unwrap</code> type class is sufficient enough in this case. But for this method to work with <code class="highlighter-rouge">Unwrap</code> type class we need implicit instances of it, but we have only implicit instances for <code class="highlighter-rouge">UnwrapAux</code> type class. One solution would be to define same implicit instances for <code class="highlighter-rouge">Unwrap</code> as we did for <code class="highlighter-rouge">UnwrapAux</code>, but that would lead to code duplication which we want to avoid. Another possibility is to reuse existing implicit <code class="highlighter-rouge">UnwrapAux</code> instances for defining implicit <code class="highlighter-rouge">Unwrap</code> instances.</p>
<p>We can achieve this by defining implicit method which will take implicit type class parameter <code class="highlighter-rouge">UnwrapAux[T, R, Out]</code> and we will use this parameter value to construct instance of <code class="highlighter-rouge">Unwrap[T, R]</code> type class. We will define this implicit method in <code class="highlighter-rouge">Unwrap</code> companion object.</p>
<p><a name="manual-construction"></a></p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Unwrap</span> <span class="o">{</span>
<span class="k">implicit</span> <span class="k">def</span> <span class="n">unwrap</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span>, <span class="kt">Out0</span><span class="o">](</span>
<span class="k">implicit</span> <span class="n">unwrapAux</span><span class="k">:</span> <span class="kt">UnwrapAux</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span>, <span class="kt">Out0</span><span class="o">])</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">Unwrap</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span><span class="o">]</span> <span class="o">{</span>
<span class="k">type</span> <span class="kt">Out</span> <span class="o">=</span> <span class="nc">Out0</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])</span><span class="k">:</span> <span class="kt">Out</span> <span class="o">=</span> <span class="n">unwrapAux</span><span class="o">(</span><span class="n">tr</span><span class="o">)</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Note that we need to use other name than <code class="highlighter-rouge">Out</code> for the name of a third type parameter in <code class="highlighter-rouge">UnwrapAux</code> type class as <code class="highlighter-rouge">Out</code> is a name of abstract type member of <code class="highlighter-rouge">Unwrap</code> type class itself. We can choose any name we like, but we will us name <code class="highlighter-rouge">Out0</code> to emphasise connection between <code class="highlighter-rouge">Out</code> and <code class="highlighter-rouge">Out0</code> types.</p>
<p>We just asked for implicit value of <code class="highlighter-rouge">unwrapAux: UnwrapAux[T, R, Out0]</code> and implemented <code class="highlighter-rouge">Unwrap[T, R]</code> by making abstract type member <code class="highlighter-rouge">Out</code> concrete by assigning it type parameter <code class="highlighter-rouge">Out0</code> and we implemented <code class="highlighter-rouge">def apply(tr: T[R])</code> method by passing input parameter <code class="highlighter-rouge">tr: T[R]</code> to <code class="highlighter-rouge">unwrapAux.apply</code> method.</p>
<p>And this is it. <code class="highlighter-rouge">Aux Pattern</code> with explicit conversion between <code class="highlighter-rouge">UnwrapAux</code> and <code class="highlighter-rouge">Unwrap</code>. I hope this will help you to understand how Concise version of <code class="highlighter-rouge">Aux Pattern</code> works.</p>
<h3 id="aux-pattern---concise-implementation">Aux Pattern - Concise implementation</h3>
<p>This version is used in a Shapeless 2.x.x and is also described in a blog post mentioned at the beginning.</p>
<p>One notable difference in comparison with Explicit version is that this version doesn’t have <code class="highlighter-rouge">UnwrapAux</code> type class at all.</p>
<p>We define implicit instances of the <code class="highlighter-rouge">Unwrap</code> type class as we did <a href="#unwrap-typeclass-instances">at the beginning</a> ie. with type <code class="highlighter-rouge">Out</code> fixed to a concrete type. What we do extra though is to define auxiliary type <code class="highlighter-rouge">type Aux[T[_], R, Out0]</code> as an alias for refined type <code class="highlighter-rouge">Unwrap[T, R] { type Out = Out0 }</code>. Note that we are refining type <code class="highlighter-rouge">Out</code> in the same way as we did in Explicit implementation:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">object</span> <span class="nc">Unwrap</span> <span class="o">{</span>
<span class="k">type</span> <span class="kt">Aux</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span>, <span class="kt">Out0</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Unwrap</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span><span class="o">]</span> <span class="o">{</span> <span class="k">type</span> <span class="kt">Out</span> <span class="o">=</span> <span class="nc">Out0</span> <span class="o">}</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">listStringSize</span> <span class="k">extends</span> <span class="nc">Unwrap</span><span class="o">[</span><span class="kt">List</span>, <span class="kt">String</span><span class="o">]</span> <span class="o">{</span>
<span class="k">type</span> <span class="kt">Out</span> <span class="o">=</span> <span class="nc">Int</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">String</span><span class="o">])</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="n">tr</span><span class="o">.</span><span class="n">size</span>
<span class="o">}</span>
<span class="k">implicit</span> <span class="k">object</span> <span class="nc">listIntMax</span> <span class="k">extends</span> <span class="nc">Unwrap</span><span class="o">[</span><span class="kt">List</span>, <span class="kt">Int</span><span class="o">]</span> <span class="o">{</span>
<span class="k">type</span> <span class="kt">Out</span> <span class="o">=</span> <span class="nc">Int</span>
<span class="k">def</span> <span class="n">apply</span><span class="o">(</span><span class="n">tr</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Int</span><span class="o">])</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="n">tr</span><span class="o">.</span><span class="n">max</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Usage of this concise implementation looks almost the same as usage with explicit <code class="highlighter-rouge">UnwrapAux</code> type class only with the difference that instead of <code class="highlighter-rouge">UnwrapAux[T, R, Out]</code> we will use <code class="highlighter-rouge">Unwrap.Aux[T, R, Out]</code> as a type for implicit value <code class="highlighter-rouge">unwrap</code>:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">extractor</span><span class="o">[</span><span class="kt">T</span><span class="o">[</span><span class="k">_</span><span class="o">]</span>, <span class="kt">R</span>, <span class="kt">Out</span><span class="o">](</span><span class="n">in</span><span class="k">:</span> <span class="kt">T</span><span class="o">[</span><span class="kt">R</span><span class="o">])(</span>
<span class="k">implicit</span>
<span class="n">unwrap</span><span class="k">:</span> <span class="kt">Unwrap.Aux</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">R</span>, <span class="kt">Out</span><span class="o">],</span>
<span class="n">withPrinter</span><span class="k">:</span> <span class="kt">Printer</span><span class="o">[</span><span class="kt">Out</span><span class="o">]</span>
<span class="o">)</span><span class="k">:</span> <span class="o">(</span><span class="kt">String</span><span class="o">,</span> <span class="kt">Out</span><span class="o">)</span> <span class="k">=</span> <span class="o">{</span>
<span class="n">withPrinter</span><span class="o">(</span><span class="n">unwrap</span><span class="o">(</span><span class="n">in</span><span class="o">))</span>
<span class="o">}</span>
</code></pre>
</div>
<p>If you are new to type refinement this imlementation may feel a little bit unclear. To make it more clear it can help to think in terms of Explicit implementation where we constructed auxiliary type <a href="#manual-construction">manually</a>. With time you will stop to worry about <code class="highlighter-rouge">Aux Pattern</code> workaround altogether and it became just natural building block to allow type dependent types to be used in single parameter block.</p>
<p>And that is all there is to <code class="highlighter-rouge">Aux Pattern</code>. I hope you’ve gained better familiarity with it by reading this blog post.</p>
<p>All code examples can be found on <a href="https://github.com/VlachJosef/aux-pattern">Github</a>.</p>
<p>Recommended sources: <a href="https://www.youtube.com/watch?v=GDbNxL8bqkY">Shapeless: Exploring Generic Programming in Scala</a></p>Josef Vlachvlach.josef@gmail.comhttp://www.vlachjosef.comWhen learning Shapeless you will sooner or later encounter the so called Aux Pattern. There exists nice tutorial by Luigi Antonini - The Aux Pattern - A short introduction to the Aux Pattern which explains this pattern quite well and you will gain good understanding what problem this pattern is solving. I recommend you to go and read that blog post first and come back if you would feel that you are still missing something in a complete understanding of a said pattern. That was exactly my feeling and motivation to write this article.Scala Tagged types - Introduction2016-05-21T17:22:12+01:002016-05-21T17:22:12+01:00/tagged-types-introduction<p>Tagged types - maybe you’ve heard about them, maybe you not, maybe you’ve even consider to use them, but decided not to bother in the end. Whatever the case in this article I will introduce them, explain what they are, show why they are useful and why to bother to use them.</p>
<p>Although all explanation is based on contrived example, it is not harming our goal to show what advantages Tagged types brings us.</p>
<h2 id="problem">Problem</h2>
<p>Let’s imagine that we are building game server for mobile RPG game and one of game features is PvP battle. PvP battle allow players play against each other. Let’s suppose that there are multiple PvP arenas in the game and that in every arena players will be placed to random bracket with another players who entered that arena. Goal of the player is to beat other players in his bracket.</p>
<p>We can model this situation in Scala with case classes like this:</p>
<p><a name="model-no-tags"></a></p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">case</span> <span class="k">class</span> <span class="nc">Arena</span><span class="o">(</span>
<span class="n">id</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="c1">// unique identifier of the arena
</span> <span class="n">name</span><span class="k">:</span> <span class="kt">String</span> <span class="c1">// name of the arena
</span><span class="o">)</span>
<span class="k">case</span> <span class="k">class</span> <span class="nc">Bracket</span><span class="o">(</span>
<span class="n">id</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="c1">// unique identifier of pvp bracket
</span> <span class="n">arenaId</span><span class="k">:</span> <span class="kt">String</span> <span class="c1">// to which arena this bracket belongs
</span><span class="o">)</span>
<span class="k">case</span> <span class="k">class</span> <span class="nc">PlayerProfile</span><span class="o">(</span>
<span class="n">id</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="c1">// unique player profile identifier
</span> <span class="n">bracketMapping</span><span class="k">:</span> <span class="kt">Map</span><span class="o">[</span><span class="kt">String</span>, <span class="kt">String</span><span class="o">]</span> <span class="c1">// arena to bracket mapping
</span><span class="o">)</span> <span class="o">{</span>
<span class="cm">/**
* Change current bracket of player in arena
*/</span>
<span class="k">def</span> <span class="n">changeBracket</span><span class="o">(</span><span class="n">arena</span><span class="k">:</span> <span class="kt">Arena</span><span class="o">,</span> <span class="n">bracket</span><span class="k">:</span> <span class="kt">Bracket</span><span class="o">)</span><span class="k">:</span> <span class="kt">PlayerProfile</span> <span class="o">=</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="n">copy</span><span class="o">(</span><span class="n">bracketMapping</span> <span class="k">=</span> <span class="k">this</span><span class="o">.</span><span class="n">bracketMapping</span> <span class="o">+</span> <span class="o">(</span><span class="n">arena</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket</span><span class="o">.</span><span class="n">id</span><span class="o">))</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p><em>This is not only way how to model this situation, but we will use it for a sake of simplicity and convenience in this article as our driving model.</em></p>
<p>Now let’s create state where there exist two arenas: <em>Fire Pit</em> and <em>Ice Dungeon</em>, where Fire Pit contains two brackets and Ice Dungeon contains single bracket, and let’s create three players and put them into different arena brackets. Situation can then look like this:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">val</span> <span class="n">firePit</span> <span class="k">=</span> <span class="nc">Arena</span><span class="o">(</span><span class="s">"firePit"</span><span class="o">,</span> <span class="s">"Fire Pit"</span><span class="o">)</span>
<span class="k">val</span> <span class="n">iceDungeon</span> <span class="k">=</span> <span class="nc">Arena</span><span class="o">(</span><span class="s">"iceDungeon"</span><span class="o">,</span> <span class="s">"Ice Dungeon"</span><span class="o">)</span>
<span class="k">val</span> <span class="n">bracket1</span> <span class="k">=</span> <span class="nc">Bracket</span><span class="o">(</span><span class="s">"bracket1"</span><span class="o">,</span> <span class="s">"firePit"</span><span class="o">)</span>
<span class="k">val</span> <span class="n">bracket2</span> <span class="k">=</span> <span class="nc">Bracket</span><span class="o">(</span><span class="s">"bracket2"</span><span class="o">,</span> <span class="s">"firePit"</span><span class="o">)</span>
<span class="k">val</span> <span class="n">bracket3</span> <span class="k">=</span> <span class="nc">Bracket</span><span class="o">(</span><span class="s">"bracket3"</span><span class="o">,</span> <span class="s">"iceDungeon"</span><span class="o">)</span>
<span class="k">val</span> <span class="n">player1</span> <span class="k">=</span> <span class="nc">PlayerProfile</span><span class="o">(</span><span class="s">"player1"</span><span class="o">,</span> <span class="nc">Map</span><span class="o">(</span><span class="n">firePit</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket1</span><span class="o">.</span><span class="n">id</span><span class="o">,</span> <span class="n">iceDungeon</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket3</span><span class="o">.</span><span class="n">id</span><span class="o">))</span>
<span class="k">val</span> <span class="n">player2</span> <span class="k">=</span> <span class="nc">PlayerProfile</span><span class="o">(</span><span class="s">"player2"</span><span class="o">,</span> <span class="nc">Map</span><span class="o">(</span><span class="n">firePit</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket1</span><span class="o">.</span><span class="n">id</span><span class="o">))</span>
<span class="k">val</span> <span class="n">player3</span> <span class="k">=</span> <span class="nc">PlayerProfile</span><span class="o">(</span><span class="s">"player3"</span><span class="o">,</span> <span class="nc">Map</span><span class="o">(</span><span class="n">firePit</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket2</span><span class="o">.</span><span class="n">id</span><span class="o">,</span> <span class="n">iceDungeon</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket3</span><span class="o">.</span><span class="n">id</span><span class="o">))</span>
</code></pre>
</div>
<p>Let’s focus our attention on the way how we defined value for field <code class="highlighter-rouge">bracketMapping</code> of <code class="highlighter-rouge">PlayerProfile</code>. For example in case of <code class="highlighter-rouge">player2</code> we defined its value in terms of <code class="highlighter-rouge">firePit</code> and <code class="highlighter-rouge">bracket1</code> instances like this <code class="highlighter-rouge">Map(firePit.id -> bracket1.id)</code>. Let’s take a closer look on this.</p>
<p>When used like this everything looks clear and sound since we have everything displayed on one screen, thus every logical connection in our model is clearly visible, but with elapsed time and as the code will become more and more complex, definition like <code class="highlighter-rouge">bracketMapping</code> from <code class="highlighter-rouge">PlayerProfile</code> will gradually become unclear and confusing. When we would look on <code class="highlighter-rouge">bracketMapping</code> definition without any comment, how clear does it look to you?</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="n">bracketMapping</span><span class="k">:</span> <span class="kt">Map</span><span class="o">[</span><span class="kt">String</span>, <span class="kt">String</span><span class="o">]</span>
</code></pre>
</div>
<p>To me it doesn’t seem clear at all. <strong>What actually keys of that map represent? And what are values?</strong> Not to mention that actual name of a field <code class="highlighter-rouge">bracketMapping</code> doesn’t help here too much.</p>
<p>On top of this there is even worse problem with such model definition. Can you spot an error in this implementation of <code class="highlighter-rouge">PlayerProfile</code> instance method <code class="highlighter-rouge">changeBracket</code>?</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">changeBracket</span><span class="o">(</span><span class="n">arena</span><span class="k">:</span> <span class="kt">Arena</span><span class="o">,</span> <span class="n">bracket</span><span class="k">:</span> <span class="kt">Bracket</span><span class="o">)</span><span class="k">:</span> <span class="kt">PlayerProfile</span> <span class="o">=</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="n">copy</span><span class="o">(</span><span class="n">bracketMapping</span> <span class="k">=</span> <span class="k">this</span><span class="o">.</span><span class="n">bracketMapping</span> <span class="o">+</span> <span class="o">(</span><span class="n">bracket</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">arena</span><span class="o">.</span><span class="n">id</span><span class="o">))</span>
<span class="o">}</span>
</code></pre>
</div>
<p>We made a mistake and interchanged expression <code class="highlighter-rouge">bracket.id</code> with <code class="highlighter-rouge">arena.id</code>. We can see correct implementation in our <a href="#model-no-tags">initial implementation</a>. The worst thing about this bug is that <strong>there was nothing to warn us when we made this mistake</strong>. Code compile just fine.</p>
<p>These types of bugs result in weird errors, where things stop to work as expected and it is usually hard to figure out where the bug is. And the worst is that they are really easy to made.</p>
<p>So in our short code example we discovered two fundamental problems:</p>
<ul>
<li>Constructs like <code class="highlighter-rouge">Map[String, String]</code> are really hard to comprehend.</li>
<li>Since every identifier is <code class="highlighter-rouge">String</code> it is easy to use wrong identifier (<code class="highlighter-rouge">bracket.id</code>) in place of another identifier (<code class="highlighter-rouge">arena.id</code>).</li>
</ul>
<h2 id="solution">Solution</h2>
<p>Desirable solution should brings us these properties:</p>
<ul>
<li>We want to keep using <code class="highlighter-rouge">Map</code> data type as it is really convenient for our needs.</li>
<li>We want compiler to catch improper use of <code class="highlighter-rouge">id</code>s for us (identifier of one class in place of identifier of second class).</li>
</ul>
<p>To solve aforementioned problems and to get these properties we can use various techniques, one of which is to use Tagged types.</p>
<h3 id="tagged-types">Tagged types</h3>
<p>Let’s first look at how our model will look like with use of Tagged types:</p>
<p><a name="model-with-tags"></a></p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">case</span> <span class="k">class</span> <span class="nc">Arena</span><span class="o">(</span>
<span class="n">id</span><span class="k">:</span> <span class="kt">ArenaId</span><span class="o">,</span> <span class="c1">// <- tagged type
</span> <span class="n">name</span><span class="k">:</span> <span class="kt">String</span>
<span class="o">)</span>
<span class="k">case</span> <span class="k">class</span> <span class="nc">Bracket</span><span class="o">(</span>
<span class="n">id</span><span class="k">:</span> <span class="kt">BracketId</span><span class="o">,</span> <span class="c1">// <- tagged type
</span> <span class="n">arenaId</span><span class="k">:</span> <span class="kt">ArenaId</span> <span class="c1">// <- tagged type
</span><span class="o">)</span>
<span class="k">case</span> <span class="k">class</span> <span class="nc">PlayerProfile</span><span class="o">(</span>
<span class="n">id</span><span class="k">:</span> <span class="kt">ProfileId</span><span class="o">,</span> <span class="c1">// <- tagged type
</span> <span class="n">bracketMapping</span><span class="k">:</span> <span class="kt">Map</span><span class="o">[</span><span class="kt">ArenaId</span>, <span class="kt">BracketId</span><span class="o">]</span> <span class="c1">// <- tagged types
</span><span class="o">)</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">changeBracket</span><span class="o">(</span><span class="n">arena</span><span class="k">:</span> <span class="kt">Arena</span><span class="o">,</span> <span class="n">bracket</span><span class="k">:</span> <span class="kt">Bracket</span><span class="o">)</span><span class="k">:</span> <span class="kt">PlayerProfile</span> <span class="o">=</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="n">copy</span><span class="o">(</span><span class="n">bracketMapping</span> <span class="k">=</span> <span class="k">this</span><span class="o">.</span><span class="n">bracketMapping</span> <span class="o">+</span> <span class="o">(</span><span class="n">arena</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket</span><span class="o">.</span><span class="n">id</span><span class="o">))</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>This is much easier to read and reason about. Even glance look at a type:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="nc">Map</span><span class="o">[</span><span class="kt">ArenaId</span>, <span class="kt">BracketId</span><span class="o">]</span>
</code></pre>
</div>
<p>is telling us what keys of this map represents and what values of this map stands for. The connection between keys and values of this <code class="highlighter-rouge">Map</code> and associated case classes is evident.</p>
<p><a name="magic-types"></a>
But what are these magical types <code class="highlighter-rouge">ArenaId</code>, <code class="highlighter-rouge">BracketId</code> and <code class="highlighter-rouge">ProfileId</code>, where are they coming from?</p>
<p>There is no magic here at all. Let’s go step by step until we got to this implementation. As a first step we need to create some so called <em>tags</em>:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">trait</span> <span class="nc">ProfileIdTag</span>
<span class="k">trait</span> <span class="nc">ArenaIdTag</span>
<span class="k">trait</span> <span class="nc">BracketIdTag</span>
</code></pre>
</div>
<p><a name="tagging-convention"></a>
As you can see, tags are ordinary traits without any implementation. In practice arbitrary type can be used as a tag, but traits are usually used for their convenience. The names also doesn’t matter but it’s good practice to use suffix like <code class="highlighter-rouge">...Tag</code> or similar as a convention to distinguish tags from other types. We will see later why.</p>
<p>Now we are ready to use these tags (traits) to create Tagged types. We are going to use Tagged types implementation provided by <a href="https://github.com/milessabin/shapeless">shapeless</a> (in second part of this article we will look at other implementations).</p>
<p>For creation of Tagged types we first need to import <a href="https://github.com/milessabin/shapeless/blob/shapeless-2.3.0-sjs-0.6.8/core/src/main/scala/shapeless/typeoperators.scala#L29">@@</a> type definition from shapeless:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">import</span> <span class="nn">shapeless.tag.</span><span class="o">@@</span>
</code></pre>
</div>
<p>Now we are able to mark (to tag) any type <code class="highlighter-rouge">T</code> with our tag and thus create Tagged type like this:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="n">T</span> <span class="o">@@</span> <span class="nc">OurIdTag</span>
</code></pre>
</div>
<p>For example when we want to tag <code class="highlighter-rouge">String</code> field of some case class we do it like this: <code class="highlighter-rouge">String @@ OurIdTag</code>. We can tag arbitrary type not just <code class="highlighter-rouge">String</code>, so if we need to tag <code class="highlighter-rouge">Int</code> field of some case class we can do it like this: <code class="highlighter-rouge">Int @@ OurIdTag</code>.</p>
<p>Let’s take a look at a definition of <code class="highlighter-rouge">PlayerProfile</code> case class with <code class="highlighter-rouge">changeBracket</code> method when we use tagged types:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">case</span> <span class="k">class</span> <span class="nc">PlayerProfile</span><span class="o">(</span>
<span class="n">id</span><span class="k">:</span> <span class="kt">String</span> <span class="kt">@@</span> <span class="kt">ProfileIdTag</span><span class="o">,</span>
<span class="n">bracketMapping</span><span class="k">:</span> <span class="kt">Map</span><span class="o">[</span><span class="kt">String</span> <span class="kt">@@</span> <span class="kt">ArenaIdTag</span>, <span class="kt">String</span> <span class="kt">@@</span> <span class="kt">BracketIdTag</span><span class="o">]</span>
<span class="o">)</span> <span class="o">{</span>
<span class="k">def</span> <span class="n">changeBracket</span><span class="o">(</span><span class="n">arena</span><span class="k">:</span> <span class="kt">Arena</span><span class="o">,</span> <span class="n">bracket</span><span class="k">:</span> <span class="kt">Bracket</span><span class="o">)</span><span class="k">:</span> <span class="kt">PlayerProfile</span> <span class="o">=</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="n">copy</span><span class="o">(</span><span class="n">bracketMapping</span> <span class="k">=</span> <span class="k">this</span><span class="o">.</span><span class="n">bracketMapping</span> <span class="o">+</span> <span class="o">(</span><span class="n">arena</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">bracket</span><span class="o">.</span><span class="n">id</span><span class="o">))</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre>
</div>
<p>As you can see it is not so much different from our <a href="#model-no-tags">initial implementation</a>, but what differs significantly is the way how we use this new definition and advantages it brings us. But before we dive into usage, let’s first tackle one problem this new definition has. This problem is unnecessary repetition of <code class="highlighter-rouge">String @@ ...</code> pattern in types declarations. To get rid of this repetition we can introduce simple type aliases for every single type <code class="highlighter-rouge">String @@ T</code>. In our example case we would need to define three type aliases:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">type</span> <span class="kt">ProfileId</span> <span class="o">=</span> <span class="nc">String</span> <span class="o">@@</span> <span class="nc">ProfileIdTag</span>
<span class="k">type</span> <span class="kt">ArenaId</span> <span class="o">=</span> <span class="nc">String</span> <span class="o">@@</span> <span class="nc">ArenaIdTag</span>
<span class="k">type</span> <span class="kt">BracketId</span> <span class="o">=</span> <span class="nc">String</span> <span class="o">@@</span> <span class="nc">BracketIdTag</span>
</code></pre>
</div>
<p>And here they are. Our magical types from <a href="#magic-types">above</a>. It is good practice to keep these type aliases short, since they will be used more than tags itself. This is the reason why we introduced that <a href="#tagging-convention">convention</a> to use <code class="highlighter-rouge">..Tag</code> suffix for traits representing our tags.</p>
<p>With use of these type aliases we got our final definition as <a href="#model-with-tags">shown above</a>.</p>
<p>We will use these type aliases in the rest of this article.</p>
<h3 id="usage">Usage</h3>
<p>Now when we try to define <code class="highlighter-rouge">PlayerProfile</code> instance explicitly for example like this:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="nc">PlayerProfile</span><span class="o">(</span><span class="s">"playerId"</span><span class="o">,</span> <span class="nc">Map</span><span class="o">(</span><span class="s">"firePit"</span> <span class="o">-></span> <span class="s">"bracket1"</span><span class="o">))</span>
</code></pre>
</div>
<p>it won’t compile and we got two errors due to type mismatch:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>[error] /Users/pepa/tagged-types/src/main/scala/io/vlach/tagged-pt1.scala:32: type mismatch;
[error] found : String("playerId")
[error] required: io.vlach.tags.ProfileId
[error] PlayerProfile("playerId", Map("firePit" -> "bracket1"))
[error] ^
[error] /Users/pepa/tagged-types/src/main/scala/io/vlach/tagged-pt1.scala:32: type mismatch;
[error] found : (String, String)
[error] required: (io.vlach.tags.ArenaId, io.vlach.tags.BracketId)
[error] PlayerProfile("playerId", Map("firePit" -> "bracket1"))
[error] ^
[error] two errors found
</code></pre>
</div>
<p>These errors are telling us that we are trying to do something what we probably didn’t mean to do. And really, we are using simple <code class="highlighter-rouge">String</code> types where Tagged types are expected. This can clearly be seen in the error messages.</p>
<p>To fix this problem we must make sure that parameters to <code class="highlighter-rouge">PlayerProfile.apply</code> method meet required tags criteria. So how can we create instances of Tagged type from a <code class="highlighter-rouge">String</code> values?</p>
<p>To turn <code class="highlighter-rouge">String</code> value into Tagged type instaagainsnce we use object <a href="https://github.com/milessabin/shapeless/blob/shapeless-2.3.0-sjs-0.6.8/core/src/main/scala/shapeless/typeoperators.scala#L25"><code class="highlighter-rouge">tag</code></a> from shapeless. Its usage is simple:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">import</span> <span class="nn">shapeless.tag</span>
<span class="k">val</span> <span class="n">profileId</span><span class="k">:</span> <span class="kt">ProfileId</span> <span class="o">=</span> <span class="n">tag</span><span class="o">[</span><span class="kt">ProfileIdTag</span><span class="o">][</span><span class="kt">String</span><span class="o">](</span><span class="s">"profileId"</span><span class="o">)</span>
<span class="k">val</span> <span class="n">arenaId</span><span class="k">:</span> <span class="kt">ArenaId</span> <span class="o">=</span> <span class="n">tag</span><span class="o">[</span><span class="kt">ArenaIdTag</span><span class="o">][</span><span class="kt">String</span><span class="o">](</span><span class="s">"thePit"</span><span class="o">)</span>
<span class="k">val</span> <span class="n">bracketId</span><span class="k">:</span> <span class="kt">BracketId</span> <span class="o">=</span> <span class="n">tag</span><span class="o">[</span><span class="kt">BracketIdTag</span><span class="o">][</span><span class="kt">String</span><span class="o">](</span><span class="s">"bracket1"</span><span class="o">)</span>
</code></pre>
</div>
<p>And that’s it. Simple like this. We can use these values to create our <code class="highlighter-rouge">PlayerProfile</code> instance explicitly like this:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="nc">PlayerProfile</span><span class="o">(</span><span class="n">playerId</span><span class="o">,</span> <span class="nc">Map</span><span class="o">(</span><span class="n">arenaId</span> <span class="o">-></span> <span class="n">bracketId</span><span class="o">))</span>
</code></pre>
</div>
<p>and everything will work as expected. In case we accidentally swapped parameters for <code class="highlighter-rouge">arenaId</code> and <code class="highlighter-rouge">bracketId</code>:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="nc">PlayerProfile</span><span class="o">(</span><span class="n">playerId</span><span class="o">,</span> <span class="nc">Map</span><span class="o">(</span><span class="n">bracketId</span> <span class="o">-></span> <span class="n">arenaId</span><span class="o">))</span>
</code></pre>
</div>
<p>We would get compiler errors (output was simplified) telling us that we are doing something we didn’t intended:</p>
<div class="highlighter-rouge"><pre class="highlight"><code>[error] /Users/pepa/tagged-types/src/main/scala/io/vlach/tagged-pt1.scala:38: type mismatch;
[error] found : (io.vlach.tags.BracketId, io.vlach.tags.ArenaId)
[error] required: (io.vlach.tags.ArenaId, io.vlach.tags.BracketId)
[error] PlayerProfile(playerId, Map(bracketId -> arenaId))
[error] ^
[error] one error found
</code></pre>
</div>
<p>Not only Tagged types save us from wrong usage of values in our program, they even protect us against wrong implementation. When we would try to implement <code class="highlighter-rouge">changeBracket</code> with <code class="highlighter-rouge">bracket.id</code> used instead of <code class="highlighter-rouge">arena.id</code> and vise versa as before:</p>
<div class="highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="n">changeBracket</span><span class="o">(</span><span class="n">arena</span><span class="k">:</span> <span class="kt">Arena</span><span class="o">,</span> <span class="n">bracket</span><span class="k">:</span> <span class="kt">Bracket</span><span class="o">)</span><span class="k">:</span> <span class="kt">PlayerProfile</span> <span class="o">=</span> <span class="o">{</span>
<span class="k">this</span><span class="o">.</span><span class="n">copy</span><span class="o">(</span><span class="n">bracketMapping</span> <span class="k">=</span> <span class="k">this</span><span class="o">.</span><span class="n">bracketMapping</span> <span class="o">+</span> <span class="o">(</span><span class="n">bracket</span><span class="o">.</span><span class="n">id</span> <span class="o">-></span> <span class="n">arena</span><span class="o">.</span><span class="n">id</span><span class="o">))</span> <span class="c1">// won't compile
</span><span class="o">}</span>
</code></pre>
</div>
<p>We would again receive compiler error warning us that our types don’t match and thus saving us from potential long bug hunting session later on.</p>
<p>I hope this article convince you that by using Tagged types you will gain lots of assistence from compiler helping you to avoid wide range of errors you would otherwise encounter at runtime or in better case have to cover by unit tests to prove correct implementation.</p>
<p>In second part of this article we will cover two main implementation of Tagged types in Scala. Namely Scalaz implementation and Shapeless implementation.</p>
<p>All code examples can be found on <a href="https://github.com/VlachJosef/tagged-types-introduction">Github</a>.</p>Josef Vlachvlach.josef@gmail.comhttp://www.vlachjosef.comTagged types - maybe you’ve heard about them, maybe you not, maybe you’ve even consider to use them, but decided not to bother in the end. Whatever the case in this article I will introduce them, explain what they are, show why they are useful and why to bother to use them.