<?xml version="1.0" encoding="utf-8"?>






<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Memetic Musings</title>
        <link>https://amitdev.github.io/</link>
        <description>Writings about programming</description>
        <generator>Hugo 0.62.2 https://gohugo.io/</generator>
        
            <language>en-US</language>
        
        
        
        
            <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
        
        <lastBuildDate>Mon, 27 Jul 2020 18:33:39 +1000</lastBuildDate>
        
            <atom:link rel="self" type="application/rss+xml" href="https://amitdev.github.io/rss.xml" />
        
        
            <item>
                <title>Countdown problem in Rust</title>
                <link>https://amitdev.github.io/posts/2020-07-27-countdown-rust/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2020-07-27-countdown-rust/</guid>
                <pubDate>Mon, 27 Jul 2020 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p>The countdown problem was presented in a paper by Graham Hutton with a simple
and elegant solution in Haskell. See the paper <a href="http://www.cs.nott.ac.uk/~pszgmh/countdown.pdf">here</a>.
In this post I'll implement the same solution in Rust and see how it looks compared to
the original Haskell solution.</p>
<h2 id="what-is-the-problem">What is the problem</h2>
<p>From the paper:</p>
<blockquote>
<p>Countdown is a popular quiz programme on British television that includes a
numbers game that we shall refer to as the countdown problem. The essence of
the problem is as follows: given a sequence of source numbers and a single target
number, attempt to construct an arithmetic expression using each of the source
numbers at most once, and such that the result of evaluating the expression is the
target number. The given numbers are restricted to being non-zero naturals, as are
the intermediate results during evaluation of the expression.</p>
</blockquote>
<p>For eg. Given the numbers <code>[1, 3, 7, 10, 25, 50]</code> and target <code>765</code>, one solution would
be <code>(1 + 50) ∗ (25 − 10)</code>.</p>
<h2 id="implementation">Implementation</h2>
<p>In the paper, an initial solution is presented which is then optimized. In this post
we will directly implement the final solution.</p>
<p>First we need a way to represent the supported operations. A sum type is ideal for this
and in Rust we can use <code>enum</code> for it:</p>
<table >
<tr>
<td> Haskell </td>
<td> Rust </td>
</tr>
<tr>
<td style="vertical-align:top">
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-haskell" data-lang="haskell"><span class="kr">data</span> <span class="kt">Op</span>
  <span class="ow">=</span> <span class="kt">Add</span> 
  <span class="o">|</span> <span class="kt">Sub</span> 
  <span class="o">|</span> <span class="kt">Mul</span> 
  <span class="o">|</span> <span class="kt">Div</span>
</code></pre></td></tr></table>
</div>
</div></td>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="cp">#[</span><span class="cp">derive(Copy, Clone)</span><span class="cp">]</span><span class="w">
</span><span class="w"></span><span class="k">enum</span> <span class="nc">Op</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">Add</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">Sub</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">Mul</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">Div</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div></td>
</tr>
</table
<p>The definitions looks very similar in both languages, though syntax is different. In Rust we also need to derive traits which
allows us to freely <a href="https://doc.rust-lang.org/std/marker/trait.Copy.html">copy</a> values of the type in the later program.</p>
<p>Next, we need to define an expression - which is either a number, or two sub-expressions
combined with an operator.</p>
<table>
<tr>
<td> Haskell </td>
<td> Rust </td>
</tr>
<tr>
<td style="vertical-align:top">
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-haskell" data-lang="haskell"><span class="kr">data</span> <span class="kt">Expr</span>
  <span class="ow">=</span> <span class="kt">Val</span> <span class="kt">Int</span>
  <span class="o">|</span> <span class="kt">App</span> <span class="kt">Op</span> <span class="kt">Expr</span> <span class="kt">Expr</span>
</code></pre></td></tr></table>
</div>
</div></td>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">type</span> <span class="nc">Int</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kt">i64</span><span class="p">;</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="cp">#[</span><span class="cp">derive(Clone)</span><span class="cp">]</span><span class="w">
</span><span class="w"></span><span class="k">enum</span> <span class="nc">Expr</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">Val</span><span class="p">(</span><span class="n">Int</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">App</span><span class="p">(</span><span class="n">Op</span><span class="p">,</span><span class="w"> </span><span class="n">Rc</span><span class="o">&lt;</span><span class="n">Expr</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">Rc</span><span class="o">&lt;</span><span class="n">Expr</span><span class="o">&gt;</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div></td>
</tr>
</table
<p>First I added a type alias for <code>Int</code> to keep the code similar to Haskell. We start to see differences - in Rust we cannot define nested
references directly. We could use smart pointer like <a href="https://doc.rust-lang.org/std/boxed/struct.Box.html">Box</a> or
<a href="https://doc.rust-lang.org/std/rc/struct.Rc.html">Rc</a>.
In our case we go with <code>Rc</code> since there will be shared sub expressions and reference counted object
performs better in that case.</p>
<p>Next, the paper defines some utility functions: to check if an expr is valid and also to apply
an expression and get its result:</p>
<table>
<tr>
<td> Haskell </td>
<td> Rust </td>
</tr>
<tr>
<td style="vertical-align:top">
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-haskell" data-lang="haskell"><span class="nf">valid</span> <span class="ow">::</span> <span class="kt">Op</span> <span class="ow">-&gt;</span> <span class="kt">Int</span> <span class="ow">-&gt;</span> <span class="kt">Int</span> <span class="ow">-&gt;</span> <span class="kt">Bool</span>
<span class="nf">valid</span> <span class="kt">Add</span> <span class="n">x</span> <span class="n">y</span> <span class="ow">=</span> <span class="n">x</span> <span class="o">&lt;=</span> <span class="n">y</span>
<span class="nf">valid</span> <span class="kt">Sub</span> <span class="n">x</span> <span class="n">y</span> <span class="ow">=</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="n">y</span>
<span class="nf">valid</span> <span class="kt">Mul</span> <span class="n">x</span> <span class="n">y</span> 
  <span class="ow">=</span> <span class="n">x</span> <span class="o">/=</span> <span class="mi">1</span> 
  <span class="o">&amp;&amp;</span> <span class="n">y</span> <span class="o">/=</span> <span class="mi">1</span> 
  <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="o">&lt;=</span> <span class="n">y</span>
<span class="nf">valid</span> <span class="kt">Div</span> <span class="n">x</span> <span class="n">y</span> 
  <span class="ow">=</span> <span class="n">y</span> <span class="o">/=</span> <span class="mi">1</span> 
  <span class="o">&amp;&amp;</span> <span class="n">x</span> <span class="p">`</span><span class="n">mod</span><span class="p">`</span> <span class="n">y</span> <span class="o">==</span> <span class="mi">0</span>

<span class="nf">apply</span> <span class="ow">::</span> <span class="kt">Op</span> <span class="ow">-&gt;</span> <span class="kt">Int</span> <span class="ow">-&gt;</span> <span class="kt">Int</span> <span class="ow">-&gt;</span> <span class="kt">Int</span>
<span class="nf">apply</span> <span class="kt">Add</span> <span class="n">x</span> <span class="n">y</span> <span class="ow">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
<span class="nf">apply</span> <span class="kt">Sub</span> <span class="n">x</span> <span class="n">y</span> <span class="ow">=</span> <span class="n">x</span> <span class="o">-</span> <span class="n">y</span>
<span class="nf">apply</span> <span class="kt">Mul</span> <span class="n">x</span> <span class="n">y</span> <span class="ow">=</span> <span class="n">x</span> <span class="o">*</span> <span class="n">y</span>
<span class="nf">apply</span> <span class="kt">Div</span> <span class="n">x</span> <span class="n">y</span> <span class="ow">=</span> <span class="n">x</span> <span class="p">`</span><span class="n">div</span><span class="p">`</span> <span class="n">y</span>
</code></pre></td></tr></table>
</div>
</div></td>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">valid</span><span class="p">(</span><span class="n">op</span>: <span class="kp">&amp;</span><span class="nc">Op</span><span class="p">,</span><span class="w"> </span><span class="n">x</span>: <span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="nc">Int</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="k">match</span><span class="w"> </span><span class="n">op</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Add</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">&lt;</span><span class="o">=</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Sub</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Mul</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">!</span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&amp;</span><span class="o">&amp;</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">!</span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&amp;</span><span class="o">&amp;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">&lt;</span><span class="o">=</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Div</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">y</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">&amp;</span><span class="o">&amp;</span><span class="w"> </span><span class="p">(</span><span class="p">(</span><span class="n">x</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="k">fn</span> <span class="nf">apply</span><span class="p">(</span><span class="n">op</span>: <span class="kp">&amp;</span><span class="nc">Op</span><span class="p">,</span><span class="w"> </span><span class="n">x</span>: <span class="nc">Int</span><span class="p">,</span><span class="w"> </span><span class="n">y</span>: <span class="nc">Int</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Int</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="k">match</span><span class="w"> </span><span class="n">op</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Add</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Sub</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Mul</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Div</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="n">y</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div></td>
</tr>
</table
<p>Apart from syntax, no major change. We can do pattern matching in Rust similar to
Haskell. However, we always need to think about lifetime of variables - here I chose to
work with reference of <code>Op</code> instead of <code>Op</code> directly. It will be clear why that is better
as we look at other functions that calls this.</p>
<p>Now we get into the core logic of implementation. We need a way to split a list at all possible
points. For eg. <code>[1, 2, 3]</code> to <code>([1], [2, 3]) and ([1, 2], [3])</code>.</p>
<table>
<tr>
<td> Haskell </td>
<td> Rust </td>
</tr>
<tr>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-haskell" data-lang="haskell"><span class="nf">split</span>        <span class="ow">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="ow">-&gt;</span> <span class="p">[</span><span class="p">(</span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="p">,</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="p">)</span><span class="p">]</span>
<span class="nf">split</span> <span class="kt">[]</span>     <span class="ow">=</span> <span class="p">[</span><span class="p">(</span><span class="kt">[]</span><span class="p">,</span> <span class="kt">[]</span><span class="p">)</span><span class="p">]</span>
<span class="nf">split</span> <span class="p">(</span><span class="n">x</span><span class="kt">:</span><span class="n">xs</span><span class="p">)</span> <span class="ow">=</span> <span class="p">(</span><span class="kt">[]</span><span class="p">,</span> <span class="n">x</span><span class="kt">:</span><span class="n">xs</span><span class="p">)</span> <span class="kt">:</span> <span class="p">[</span><span class="p">(</span><span class="n">x</span><span class="kt">:</span><span class="n">ls</span><span class="p">,</span> <span class="n">rs</span><span class="p">)</span>
               <span class="o">|</span> <span class="p">(</span><span class="n">ls</span><span class="p">,</span><span class="n">rs</span><span class="p">)</span> <span class="ow">&lt;-</span> <span class="n">split</span> <span class="n">xs</span><span class="p">]</span>

<span class="nf">ne</span>         <span class="ow">::</span> <span class="p">(</span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="p">,</span> <span class="p">[</span><span class="n">b</span><span class="p">]</span><span class="p">)</span> <span class="ow">-&gt;</span> <span class="kt">Bool</span>
<span class="nf">ne</span> <span class="p">(</span><span class="n">xs</span><span class="p">,</span><span class="n">ys</span><span class="p">)</span> <span class="ow">=</span> <span class="n">not</span> <span class="p">(</span><span class="n">null</span> <span class="n">xs</span> <span class="o">||</span> <span class="n">null</span> <span class="n">ys</span><span class="p">)</span>

<span class="nf">nesplit</span> <span class="ow">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="ow">-&gt;</span> <span class="p">[</span><span class="p">(</span><span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="p">,</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span><span class="p">)</span><span class="p">]</span>
<span class="nf">nesplit</span> <span class="ow">=</span> <span class="n">filter</span> <span class="n">ne</span> <span class="o">.</span> <span class="n">split</span>

</code></pre></td></tr></table>
</div>
</div></td>
<td style="vertical-align:top">
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">split</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ns</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="n">T</span><span class="p">]</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">  </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="p">(</span><span class="o">&amp;</span><span class="p">[</span><span class="n">T</span><span class="p">]</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="p">[</span><span class="n">T</span><span class="p">]</span><span class="p">)</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="p">(</span><span class="mi">1</span><span class="p">.</span><span class="p">.</span><span class="n">ns</span><span class="p">.</span><span class="n">len</span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">i</span><span class="o">|</span><span class="w"> </span><span class="n">ns</span><span class="p">.</span><span class="n">split_at</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">collect</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div></td>
</tr>
</table
<p>The main difference in the Rust version is the absense of list comprehensions - that
syntactic sugar is not available, but it possible to achieve something similar using macros.</p>
<p>For eg, using the <a href="https://crates.io/crates/cute">cute</a> crate, we can rewrite the <code>split</code> function as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">split</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">ns</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="n">T</span><span class="p">]</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="p">(</span><span class="o">&amp;</span><span class="p">[</span><span class="n">T</span><span class="p">]</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="p">[</span><span class="n">T</span><span class="p">]</span><span class="p">)</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">c</span><span class="o">!</span><span class="p">[</span><span class="n">ns</span><span class="p">.</span><span class="n">split_at</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="p">,</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="p">.</span><span class="p">.</span><span class="n">ns</span><span class="p">.</span><span class="n">len</span><span class="p">(</span><span class="p">)</span><span class="p">]</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>While this is concise, I'll stick with what we can do with standard Rust in this post.</p>
<p>Next we need a function that returns the list of all permutations of all subsequences of a list.
In the paper it is called <code>subbags</code> and uses predefined functions that returns permutations etc.
We use the <code>permutations</code> function in the <a href="https://crates.io/crates/itertools">itertools</a> crate in Rust for simplicity:</p>
<table>
<tr>
<td> Haskell </td>
<td> Rust </td>
</tr>
<tr>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-haskell" data-lang="haskell"><span class="nf">subbags</span> <span class="ow">::</span> <span class="p">[</span><span class="n">a</span><span class="p">]</span> <span class="ow">-&gt;</span>  <span class="p">[</span><span class="p">[</span><span class="n">a</span> <span class="p">]</span><span class="p">]</span>
<span class="nf">subbags</span> <span class="n">xs</span> <span class="ow">=</span> <span class="p">[</span><span class="n">zs</span> <span class="o">|</span> <span class="n">ys</span> <span class="ow">&lt;-</span> <span class="n">subs</span> <span class="n">xs</span><span class="p">,</span>
                   <span class="n">zs</span> <span class="ow">&lt;-</span> <span class="n">perms</span> <span class="n">ys</span><span class="p">]</span>

<span class="c1">-- subs and perms defined elsewhere</span>
</code></pre></td></tr></table>
</div>
</div></td>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">sub_bags</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nb">Clone</span><span class="o">&gt;</span><span class="p">(</span><span class="n">xs</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">  </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="p">.</span><span class="n">xs</span><span class="p">.</span><span class="n">len</span><span class="p">(</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="o">|</span><span class="n">i</span><span class="o">|</span><span class="w">
</span><span class="w"></span><span class="w">      </span><span class="n">xs</span><span class="p">.</span><span class="n">iter</span><span class="p">(</span><span class="p">)</span><span class="p">.</span><span class="n">cloned</span><span class="p">(</span><span class="p">)</span><span class="p">.</span><span class="n">permutations</span><span class="p">(</span><span class="n">i</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">collect</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div></td>
</tr>
</table
<p>With all the utility functions in place, we are ready to implement the logic for the countdown problem.
The idea is to consider all valid expressions and sub results and combine them to see if we can get the
intended result.</p>
<table>
<tr>
<td> Haskell </td>
<td> Rust </td>
</tr>
<tr>
<td style="vertical-align:top">
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-haskell" data-lang="haskell"><span class="nf">combine</span> <span class="ow">::</span> <span class="kt">Result</span> <span class="ow">-&gt;</span> <span class="kt">Result</span> 
           <span class="ow">-&gt;</span> <span class="p">[</span><span class="kt">Result</span><span class="p">]</span>
<span class="nf">combine</span> <span class="p">(</span><span class="n">l</span><span class="p">,</span><span class="n">x</span><span class="p">)</span> <span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="n">y</span><span class="p">)</span>
  <span class="ow">=</span> <span class="p">[</span><span class="p">(</span><span class="kt">App</span> <span class="n">o</span> <span class="n">l</span> <span class="n">r</span><span class="p">,</span> <span class="n">apply</span> <span class="n">o</span> <span class="n">x</span> <span class="n">y</span><span class="p">)</span>
      <span class="o">|</span> <span class="n">o</span> <span class="ow">&lt;-</span> <span class="n">ops</span><span class="p">,</span> <span class="n">valid</span> <span class="n">o</span> <span class="n">x</span> <span class="n">y</span><span class="p">]</span>
</code></pre></td></tr></table>
</div>
</div></td>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">combine</span><span class="p">(</span><span class="p">(</span><span class="n">l</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">)</span>: <span class="kp">&amp;</span><span class="nb">Result</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="w"> </span><span class="n">y</span><span class="p">)</span>: <span class="kp">&amp;</span><span class="nb">Result</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">  </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">Result</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="p">[</span><span class="n">Add</span><span class="p">,</span><span class="w"> </span><span class="n">Sub</span><span class="p">,</span><span class="w"> </span><span class="n">Mul</span><span class="p">,</span><span class="w"> </span><span class="n">Div</span><span class="p">]</span><span class="p">.</span><span class="n">iter</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="n">op</span><span class="o">|</span><span class="w"> </span><span class="n">valid</span><span class="p">(</span><span class="n">op</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">y</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">op</span><span class="o">|</span><span class="w">
</span><span class="w"></span><span class="w">      </span><span class="p">(</span><span class="n">App</span><span class="p">(</span><span class="o">*</span><span class="n">op</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">           </span><span class="n">Rc</span>::<span class="n">new</span><span class="p">(</span><span class="n">l</span><span class="p">.</span><span class="n">clone</span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">           </span><span class="n">Rc</span>::<span class="n">new</span><span class="p">(</span><span class="n">r</span><span class="p">.</span><span class="n">clone</span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">      </span><span class="n">apply</span><span class="p">(</span><span class="n">op</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">y</span><span class="p">)</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">collect</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div></td>
</tr>
</table
<p>The main difference in Rust has to do with ownership again. To create an <code>App</code> we need
to create a new <code>Rc</code> for the sub expressions (lines 7 and 8).</p>
<p>Finally the function that ties everything together:</p>
<table>
<tr>
<td> Haskell </td>
<td> Rust </td>
</tr>
<tr>
<td style="vertical-align:top">
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-haskell" data-lang="haskell"><span class="nf">results</span> <span class="ow">::</span> <span class="p">[</span><span class="kt">Int</span><span class="p">]</span> <span class="ow">-&gt;</span> <span class="p">[</span><span class="kt">Result</span><span class="p">]</span>
<span class="nf">results</span> <span class="kt">[]</span>  <span class="ow">=</span> <span class="kt">[]</span>
<span class="nf">results</span> <span class="p">[</span><span class="n">n</span><span class="p">]</span> <span class="ow">=</span> <span class="p">[</span><span class="p">(</span><span class="kt">Val</span> <span class="n">n</span><span class="p">,</span><span class="n">n</span><span class="p">)</span> <span class="o">|</span> <span class="n">n</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">]</span>
<span class="nf">results</span> <span class="n">ns</span>
  <span class="ow">=</span> <span class="p">[</span><span class="n">res</span> <span class="o">|</span> <span class="p">(</span><span class="n">ls</span><span class="p">,</span><span class="n">rs</span><span class="p">)</span> <span class="ow">&lt;-</span> <span class="n">nesplit</span> <span class="n">ns</span>
         <span class="p">,</span> <span class="n">lx</span>  <span class="ow">&lt;-</span> <span class="n">results</span> <span class="n">ls</span>
         <span class="p">,</span> <span class="n">ry</span>  <span class="ow">&lt;-</span> <span class="n">results</span> <span class="n">rs</span>
         <span class="p">,</span> <span class="n">res</span> <span class="ow">&lt;-</span> <span class="n">combine</span> <span class="n">lx</span> <span class="n">ry</span><span class="p">]</span>

<span class="nf">solutions</span> <span class="ow">::</span> <span class="p">[</span><span class="kt">Int</span><span class="p">]</span> <span class="ow">-&gt;</span> <span class="kt">Int</span> <span class="ow">-&gt;</span> <span class="p">[</span><span class="kt">Expr</span><span class="p">]</span>
<span class="nf">solutions</span> <span class="n">ns</span> <span class="n">n</span>
  <span class="ow">=</span> <span class="p">[</span><span class="n">e</span> <span class="o">|</span> <span class="n">ns&#39;</span> <span class="ow">&lt;-</span> <span class="n">subbags</span> <span class="n">ns</span>
       <span class="p">,</span> <span class="p">(</span><span class="n">e</span><span class="p">,</span><span class="n">m</span><span class="p">)</span> <span class="ow">&lt;-</span> <span class="n">results</span> <span class="n">ns&#39;</span>
       <span class="p">,</span> <span class="n">m</span> <span class="o">==</span> <span class="n">n</span><span class="p">]</span>
</code></pre></td></tr></table>
</div>
</div></td>
<td>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">results</span><span class="p">(</span><span class="n">ns</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="n">Int</span><span class="p">]</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">Result</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="k">match</span><span class="w"> </span><span class="n">ns</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">[</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">(</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">[</span><span class="n">n</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">vec</span><span class="o">!</span><span class="p">(</span><span class="p">(</span><span class="n">Val</span><span class="p">(</span><span class="o">*</span><span class="n">n</span><span class="p">)</span><span class="p">,</span><span class="w"> </span><span class="o">*</span><span class="n">n</span><span class="p">)</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">_results</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="k">fn</span> <span class="nf">_results</span><span class="p">(</span><span class="n">ns</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="n">Int</span><span class="p">]</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">Result</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">split</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span><span class="p">.</span><span class="n">iter</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="o">|</span><span class="p">(</span><span class="n">ls</span><span class="p">,</span><span class="w"> </span><span class="n">rs</span><span class="p">)</span><span class="o">|</span><span class="w"> </span><span class="n">results</span><span class="p">(</span><span class="n">ls</span><span class="p">)</span><span class="p">.</span><span class="n">into_iter</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">      </span><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">|</span><span class="n">lx</span><span class="o">|</span><span class="w"> </span><span class="n">results</span><span class="p">(</span><span class="n">rs</span><span class="p">)</span><span class="p">.</span><span class="n">into_iter</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">|</span><span class="n">ry</span><span class="o">|</span><span class="w"> </span><span class="n">combine</span><span class="p">(</span><span class="o">&amp;</span><span class="n">lx</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="n">ry</span><span class="p">)</span><span class="p">)</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">collect</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">solutions</span><span class="p">(</span><span class="n">ns</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Int</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">n</span>: <span class="nc">Int</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">  </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Expr</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">sub_bags</span><span class="p">(</span><span class="n">ns</span><span class="p">)</span><span class="p">.</span><span class="n">iter</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="o">|</span><span class="n">b</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="n">results</span><span class="p">(</span><span class="o">&amp;</span><span class="n">b</span><span class="p">)</span><span class="p">.</span><span class="n">into_iter</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">          </span><span class="p">.</span><span class="n">filter</span><span class="p">(</span><span class="o">|</span><span class="p">(</span><span class="n">_</span><span class="p">,</span><span class="w"> </span><span class="n">m</span><span class="p">)</span><span class="o">|</span><span class="w"> </span><span class="o">*</span><span class="n">m</span><span class="w"> </span><span class="o">=</span><span class="o">=</span><span class="w"> </span><span class="n">n</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">          </span><span class="p">.</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="p">(</span><span class="n">e</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="o">|</span><span class="w"> </span><span class="n">e</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">          </span><span class="p">.</span><span class="n">collect</span>::<span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Expr</span><span class="o">&gt;</span><span class="o">&gt;</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">}</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">.</span><span class="n">collect</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div></td>
</tr>
</table
<p>That's it. This is  the complete implementation. You can checkout the complete runnable code
<a href="https://github.com/amitdev/count_down">here</a>.</p>
<h3 id="sidenote---adding-parallelism">Sidenote - adding parallelism</h3>
<p>Since our code is written in a functional way it is trivial to make parts of it parallel.
By using the <a href="https://crates.io/crates/rayon">rayon</a> crate and just making two <a href="https://github.com/amitdev/count_down/commit/1516ce5ea24bf7c6e01d0afa1807b6d1b74ee57b">minor</a> changes:</p>
<ul>
<li><code>sub_bags(ns).iter()</code> &ndash;&gt; <code>sub_bags(ns).par_iter()</code></li>
<li><code>Rc</code> &ndash;&gt; <code>Arc</code></li>
</ul>
<p>this reduces the execution time from <em>~370ms</em> to <em>~70ms</em> for the above example.</p>
<h2 id="summary">Summary</h2>
<p>Rust is a fairly expressive language and using the functional style is
quite natural. Ownership and lifetimes do get in the way sometimes,
but it is a price worth paying considering the runtime benefits.
Also the compiler error messages are really helpful and guides you to
the right solution.</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/programming/">Programming</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/rust/">rust</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/haskell/">haskell</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Functional programming in Rust</title>
                <link>https://amitdev.github.io/posts/2019-03-26-functional-rust/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2019-03-26-functional-rust/</guid>
                <pubDate>Tue, 26 Mar 2019 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p><a href="https://www.rust-lang.org/">Rust</a> is a modern, multi paradigm language with the following primary goals:</p>
<ul>
<li>Performance (zero cost abstractions)</li>
<li>Reliability (no data races)</li>
</ul>
<p>Rust is strongly influenced by functional programming languages like ML, so it is
possible to follow a functional coding style in it.
However being functional is not one of Rust's explicit goals.</p>
<p>In this post (and possibly follow up ones) I'll explore functional programming in  Rust. This is not an introduction to
Rust or functional programming. Basic familiarity with them is assumed.</p>
<h2 id="functional-programming">Functional Programming</h2>
<p>The goal of programming is to manage complexity.</p>
<p>In functional programming we manage complexity by principled composition - large things are composed of
small things.</p>
<p>The more things we can compose together the better abstractions
we can build and reduce complexity. The building blocks are types and functions, and let us
see how well we can compose them in Rust.</p>
<h2 id="algebraic-data-types">Algebraic data types</h2>
<p>Lets start with types. One way to classify types is by looking at number of inhabitants,
that is, how many values of a particular type exists. For eg, the unit type (<code>()</code> in Rust) has only
one value, <code>bool</code> has two values etc. Apart from builtin types, Rust supports Sum and Product types, which means we can
combine basic types using addition or multiplication (in terms of number of inhabitants). The key
insight here is that we can use the familiar algebra from maths to reason about them, hence the name.</p>
<p>In Rust we could create a sum type
by using <code>enum</code>. Think of it more like type constructor in Haskell, than enum in C/Java.</p>
<p>For eg. we can create a type with a two values as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">enum</span> <span class="nc">Wing</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// name of type
</span><span class="c1"></span><span class="w">    </span><span class="n">Left</span><span class="w">    </span><span class="c1">// value
</span><span class="c1"></span><span class="w">    </span><span class="n">Right</span><span class="w">   </span><span class="c1">// value
</span><span class="c1"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>A product type can be created using a tuple <code>(A, B)</code> or <code>struct</code>.</p>
<p>Here are examples of some types:</p>
<table>
<thead>
<tr>
<th># of Inhabitants</th>
<th>Rust</th>
<th>Haskell</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td><code>enum Void {}</code></td>
<td><code>data Void</code> or <br> <code>Data.Void</code></td>
</tr>
<tr>
<td>1</td>
<td><code>enum Unit { Unit }</code> or <br> <code>()</code></td>
<td><code>data Unit = Unit</code> or <br> <code>()</code></td>
</tr>
<tr>
<td>1 + 1</td>
<td><code>enum Direction { Up, Down }</code> or <br> <code>bool</code></td>
<td><code>data Direction = Up | Down</code> or <br> <code>Boolean</code></td>
</tr>
<tr>
<td>1 + A</td>
<td><code>enum Option&lt;A&gt; { Some(A), None }</code></td>
<td><code>data Maybe a = Just a | Nothing</code></td>
</tr>
<tr>
<td>A + B</td>
<td><code>enum Result&lt;A, B&gt; { Ok(A), Err(B) }</code></td>
<td><code>data Either a b = Left a | Right b</code></td>
</tr>
<tr>
<td>A * B</td>
<td><code>(A, B)</code> or <br> <code>struct Tuple { a: A, b: B }</code></td>
<td><code>data (a, b) = (a, b)</code></td>
</tr>
</tbody>
</table>
<p>As you can see we can compose types using addition or multiplication. This is useful in modelling
types.</p>
<p>For eg. since <code>A + A = 2 * A</code>, we could represent a type <code>enum Score&lt;A&gt; { Left(A), Right(A) }</code>
as <code>(bool, A)</code>. Intuitively, the boolean represents whether the value is left or right.</p>
<h2 id="pattern-matching">Pattern matching</h2>
<p>A language feature that goes well with algebraic data types in pattern matching. It helps to deconstruct
data out of types in a simple way. Rust offers powerful pattern matching support and almost anything can
be deconsutructed using it. For example with the following types:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">enum</span> <span class="nc">Maybe</span><span class="o">&lt;</span><span class="n">A</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Just</span><span class="p">(</span><span class="n">A</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Nothing</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="k">struct</span> <span class="nc">Person</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">name</span>: <span class="nb">String</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">age</span>: <span class="kt">u8</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">email</span>: <span class="nc">Maybe</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>we can pattern match things out of it using:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="kd">let</span><span class="w"> </span><span class="n">person</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Person</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">name</span>: <span class="s">&#34;Alice&#34;</span><span class="p">.</span><span class="n">to_string</span><span class="p">(</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">  </span><span class="n">age</span>: <span class="mi">25</span><span class="p">,</span><span class="w"> 
</span><span class="w">  </span><span class="n">email</span>: <span class="nc">Just</span><span class="p">(</span><span class="s">&#34;alice@example.com&#34;</span><span class="p">.</span><span class="n">to_string</span><span class="p">(</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="p">;</span><span class="w">
</span><span class="w"></span><span class="k">match</span><span class="w"> </span><span class="n">person</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Person</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">name</span><span class="w"> </span>: <span class="nc">name</span><span class="p">,</span><span class="w"> </span><span class="n">age</span>: <span class="nc">age</span><span class="p">,</span><span class="w"> </span><span class="n">email</span><span class="w"> </span>: <span class="nc">Just</span><span class="p">(</span><span class="n">email</span><span class="p">)</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">      </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&#34;Person {}, aged {} with email {}&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="n">age</span><span class="p">,</span><span class="w"> </span><span class="n">email</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">Person</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">name</span>: <span class="nc">name</span><span class="p">,</span><span class="w"> </span><span class="n">age</span>: <span class="nc">age</span><span class="p">,</span><span class="w"> </span><span class="n">email</span><span class="w"> </span>: <span class="nc">Nothing</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">      </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&#34;Person {}, aged {} with no email&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">name</span><span class="p">,</span><span class="w"> </span><span class="n">age</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>Pattern guards and capturing pattern in a single variable is also supported. For eg:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">match</span><span class="w"> </span><span class="n">someVar</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">@</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="p">.</span><span class="p">.</span><span class="p">.</span><span class="w"> </span><span class="mi">9</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&#34;within 0 to 9, {}&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="mi">20</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&#34;greater than 20, {}&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&#34;Should be less than 20, {}&#34;</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="nb">None</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">println</span><span class="o">!</span><span class="p">(</span><span class="s">&#34;None&#34;</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>Patterns is commonly used in match expressions but they can be used in place of identifier in other places as well like
variable declaration, function arguments etc.</p>
<h2 id="functions">Functions</h2>
<p>Functions are first class in Rust and it supports <a href="https://doc.rust-lang.org/book/ch13-01-closures.html">closures</a> as well.</p>
<p>However, one has to think about ownership and lifetime of variables when dealing with them.
Basically Rust is not a language with garbage collection and the programmer has to
give hints to the compiler about ownership of variables so they can be <em>dropped</em> after use. This is
probably the hardest part to get while learning Rust and also what makes Rust special.</p>
<p>Read more about ownership <a href="https://doc.rust-lang.org/book/ch04-01-what-is-ownership.html">here</a>.</p>
<p>Lets start with a simple definition of factorial:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">n</span>: <span class="kt">u64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">u64</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="k">match</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="mi">0</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="n">n</span><span class="w">     </span><span class="o">=</span><span class="o">&gt;</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">factorial</span><span class="p">(</span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="p">,</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>This is a straightforward translation of recursive definition of factorial; <code>factorial(n) = n * factorial(n-1)</code>.
While this is fairly clear, it is often better to use high level combinators than explicit recursion.
So we can write above as:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">n</span>: <span class="kt">u64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">u64</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">(</span><span class="mi">1</span><span class="p">.</span><span class="p">.</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="p">.</span><span class="n">fold</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">acc</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="o">|</span><span class="w"> </span><span class="n">acc</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>where <code>|acc, i| acc * i</code> is a closure (similar to <code>\acc i -&gt; acc * i</code> in Haskell, or <code>(acc, i) -&gt; acc * i</code> in Java).
So the above code basically takes range of numbers from 1 to n inclusive and multiplies them.</p>
<p>Note: Most of the operators in Rust have traits associated with it. So the <code>*</code> operator above is defined in
<code>std::ops::Mul</code> trait and <code>acc * i</code> is a short hand for <code>acc.mul(i)</code>. So the above can also be written as:</p>
<p><code>(1..n+1).fold(1, Mul::mul)</code></p>
<p>This makes it clear that <code>factorial(n)</code> is the product of first n natural numbers. It can be made
explicit by using the builtin <code>product</code> function, which folds over using multiplication.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">n</span>: <span class="kt">u64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">u64</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">(</span><span class="mi">1</span><span class="p">.</span><span class="p">.</span><span class="n">n</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="p">.</span><span class="n">product</span><span class="p">(</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>The key here is all of the above does not have any performance overhead, it performs similar to an
imperative loop that multiplies the numbers.</p>
<h2 id="higher-order-functions">Higher order functions</h2>
<p>Now lets look at how to define and use higher order functions. Function types in Rust implement
the <code>Fn</code> trait (think of traits as something similar to type classes). A function that takes in
type <code>X</code> and return type <code>Y</code> can be represented as <code>Fn(X) -&gt; Y</code>.</p>
<p>For example, consider a function that takes a function and calls it with given argument:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">apply</span><span class="o">&lt;</span><span class="n">F</span><span class="p">,</span><span class="w"> </span><span class="n">A</span><span class="p">,</span><span class="w"> </span><span class="n">B</span><span class="o">&gt;</span><span class="p">(</span><span class="n">f</span>: <span class="nc">F</span><span class="p">,</span><span class="w"> </span><span class="n">arg</span>: <span class="nc">A</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">B</span><span class="w"> 
</span><span class="w"></span><span class="k">where</span><span class="w"> </span><span class="n">F</span>: <span class="nb">Fn</span><span class="p">(</span><span class="n">A</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">B</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">f</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="k">fn</span> <span class="nf">square</span><span class="p">(</span><span class="n">a</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="c1">// apply can take another function as argument
</span><span class="c1"></span><span class="kd">let</span><span class="w"> </span><span class="n">n</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">apply</span><span class="p">(</span><span class="n">square</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="p">;</span><span class="w">    </span><span class="c1">// n = 16
</span><span class="c1"></span><span class="c1">// apply can also take a closure as argument
</span><span class="c1"></span><span class="kd">let</span><span class="w"> </span><span class="n">n</span>: <span class="kt">i32</span> <span class="o">=</span><span class="w"> </span><span class="n">apply</span><span class="p">(</span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="mi">4</span><span class="p">)</span><span class="p">;</span><span class="w"> </span><span class="c1">// n = 16
</span></code></pre></td></tr></table>
</div>
</div><p>A more interesting example of higher order function is the fixed point function. A fixed point of a function <code>f</code> is a value <code>a</code> such that <code>f(a) == a</code>.
One way to define the fixed point function is provided in <a href="https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-12.html#%25_sec_1.3.3">sicp</a>.
We can translate that to Rust almost verbatim by adding in the right types.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">const</span><span class="w"> </span><span class="n">TOLERANCE</span>: <span class="kt">f64</span> <span class="o">=</span><span class="w"> </span><span class="mf">0.000001</span><span class="p">;</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="k">fn</span> <span class="nf">fixed_point</span><span class="o">&lt;</span><span class="n">F</span><span class="o">&gt;</span><span class="p">(</span><span class="n">f</span>: <span class="nc">F</span><span class="p">,</span><span class="w"> </span><span class="n">first_guess</span>: <span class="kt">f64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">f64</span>
    <span class="nc">where</span><span class="w"> </span><span class="n">F</span>: <span class="nb">Fn</span><span class="p">(</span><span class="kt">f64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">f64</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="c1">// Check if v1 and v2 are close enough to be considered equal
</span><span class="c1"></span><span class="w">    </span><span class="k">fn</span> <span class="nf">close_enough</span><span class="p">(</span><span class="n">v1</span>: <span class="kt">f64</span><span class="p">,</span><span class="w"> </span><span class="n">v2</span>: <span class="kt">f64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">bool</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="p">(</span><span class="n">v2</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">v1</span><span class="p">)</span><span class="p">.</span><span class="n">abs</span><span class="p">(</span><span class="p">)</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">TOLERANCE</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="c1">// Call f(guess) and see if it is close enough to guess. If so
</span><span class="c1"></span><span class="w">    </span><span class="c1">// we have found the fix point of f
</span><span class="c1"></span><span class="w">    </span><span class="k">fn</span> <span class="nf">try_guess</span><span class="o">&lt;</span><span class="n">F</span><span class="o">&gt;</span><span class="p">(</span><span class="n">guess</span>: <span class="kt">f64</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="nc">F</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">f64</span> 
        <span class="nc">where</span><span class="w"> </span><span class="n">F</span>: <span class="nb">Fn</span><span class="p">(</span><span class="kt">f64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">f64</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="kd">let</span><span class="w"> </span><span class="n">next</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">f</span><span class="p">(</span><span class="n">guess</span><span class="p">)</span><span class="p">;</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="n">close_enough</span><span class="p">(</span><span class="n">guess</span><span class="p">,</span><span class="w"> </span><span class="n">next</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">            </span><span class="n">guess</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">            </span><span class="n">try_guess</span><span class="p">(</span><span class="n">next</span><span class="p">,</span><span class="w"> </span><span class="n">f</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="w">        </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">try_guess</span><span class="p">(</span><span class="n">first_guess</span><span class="p">,</span><span class="w"> </span><span class="n">f</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span><span class="w"></span><span class="w">
</span><span class="w"></span><span class="k">fn</span> <span class="nf">sqrt</span><span class="p">(</span><span class="n">x</span>: <span class="kt">f64</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">f64</span> <span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="n">fixed_point</span><span class="p">(</span><span class="o">|</span><span class="n">y</span><span class="o">|</span><span class="w"> </span><span class="p">(</span><span class="n">y</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">x</span><span class="o">/</span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">2.0</span><span class="p">,</span><span class="w"> </span><span class="mf">1.0</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>How about functions returning functions? One way is to return a closure, but it requires little more work
that you would expect. For example, consider the <code>compose</code> function that composes two functions <code>f</code> and <code>g</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-rust" data-lang="rust"><span class="k">fn</span> <span class="nf">compose</span><span class="o">&lt;</span><span class="n">X</span><span class="p">,</span><span class="w"> </span><span class="n">Y</span><span class="p">,</span><span class="w"> </span><span class="n">Z</span><span class="p">,</span><span class="w"> </span><span class="n">F</span><span class="p">,</span><span class="w"> </span><span class="n">G</span><span class="o">&gt;</span><span class="p">(</span><span class="n">f</span>: <span class="nc">F</span><span class="p">,</span><span class="w"> </span><span class="n">g</span>: <span class="nc">G</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">impl</span><span class="w"> </span><span class="nb">Fn</span><span class="p">(</span><span class="n">X</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Z</span><span class="w">
</span><span class="w"></span><span class="k">where</span><span class="w"> </span><span class="n">F</span>: <span class="nb">Fn</span><span class="p">(</span><span class="n">X</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Y</span><span class="p">,</span><span class="w"> </span><span class="n">G</span>: <span class="nb">Fn</span><span class="p">(</span><span class="n">Y</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">Z</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="w"></span><span class="w">    </span><span class="k">move</span><span class="w"> </span><span class="o">|</span><span class="n">x</span><span class="o">|</span><span class="w"> </span><span class="n">g</span><span class="p">(</span><span class="n">f</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="p">)</span><span class="w">
</span><span class="w"></span><span class="p">}</span><span class="w">
</span></code></pre></td></tr></table>
</div>
</div><p>This might look unfamiliar, so lets go through it:</p>
<ul>
<li><code>X, Y, Z, F and G</code> are type parameters. <code>F</code> is type of a function that takes an argument of type <code>X</code> and returns <code>Y</code> etc.</li>
<li><code>impl Fn(X) -&gt; Z</code>: The function returns a closure. Since the actual type that is returned might vary per call
(each closure is of a different type since the capturing variables might differ), we need to tell compiler that what we really return is an implementation of the <code>Fn</code> trait.</li>
<li><code>move</code> This is related to ownership. Since we return a closure, we don't know when that is called and its lifetime may outlive the function. So the closure needs to own
the variables instead of borrowing it. This might seem confusing at first, but rust compiler has excellent <a href="https://doc.rust-lang.org/error-index.html#E0373">error messages</a> to guide you here.</li>
</ul>
<p>Note: <code>Fn</code> is not the only function type. There is also <a href="https://doc.rust-lang.org/std/ops/trait.FnOnce.html">FnOnce</a> which only can be called once, and <a href="https://doc.rust-lang.org/std/ops/trait.FnMut.html">FnMut</a>
which allows the closure to mutate state.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Hope you got a basic taste of functional programming in Rust. Rust has pretty good support for functional programming
compared to languages like Java or C++, but not as much as a pure functional language like Haskell.
Rust is a good choice if performance and reliability
are what you are after with good support for building composable software. It has excellent <a href="https://doc.rust-lang.org/">documentation</a>, good community and a
friendly compiler.</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/programming/">Programming</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/rust/">rust</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>A functional design pattern</title>
                <link>https://amitdev.github.io/posts/2014-07-28-a-functional-design-pattern/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2014-07-28-a-functional-design-pattern/</guid>
                <pubDate>Mon, 28 Jul 2014 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p>This is not an attempt to be yet another Monad tutorial. There are probably more Monad tutorials than one can read already out there - see this <a href="http://www.haskell.org/haskellwiki/Monad_tutorials_timeline">timeline</a> or do a google search. This rather is a simple introduction to understand Monads based on the <a href="http://homepages.inf.ed.ac.uk/wadler/papers/essence/essence.ps">Essence of FP</a> paper. Not the theory, just the design idea which is arguably simpler to understand.</p>
<h2 id="a-basic-interpreter">A basic interpreter</h2>
<p>Let's consider implementing a basic interpreter - one which can add numbers (the paper talks about a bigger one, but this simple example will serve our purpose). And we are concerned only with evaluation, we assume the AST is already available to us. So, we should be able to do things like:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="n">Num</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<span class="n">Add</span><span class="p">(</span><span class="n">Num</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="p">,</span> <span class="n">Num</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="p">)</span> <span class="o">==</span> <span class="mi">5</span>
<span class="n">Add</span><span class="p">(</span><span class="n">Num</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span><span class="p">,</span> <span class="n">Var</span><span class="p">(</span><span class="sa"></span><span class="s2">&#34;</span><span class="s2">v</span><span class="s2">&#34;</span><span class="p">)</span><span class="p">)</span> <span class="p">{</span><span class="sa"></span><span class="s2">&#34;</span><span class="s2">v</span><span class="s2">&#34;</span> <span class="p">:</span> <span class="mi">5</span><span class="p">}</span> <span class="o">==</span> <span class="mi">15</span>
</code></pre></td></tr></table>
</div>
</div><p>In the last example, a variable is defined which should be available via an environment. Let us consider an implementation in Python.</p>
<script src="https://gist.github.com/amitdev/200bd0bc38a503ed5d73/6df6227018ae357cb10c0b98b8dbadb7ca53d1fc.js"></script>
<p>Note: Don't focus too much on the implementation - I've chosen the commonly used way in Python, it doesn't matter if you use objects or functions here.</p>
<p>Coming back to the code above, there are three objects: <code>Num</code> which evaluates to its value, <code>Var</code> which evaluates to value defined in env and <code>Add</code> which evaluates its left and right operands and adds them. Pretty simple.</p>
<h2 id="error-handling">Error Handling</h2>
<p>Currently we don't have any error handling. What if <code>Num</code> contains something other than numbers? a variable is not defined? One option is to return something like <code>None</code>, but that means every caller should check that explicitly. We could raise exceptions, but they don't compose well. Besides, currently all expressions evaluate to same type. Consistency is nice. So what could we do?</p>
<blockquote>
<p>All problems in computer science can be solved by another level of indirection - Butler Lampson</p>
</blockquote>
<p>Ok. Let us try to abstract the return type. Currently it is returning the value (number). Instead let us return an object that contains the value. Maybe we can extend this object later. Following is the first iteration - without changing any behavior, but only wrapping the result in the new object.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="k">class</span> <span class="nc">M</span><span class="p">(</span><span class="nb">object</span><span class="p">)</span><span class="p">:</span>
  <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span><span class="p">:</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">val</span> <span class="o">=</span> <span class="n">val</span>

  <span class="k">def</span> <span class="fm">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="p">:</span>
    <span class="k">return</span> <span class="sa"></span><span class="s2">&#34;</span><span class="si">%s</span><span class="s2">(</span><span class="si">%r</span><span class="s2">)</span><span class="s2">&#34;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">val</span><span class="p">)</span>

  <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span><span class="p">:</span>
    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">val</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">val</span>

<span class="k">def</span> <span class="nf">unit</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="p">:</span>
  <span class="k">return</span> <span class="n">M</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">bind</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span><span class="p">:</span>
  <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">val</span><span class="p">)</span> 
</code></pre></td></tr></table>
</div>
</div><p>So <code>M</code> is our container object. We also added two utility functions: <code>unit</code> which just creates <code>M</code>, and <code>bind</code> which applies a given function to value in <code>M</code>. Only changes to our interpreter is in <code>evaluate</code> methods:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="c1"># In Num.evaluate:</span>
  <span class="k">return</span> <span class="n">unit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val</span><span class="p">)</span> <span class="c1"># Instead of just self.val</span>

<span class="c1"># In Var.evaluate:</span>
  <span class="k">return</span> <span class="n">unit</span><span class="p">(</span><span class="n">env</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">]</span><span class="p">)</span> <span class="c1"># Instead of just env[self.name]</span>

<span class="c1"># In Add.evaluate:</span>
  <span class="k">return</span> <span class="n">bind</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">left</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">env</span><span class="p">)</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">bind</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">right</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">env</span><span class="p">)</span><span class="p">,</span> <span class="k">lambda</span> <span class="n">y</span><span class="p">:</span> <span class="n">unit</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span><span class="p">)</span><span class="p">)</span>
</code></pre></td></tr></table>
</div>
</div><p>The change to <code>Add</code> might seem complicated, so lets go through it. In <code>evaluate</code>, previously we get two numbers and add them. But now we get two <code>M</code> objects. Say, we got <code>M(2)</code> and <code>M(3)</code>. How will we make an <code>M(5)</code> out of it? That is where the <code>bind</code> function comes in. It helps us to peek inside <code>M</code> and access the value. So in the example, the above code is equivalent to:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="c1"># bind(M(2), lambda x: ..)</span>
<span class="c1">#	=&gt; {x = 2} bind(M(3), lambda y: ...)</span>
<span class="c1">#	=&gt; {x=2, y=3} unit(x+y) </span>
<span class="c1">#	=&gt; unit(2+3) </span>
<span class="c1">#	=&gt; M(5). </span>
</code></pre></td></tr></table>
</div>
</div><p>I hope it is clear now, otherwise try to take it apart yourself. So our interpreter still has the same functionality, but returns a new type now:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="n">Num</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="n">M</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="n">Add</span><span class="p">(</span><span class="n">Num</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="p">,</span> <span class="n">Num</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="p">)</span> <span class="o">==</span> <span class="n">M</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="n">Add</span><span class="p">(</span><span class="n">Num</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span><span class="p">,</span> <span class="n">Var</span><span class="p">(</span><span class="sa"></span><span class="s2">&#34;</span><span class="s2">v</span><span class="s2">&#34;</span><span class="p">)</span><span class="p">)</span> <span class="p">{</span><span class="sa"></span><span class="s2">&#34;</span><span class="s2">v</span><span class="s2">&#34;</span> <span class="p">:</span> <span class="mi">5</span><span class="p">}</span> <span class="o">==</span> <span class="n">M</span><span class="p">(</span><span class="mi">15</span><span class="p">)</span>
</code></pre></td></tr></table>
</div>
</div><p>Now that we have a generic return type, we could add error as a first class type.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="k">class</span> <span class="nc">Error</span><span class="p">(</span><span class="n">M</span><span class="p">)</span><span class="p">:</span>
  <span class="k">pass</span> 
</code></pre></td></tr></table>
</div>
</div><p>We can start handling errors like so:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="c1"># In Num.evaluate:</span>
  <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val</span><span class="p">,</span> <span class="n">Number</span><span class="p">)</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">unit</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val</span><span class="p">)</span>
  <span class="k">else</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">Error</span><span class="p">(</span><span class="sa"></span><span class="s2">&#34;</span><span class="si">%s</span><span class="s2"> is not a number</span><span class="s2">&#34;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">val</span><span class="p">)</span> 
</code></pre></td></tr></table>
</div>
</div><p>We need to do one last thing. <code>bind</code> on an <code>Error</code> should pass it on instead of applying the operation:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">bind</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span><span class="p">:</span>
  <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">Error</span><span class="p">)</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">m</span>
  <span class="k">return</span> <span class="n">f</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">val</span><span class="p">)</span> 
</code></pre></td></tr></table>
</div>
</div><p>That's all. Now our interpreter can handle errors and still maintain the same interface. Let us call this design technique <em>Monads</em>. In theory there are <a href="http://en.wikipedia.org/wiki/Monad_%28functional_programming%29#Monad_laws">laws</a> governing Monads, but let's ignore them for now.</p>
<blockquote>
<p>Monads are return types that guide you through the happy path - Erik Meijer</p>
</blockquote>
<p>See the complete code <a href="https://gist.github.com/amitdev/200bd0bc38a503ed5d73/d1cb471cf4809d3112363720b2baf50a748e842b">here</a>.</p>
<h2 id="adding-state">Adding State</h2>
<p>What if we need to add some state to our interpreter? Say we need to keep track of number of times add was performed (it could be any state that we want to maintain). One option is to add global variable to keep track, but that is evil. Since we already have abstracted the return type, let us see if we can utilize that. One way to model it is to return a pair of values - the result and count. For eg:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="n">Num</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="o">==</span> <span class="n">State</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>                           <span class="c1"># 0 addition</span>
<span class="n">Add</span><span class="p">(</span><span class="n">Num</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="p">,</span> <span class="n">Num</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="p">)</span> <span class="o">==</span> <span class="n">State</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>              <span class="c1"># 1 addition</span>
<span class="n">Add</span><span class="p">(</span><span class="n">Num</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span><span class="p">,</span> <span class="n">Add</span><span class="p">(</span><span class="n">Num</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="p">,</span> <span class="n">Num</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span><span class="p">)</span><span class="p">)</span> <span class="o">==</span> <span class="n">State</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="c1"># 2 addition</span>
</code></pre></td></tr></table>
</div>
</div><p>So we will define <code>State</code> which encapsulates the data we need to track. It will a lazy object that when invoked will return the actual state.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="k">class</span> <span class="nc">State</span><span class="p">(</span><span class="n">M</span><span class="p">)</span><span class="p">:</span>
  <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">val</span><span class="p">,</span> <span class="n">count</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">old</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">f</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span><span class="p">:</span>
    <span class="nb">super</span><span class="p">(</span><span class="n">State</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">=</span> <span class="n">count</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">old</span> <span class="o">=</span> <span class="n">old</span>
    <span class="bp">self</span><span class="o">.</span><span class="n">f</span> <span class="o">=</span> <span class="n">f</span>

  <span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">count</span><span class="p">)</span><span class="p">:</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">old</span><span class="p">:</span>
      <span class="k">return</span> <span class="n">State</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val</span><span class="p">,</span> <span class="n">count</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
      <span class="n">new_state</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">old</span><span class="p">(</span><span class="n">count</span><span class="p">)</span>
      <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">f</span><span class="p">(</span><span class="n">new_state</span><span class="o">.</span><span class="n">val</span><span class="p">)</span><span class="p">(</span><span class="n">new_state</span><span class="o">.</span><span class="n">count</span><span class="p">)</span>

  <span class="k">def</span> <span class="fm">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">other</span><span class="p">)</span><span class="p">:</span>
    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">val</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">val</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">count</span> <span class="o">==</span> <span class="n">other</span><span class="o">.</span><span class="n">count</span>

<span class="k">class</span> <span class="nc">Counter</span><span class="p">(</span><span class="n">State</span><span class="p">)</span><span class="p">:</span>
  <span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">count</span><span class="p">)</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">State</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">val</span><span class="p">,</span> <span class="n">count</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
</code></pre></td></tr></table>
</div>
</div><p>The <code>unit</code> and <code>bind</code> now return <code>State</code> objects:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="k">def</span> <span class="nf">unit</span><span class="p">(</span><span class="n">v</span><span class="p">)</span><span class="p">:</span>
  <span class="k">return</span> <span class="n">State</span><span class="p">(</span><span class="n">v</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">bind</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span><span class="p">:</span>
  <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">Error</span><span class="p">)</span><span class="p">:</span>
    <span class="k">return</span> <span class="n">m</span>
  <span class="k">return</span> <span class="n">State</span><span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">val</span><span class="p">,</span> <span class="n">old</span><span class="o">=</span><span class="n">m</span><span class="p">,</span> <span class="n">f</span><span class="o">=</span><span class="n">f</span><span class="p">)</span>
</code></pre></td></tr></table>
</div>
</div><p>The only change required in the interpreter is in <code>Add</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-python" data-lang="python"><span class="c1"># In Add.evaluate</span>
  <span class="k">return</span> <span class="n">bind</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">left</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">env</span><span class="p">)</span><span class="p">,</span>
	      <span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">bind</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">right</span><span class="o">.</span><span class="n">evaluate</span><span class="p">(</span><span class="n">env</span><span class="p">)</span><span class="p">,</span>
                             <span class="k">lambda</span> <span class="n">y</span><span class="p">:</span> <span class="n">bind</span><span class="p">(</span><span class="n">Counter</span><span class="p">(</span><span class="bp">None</span><span class="p">)</span><span class="p">,</span> 
                                            <span class="k">lambda</span> <span class="n">t</span><span class="p">:</span> <span class="n">unit</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">)</span><span class="p">)</span><span class="p">)</span><span class="p">)</span>
</code></pre></td></tr></table>
</div>
</div><p>An additional bind call is added to get the result (<code>unit(x+y)</code>) and apply <code>Counter</code> to maintain count. The complete code is <a href="https://gist.github.com/amitdev/200bd0bc38a503ed5d73">here</a>.</p>
<h2 id="conclusion">Conclusion</h2>
<p>You probably are aware of higher order functions like <code>map</code> which takes a function that acts on values inside a <em>container</em> and produce new values. But the shape of the <em>container</em> itself does not change. With Monads, the function (in <code>bind</code>) acts on value inside the <em>container</em> but returns a <em>new container</em>. This is where Monads get the power from. Languages like Haskell, Scala etc provide rich set of generic operations and syntactic sugar around it.</p>
<p>In any case, considering it purely as a design approach, this is simple and something anyone could've invented.</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/programming/">Programming</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/python/">python</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Learning Functional Programming - A Roadmap</title>
                <link>https://amitdev.github.io/posts/2014-06-29-learning-functional-programming/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2014-06-29-learning-functional-programming/</guid>
                <pubDate>Sun, 29 Jun 2014 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p>This is a learning roadmap for Functional Programming (FP). There are quite a lot of resources to learn FP on the web (just like on any subject). So the challenge is not to find a resource to learn, but to find <em>quality</em> resources. This post is an attempt to compile those (obviously based on what helped me, and might be subjective to some extent).</p>
<h2 id="starting-point">Starting Point</h2>
<p>What you pick first is often important since unlearning is more difficult than learning. So start with the best - SICP. The <a href="http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/video-lectures/">course videos</a> as well as the <a href="http://mitpress.mit.edu/sicp/full-text/book/book.html">book</a> are freely available online.</p>
<h2 id="other-excellent-courses">Other excellent courses</h2>
<p>This can be followed up with some other good courses available online (at the time of writing):</p>
<ul>
<li><a href="https://courses.edx.org/courses/LouvainX/Louv1.01x/1T2014/info">The Paradigms of computer programming</a> has a section on FP. The course is also good overall, if you want to learn different paradigms of programming. Like SICP, the accompanying <a href="http://mitpress.mit.edu/books/concepts-techniques-and-models-computer-programming">text</a> is also a masterpiece.</li>
<li><a href="https://www.coursera.org/course/progfun">The functional programming course</a> offers a modern perspective based on <a href="http://scala-lang.org/">Scala</a>. Again highly recommended along with the <a href="http://www.artima.com/shop/programming_in_scala_2ed">book</a>.</li>
</ul>
<h2 id="short-bytes">Short bytes</h2>
<p>If you are looking for short insights into why FP is important or some key aspects of it, following videos are recommended:</p>
<ul>
<li><a href="http://www.infoq.com/presentations/Simple-Made-Easy">Simple Made Easy</a></li>
<li><a href="http://www.haskell.org/haskellwiki/Video_presentations#Introductions_to_Haskell">Introduction to Haskel</a> has couple of FP talks.</li>
<li><a href="http://www.youtube.com/watch?v=4L3cYhfSUZs">Reactive Programming</a> talk explains why FP is one of the best choices for <a href="http://www.reactivemanifesto.org/">reactive</a> programming.</li>
</ul>
<h2 id="thinking-functionally">Thinking functionally</h2>
<p>After you learn the basics, the most important skill needed is to think functionally. The best way to grok that is to get your hands dirty - do the exercises, apply it on the next programming task you do, etc.</p>
<p>Following are some good books which will deepen your knowledge on FP:</p>
<ul>
<li><a href="http://www.amazon.com/Introduction-Functional-Programming-Haskell-Edition/dp/0134843460">Introduction to Functional Programming</a>.</li>
<li><a href="http://learnyouahaskell.com/">Learn you a haskell</a>.</li>
</ul>
<p>Developing purely functional data structures is another art to master. Okasaki's <a href="http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504">Purely Functional Data Structures</a> is still the best resource in this area. This <a href="http://cstheory.stackexchange.com/questions/1539/whats-new-in-purely-functional-data-structures-since-okasaki">post</a> highlights some of the other functional data structures.</p>
<h2 id="interesting-papers">Interesting Papers</h2>
<ul>
<li><a href="http://www.cse.chalmers.se/~rjmh/Papers/whyfp.pdf">Why FP matters</a></li>
<li><a href="http://homepages.inf.ed.ac.uk/wadler/papers/essence/essence.ps">Essence of Monads</a>. I found this to be the best introduction to Monads.</li>
<li><a href="http://www-formal.stanford.edu/jmc/recursive/recursive.html">Original paper on Lisp</a></li>
<li><a href="http://www.cs.nott.ac.uk/~gmh/bib.html">All papers</a> by Graham Hutton are excellent. Its hard to pick and choose from them.</li>
<li>Somewhat advanced papers on <a href="http://www.haskell.org/haskellwiki/Research_papers/Functional_pearls">functional pearls</a>.</li>
</ul>
<h2 id="summing-up">Summing up</h2>
<p>These are just some pointers that came to my mind. If I missed anything important please let me know.</p>
<p>I hope this helps you in your functional programming journey!</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/learning/">Learning</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Purely functional Priority Queue</title>
                <link>https://amitdev.github.io/posts/2014-03-06-priority-queue/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2014-03-06-priority-queue/</guid>
                <pubDate>Thu, 06 Mar 2014 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p>This is part of a series of articles on implementing various functional data structures in Scala. See other articles in this series:</p>
<ul>
<li><a href="/posts/2013-12-31-functional-stack/">Functional Stacks</a></li>
<li><a href="/posts/2014-01-20-functional-set/">Functional Sets</a></li>
</ul>
<p>In this part we will implement a basic Priority Queue in Scala. It will support the following operations efficiently:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">abstract</span> <span class="k">class</span> <span class="nc">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">(</span><span class="k">implicit</span> <span class="k">val</span> <span class="n">ord</span><span class="k">:</span> <span class="kt">Ordering</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span> <span class="o">{</span>
  <span class="c1">// Add an item
</span><span class="c1"></span>  <span class="k">def</span> <span class="o">+</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">A</span><span class="o">)</span> <span class="k">:</span> <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span>
  <span class="c1">// Find min item
</span><span class="c1"></span>  <span class="k">def</span> <span class="n">findMin</span><span class="k">:</span> <span class="kt">A</span>
  <span class="c1">// New Priority queue with min item deleted
</span><span class="c1"></span>  <span class="k">def</span> <span class="n">deleteMin</span><span class="o">(</span><span class="o">)</span><span class="k">:</span> <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span>
  <span class="c1">// Merges two PriorityQueue together
</span><span class="c1"></span>  <span class="k">def</span> <span class="n">meld</span><span class="o">(</span><span class="n">that</span><span class="k">:</span> <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span> <span class="k">:</span> <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="basics">Basics</h2>
<p>There are <a href="http://en.wikipedia.org/wiki/Priority_queue#Usual_implementation">different</a> ways to implement a Priority Queue. We will use <a href="http://en.wikipedia.org/wiki/Binomial_heap">Binomial Heap</a>. As usual we follow the approach from Okasaki. See <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.48.973">this paper</a> for details about implementing efficient and purely functional priority queues. We start with the basic implementation which is simple to understand. If you know how Binomial heaps work, skip to the <a href="#implementation">next</a> section. Else read on.</p>
<p>A Binomial heap is a forest of Binomial trees. A binomial tree of rank 0 has just a single node and of rank k (k &gt; 0) has binomial trees of rank (0, 1, .. k-1) as its children. So it looks like (image from wikipedia):</p>
<img src="http://upload.wikimedia.org/wikipedia/commons/c/cf/Binomial_Trees.svg" style="width: 60%; height: 60%"/>
<p>Another way to think about binomial tree is: to get binomial tree of rank k, take binomial tree of rank k-1 and insert another tree of rank k-1 as a child to the first tree's root.</p>
<img src="/images/bt.svg" style="width: 60%; height: 60%"/>
<p>In any case, a Binomial heap of n elements would contain only trees of the above form and it will correspond to (k<sub>1</sub>, k<sub>2</sub>, ..k<sub>j</sub>) where k<sub>1</sub>k<sub>2</sub>..k<sub>j</sub> is the binary representation of n. So a heap of 5 (101) elements would have trees of rank 0 and 2. This means merging two binomial heap is similar to adding two binary numbers etc.</p>
<p>Ok, but how can we use a Binomial heap as a Priority Queue? Let's walk through an example and add the following items: (3, 5, 1, 2, 13, 15, 11, 12) in this order and see what we get:</p>
<p><img src="/images/bh3.svg" alt="drawing"></p>
<p>So you get the picture. Now to find the min element, we just need to walk through the roots of trees (<code>log(n)</code> items) and return the min. Adding an element is similar to adding 1 to a binary number and deletion is similar. Merging (aka melding) is like adding two binary numbers. In all operations all we need to make sure is that the root is properly selected (since that should always have the minimum).</p>
<p><a name="implementation"></a></p>
<h2 id="implementation">Implementation</h2>
<p>Now that the idea is clear, let's start writing some code. We have a concrete class <code>BinomialQueue</code> to represent the queue and a <code>Node</code> class to represent individual trees. Let's look at the <code>Node</code> class first:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">case</span> <span class="k">class</span> <span class="nc">Node</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">(</span><span class="n">data</span><span class="k">:</span> <span class="kt">A</span><span class="o">,</span> <span class="n">rank</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">0</span><span class="o">,</span> <span class="n">children</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Nil</span><span class="o">)</span>
                          <span class="o">(</span><span class="k">implicit</span> <span class="k">val</span> <span class="n">ord</span><span class="k">:</span> <span class="kt">Ordering</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">Ordered</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">]</span> <span class="o">{</span>

  <span class="k">def</span> <span class="n">link</span><span class="o">(</span><span class="n">other</span><span class="k">:</span> <span class="kt">Node</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span> <span class="k">=</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">ord</span><span class="o">.</span><span class="n">compare</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="n">other</span><span class="o">.</span><span class="n">data</span><span class="o">)</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="o">)</span> <span class="nc">Node</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="n">rank</span><span class="o">+</span><span class="mi">1</span><span class="o">,</span> <span class="n">other</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">children</span><span class="o">)</span>
    <span class="k">else</span> <span class="nc">Node</span><span class="o">(</span><span class="n">other</span><span class="o">.</span><span class="n">data</span><span class="o">,</span> <span class="n">other</span><span class="o">.</span><span class="n">rank</span><span class="o">+</span><span class="mi">1</span><span class="o">,</span> <span class="k">this</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">other</span><span class="kt">.</span><span class="kt">children</span><span class="o">)</span>

  <span class="k">override</span> <span class="k">def</span> <span class="n">compare</span><span class="o">(</span><span class="n">that</span><span class="k">:</span> <span class="kt">Node</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="n">ord</span><span class="o">.</span><span class="n">compare</span><span class="o">(</span><span class="n">data</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="n">data</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>For simplicity, every <code>Node</code> stores its rank and have data and list of children. It is ordered based on the data (which needs to have an implicit <code>Ordering</code>). Other than this we have a <code>link</code> method which links two <code>Node</code> together keeping the min element as new root. For example, in the above figure, when we insert <code>2</code>, we link <code>[1,2]</code> and <code>[3,5]</code> together and <code>1</code> gets to be the root.</p>
<p>Now we can define the <code>BinomialQueue</code> class:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">private</span> <span class="k">final</span> <span class="k">case</span> <span class="k">class</span> <span class="nc">BinomialQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="o">(</span><span class="n">nodes</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">]</span><span class="o">)</span>
                        <span class="o">(</span><span class="k">implicit</span> <span class="k">override</span> <span class="k">val</span> <span class="n">ord</span><span class="k">:</span> <span class="kt">Ordering</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span>
                        <span class="k">extends</span> <span class="nc">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="o">{</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="operations">Operations</h2>
<h4 id="insert">Insert</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="o">+</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">A</span><span class="o">)</span> <span class="k">:</span> <span class="kt">BinomialQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="nc">BinomialQueue</span><span class="o">(</span><span class="n">insertNode</span><span class="o">(</span><span class="nc">Node</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">,</span> <span class="n">nodes</span><span class="o">)</span><span class="o">)</span>

<span class="k">private</span> <span class="k">def</span> <span class="n">insertNode</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">n</span><span class="k">:</span> <span class="kt">Node</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">lst</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span><span class="o">)</span> <span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="n">lst</span> <span class="k">match</span> <span class="o">{</span>
  <span class="k">case</span> <span class="nc">Nil</span> <span class="k">=&gt;</span> <span class="nc">List</span><span class="o">(</span><span class="n">n</span><span class="o">)</span>
  <span class="k">case</span> <span class="n">x</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">xs</span> <span class="o">=&gt;</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">n</span><span class="o">.</span><span class="n">rank</span> <span class="o">&lt;</span> <span class="n">x</span><span class="o">.</span><span class="n">rank</span><span class="o">)</span> <span class="n">n</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">x</span> <span class="kt">::</span> <span class="kt">xs</span>
    <span class="k">else</span> <span class="n">insertNode</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">link</span><span class="o">(</span><span class="n">n</span><span class="o">)</span><span class="o">,</span> <span class="n">xs</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>We have 3 case to handle. Inserting to:</p>
<ul>
<li>Empty heap : Create a new List having a rank-0 Node (Eg. inserting 3 above)</li>
<li>Heap without a rank-0 node: Just add a rank-0 Node to our list (Eg. inserting 1, 13 etc above)</li>
<li>Heap with a rank-0 Node: Now we need to merge and recursively insert merged Node (Eg. inserting 5, 2 etc)</li>
</ul>
<h4 id="find-minimum">Find Minimum</h4>
<p>Just returns the <code>Node</code> with min element.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">findMin</span><span class="k">:</span> <span class="kt">A</span> <span class="o">=</span> <span class="n">nodes</span><span class="o">.</span><span class="n">min</span><span class="o">.</span><span class="n">data</span>
</code></pre></td></tr></table>
</div>
</div><h4 id="merge">Merge</h4>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">meld</span><span class="o">(</span><span class="n">that</span><span class="k">:</span> <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span> <span class="k">:</span> <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span>
  <span class="nc">BinomialQueue</span><span class="o">(</span><span class="n">meldLists</span><span class="o">(</span><span class="k">this</span><span class="o">.</span><span class="n">nodes</span><span class="o">,</span> <span class="n">that</span><span class="o">.</span><span class="n">nodes</span><span class="o">)</span><span class="o">)</span>

<span class="k">private</span> <span class="k">def</span> <span class="n">meldLists</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">q1</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span><span class="o">,</span> <span class="n">q2</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span><span class="o">)</span> <span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">Node</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="o">(</span><span class="n">q1</span><span class="o">,</span> <span class="n">q2</span><span class="o">)</span> <span class="k">match</span> <span class="o">{</span>
  <span class="k">case</span> <span class="o">(</span><span class="nc">Nil</span><span class="o">,</span> <span class="n">q</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">q</span>
  <span class="k">case</span> <span class="o">(</span><span class="n">q</span><span class="o">,</span> <span class="nc">Nil</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">q</span>
  <span class="k">case</span> <span class="o">(</span><span class="n">x</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">xs</span><span class="o">,</span> <span class="n">y</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">ys</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="k">if</span> <span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">rank</span> <span class="o">&lt;</span> <span class="n">y</span><span class="o">.</span><span class="n">rank</span><span class="o">)</span> <span class="n">x</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">meldLists</span><span class="o">(</span><span class="kt">xs</span><span class="o">,</span> <span class="kt">y</span> <span class="kt">::</span> <span class="kt">ys</span><span class="o">)</span>
  <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">rank</span> <span class="o">&gt;</span> <span class="n">y</span><span class="o">.</span><span class="n">rank</span><span class="o">)</span> <span class="n">y</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">meldLists</span><span class="o">(</span><span class="kt">x</span> <span class="kt">::</span> <span class="kt">xs</span><span class="o">,</span> <span class="kt">ys</span><span class="o">)</span>
  <span class="k">else</span> <span class="n">insertNode</span><span class="o">(</span><span class="n">x</span><span class="o">.</span><span class="n">link</span><span class="o">(</span><span class="n">y</span><span class="o">)</span><span class="o">,</span> <span class="n">meldLists</span><span class="o">(</span><span class="n">xs</span><span class="o">,</span> <span class="n">ys</span><span class="o">)</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>Logic is similar to insert: If a particular ranked node does not exist on one list we can just copy it to output. Same ranked Nodes are merged via linking them together.</p>
<h3 id="delete-minimum">Delete Minimum</h3>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">deleteMin</span><span class="o">(</span><span class="o">)</span><span class="k">:</span> <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">val</span> <span class="n">minNode</span> <span class="k">=</span> <span class="n">nodes</span><span class="o">.</span><span class="n">min</span>
  <span class="nc">BinomialQueue</span><span class="o">(</span><span class="n">meldLists</span><span class="o">(</span><span class="n">nodes</span><span class="o">.</span><span class="n">filter</span><span class="o">(</span><span class="k">_</span> <span class="o">!=</span> <span class="n">minNode</span><span class="o">)</span><span class="o">,</span> <span class="n">minNode</span><span class="o">.</span><span class="n">children</span><span class="o">.</span><span class="n">reverse</span><span class="o">)</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>Finds the min Node and removes it. The children of a Binary tree conveniently forms a Binary heap in reversed order, so we just merge that to other Nodes.</p>
<h2 id="adapting-to-scala-collections">Adapting to Scala Collections</h2>
<p>We are done and have a working Priority Queue implementation (we could make some operations more efficient by using Skew binary heaps, but thats for a later time). However, the other common operations on collections like iterating, map, filter etc are missing. Scala has a rich collections library and it is not difficult to reuse most of it for a new collection object. See this <a href="http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html">excellent</a> guide to understand the design of Scala collections and how to adapt your collection to use it.</p>
<p>In a nutshell we need to do two things: Provide a way to iterate over the items (<code>Traversable</code> or <code>Iterable</code>) and a way to build a new collection (<code>Builder</code>). There are also higher level of abstractions that make things easier. So we change the <code>PriorityQueue</code> definition as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">abstract</span> <span class="k">class</span> <span class="nc">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">(</span><span class="k">implicit</span> <span class="k">val</span> <span class="n">ord</span><span class="k">:</span> <span class="kt">Ordering</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span>
  <span class="k">extends</span> <span class="nc">Iterable</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span>
  <span class="k">with</span> <span class="nc">GenericOrderedTraversableTemplate</span><span class="o">[</span><span class="kt">A</span>, <span class="kt">PriorityQueue</span><span class="o">]</span>
  <span class="k">with</span> <span class="nc">IterableLike</span><span class="o">[</span><span class="kt">A</span>, <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">]</span> <span class="o">{</span>
</code></pre></td></tr></table>
</div>
</div><p>That's quite a mouthfull, so let's take it one by one. <a href="http://docs.scala-lang.org/overviews/collections/trait-iterable.html">Iterable</a> just defines an <code>iterator</code> method which yields elements of the collection in some order and an <code>isEmpty</code> method. We can implement it as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">override</span> <span class="k">def</span> <span class="n">isEmpty</span><span class="k">:</span> <span class="kt">Boolean</span> <span class="o">=</span> <span class="n">nodes</span><span class="o">.</span><span class="n">isEmpty</span>

<span class="c1">//Inside BinomialHeap
</span><span class="c1"></span><span class="k">override</span> <span class="k">def</span> <span class="n">iterator</span><span class="k">:</span> <span class="kt">Iterator</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="n">nodes</span><span class="o">.</span><span class="n">flatMap</span><span class="o">(</span><span class="k">_</span><span class="o">.</span><span class="n">toList</span><span class="o">)</span><span class="o">.</span><span class="n">iterator</span>

<span class="c1">//Inside Node:
</span><span class="c1"></span><span class="k">def</span> <span class="n">toList</span> <span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="k">=</span> <span class="n">data</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">children</span><span class="kt">.</span><span class="kt">flatMap</span><span class="o">(</span><span class="k">_</span><span class="kt">.</span><span class="kt">toList</span><span class="o">)</span>
</code></pre></td></tr></table>
</div>
</div><p><code>IterableLike</code> is for ensuring the same-result-type principle. <a href="http://www.scala-lang.org/api/2.10.3/index.html#scala.collection.generic.GenericOrderedTraversableTemplate">GenericOrderedTraversableTemplate</a> is an easy way to define the builder using a companion object for ordered collections. It has following methods to be implemented:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">override</span> <span class="k">def</span> <span class="n">orderedCompanion</span><span class="k">:</span> <span class="kt">GenericOrderedCompanion</span><span class="o">[</span><span class="kt">PriorityQueue</span><span class="o">]</span> <span class="k">=</span> <span class="nc">PriorityQueue</span>
<span class="k">override</span> <span class="k">protected</span><span class="o">[</span><span class="kt">this</span><span class="o">]</span> <span class="k">def</span> <span class="n">newBuilder</span><span class="k">:</span> <span class="kt">mutable.Builder</span><span class="o">[</span><span class="kt">A</span>, <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span>
                                                             <span class="nc">PriorityQueue</span><span class="o">.</span><span class="n">newBuilder</span>
</code></pre></td></tr></table>
</div>
</div><p>Basically we just need to tell which is the companion object where the builder is specified. Finally we need to define the companion object which defines how to build a <code>BinomialQueue</code> from other collections:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">object</span> <span class="nc">PriorityQueue</span> <span class="k">extends</span> <span class="nc">OrderedTraversableFactory</span><span class="o">[</span><span class="kt">PriorityQueue</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">override</span> <span class="k">def</span> <span class="n">newBuilder</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">(</span><span class="k">implicit</span> <span class="n">ord</span><span class="k">:</span> <span class="kt">Ordering</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span><span class="k">:</span>
                                 <span class="kt">mutable.Builder</span><span class="o">[</span><span class="kt">A</span>, <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span>
    <span class="k">new</span> <span class="nc">ArrayBuffer</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span> <span class="n">mapResult</span> <span class="o">{</span> <span class="n">xs</span> <span class="k">=&gt;</span>
      <span class="n">xs</span><span class="o">.</span><span class="n">foldLeft</span><span class="o">(</span><span class="nc">BinomialQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">(</span><span class="nc">Nil</span><span class="o">)</span><span class="o">)</span><span class="o">(</span><span class="o">(</span><span class="n">t</span><span class="o">,</span> <span class="n">x</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">t</span> <span class="o">+</span> <span class="n">x</span><span class="o">)</span>
    <span class="o">}</span>

  <span class="k">implicit</span> <span class="k">def</span> <span class="n">canBuildFrom</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">(</span><span class="k">implicit</span> <span class="n">ord</span><span class="k">:</span> <span class="kt">Ordering</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">)</span><span class="k">:</span>
   <span class="kt">CanBuildFrom</span><span class="o">[</span><span class="kt">Coll</span>, <span class="kt">A</span>, <span class="kt">PriorityQueue</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">GenericCanBuildFrom</span><span class="o">[</span><span class="kt">A</span><span class="o">]</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>Now we can use all the power of Scala collections.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">val</span> <span class="n">pq</span> <span class="k">=</span> <span class="nc">PriorityQueue</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span><span class="mi">2</span><span class="o">,</span><span class="mi">3</span><span class="o">,</span><span class="mi">4</span><span class="o">,</span><span class="mi">5</span><span class="o">,</span><span class="mi">6</span><span class="o">)</span>        <span class="c1">// BinomialQueue(5, 6, 1, 3, 4, 2)
</span><span class="c1"></span><span class="n">pq</span> <span class="n">map</span> <span class="o">(</span><span class="k">_</span> <span class="o">*</span> <span class="mi">2</span><span class="o">)</span> <span class="n">filter</span> <span class="o">(</span><span class="k">_</span> <span class="o">&lt;</span> <span class="mi">6</span><span class="o">)</span>              <span class="c1">// BinomialQueue(2, 4)
</span><span class="c1"></span><span class="k">val</span> <span class="n">sq</span> <span class="k">=</span> <span class="nc">PriorityQueue</span><span class="o">(</span><span class="s">&#34;a&#34;</span><span class="o">,</span> <span class="s">&#34;aa&#34;</span><span class="o">,</span> <span class="s">&#34;aaaaa&#34;</span><span class="o">)</span> <span class="c1">// BinomialQueue(aaaaa, a, aa)
</span><span class="c1"></span><span class="n">sq</span> <span class="n">map</span> <span class="o">(</span><span class="k">_</span><span class="o">.</span><span class="n">length</span><span class="o">)</span> <span class="n">reduce</span> <span class="o">(</span><span class="k">_</span><span class="o">*</span><span class="k">_</span><span class="o">)</span>             <span class="c1">// 10
</span><span class="c1"></span>
</code></pre></td></tr></table>
</div>
</div><p>Isn't that cool?</p>
<p>You can find the complete code <a href="https://github.com/amitdev/functional-ds/blob/master/src/main/scala/ds/PriorityQueue.scala">here</a>. The Binomial heap images were generated using <a href="https://github.com/amitdev/functional-ds/blob/master/src/main/scala/ds/PriorityQueueUtil.scala">this code</a>.
That's all for now, see you later!</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/programming/">Programming</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/scala/">scala</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Drawing Trees</title>
                <link>https://amitdev.github.io/posts/2014-01-24-augmented-data/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2014-01-24-augmented-data/</guid>
                <pubDate>Fri, 24 Jan 2014 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p>In the <a href="/posts/2014-01-20-functional-sets/">last article</a> we saw one way of implementing Binary Search Trees and Red Black Trees. This data structure can be used to implement a Set (like we saw before), but there are many other use cases if we can <em>augment</em> the data stored on the nodes. One example is a TreeMap which is a key-value store - similar to HashMap but with <em>log(n)</em> time guarantee for operations. Other <a href="http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-046j-introduction-to-algorithms-sma-5503-fall-2005/video-lectures/lecture-11-augmenting-data-structures-dynamic-order-statistics-interval-trees/lec11.pdf">examples</a> are Interval trees, dynamic order statistics etc.</p>
<h2 id="how-to-augment-the-data">How to Augment the Data</h2>
<p>Recall that a <code>Node</code> in our RBT looked like the following:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">case</span> <span class="k">class</span> <span class="nc">Node</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">color</span><span class="k">:</span> <span class="kt">Color</span><span class="o">,</span> <span class="n">v</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">left</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">right</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span>
</code></pre></td></tr></table>
</div>
</div><p>One way to augment the data is to subclass <code>Node</code> and add relevant data to that class. But there is a simpler approach. Note that in the above declaration, the data stored has an abstract type <code>T</code> whose only constraint is that it should be <code>Orderable</code>. So we could package all the data we need in <code>T</code> itself and provide appropriate ordering logic. For example, in case of a TreeMap, <code>T</code> can be a pair of (K, V) so that ordering is only done on K. A generic <code>AugmentedData</code> class can be written as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">case</span> <span class="k">class</span> <span class="nc">AugmentedData</span><span class="o">[</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span>, <span class="kt">U</span><span class="o">]</span><span class="o">(</span><span class="n">v</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">data</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span>
                              <span class="k">extends</span> <span class="nc">Ordered</span><span class="o">[</span><span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">U</span><span class="o">]</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">compare</span><span class="o">(</span><span class="n">that</span><span class="k">:</span> <span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="kt">U</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="k">this</span><span class="o">.</span><span class="n">v</span><span class="o">.</span><span class="n">compare</span><span class="o">(</span><span class="n">that</span><span class="o">.</span><span class="n">v</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>So an <code>AugmentedData</code> would have a value <code>v</code> which is orderable and additional <code>data</code> of some type <code>U</code>.</p>
<h2 id="example---drawing-trees">Example - Drawing Trees</h2>
<p>Let's look at an example where we augment data. Let's say we need to draw a given RBT (or BST). There are two logical steps to it:</p>
<ul>
<li>Identify position of each Node in the picture</li>
<li>Draw the picture</li>
</ul>
<p>We separate these two steps because drawing a picture can be done in different ways - as an image, in a terminal etc.</p>
<h3 id="step-1---finding-positions">Step 1 - Finding positions</h3>
<p>First we need to Augment the data stored in a <code>Node</code> to include its position (x,y) as well. Then we need to find and populate the positions.</p>
<p>We could just use the depth of a node in the tree as its vertical position (y-coordinate). Finding a horizontal position (x-coordinate) is slightly tricky and there are many different ways to do it. We will use the simple approach of taking a node's position in the inorder traversal of the tree. By definition, node on the left comes first and will have a lower x coordinate value than its root which will be lesser than its right child etc. This is not the best approach but suffices for our discussion.</p>
<p>We are going to define a function which takes a RBT node and gives back an RBT node which is the root of tree with augmented data. So it will look like:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">toPos</span><span class="o">[</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">node</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">d</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">80</span><span class="o">,</span> <span class="n">start</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">30</span><span class="o">)</span> <span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="o">(</span><span class="kt">Int</span>, <span class="kt">Int</span><span class="o">)</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="o">???</span>
</code></pre></td></tr></table>
</div>
</div><p>It has two additional parameters; to adjust the space between nodes: <code>d</code> and start position: <code>start</code>. To simplify things, we can use a helper function <code>calcPos</code> which finds the position and propogates it back.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">toPos</span><span class="o">[</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">node</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">d</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">80</span><span class="o">,</span> <span class="n">start</span><span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">30</span><span class="o">)</span> <span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="o">(</span><span class="kt">Int</span>, <span class="kt">Int</span><span class="o">)</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">calcPos</span><span class="o">(</span><span class="n">n</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">x</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span> <span class="n">y</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">RBT</span><span class="o">[</span><span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="o">(</span><span class="kt">Int</span>, <span class="kt">Int</span><span class="o">)</span><span class="o">]</span><span class="o">]</span><span class="o">,</span> <span class="nc">Int</span><span class="o">)</span> <span class="k">=</span> <span class="o">{</span>
    <span class="n">n</span> <span class="k">match</span> <span class="o">{</span>
      <span class="k">case</span> <span class="nc">Leaf</span> <span class="k">=&gt;</span> <span class="o">(</span><span class="nc">Leaf</span><span class="o">,</span> <span class="n">x</span><span class="o">)</span>
      <span class="k">case</span> <span class="nc">Node</span><span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="n">v</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="k">=&gt;</span>
        <span class="k">val</span> <span class="o">(</span><span class="n">leftTree</span><span class="o">,</span> <span class="n">myX</span><span class="o">)</span> <span class="k">=</span> <span class="n">calcPos</span><span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">y</span><span class="o">+</span><span class="n">d</span><span class="o">)</span>
        <span class="k">val</span> <span class="o">(</span><span class="n">rightTree</span><span class="o">,</span> <span class="n">nextX</span><span class="o">)</span> <span class="k">=</span> <span class="n">calcPos</span><span class="o">(</span><span class="n">right</span><span class="o">,</span> <span class="n">myX</span><span class="o">+</span><span class="n">d</span><span class="o">,</span> <span class="n">y</span><span class="o">+</span><span class="n">d</span><span class="o">)</span>
        <span class="o">(</span><span class="nc">Node</span><span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="nc">AugmentedData</span><span class="o">(</span><span class="n">v</span><span class="o">,</span> <span class="o">(</span><span class="n">myX</span><span class="o">,</span> <span class="n">y</span><span class="o">)</span><span class="o">)</span><span class="o">,</span> <span class="n">leftTree</span><span class="o">,</span> <span class="n">rightTree</span><span class="o">)</span><span class="o">,</span> <span class="n">nextX</span><span class="o">)</span>
    <span class="o">}</span>
  <span class="o">}</span>
  <span class="n">calcPos</span><span class="o">(</span><span class="n">node</span><span class="o">,</span> <span class="n">start</span><span class="o">,</span> <span class="n">start</span><span class="o">)</span><span class="o">.</span><span class="n">_1</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h3 id="step-2---drawing-the-tree">Step 2 - Drawing the Tree</h3>
<p>Once we have the positions, drawing a tree is trivial. A natural way to represent the tree is using <a href="http://en.wikipedia.org/wiki/Scalable_Vector_Graphics">SVG</a> format. Since it is xml the tree structure can be directly represented. Scala also support XML literals which makes things easier.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">toSvg</span><span class="o">[</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">node</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="o">(</span><span class="kt">Int</span>, <span class="kt">Int</span><span class="o">)</span><span class="o">]</span><span class="o">]</span><span class="o">,</span>
                         <span class="n">width</span> <span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">640</span><span class="o">,</span> <span class="n">height</span> <span class="k">:</span> <span class="kt">Int</span> <span class="o">=</span> <span class="mi">480</span><span class="o">)</span><span class="k">:</span> <span class="kt">NodeSeq</span> <span class="o">=</span> <span class="o">{</span>

  <span class="k">val</span> <span class="n">rgb</span> <span class="k">=</span> <span class="nc">Map</span><span class="o">[</span><span class="kt">Color</span>, <span class="kt">String</span><span class="o">]</span><span class="o">(</span><span class="nc">Black</span> <span class="o">-&gt;</span> <span class="s">&#34;#000000&#34;</span><span class="o">,</span> <span class="nc">Red</span> <span class="o">-&gt;</span> <span class="s">&#34;#7f0000&#34;</span><span class="o">)</span>

  <span class="k">def</span> <span class="n">genNode</span><span class="o">(</span><span class="n">n</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="o">(</span><span class="kt">Int</span>, <span class="kt">Int</span><span class="o">)</span><span class="o">]</span><span class="o">]</span><span class="o">,</span> <span class="n">x</span><span class="k">:</span> <span class="kt">Int</span><span class="o">,</span> <span class="n">y</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span><span class="k">:</span> <span class="kt">NodeSeq</span> <span class="o">=</span>
    <span class="n">n</span> <span class="k">match</span> <span class="o">{</span>
      <span class="k">case</span> <span class="nc">Node</span><span class="o">(</span><span class="k">_</span><span class="o">,</span> <span class="nc">AugmentedData</span><span class="o">(</span><span class="k">_</span><span class="o">,</span> <span class="o">(</span><span class="n">lx</span><span class="o">,</span> <span class="n">ly</span><span class="o">)</span><span class="o">)</span><span class="o">,</span> <span class="k">_</span><span class="o">,</span> <span class="k">_</span><span class="o">)</span> <span class="k">=&gt;</span>
        <span class="o">&lt;</span><span class="n">line</span> <span class="n">id</span><span class="o">=</span><span class="s">&#34;svg_1&#34;</span> <span class="n">y2</span><span class="o">=</span><span class="o">{</span><span class="n">y</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">x2</span><span class="o">=</span><span class="o">{</span><span class="n">x</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">y1</span><span class="o">=</span><span class="o">{</span><span class="n">ly</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span>
              <span class="n">x1</span><span class="o">=</span><span class="o">{</span><span class="n">lx</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">stroke</span><span class="o">-</span><span class="n">width</span><span class="o">=</span><span class="s">&#34;3&#34;</span> <span class="n">stroke</span><span class="o">=</span><span class="s">&#34;#000000&#34;</span> <span class="n">fill</span><span class="o">=</span><span class="s">&#34;none&#34;</span><span class="o">/&gt;</span> <span class="o">++</span>
        <span class="n">genSvg</span><span class="o">(</span><span class="n">n</span><span class="o">)</span>
      <span class="k">case</span> <span class="nc">Leaf</span> <span class="k">=&gt;</span> <span class="o">&lt;!--</span> <span class="n">leaf</span> <span class="o">--&gt;</span>
  <span class="o">}</span>

  <span class="k">def</span> <span class="n">genSvg</span><span class="o">(</span><span class="n">n</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">AugmentedData</span><span class="o">[</span><span class="kt">T</span>, <span class="o">(</span><span class="kt">Int</span>, <span class="kt">Int</span><span class="o">)</span><span class="o">]</span><span class="o">]</span><span class="o">)</span> <span class="k">:</span> <span class="kt">NodeSeq</span> <span class="o">=</span> <span class="n">n</span> <span class="k">match</span> <span class="o">{</span>
    <span class="k">case</span> <span class="nc">Node</span><span class="o">(</span><span class="n">c</span><span class="o">,</span> <span class="nc">AugmentedData</span><span class="o">(</span><span class="n">t</span><span class="o">,</span> <span class="o">(</span><span class="n">x</span><span class="o">,</span> <span class="n">y</span><span class="o">)</span><span class="o">)</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="k">=&gt;</span>
      <span class="n">genNode</span><span class="o">(</span><span class="n">left</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">y</span><span class="o">)</span> <span class="o">++</span>
      <span class="n">genNode</span><span class="o">(</span><span class="n">right</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">y</span><span class="o">)</span> <span class="o">++</span>
      <span class="o">&lt;</span><span class="n">ellipse</span> <span class="n">stroke</span><span class="o">=</span><span class="o">{</span><span class="n">rgb</span><span class="o">(</span><span class="n">c</span><span class="o">)</span><span class="o">}</span> <span class="n">fill</span><span class="o">=</span><span class="o">{</span><span class="n">rgb</span><span class="o">(</span><span class="n">c</span><span class="o">)</span><span class="o">}</span> <span class="n">cy</span><span class="o">=</span><span class="o">{</span><span class="n">y</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">cx</span><span class="o">=</span><span class="o">{</span><span class="n">x</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span>
               <span class="n">ry</span><span class="o">=</span><span class="s">&#34;20&#34;</span> <span class="n">rx</span><span class="o">=</span><span class="s">&#34;20&#34;</span> <span class="n">stroke</span><span class="o">-</span><span class="n">width</span><span class="o">=</span><span class="s">&#34;5&#34;</span><span class="o">/&gt;</span> <span class="o">++</span>
      <span class="o">&lt;</span><span class="n">text</span> <span class="n">xml</span><span class="k">:</span><span class="kt">space</span><span class="o">=</span><span class="s">&#34;preserve&#34;</span> <span class="n">text</span><span class="o">-</span><span class="n">anchor</span><span class="o">=</span><span class="s">&#34;middle&#34;</span> <span class="n">font</span><span class="o">-</span><span class="n">family</span><span class="o">=</span><span class="s">&#34;serif&#34;</span>
            <span class="n">font</span><span class="o">-</span><span class="n">size</span><span class="o">=</span><span class="s">&#34;24&#34;</span> <span class="n">y</span><span class="o">=</span><span class="o">{</span><span class="o">(</span><span class="n">y</span><span class="o">+</span><span class="mi">7</span><span class="o">)</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">x</span><span class="o">=</span><span class="o">{</span><span class="n">x</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">stroke</span><span class="o">=</span><span class="s">&#34;#ffffff&#34;</span>
            <span class="n">fill</span><span class="o">=</span><span class="s">&#34;#ffffff&#34;</span><span class="o">&gt;</span><span class="o">{</span><span class="n">t</span><span class="o">}</span><span class="o">&lt;/</span><span class="n">text</span><span class="o">&gt;</span>
    <span class="k">case</span> <span class="nc">Leaf</span> <span class="k">=&gt;</span> <span class="o">&lt;!--</span> <span class="n">leaf</span> <span class="o">--&gt;</span>
  <span class="o">}</span>
  <span class="o">&lt;</span><span class="n">svg</span> <span class="n">width</span><span class="o">=</span><span class="o">{</span><span class="n">width</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">height</span><span class="o">=</span><span class="o">{</span><span class="n">height</span><span class="o">.</span><span class="n">toString</span><span class="o">}</span> <span class="n">xmlns</span><span class="o">=</span><span class="s">&#34;http://www.w3.org/2000/svg&#34;</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">g</span><span class="o">&gt;</span>
      <span class="o">&lt;</span><span class="n">title</span><span class="o">&gt;</span><span class="nc">RBT</span><span class="o">&lt;/</span><span class="n">title</span><span class="o">&gt;</span>
      <span class="o">{</span><span class="n">genSvg</span><span class="o">(</span><span class="n">node</span><span class="o">)</span><span class="o">}</span>
    <span class="o">&lt;/</span><span class="n">g</span><span class="o">&gt;</span>
  <span class="o">&lt;/</span><span class="n">svg</span><span class="o">&gt;</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>This produces svg images like the following:</p>
<img src="/images/r.svg" alt="1" style="width: 50%; height: 50%"/>
<p>See the complete code <a href="https://github.com/amitdev/functional-ds/blob/master/src/main/scala/ds/SetUtil.scala">here</a>.</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/programming/">Programming</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/scala/">scala</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>A basic, immutable Set in Scala</title>
                <link>https://amitdev.github.io/posts/2014-01-20-functional-set/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2014-01-20-functional-set/</guid>
                <pubDate>Mon, 20 Jan 2014 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p>In the <a href="/posts/2013-12-31-functional-stack/">last article</a> we saw one way of implementing an object-functional, immutable Stack data structure. Now let's see how to implement a Set data structure. A Set is a container which supports the following operations efficiently:</p>
<ul>
<li><code>insert</code>: adds a new item to the Set</li>
<li><code>delete</code>: removes given item from the Set</li>
<li><code>member</code>: check if a given item is in the Set</li>
</ul>
<p>As we did before with the Stack, we can define this behavior in a Trait like the following:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">trait</span> <span class="nc">Set</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">item</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Set</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">delete</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">item</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Set</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">member</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">item</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Boolean</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="ordering">Ordering</h2>
<p>We are planning to implement the Set using <a href="http://en.wikipedia.org/wiki/Binary_search_tree">Binary Search Trees</a> (BST) which means elements in the Set needs to be comparable (or can be ordered). One way to do it is by constraining the type <code>T</code> to be a subclass of <code>Ordered[T]</code>. But a more lenient approach is to allow the caller to use any type as long as it can be <a href="http://www.artima.com/pins1ed/implicit-conversions-and-parameters.html">implicitly</a> converted to an <code>Ordered[T]</code>. Scala provides syntactic sugar for doing this easily called <a href="http://twitter.github.io/scala_school/advanced-types.html">view bounds</a> using which we can define the type as <code>+T &lt;% Ordered[T]</code>. Since an implicit parameter needs to be passed under the hood, we define <code>Set</code> as an abstract class. A partial definition will look like the following:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">Set</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span> <span class="k">&lt;%</span> <span class="kt">Ordered</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="k">&lt;%</span> <span class="kt">Ordered</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Set</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>There are <a href="https://issues.scala-lang.org/browse/SI-7629">plans</a> to deprecate view bounds from Scala. We could use the equivalent:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">Set</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="k">implicit</span> <span class="n">t2ord</span><span class="k">:</span> <span class="kt">T</span> <span class="o">=&gt;</span> <span class="nc">Ordered</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span><span class="o">(</span><span class="k">implicit</span> <span class="n">u2ord</span> <span class="k">:</span> <span class="kt">U</span> <span class="o">=&gt;</span> <span class="nc">Ordered</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Set</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>This is a bit verbose since we have to repeat the implicit parameter at multiple places.  A better option is to use <a href="http://stackoverflow.com/questions/2982276/what-is-a-context-bound-in-scala">context bounds</a>. We can also define a type alias for <code>T =&gt; Ordered[T]</code> to simplify things:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">type</span> <span class="kt">Orderable</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span> <span class="k">=</span> <span class="n">T</span> <span class="k">=&gt;</span> <span class="nc">Ordered</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span>

<span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">Set</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Set</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">delete</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Set</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">member</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">Boolean</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="unbalanced-bst">Unbalanced BST</h2>
<p>Now that we are done with defining proper types, let's start with the actual implementation. We will first implement an unbalanced version. A BST node can either be a <code>Leaf</code> which is a sentinel for empty, or a <code>Node</code> which has a value, left tree and right tree. Once we have this, implementing the operations recursively is trivial since the structure of the tree is also recursive. For instance, to insert a value we need to compare with the root and if the value is less insert on left tree otherwise on right tree etc.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">abstract</span> <span class="k">class</span> <span class="nc">BST</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span> <span class="nc">extends</span> <span class="nc">Set</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">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
<span class="o">}</span>

<span class="k">object</span> <span class="nc">BST</span> <span class="o">{</span>
  <span class="k">class</span> <span class="nc">Leaf</span> <span class="k">extends</span> <span class="nc">BST</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span> <span class="o">{</span>
    <span class="k">def</span> <span class="n">member</span><span class="o">[</span><span class="kt">U</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">=</span> <span class="kc">false</span>
    <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Node</span><span class="o">(</span><span class="n">x</span><span class="o">,</span> <span class="nc">Leaf</span><span class="o">,</span> <span class="nc">Leaf</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">class</span> <span class="nc">Node</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">y</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">left</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">right</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">BST</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">member</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">=</span>
                               <span class="k">if</span> <span class="o">(</span><span class="n">x</span> <span class="o">&lt;</span> <span class="n">y</span><span class="o">)</span> <span class="n">left</span><span class="o">.</span><span class="n">member</span><span class="o">(</span><span class="n">x</span><span class="o">)</span>
                               <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="n">y</span><span class="o">)</span> <span class="n">right</span><span class="o">.</span><span class="n">member</span><span class="o">(</span><span class="n">x</span><span class="o">)</span>
                               <span class="k">else</span> <span class="kc">true</span>

    <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span>
                               <span class="k">if</span> <span class="o">(</span><span class="n">x</span> <span class="o">&lt;</span> <span class="n">y</span><span class="o">)</span> <span class="nc">Node</span><span class="o">(</span><span class="n">y</span><span class="o">,</span> <span class="n">left</span><span class="o">.</span><span class="n">insert</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>
                               <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="n">y</span><span class="o">)</span> <span class="nc">Node</span><span class="o">(</span><span class="n">y</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">.</span><span class="n">insert</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">)</span>
                               <span class="k">else</span> <span class="k">this</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>As is the case with persistent data structures, the operations will result in new copies with potential sharing of structure. For instance, if we insert a value which is less than that in root node, the complete right subtree can be shared etc.</p>
<h3 id="deletion">Deletion</h3>
<p>Deleting a node from BST is slightly more <a href="http://en.wikipedia.org/wiki/Binary_search_tree#Deletion">complex</a>. One way is to replace the deleted node with its inorder predecessor. Additionally we need to reconstruct the subtree containing the deleted and predecessor nodes since our data structure is immutable. There are special cases to consider like one or both children being empty which can be handled by the <code>Leaf</code> object. In the following implementation we use <code>delete</code> method to locate the node to be deleted and <code>deleteCurrent</code> to actually replace stuff. It uses a recursive <code>fixNodes</code> function which finds the predecessor and propagates it back to deleted node rebuilding the tree.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">class</span> <span class="nc">Leaf</span> <span class="k">extends</span> <span class="nc">BST</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">delete</span><span class="o">[</span><span class="kt">U</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="k">this</span>
  <span class="k">protected</span> <span class="k">def</span> <span class="n">deleteCurrent</span><span class="o">[</span><span class="kt">U</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span> <span class="k">=</span> <span class="n">t</span>
  <span class="k">protected</span> <span class="k">def</span> <span class="n">fixNodes</span><span class="o">[</span><span class="kt">U</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span> <span class="k">=</span> <span class="kc">null</span>
<span class="o">}</span>

<span class="k">class</span> <span class="nc">Node</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">y</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">left</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">right</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">BST</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">delete</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span>
                    <span class="k">if</span> <span class="o">(</span><span class="n">x</span> <span class="o">&lt;</span> <span class="n">y</span><span class="o">)</span> <span class="nc">Node</span><span class="o">(</span><span class="n">y</span><span class="o">,</span> <span class="n">left</span><span class="o">.</span><span class="n">delete</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span>
                    <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">x</span> <span class="o">&gt;</span> <span class="n">y</span><span class="o">)</span> <span class="nc">Node</span><span class="o">(</span><span class="n">y</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">.</span><span class="n">delete</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">)</span>
                    <span class="k">else</span> <span class="n">left</span><span class="o">.</span><span class="n">deleteCurrent</span><span class="o">(</span><span class="n">right</span><span class="o">)</span>

  <span class="k">protected</span> <span class="k">def</span> <span class="n">fixNodes</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span> <span class="k">:</span> <span class="o">(</span><span class="kt">U</span><span class="o">,</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">val</span> <span class="n">r</span> <span class="k">=</span> <span class="n">right</span><span class="o">.</span><span class="n">fixNodes</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">r</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
      <span class="k">val</span> <span class="o">(</span><span class="n">ny</span><span class="o">,</span> <span class="n">nr</span><span class="o">)</span> <span class="k">=</span> <span class="n">r</span>
      <span class="o">(</span><span class="n">ny</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="n">y</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">nr</span><span class="o">)</span><span class="o">)</span>
    <span class="o">}</span> <span class="k">else</span> <span class="o">(</span><span class="n">y</span><span class="o">,</span> <span class="n">left</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">protected</span> <span class="k">def</span> <span class="n">deleteCurrent</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">val</span> <span class="o">(</span><span class="n">ny</span><span class="o">,</span> <span class="n">nl</span><span class="o">)</span> <span class="k">=</span> <span class="n">fixNodes</span>
    <span class="nc">Node</span><span class="o">(</span><span class="n">ny</span><span class="o">,</span> <span class="n">nl</span><span class="o">,</span> <span class="n">t</span><span class="o">)</span>
  <span class="o">}</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="balanced-bst">Balanced BST</h2>
<p>As you would know, we need a better solution to work efficiently on all inputs. The tree operations take <code>O(d)</code> time where d is the depth of the tree. If we insert <em>n</em> items which are in sorted order, we create a tree with depth <em>n</em> which makes the operations linear time. To avoid this, we need to keep the tree balanced so that the depth is roughly <em>log(n)</em>. There are multiple ways to do this like AVL trees, Red Black trees(RBT) etc. We will consider a Red black tree implementation here.</p>
<p>Okasaki gives an elegant implementation of RBT in the <a href="http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504">book</a> (If you don't have a copy see <a href="http://www.cs.tufts.edu/~nr/cs257/archive/chris-okasaki/redblack99.ps">this</a> paper). As usual, we will adopt the solution to Scala and it is natural to extend from the <code>BST</code>, <code>Leaf</code> and <code>Node</code> classes which we already have. We need an additional method <code>balancedInsert</code> to take care of balancing, so let's create a Trait to capture RBT specific stuff:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">trait</span> <span class="nc">RBT</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span> <span class="nc">extends</span> <span class="nc">BST</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">balancedInsert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>RBT is a BST with the following additional properties which guarantees that the tree remains balanced:</p>
<ol>
<li>Every node is either Red or Black. The <code>Leaf</code> nodes are black by convention.</li>
<li>A red node cannot have a red parent</li>
<li>Every path from root to leaf should have same no.of black nodes.</li>
</ol>
<p><code>balancedInsert</code> makes sure that (2) and (3) above are not violated when inserting an item. We start defining the <code>Node</code> for RBT as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">Color</span>
<span class="k">case</span> <span class="k">object</span> <span class="nc">Red</span> <span class="k">extends</span> <span class="nc">Color</span>
<span class="k">case</span> <span class="k">object</span> <span class="nc">Black</span> <span class="k">extends</span> <span class="nc">Color</span>

<span class="k">case</span> <span class="k">class</span> <span class="nc">Node</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">color</span><span class="k">:</span> <span class="kt">Color</span><span class="o">,</span> <span class="n">v</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">left</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">,</span> <span class="n">right</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span>
                                <span class="k">extends</span> <span class="nc">BST</span><span class="o">.</span><span class="nc">Node</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">v</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span> <span class="k">with</span> <span class="nc">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span> <span class="o">{</span>

  <span class="k">override</span> <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">e</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
    <span class="k">val</span> <span class="nc">Node</span><span class="o">(</span><span class="k">_</span><span class="o">,</span> <span class="n">a1</span><span class="o">,</span><span class="n">a2</span><span class="o">,</span><span class="n">a3</span><span class="o">)</span> <span class="k">=</span> <span class="n">balancedInsert</span><span class="o">(</span><span class="n">e</span><span class="o">)</span>
    <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">a1</span><span class="o">,</span> <span class="n">a2</span><span class="o">,</span> <span class="n">a3</span><span class="o">)</span>
  <span class="o">}</span>

<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>Note that we don't need to define the <code>member</code> function here. The behavior is same as that of a <code>BST</code> and since we inherit from <code>BST.Node</code> we get that for free. We override <code>insert</code> and make sure we balance things when something is inserted if needed. Finally we maintain the invariant that the root node is always Black.</p>
<p>Let's define the <code>Leaf</code> for RBT which is simple enough:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">case</span> <span class="k">object</span> <span class="nc">Leaf</span> <span class="k">extends</span> <span class="nc">BST</span><span class="o">.</span><span class="nc">Leaf</span> <span class="k">with</span> <span class="nc">RBT</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">override</span> <span class="k">def</span> <span class="n">insert</span><span class="o">[</span><span class="kt">U</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span> <span class="k">=</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="nc">Leaf</span><span class="o">,</span> <span class="nc">Leaf</span><span class="o">)</span>
  <span class="k">def</span> <span class="n">balancedInsert</span><span class="o">[</span><span class="kt">U</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">x</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span>  <span class="k">=</span> <span class="n">insert</span><span class="o">(</span><span class="n">x</span><span class="o">)</span>
<span class="o">}</span>

</code></pre></td></tr></table>
</div>
</div><p>So far we haven't done much in RBT and once we define <code>balancedInsert</code> we are done! Of course balancing the tree is the heart of <code>insert</code> operation. As discussed in the paper, we just need to handle balancing (by rotation) in four cases:</p>
<img src="/images/rbt.svg" alt="Balancing Cases" style="width: 60%; height: 60%"/>
<p>This can be declaratively expressed in code, thanks to pattern matching as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">balancedInsert</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">e</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">balance</span><span class="o">(</span><span class="n">cn</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">RBT</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="n">cn</span> <span class="k">match</span> <span class="o">{</span>
    <span class="k">case</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span><span class="o">,</span> <span class="n">c</span><span class="o">)</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span> <span class="k">=&gt;</span>
      <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span><span class="o">)</span>
    <span class="k">case</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="n">b</span><span class="o">,</span> <span class="n">c</span><span class="o">)</span><span class="o">)</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span> <span class="k">=&gt;</span>
      <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span><span class="o">)</span>
    <span class="k">case</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="n">b</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span><span class="o">)</span><span class="o">)</span> <span class="k">=&gt;</span>
      <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span><span class="o">)</span>
    <span class="k">case</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="n">b</span><span class="o">,</span> <span class="n">c</span><span class="o">)</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span><span class="o">)</span> <span class="k">=&gt;</span>
      <span class="nc">Node</span><span class="o">(</span><span class="nc">Red</span><span class="o">,</span> <span class="n">y</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">x</span><span class="o">,</span> <span class="n">a</span><span class="o">,</span> <span class="n">b</span><span class="o">)</span><span class="o">,</span> <span class="nc">Node</span><span class="o">(</span><span class="nc">Black</span><span class="o">,</span> <span class="n">z</span><span class="o">,</span> <span class="n">c</span><span class="o">,</span> <span class="n">d</span><span class="o">)</span><span class="o">)</span>
    <span class="k">case</span> <span class="n">c</span> <span class="k">=&gt;</span> <span class="n">c</span>
  <span class="o">}</span>

  <span class="k">if</span> <span class="o">(</span><span class="n">e</span> <span class="o">&lt;</span> <span class="n">v</span><span class="o">)</span> <span class="n">balance</span><span class="o">(</span><span class="nc">Node</span><span class="o">(</span><span class="n">color</span><span class="o">,</span> <span class="n">v</span><span class="o">,</span> <span class="n">left</span><span class="o">.</span><span class="n">balancedInsert</span><span class="o">(</span><span class="n">e</span><span class="o">)</span><span class="o">,</span> <span class="n">right</span><span class="o">)</span><span class="o">)</span>
  <span class="k">else</span> <span class="k">if</span> <span class="o">(</span><span class="n">e</span> <span class="o">&gt;</span> <span class="n">v</span><span class="o">)</span> <span class="n">balance</span><span class="o">(</span><span class="nc">Node</span><span class="o">(</span><span class="n">color</span><span class="o">,</span> <span class="n">v</span><span class="o">,</span> <span class="n">left</span><span class="o">,</span> <span class="n">right</span><span class="o">.</span><span class="n">balancedInsert</span><span class="o">(</span><span class="n">e</span><span class="o">)</span><span class="o">)</span><span class="o">)</span>
  <span class="k">else</span> <span class="k">this</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p><code>balance</code> does the actual rotation and it corresponds as is to the above diagram. This, in fact, is the heart of the algorithm. Most of the other things we talked about are about how we organize code cleanly, adding flexible type support etc.</p>
<p>Side Note: We didn't tackle deletion of a node here. Implementing the <code>delete</code> operation is slightly involved for <code>RBT</code>. See <a href="http://matt.might.net/articles/red-black-delete/">this</a> post to see how it can be done.</p>
<h2 id="example">Example</h2>
<p>Let's see a sample tree construction to see how it works. Assume we insert 1,2,3,4 in this order, we get something like the following:</p>
<img src="/images/s.svg" alt="1" style="width: 80%; height: 80%"/>
<p>We are only discussing the very basic operations of the data structure here. Using this other convenience functions can be easily added. For example, we can add an <code>apply</code> function to help creating a Set from its arguments as follows:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">def</span> <span class="n">apply</span><span class="o">[</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="n">xs</span><span class="k">:</span> <span class="kt">T</span><span class="kt">*</span><span class="o">)</span> <span class="k">=</span> <span class="n">xs</span><span class="o">.</span><span class="n">foldLeft</span><span class="o">(</span><span class="nc">Leaf</span><span class="o">.</span><span class="n">asInstanceOf</span><span class="o">[</span><span class="kt">RBT</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span><span class="o">)</span><span class="o">(</span><span class="o">(</span><span class="n">t</span><span class="o">,</span> <span class="n">x</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">t</span><span class="o">.</span><span class="n">insert</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">)</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="testing">Testing</h2>
<p>As we did before, tests using <a href="http://www.scalacheck.org/">Scalacheck</a> can be written once we have a generator of random trees.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">implicit</span> <span class="k">def</span> <span class="n">arbBST</span><span class="o">[</span><span class="kt">T</span> <span class="kt">:</span> <span class="kt">Orderable</span><span class="o">]</span><span class="o">(</span><span class="k">implicit</span> <span class="n">a</span><span class="k">:</span> <span class="kt">Arbitrary</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span> <span class="k">=</span> <span class="nc">Arbitrary</span> <span class="o">{</span>
  <span class="k">for</span> <span class="o">{</span>
    <span class="n">v</span> <span class="k">&lt;-</span> <span class="nc">Arbitrary</span><span class="o">.</span><span class="n">arbitrary</span><span class="o">[</span><span class="kt">List</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span>
  <span class="o">}</span> <span class="k">yield</span> <span class="nc">BST</span><span class="o">(</span><span class="n">v</span><span class="k">:</span><span class="k">_</span><span class="kt">*</span><span class="o">)</span>
<span class="o">}</span>

<span class="n">test</span><span class="o">(</span><span class="s">&#34;Set Insert&#34;</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">check</span><span class="o">(</span><span class="o">(</span><span class="n">s</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">,</span> <span class="n">x</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">s</span><span class="o">.</span><span class="n">insert</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">.</span><span class="n">member</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">)</span>
<span class="o">}</span>

<span class="n">test</span><span class="o">(</span><span class="s">&#34;Set delete&#34;</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">check</span><span class="o">(</span><span class="o">(</span><span class="n">s</span><span class="k">:</span> <span class="kt">BST</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">,</span> <span class="n">x</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="o">!</span><span class="n">s</span><span class="o">.</span><span class="n">delete</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">.</span><span class="n">member</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">)</span>
<span class="o">}</span>

</code></pre></td></tr></table>
</div>
</div><p>That's all for now. See the complete code for <a href="https://github.com/amitdev/functional-ds/blob/master/src/main/scala/ds/Set.scala">Set</a>. Scala standard library also provides an implementation of <a href="https://github.com/scala/scala/blob/master/src/library/scala/collection/immutable/RedBlackTree.scala">RBT</a> in a different style.</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/programming/">Programming</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/scala/">scala</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>A basic, immutable Stack in Scala</title>
                <link>https://amitdev.github.io/posts/2013-12-31-functional-stack/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/2013-12-31-functional-stack/</guid>
                <pubDate>Tue, 31 Dec 2013 00:00:00 +0000</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p><a href="http://scala-lang.org/">Scala</a> was one language that I played around with many years back (and <a href="http://memuser.blogspot.in/search/label/Scala">blogged</a> about then). Recently, I took the excellent <a href="https://www.coursera.org/course/reactive">course</a> on reactive programming which rekindled my interest in Scala and I decided to brush up my knowledge on it as well as functional programming. I also happen to be reading what seems to be the best resource on functional data structures - Chris Okasaki's <a href="http://www.amazon.com/Purely-Functional-Structures-Chris-Okasaki/dp/0521663504">Purely Functional Data Structures</a>. This blog is an introduction on how to implement some of those data structures in Scala. Since Scala is a general purpose programming language with an objective to fuse object oriented and functional programming, our implementation will follow that approach. It is also possible to do pure functional programming in Scala without bringing in object orientation, but that's not our focus here. So I'll call this implementation object-functional versus purely functional, but the properties are the same, the differences are only in the way code is organized.</p>
<h2 id="stack">Stack</h2>
<p>We start with implementation of a really simple data structure. It is a container which supports the following operation:</p>
<ul>
<li><code>cons</code>: adds a new item to the container</li>
<li><code>head</code> : get last inserted item</li>
<li><code>tail</code> : get rest of the items</li>
<li><code>isEmpty</code>: the container is empty or not</li>
</ul>
<p>You can think of it as a <a href="http://en.wikipedia.org/wiki/Cons">cons list</a> or Stack as Okasaki calls it. Before thinking about implementation, we can capture the behavior in a Trait like so:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">trait</span> <span class="nc">Stack</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">isEmpty</span><span class="k">:</span> <span class="kt">Boolean</span>
  <span class="k">def</span> <span class="n">cons</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="kt">Stack</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">head</span><span class="k">:</span> <span class="kt">T</span>
  <span class="k">def</span> <span class="n">tail</span><span class="k">:</span> <span class="kt">Stack</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="digression-variance">Digression: Variance</h2>
<p>In Scala, the type parameters are invariant by default, which means if you have a <code>Stack[Shape]</code>, you cannot add a <code>Circle</code> to it though <code>Circle</code> is a subclass of <code>Shape</code>. For immutable collections it is better to have this behavior, so we need to make it covariant which can be easily done by adding a <code>+</code> to the type parameter. When you do that, <code>Stack[Shape]</code> will behave like a superclass of <code>Stack[Circle]</code>. But this also means that the following is possible:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">val</span> <span class="n">onlyCircles</span><span class="k">:</span> <span class="kt">Stack</span><span class="o">[</span><span class="kt">Circle</span><span class="o">]</span> <span class="k">=</span> <span class="o">.</span><span class="o">.</span><span class="o">.</span>
<span class="k">val</span> <span class="n">shapes</span><span class="k">:</span> <span class="kt">Stack</span><span class="o">[</span><span class="kt">Shape</span><span class="o">]</span> <span class="k">=</span> <span class="n">onlyCircles</span>
<span class="n">shapes</span><span class="o">.</span><span class="n">cons</span><span class="o">(</span><span class="k">new</span> <span class="nc">Square</span><span class="o">)</span>
</code></pre></td></tr></table>
</div>
</div><p>This is clearly a problem so Scala compiler will prevent you from creating such an <code>cons</code> function. In the example above, <code>cons</code> should ensure that it only accepts a <code>Circle</code> or its subclass. This can be specified by constraining its type to <code>[U &gt;: T]</code> where <code>T</code> is the type parameter for <code>Stack</code>. This is the intuition behind variance (we skipped contravariance) and if you are interested, read more <a href="http://twitter.github.io/scala_school/type-basics.html#variance">here</a>.</p>
<p>Armed with the idea of variance, we can make our <code>Stack</code> trait more general:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">trait</span> <span class="nc">Stack</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">isEmpty</span><span class="k">:</span> <span class="kt">Boolean</span>
  <span class="k">def</span> <span class="n">cons</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span><span class="k">:</span> <span class="kt">Stack</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">head</span><span class="k">:</span> <span class="kt">T</span>
  <span class="k">def</span> <span class="n">tail</span><span class="k">:</span> <span class="kt">Stack</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><h2 id="implementation">Implementation</h2>
<p>One way to implement <code>Stack</code> is to consider two cases. A <code>Stack</code> could be empty or it could have a head and tail. Further, empty can be a singleton and we introduce an abstract class <code>CList</code> to represent this particular implementation:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">CList</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span> <span class="nc">extends</span> <span class="nc">Stack</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">cons</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">U</span><span class="o">)</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="k">new</span> <span class="nc">Cons</span><span class="o">(</span><span class="n">t</span><span class="o">,</span> <span class="k">this</span><span class="o">)</span>
<span class="o">}</span>

<span class="k">case</span> <span class="k">object</span> <span class="nc">Empty</span> <span class="k">extends</span> <span class="nc">CList</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">isEmpty</span><span class="k">:</span> <span class="kt">Boolean</span> <span class="o">=</span> <span class="kc">true</span>
  <span class="k">def</span> <span class="n">head</span><span class="k">:</span> <span class="kt">Nothing</span> <span class="o">=</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">NoSuchElementException</span><span class="o">(</span><span class="o">)</span>
  <span class="k">def</span> <span class="n">tail</span><span class="k">:</span> <span class="kt">Nothing</span> <span class="o">=</span> <span class="k">throw</span> <span class="k">new</span> <span class="nc">NoSuchElementException</span><span class="o">(</span><span class="o">)</span>
<span class="o">}</span>

<span class="k">case</span> <span class="k">class</span> <span class="nc">Cons</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">hd</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">tl</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">CList</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">isEmpty</span><span class="k">:</span> <span class="kt">Boolean</span> <span class="o">=</span> <span class="kc">false</span>
  <span class="k">def</span> <span class="n">head</span><span class="k">:</span> <span class="kt">T</span> <span class="o">=</span> <span class="n">hd</span>
  <span class="k">def</span> <span class="n">tail</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span> <span class="k">=</span> <span class="n">tl</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>Given this, one could create a Stack like:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">val</span> <span class="n">stack</span> <span class="k">=</span> <span class="nc">Cons</span><span class="o">(</span><span class="mi">1</span><span class="o">,</span> <span class="nc">Cons</span><span class="o">(</span><span class="mi">2</span><span class="o">,</span> <span class="nc">Empty</span><span class="o">)</span><span class="o">)</span> <span class="c1">// head = 1, tail = [2]
</span></code></pre></td></tr></table>
</div>
</div><h2 id="persistent">Persistent</h2>
<p>An important property of functional data structures is that they are immutable, any change on them would give us a new copy. This may not be as bad as it sounds since the structure can be often shared. For instance, if we have a list:</p>
<p><img src="/images/one.png" alt="drawing"></p>
<p>and we append <code>0</code> to it, we get a new list:</p>
<p><img src="/images/two.png" alt="drawing"></p>
<p>but the tail of second list is just a pointer to first list (in the image, only <code>0</code> is a new node as the color shows), so no extra space is required. If we insert an element in between, the elements till that needs to be copied but rest can be shared. If we append two lists, <code>xs</code> and <code>ys</code>, all elements in <code>xs</code> needs to be copied but <code>ys</code> can be shared:</p>
<p><img src="/images/one.png" alt="drawing"> ++
<img src="/images/sa1.png" alt="drawing"> ==
<img src="/images/sa2.png" alt="drawing"></p>
<p>There are ways to optimize this to minimize copying.</p>
<p>But keeping things immutable has many <a href="http://stackoverflow.com/questions/4399837/what-is-the-benefit-of-purely-functional-data-structure">advantages</a>. One particular benefit is even after updates the previous &lsquo;version&rsquo; of the data structure is available since we don't modify anything. For this reason, functional data structures are also called persistent.</p>
<h2 id="other-operations">Other operations</h2>
<p>The implementation we have so far is trivial and we can add other operations:</p>
<ul>
<li><code>update</code>: inserts an element at a given index.</li>
<li><code>++</code>: catenates two Stacks together</li>
</ul>
<p>The implementation for this is straightforward. We just need to handle the two cases. Let's also add a <code>toList</code> function to convert this to Scala <code>List</code> for debugging.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">CList</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span> <span class="nc">extends</span> <span class="nc">Stack</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="o">++</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">ys</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">update</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">U</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="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span>
  <span class="k">def</span> <span class="n">toList</span><span class="k">:</span> <span class="kt">List</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span>
<span class="o">}</span>

<span class="k">case</span> <span class="k">object</span> <span class="nc">Empty</span> <span class="k">extends</span> <span class="nc">CList</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="o">++</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">(</span><span class="n">ys</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="n">ys</span>
  <span class="k">def</span> <span class="n">update</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">U</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="k">throw</span> <span class="k">new</span> <span class="nc">IndexOutOfBoundsException</span><span class="o">(</span><span class="o">)</span>
  <span class="k">def</span> <span class="n">toList</span> <span class="k">=</span> <span class="nc">Nil</span>
<span class="o">}</span>

<span class="k">case</span> <span class="k">class</span> <span class="nc">Cons</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">hd</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">tl</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">CList</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="o">++</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">ys</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Cons</span><span class="o">(</span><span class="n">head</span><span class="o">,</span> <span class="n">tail</span> <span class="o">++</span> <span class="n">ys</span><span class="o">)</span>
  <span class="k">def</span> <span class="n">update</span><span class="o">[</span><span class="kt">U</span> <span class="k">&gt;:</span> <span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">t</span><span class="k">:</span> <span class="kt">U</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="kt">CList</span><span class="o">[</span><span class="kt">U</span><span class="o">]</span> <span class="k">=</span> <span class="k">if</span> <span class="o">(</span><span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="o">)</span> <span class="nc">Cons</span><span class="o">(</span><span class="n">t</span><span class="o">,</span> <span class="k">this</span><span class="o">)</span> <span class="k">else</span> <span class="nc">Cons</span><span class="o">(</span><span class="n">head</span><span class="o">,</span> <span class="n">tail</span><span class="o">.</span><span class="n">update</span><span class="o">(</span><span class="n">t</span><span class="o">,</span> <span class="n">i</span><span class="o">-</span><span class="mi">1</span><span class="o">)</span><span class="o">)</span>
  <span class="k">def</span> <span class="n">toList</span> <span class="k">=</span> <span class="n">head</span> <span class="k">:</span><span class="kt">:</span> <span class="kt">tail.toList</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>Note that the <code>update</code> and <code>++</code> operations return a new Stack which potentially shares the structure of old Stack as we discussed before.</p>
<h2 id="digression-testing">Digression: Testing</h2>
<p>Now that we have written some code, how do we test it? We need to have some test data and unit tests for testing Stack. Also we need to test for <code>Empty</code> and <code>Cons</code> case separately. Instead of writing specific test cases, let's use <a href="http://www.scalacheck.org/">Scalacheck</a>. Scalacheck basically allows us to assert properties or invariants about the data structure and it takes care of generating random data for us.</p>
<p>Since we have a new data structure, which Scalacheck does not know about, we need to describe how to generate data. One way to do it is:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">implicit</span> <span class="k">def</span> <span class="n">arbStack</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="k">implicit</span> <span class="n">a</span><span class="k">:</span> <span class="kt">Arbitrary</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span><span class="k">:</span> <span class="kt">Arbitrary</span><span class="o">[</span><span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Arbitrary</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">genStack</span><span class="k">:</span> <span class="kt">Gen</span><span class="o">[</span><span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="n">oneOf</span><span class="o">(</span><span class="nc">Empty</span><span class="o">,</span> <span class="k">for</span> <span class="o">{</span>
    <span class="n">v</span> <span class="k">&lt;-</span> <span class="n">arbitrary</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span>
    <span class="n">s</span> <span class="k">&lt;-</span> <span class="n">genStack</span>
  <span class="o">}</span> <span class="k">yield</span> <span class="n">s</span><span class="o">.</span><span class="n">cons</span><span class="o">(</span><span class="n">v</span><span class="o">)</span><span class="o">)</span>
  <span class="n">genStack</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>It might look a bit complicated, but all it is doing is describing how we can construct arbitrary Stacks. Once this is done, we can start writing our tests by just describing properties:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="n">test</span><span class="o">(</span><span class="s">&#34;Stack head&#34;</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">check</span><span class="o">(</span><span class="o">(</span><span class="n">s</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">,</span> <span class="n">x</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">s</span><span class="o">.</span><span class="n">cons</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">.</span><span class="n">head</span> <span class="o">==</span> <span class="n">x</span><span class="o">)</span>
<span class="o">}</span>

<span class="n">test</span><span class="o">(</span><span class="s">&#34;Stack tail&#34;</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">check</span><span class="o">(</span><span class="o">(</span><span class="n">s</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">,</span> <span class="n">x</span><span class="k">:</span> <span class="kt">Int</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">s</span><span class="o">.</span><span class="n">cons</span><span class="o">(</span><span class="n">x</span><span class="o">)</span><span class="o">.</span><span class="n">tail</span> <span class="o">==</span> <span class="n">s</span><span class="o">)</span>
<span class="o">}</span>

<span class="n">test</span><span class="o">(</span><span class="s">&#34;Stack append&#34;</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">check</span><span class="o">(</span><span class="o">(</span><span class="n">xs</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">,</span> <span class="n">ys</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="n">size</span><span class="o">(</span><span class="n">xs</span> <span class="o">++</span> <span class="n">ys</span><span class="o">)</span> <span class="o">==</span> <span class="n">size</span><span class="o">(</span><span class="n">xs</span><span class="o">)</span> <span class="o">+</span> <span class="n">size</span><span class="o">(</span><span class="n">ys</span><span class="o">)</span><span class="o">)</span>
<span class="o">}</span>

<span class="n">test</span><span class="o">(</span><span class="s">&#34;Stack update&#34;</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">check</span><span class="o">(</span><span class="o">(</span><span class="n">xs</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">,</span> <span class="n">x</span><span class="k">:</span> <span class="kt">Int</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">=&gt;</span> <span class="o">{</span>
    <span class="k">if</span> <span class="o">(</span><span class="n">i</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">size</span><span class="o">(</span><span class="n">xs</span><span class="o">)</span><span class="o">)</span> <span class="n">size</span><span class="o">(</span><span class="n">xs</span><span class="o">.</span><span class="n">update</span><span class="o">(</span><span class="n">x</span><span class="o">,</span> <span class="n">i</span><span class="o">)</span><span class="o">)</span> <span class="o">==</span> <span class="n">size</span><span class="o">(</span><span class="n">xs</span><span class="o">)</span><span class="o">+</span><span class="mi">1</span>
    <span class="k">else</span> <span class="k">try</span> <span class="o">{</span>
      <span class="n">xs</span><span class="o">.</span><span class="n">update</span><span class="o">(</span><span class="n">x</span><span class="o">,</span> <span class="n">i</span><span class="o">)</span>
      <span class="kc">false</span>
    <span class="o">}</span> <span class="k">catch</span> <span class="o">{</span>
      <span class="k">case</span> <span class="k">_</span><span class="k">:</span><span class="kt">IndexOutOfBoundsException</span> <span class="o">=&gt;</span> <span class="kc">true</span>
    <span class="o">}</span>
  <span class="o">}</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>Note that we did not provide any sample <code>CList</code>. ScalaCheck will do that for us by testing with various randomly generated <code>CList</code>.</p>
<h2 id="exercise">Exercise</h2>
<p>Implementing a <code>suffixes</code> operation is provided as an exercise - given a <code>Stack</code> generate all its suffices. So suffixes of <code>[1,2,3]</code> should be <code>[[1,2,3], [2,3], [3], []]</code>. It has to be generating in decreasing order of size. Given our classes, this can be easily done:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="k">sealed</span> <span class="k">abstract</span> <span class="k">class</span> <span class="nc">CList</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span> <span class="nc">extends</span> <span class="nc">Stack</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">suffixes</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span>
<span class="o">}</span>

<span class="k">case</span> <span class="k">object</span> <span class="nc">Empty</span> <span class="k">extends</span> <span class="nc">CList</span><span class="o">[</span><span class="kt">Nothing</span><span class="o">]</span> <span class="o">{</span>
  <span class="k">def</span> <span class="n">suffixes</span> <span class="k">=</span> <span class="nc">Cons</span><span class="o">(</span><span class="nc">Empty</span><span class="o">,</span> <span class="nc">Empty</span><span class="o">)</span>
<span class="o">}</span>

<span class="k">case</span> <span class="k">class</span> <span class="nc">Cons</span><span class="o">[</span><span class="kt">+</span><span class="kt">T</span><span class="o">]</span><span class="o">(</span><span class="n">hd</span><span class="k">:</span> <span class="kt">T</span><span class="o">,</span> <span class="n">tl</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">)</span> <span class="k">extends</span> <span class="nc">CList</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">suffixes</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">CList</span><span class="o">[</span><span class="kt">T</span><span class="o">]</span><span class="o">]</span> <span class="k">=</span> <span class="nc">Cons</span><span class="o">(</span><span class="k">this</span><span class="o">,</span> <span class="n">tail</span><span class="o">.</span><span class="n">suffixes</span><span class="o">)</span>
</code></pre></td></tr></table>
</div>
</div><p>and a simple test which passes:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre class="chroma"><code class="language-scala" data-lang="scala"><span class="n">test</span><span class="o">(</span><span class="s">&#34;Stack suffixes&#34;</span><span class="o">)</span> <span class="o">{</span>
  <span class="n">check</span><span class="o">(</span><span class="o">(</span><span class="n">xs</span><span class="k">:</span> <span class="kt">CList</span><span class="o">[</span><span class="kt">Int</span><span class="o">]</span><span class="o">)</span> <span class="k">=&gt;</span> <span class="o">{</span>
    <span class="k">val</span> <span class="n">suffixes</span> <span class="k">=</span> <span class="n">xs</span><span class="o">.</span><span class="n">suffixes</span>
    <span class="n">size</span><span class="o">(</span><span class="n">suffixes</span><span class="o">)</span> <span class="o">==</span> <span class="n">size</span><span class="o">(</span><span class="n">xs</span><span class="o">)</span> <span class="o">+</span> <span class="mi">1</span>
  <span class="o">}</span><span class="o">)</span>
<span class="o">}</span>
</code></pre></td></tr></table>
</div>
</div><p>That is all for a basic implementation of <code>Stack</code>. See the complete code for <a href="https://github.com/amitdev/functional-ds/blob/master/src/main/scala/ds/Stack.scala">Stack</a> and the <a href="https://github.com/amitdev/functional-ds/blob/master/src/test/scala/StackTest.scala">test</a>. We could add many operations like <code>map</code>, <code>filter</code> etc in a similar way. If you are interested, take a look a Scala's implementation of <a href="https://github.com/scala/scala/blob/master/src/library/scala/collection/immutable/List.scala">List</a> which is more general and feature rich.</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/programming/">Programming</category>
                                
                            
                        
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/functional-programming/">functional programming</category>
                                
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/tags/scala/">scala</category>
                                
                            
                        
                    
                
            </item>
        
            <item>
                <title>Moving in from Blogger</title>
                <link>https://amitdev.github.io/posts/first-post/</link>
                <guid isPermaLink="true">https://amitdev.github.io/posts/first-post/</guid>
                <pubDate>Sun, 15 Dec 2013 11:34:15 +1100</pubDate>
                
                <copyright>[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)</copyright>
                
                    <description><![CDATA[<p>Some of my older posts are in <a href="http://memuser.blogspot.in/">blogger</a>.</p>
]]></description>
                
                
                
                
                
                    
                        
                            
                                
                                
                                
                                    <category domain="https://amitdev.github.io/categories/general/">General</category>
                                
                            
                        
                    
                        
                    
                
            </item>
        
    </channel>
</rss>