David Raab2022-11-05T15:10:37+00:00https://sidburn.github.ioDavid RaabFrom mutable loops to immutable folds2016-04-05T00:00:00+00:00https://sidburn.github.io/blog/2016/04/05/mutable-loops-to-immutability<p>When we ask of <em>key-features</em> of functional programming, you will probably hear two things most often.
Immutability and recursion. But why is that so? As Immutability also becomes more important in OO
languages you will probably find a lot of reason for that one, but why are recursive
functions so important? The short answer is, because of Immutability! To understand the connection
between those, let's start with some code that uses loops with mutation.</p>
<h2>ResizeArray</h2>
<p>Let's start with <code>ResizeArray</code>, and let's implement a <code>map</code> for it. The interesting idea,
even if we have a <em>mutable data-structures</em> we still can write functions that behaves as
if we had <em>immutable data</em>. That means, we return new data, instead of <em>mutating</em> data.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">module</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="t">ResizeArray</span> <span class="o">=</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="f">map</span> <span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="f">f</span> <span onmouseout="hideTip(event, 'fs5', 5)" onmouseover="showTip(event, 'fs5', 5)" class="i">oldArray</span> <span class="o">=</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs6', 6)" onmouseover="showTip(event, 'fs6', 6)" class="i">newArray</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 7)" onmouseover="showTip(event, 'fs2', 7)" class="t">ResizeArray</span><span class="o"><</span>_<span class="o">></span>()
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs7', 8)" onmouseover="showTip(event, 'fs7', 8)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs5', 9)" onmouseover="showTip(event, 'fs5', 9)" class="i">oldArray</span> <span class="k">do</span>
<span onmouseout="hideTip(event, 'fs6', 10)" onmouseover="showTip(event, 'fs6', 10)" class="i">newArray</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs8', 11)" onmouseover="showTip(event, 'fs8', 11)" class="f">Add</span> (<span onmouseout="hideTip(event, 'fs4', 12)" onmouseover="showTip(event, 'fs4', 12)" class="f">f</span> <span onmouseout="hideTip(event, 'fs7', 13)" onmouseover="showTip(event, 'fs7', 13)" class="i">x</span>)
<span onmouseout="hideTip(event, 'fs6', 14)" onmouseover="showTip(event, 'fs6', 14)" class="i">newArray</span>
</code></pre></td>
</tr>
</table>
<p>Now we can do stuff like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs9', 15)" onmouseover="showTip(event, 'fs9', 15)" class="i">numbers</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs10', 16)" onmouseover="showTip(event, 'fs10', 16)" class="t">ResizeArray</span><span class="o"><</span>_<span class="o">></span>()
<span onmouseout="hideTip(event, 'fs9', 17)" onmouseover="showTip(event, 'fs9', 17)" class="i">numbers</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 18)" onmouseover="showTip(event, 'fs11', 18)" class="f">Add</span>(<span class="n">1</span>)
<span onmouseout="hideTip(event, 'fs9', 19)" onmouseover="showTip(event, 'fs9', 19)" class="i">numbers</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 20)" onmouseover="showTip(event, 'fs11', 20)" class="f">Add</span>(<span class="n">2</span>)
<span onmouseout="hideTip(event, 'fs9', 21)" onmouseover="showTip(event, 'fs9', 21)" class="i">numbers</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 22)" onmouseover="showTip(event, 'fs11', 22)" class="f">Add</span>(<span class="n">3</span>)
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 23)" onmouseover="showTip(event, 'fs12', 23)" class="i">squaredNumbers</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs10', 24)" onmouseover="showTip(event, 'fs10', 24)" class="t">ResizeArray</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs3', 25)" onmouseover="showTip(event, 'fs3', 25)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs13', 26)" onmouseover="showTip(event, 'fs13', 26)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 27)" onmouseover="showTip(event, 'fs13', 27)" class="i">x</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs13', 28)" onmouseover="showTip(event, 'fs13', 28)" class="i">x</span>) <span onmouseout="hideTip(event, 'fs9', 29)" onmouseover="showTip(event, 'fs9', 29)" class="i">numbers</span>
</code></pre></td>
</tr>
</table>
<p>We now have two <code>ResizeArray</code>. <code>numbers</code> still contains <code>1</code>, <code>2</code> and <code>3</code> while <code>squaredNumbers</code>
contains <code>1</code>, <code>4</code>, <code>9</code>. So while this behaves like <em>immutability</em>, it still isn't exactly
<em>immutable</em>. We also see that in the <code>map</code> implementation. In <code>map</code> we first create
an empty <em>mutable</em> <code>newArray</code>. While we loop over <code>oldArray</code> we <em>mutate</em> <code>newArray</code> by adding
the result of the transformation <code>f x</code> to <code>newArray</code>. But the only reason why we could do that
is because <code>newArray</code> is <em>mutable</em>!</p>
<p>But what do we do if we have a true <em>immutable list</em> like the built-in F# list? We cannot start with
an <code>empty list</code> just loop over <code>oldArray</code> and directly add an element to the empty list. We only can
prepend elements, but this would create a whole new list and not <em>mutate</em> the empty list.</p>
<p>Sure we can assign the new list to a new variable inside the loop. But this doesn't make much sense
as with the next iteration we will lose our newly created list. The thing is, looping always need
some kind of <em>mutable</em> variable outside of the loop that we can <em>mutate</em>.</p>
<p>Actually F# supports <em>mutable variables</em> so as a quick fix we could define a <em>mutable variable</em>
outside the loop.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs14', 30)" onmouseover="showTip(event, 'fs14', 30)" class="f">mapWithImmutableList</span> <span onmouseout="hideTip(event, 'fs4', 31)" onmouseover="showTip(event, 'fs4', 31)" class="f">f</span> (<span onmouseout="hideTip(event, 'fs15', 32)" onmouseover="showTip(event, 'fs15', 32)" class="i">list</span><span class="o">:</span>_ <span onmouseout="hideTip(event, 'fs15', 33)" onmouseover="showTip(event, 'fs15', 33)" class="t">list</span>) <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs16', 34)" onmouseover="showTip(event, 'fs16', 34)" class="v">acc</span> <span class="o">=</span> []
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs7', 35)" onmouseover="showTip(event, 'fs7', 35)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs15', 36)" onmouseover="showTip(event, 'fs15', 36)" class="i">list</span> <span class="k">do</span>
<span onmouseout="hideTip(event, 'fs16', 37)" onmouseover="showTip(event, 'fs16', 37)" class="v">acc</span> <span class="o"><-</span> (<span onmouseout="hideTip(event, 'fs4', 38)" onmouseover="showTip(event, 'fs4', 38)" class="f">f</span> <span onmouseout="hideTip(event, 'fs7', 39)" onmouseover="showTip(event, 'fs7', 39)" class="i">x</span>) <span class="o">::</span> <span onmouseout="hideTip(event, 'fs16', 40)" onmouseover="showTip(event, 'fs16', 40)" class="v">acc</span>
<span onmouseout="hideTip(event, 'fs16', 41)" onmouseover="showTip(event, 'fs16', 41)" class="v">acc</span>
</code></pre></td>
</tr>
</table>
<p>It doesn't mean we created a <em>mutable list</em> here. We still only have <em>immutable lists</em>.
But <code>acc</code> itself is <em>mutable</em> and can be changed to point to a new <em>immutable list</em>.</p>
<p>With <code>(f x) :: acc</code> we always create a whole new <em>immutable list</em> by using the <code>acc</code>
from the previous <em>loop iteration</em>. So <code>acc</code> only keeps track of the <em>last or newest</em>
<code>acc</code>.</p>
<p>This implementation still has a problem as we will also <em>reverse</em> the list. The problem
is that we only can <em>prepend</em> elements to a list and not <em>append</em> them.</p>
<p>But on top, we still relaying on <em>mutable</em> variables. Let's first forget about the <em>reverse</em>
problem. Here we see a general problem. Looping needs <em>mutable</em> variables! Sure, we
also can do just some <em>side-effects</em> and don't <em>mutate</em> anything, but whenever you really
want to compute something you are forced to use <em>mutation</em> if you choose a loop.</p>
<p>Looping constructs in general just don't work nicely together with <em>immuability</em>. That's also
the reason why looping is discouraged in functional programming. But it opens up the
question how we solve the problems that <em>looping</em> solves. How can we for example go through an
<em>immutable list</em> without <em>looping</em>? And how can we compute something with every element
without accessing a <em>mutable variable</em>?</p>
<p>The answer is: Through recursion!</p>
<h2>Looping with recursion</h2>
<p>To understand how we can replace loops through recursion, let's start with something simple. We
start with a typical <code>for</code> loop as you can see with <code>C#</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">for</span> (<span class="k">int</span> i=<span class="n">0</span>; i<<span class="n">10</span>; i+<span class="o">+</span>) {
Console.WriteLine(<span class="s">"{0}"</span>, i);
}
</code></pre></td></tr></table>
<p>If we really appreciate <em>immutability</em> we cannot directly create such a looping construct.
Because such a <code>for</code> loop relies on mutating <code>i</code> after every step. But it doesn't mean we can
calculate <code>i + 1</code>. We can increment <code>i</code>, but we have to assign the result to a new variable.
Technically we could expand the looping construct into separate statements.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs17', 42)" onmouseover="showTip(event, 'fs17', 42)" class="i">i</span> <span class="o">=</span> <span class="n">0</span>
<span onmouseout="hideTip(event, 'fs18', 43)" onmouseover="showTip(event, 'fs18', 43)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs17', 44)" onmouseover="showTip(event, 'fs17', 44)" class="i">i</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs19', 45)" onmouseover="showTip(event, 'fs19', 45)" class="i">i1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs17', 46)" onmouseover="showTip(event, 'fs17', 46)" class="i">i</span> <span class="o">+</span> <span class="n">1</span>
<span onmouseout="hideTip(event, 'fs18', 47)" onmouseover="showTip(event, 'fs18', 47)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs19', 48)" onmouseover="showTip(event, 'fs19', 48)" class="i">i1</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs20', 49)" onmouseover="showTip(event, 'fs20', 49)" class="i">i2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs19', 50)" onmouseover="showTip(event, 'fs19', 50)" class="i">i1</span> <span class="o">+</span> <span class="n">1</span>
<span onmouseout="hideTip(event, 'fs18', 51)" onmouseover="showTip(event, 'fs18', 51)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs20', 52)" onmouseover="showTip(event, 'fs20', 52)" class="i">i2</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs21', 53)" onmouseover="showTip(event, 'fs21', 53)" class="i">i3</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs20', 54)" onmouseover="showTip(event, 'fs20', 54)" class="i">i2</span> <span class="o">+</span> <span class="n">1</span>
<span onmouseout="hideTip(event, 'fs18', 55)" onmouseover="showTip(event, 'fs18', 55)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs21', 56)" onmouseover="showTip(event, 'fs21', 56)" class="i">i3</span>
<span class="c">// ...</span>
</code></pre></td>
</tr>
</table>
<p>Sure, writing stuff like that is simple stupid. We don't want to increment <code>i</code> ten times, always
create a new variable, and a new print statement. But it is still interesting that the idea
is the same with our first <code>map</code> implementation we did for <code>ResizeArray</code>.</p>
<p>We always create a new <em>immutable state</em>, by using the previous state. And that is where functions
come into play. Actually we are not limited to just assign the result of a calculation just to a
variable. We also can pass the result to a function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs22', 57)" onmouseover="showTip(event, 'fs22', 57)" class="i">calc</span> <span class="o">=</span> <span class="i">i</span> <span class="o">+</span> <span class="n">1</span>
<span class="i">f</span> <span onmouseout="hideTip(event, 'fs22', 58)" onmouseover="showTip(event, 'fs22', 58)" class="i">calc</span>
</code></pre></td>
</tr>
</table>
<p>or better, we can do it in one step.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">f</span> (<span class="i">i</span> <span class="o">+</span> <span class="n">1</span>)
</code></pre></td>
</tr>
</table>
<p>This is an important idea. It just means that when we call a function, it is also an assign statement
at the same time! With this idea, we can actually create a looping construct just out of functions.
Instead of mutating <code>i</code> at the end of a loop and repeating our loop. We just call our function
recursively and pass it the next state as an argument!</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs23', 59)" onmouseover="showTip(event, 'fs23', 59)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs24', 60)" onmouseover="showTip(event, 'fs24', 60)" class="i">i</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs18', 61)" onmouseover="showTip(event, 'fs18', 61)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs24', 62)" onmouseover="showTip(event, 'fs24', 62)" class="i">i</span>
<span onmouseout="hideTip(event, 'fs23', 63)" onmouseover="showTip(event, 'fs23', 63)" class="f">loop</span> (<span onmouseout="hideTip(event, 'fs24', 64)" onmouseover="showTip(event, 'fs24', 64)" class="i">i</span><span class="o">+</span><span class="n">1</span>)
<span onmouseout="hideTip(event, 'fs23', 65)" onmouseover="showTip(event, 'fs23', 65)" class="f">loop</span> <span class="n">0</span> <span class="c">// infinity loop</span>
</code></pre></td>
</tr>
</table>
<p>Sure, we now have another problem, as we currently have an infinity loop. We now <em>always</em> call <code>loop i+1</code>.
So we have to add some condition when we really want to loop.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs25', 66)" onmouseover="showTip(event, 'fs25', 66)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs24', 67)" onmouseover="showTip(event, 'fs24', 67)" class="i">i</span> <span class="o">=</span>
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs24', 68)" onmouseover="showTip(event, 'fs24', 68)" class="i">i</span> <span class="o"><</span> <span class="n">10</span> <span class="k">then</span>
<span onmouseout="hideTip(event, 'fs18', 69)" onmouseover="showTip(event, 'fs18', 69)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs24', 70)" onmouseover="showTip(event, 'fs24', 70)" class="i">i</span>
<span onmouseout="hideTip(event, 'fs25', 71)" onmouseover="showTip(event, 'fs25', 71)" class="f">loop</span> (<span onmouseout="hideTip(event, 'fs24', 72)" onmouseover="showTip(event, 'fs24', 72)" class="i">i</span><span class="o">+</span><span class="n">1</span>)
<span onmouseout="hideTip(event, 'fs25', 73)" onmouseover="showTip(event, 'fs25', 73)" class="f">loop</span> <span class="n">0</span> <span class="c">// Will now print numbers from 0 to 9</span>
</code></pre></td>
</tr>
</table>
<p>Let's abstract it further. Instead of hard coding <code>10</code> we want to provide the end as an argument.
Additionally, we also want to be able to execute <em>any code</em> <em>inside our loop</em> iteration, instead
of hard-coding the <em>print-statement</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs26', 74)" onmouseover="showTip(event, 'fs26', 74)" class="f">forLoop</span> <span onmouseout="hideTip(event, 'fs24', 75)" onmouseover="showTip(event, 'fs24', 75)" class="i">i</span> <span onmouseout="hideTip(event, 'fs27', 76)" onmouseover="showTip(event, 'fs27', 76)" class="i">stop</span> <span onmouseout="hideTip(event, 'fs28', 77)" onmouseover="showTip(event, 'fs28', 77)" class="f">f</span> <span class="o">=</span>
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs24', 78)" onmouseover="showTip(event, 'fs24', 78)" class="i">i</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs27', 79)" onmouseover="showTip(event, 'fs27', 79)" class="i">stop</span> <span class="k">then</span>
<span onmouseout="hideTip(event, 'fs28', 80)" onmouseover="showTip(event, 'fs28', 80)" class="f">f</span> <span onmouseout="hideTip(event, 'fs24', 81)" onmouseover="showTip(event, 'fs24', 81)" class="i">i</span>
<span onmouseout="hideTip(event, 'fs26', 82)" onmouseover="showTip(event, 'fs26', 82)" class="f">forLoop</span> (<span onmouseout="hideTip(event, 'fs24', 83)" onmouseover="showTip(event, 'fs24', 83)" class="i">i</span><span class="o">+</span><span class="n">1</span>) <span onmouseout="hideTip(event, 'fs27', 84)" onmouseover="showTip(event, 'fs27', 84)" class="i">stop</span> <span onmouseout="hideTip(event, 'fs28', 85)" onmouseover="showTip(event, 'fs28', 85)" class="f">f</span>
<span onmouseout="hideTip(event, 'fs26', 86)" onmouseover="showTip(event, 'fs26', 86)" class="f">forLoop</span> <span class="n">0</span> <span class="n">10</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs24', 87)" onmouseover="showTip(event, 'fs24', 87)" class="i">i</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 88)" onmouseover="showTip(event, 'fs18', 88)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs24', 89)" onmouseover="showTip(event, 'fs24', 89)" class="i">i</span>)
</code></pre></td>
</tr>
</table>
<p>We now basically recreated a <code>for</code> loop through a recursive function! We just can provide
the starting and the stop value and just provide a function for the <em>loop-body</em> that describes
what should be done at every step. The current <code>i</code> is just passed as an argument to our function
<code>f</code>. This way we can do something with the value.</p>
<p>Let's improve that solution a little bit. It feels a little bit awkward that we have
to provide <code>stop</code> and <code>f</code> again as arguments. We can fix this problem by just creating a special
<code>loop</code> function inside <code>forLoop</code> instead.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs29', 90)" onmouseover="showTip(event, 'fs29', 90)" class="f">forLoop</span> <span onmouseout="hideTip(event, 'fs30', 91)" onmouseover="showTip(event, 'fs30', 91)" class="i">start</span> <span onmouseout="hideTip(event, 'fs27', 92)" onmouseover="showTip(event, 'fs27', 92)" class="i">stop</span> <span onmouseout="hideTip(event, 'fs28', 93)" onmouseover="showTip(event, 'fs28', 93)" class="f">f</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs31', 94)" onmouseover="showTip(event, 'fs31', 94)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs24', 95)" onmouseover="showTip(event, 'fs24', 95)" class="i">i</span> <span class="o">=</span>
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs24', 96)" onmouseover="showTip(event, 'fs24', 96)" class="i">i</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs27', 97)" onmouseover="showTip(event, 'fs27', 97)" class="i">stop</span> <span class="k">then</span>
<span onmouseout="hideTip(event, 'fs28', 98)" onmouseover="showTip(event, 'fs28', 98)" class="f">f</span> <span onmouseout="hideTip(event, 'fs24', 99)" onmouseover="showTip(event, 'fs24', 99)" class="i">i</span>
<span onmouseout="hideTip(event, 'fs31', 100)" onmouseover="showTip(event, 'fs31', 100)" class="f">loop</span> (<span onmouseout="hideTip(event, 'fs24', 101)" onmouseover="showTip(event, 'fs24', 101)" class="i">i</span><span class="o">+</span><span class="n">1</span>)
<span onmouseout="hideTip(event, 'fs31', 102)" onmouseover="showTip(event, 'fs31', 102)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs30', 103)" onmouseover="showTip(event, 'fs30', 103)" class="i">start</span>
<span onmouseout="hideTip(event, 'fs29', 104)" onmouseover="showTip(event, 'fs29', 104)" class="f">forLoop</span> <span class="n">0</span> <span class="n">10</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs24', 105)" onmouseover="showTip(event, 'fs24', 105)" class="i">i</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 106)" onmouseover="showTip(event, 'fs18', 106)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs24', 107)" onmouseover="showTip(event, 'fs24', 107)" class="i">i</span>)
</code></pre></td>
</tr>
</table>
<p>Our <code>forLoop</code> function is not a recursive function any more, instead it contains a recursive <code>loop</code>
function. <code>loop</code> only contains those variables as arguments that we really expect to change.</p>
<p>This has several advantages:</p>
<ol>
<li><code>loop</code> itself is easier and nearly resembles the first <code>loop</code> we started with.</li>
<li>
We don't need to pass variables like <code>f</code> or <code>stop</code> to the recursive call as we don't expect
them to change.
</li>
<li>
This reduces the possibility of bugs as we cannot change variables that we didn't expect to change.
For example, previously we could write: <code>forLoop (i+1) (stop+1) f</code>
</li>
<li>
In other cases it also means we can <em>pre-</em> or <em>post-process</em> data before or after the loop
starts/finish.
</li>
<li>
Sometimes we just want to provide a fixed starting value. For example in a <code>sum</code> function
we provide <code>0</code> as the starting value. We don't want that the user must enter <code>0</code> as a
starting value for the recursion call!
</li>
<li>
Different names for arguments. For example our <code>forLoop</code> now has <code>start</code> instead of <code>i</code>. But
it doesn't make sense to use <code>start</code> inside of <code>loop</code>. Clearer names can help in understanding
code. But it also helps users of <code>forEach</code>. As they now see <code>start</code> as an argument, not <code>i</code>.
</li>
</ol>
<p>The only problem so far is that we only can call functions that do some sort of side-effect.
But we cannot for example create something new out of the looping. For example if we want to
create the sum of all numbers from 0 to 9 we could write something like this in C#</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">int</span> sum <span class="o">=</span> <span class="n">0</span>
<span class="k">for</span> (<span class="k">int</span> i=<span class="n">0</span>; i<<span class="n">10</span>; i+<span class="o">+</span>) {
sum <span class="o">=</span> sum <span class="o">+</span> i;
}
</code></pre></td></tr></table>
<p>But we now know how to fix that problem. We just add <code>sum</code> to the <code>loop</code> function
as this is a value that we expect to change with every <em>iteration</em>. On top our function <code>f</code> must
change. In the body of a loop we have access to <code>i</code> and access to <code>sum</code> outside of the loop.
With recursion we only get access to those data that we pass to the <code>f</code> function. So we also must
pass <code>sum</code> as an argument to our <code>f</code> function. As we cannot <em>mutate</em> <code>sum</code> inside <code>f</code> we expect that
<code>f</code> returns the new <code>sum</code> that we then use for the next <em>recursive call</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs32', 108)" onmouseover="showTip(event, 'fs32', 108)" class="f">forLoop</span> <span onmouseout="hideTip(event, 'fs30', 109)" onmouseover="showTip(event, 'fs30', 109)" class="i">start</span> <span onmouseout="hideTip(event, 'fs27', 110)" onmouseover="showTip(event, 'fs27', 110)" class="i">stop</span> <span onmouseout="hideTip(event, 'fs33', 111)" onmouseover="showTip(event, 'fs33', 111)" class="f">f</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs34', 112)" onmouseover="showTip(event, 'fs34', 112)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs24', 113)" onmouseover="showTip(event, 'fs24', 113)" class="i">i</span> <span onmouseout="hideTip(event, 'fs35', 114)" onmouseover="showTip(event, 'fs35', 114)" class="i">sum</span> <span class="o">=</span>
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs24', 115)" onmouseover="showTip(event, 'fs24', 115)" class="i">i</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs27', 116)" onmouseover="showTip(event, 'fs27', 116)" class="i">stop</span> <span class="k">then</span>
<span class="c">// create the next sum</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs36', 117)" onmouseover="showTip(event, 'fs36', 117)" class="i">nextSum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs33', 118)" onmouseover="showTip(event, 'fs33', 118)" class="f">f</span> <span onmouseout="hideTip(event, 'fs24', 119)" onmouseover="showTip(event, 'fs24', 119)" class="i">i</span> <span onmouseout="hideTip(event, 'fs35', 120)" onmouseover="showTip(event, 'fs35', 120)" class="i">sum</span>
<span class="c">// next recursive call with updated "i" and "sum"</span>
<span onmouseout="hideTip(event, 'fs34', 121)" onmouseover="showTip(event, 'fs34', 121)" class="f">loop</span> (<span onmouseout="hideTip(event, 'fs24', 122)" onmouseover="showTip(event, 'fs24', 122)" class="i">i</span><span class="o">+</span><span class="n">1</span>) <span onmouseout="hideTip(event, 'fs36', 123)" onmouseover="showTip(event, 'fs36', 123)" class="i">nextSum</span>
<span class="k">else</span>
<span class="c">// Return "sum" as soon we reach stop</span>
<span onmouseout="hideTip(event, 'fs35', 124)" onmouseover="showTip(event, 'fs35', 124)" class="i">sum</span>
<span onmouseout="hideTip(event, 'fs34', 125)" onmouseover="showTip(event, 'fs34', 125)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs30', 126)" onmouseover="showTip(event, 'fs30', 126)" class="i">start</span> <span class="n">0</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs37', 127)" onmouseover="showTip(event, 'fs37', 127)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs32', 128)" onmouseover="showTip(event, 'fs32', 128)" class="f">forLoop</span> <span class="n">0</span> <span class="n">10</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs24', 129)" onmouseover="showTip(event, 'fs24', 129)" class="i">i</span> <span onmouseout="hideTip(event, 'fs35', 130)" onmouseover="showTip(event, 'fs35', 130)" class="i">sum</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs35', 131)" onmouseover="showTip(event, 'fs35', 131)" class="i">sum</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs24', 132)" onmouseover="showTip(event, 'fs24', 132)" class="i">i</span>) <span class="c">// 45</span>
</code></pre></td>
</tr>
</table>
<p>The only thing I dislike at this point is that the usage of our <code>forLoop</code> is still limited. We have
the signature.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">start</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs38', 133)" onmouseover="showTip(event, 'fs38', 133)" class="i">int</span> <span class="k">-></span> <span class="i">stop</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs38', 134)" onmouseover="showTip(event, 'fs38', 134)" class="i">int</span> <span class="k">-></span> <span class="i">f</span><span class="o">:</span>(<span onmouseout="hideTip(event, 'fs38', 135)" onmouseover="showTip(event, 'fs38', 135)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs38', 136)" onmouseover="showTip(event, 'fs38', 136)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs38', 137)" onmouseover="showTip(event, 'fs38', 137)" class="i">int</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs38', 138)" onmouseover="showTip(event, 'fs38', 138)" class="i">int</span>
</code></pre></td>
</tr>
</table>
<p>It makes sense that <code>start</code> and <code>stop</code> are <code>int</code>. But usually we expect that the <em>looping-body</em> (<code>f</code>)
can work with any type. Or in other words, that <code>sum</code> can be of any type. And that a <code>forLoop</code>
also can return any type. But currently we are limited to <code>int</code>.</p>
<p>It is an <code>int</code> because we call <code>loop start 0</code> and directly pass <code>0</code> (an <code>int</code>) as <code>sum</code>.
It makes more sense that the user can provide the <em>initial-value</em>. And <code>f</code> just returns a new value
of the same type. This way, the <em>initial-value</em> can be generic.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs39', 139)" onmouseover="showTip(event, 'fs39', 139)" class="f">forLoop</span> <span onmouseout="hideTip(event, 'fs30', 140)" onmouseover="showTip(event, 'fs30', 140)" class="i">start</span> <span onmouseout="hideTip(event, 'fs27', 141)" onmouseover="showTip(event, 'fs27', 141)" class="i">stop</span> <span onmouseout="hideTip(event, 'fs40', 142)" onmouseover="showTip(event, 'fs40', 142)" class="i">init</span> <span onmouseout="hideTip(event, 'fs41', 143)" onmouseover="showTip(event, 'fs41', 143)" class="f">f</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs42', 144)" onmouseover="showTip(event, 'fs42', 144)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs24', 145)" onmouseover="showTip(event, 'fs24', 145)" class="i">i</span> <span onmouseout="hideTip(event, 'fs43', 146)" onmouseover="showTip(event, 'fs43', 146)" class="i">acc</span> <span class="o">=</span>
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs24', 147)" onmouseover="showTip(event, 'fs24', 147)" class="i">i</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs27', 148)" onmouseover="showTip(event, 'fs27', 148)" class="i">stop</span> <span class="k">then</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs44', 149)" onmouseover="showTip(event, 'fs44', 149)" class="i">nextAcc</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs41', 150)" onmouseover="showTip(event, 'fs41', 150)" class="f">f</span> <span onmouseout="hideTip(event, 'fs24', 151)" onmouseover="showTip(event, 'fs24', 151)" class="i">i</span> <span onmouseout="hideTip(event, 'fs43', 152)" onmouseover="showTip(event, 'fs43', 152)" class="i">acc</span>
<span onmouseout="hideTip(event, 'fs42', 153)" onmouseover="showTip(event, 'fs42', 153)" class="f">loop</span> (<span onmouseout="hideTip(event, 'fs24', 154)" onmouseover="showTip(event, 'fs24', 154)" class="i">i</span><span class="o">+</span><span class="n">1</span>) <span onmouseout="hideTip(event, 'fs44', 155)" onmouseover="showTip(event, 'fs44', 155)" class="i">nextAcc</span>
<span class="k">else</span>
<span onmouseout="hideTip(event, 'fs43', 156)" onmouseover="showTip(event, 'fs43', 156)" class="i">acc</span>
<span onmouseout="hideTip(event, 'fs42', 157)" onmouseover="showTip(event, 'fs42', 157)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs30', 158)" onmouseover="showTip(event, 'fs30', 158)" class="i">start</span> <span onmouseout="hideTip(event, 'fs40', 159)" onmouseover="showTip(event, 'fs40', 159)" class="i">init</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs37', 160)" onmouseover="showTip(event, 'fs37', 160)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs39', 161)" onmouseover="showTip(event, 'fs39', 161)" class="f">forLoop</span> <span class="n">0</span> <span class="n">10</span> <span class="n">0</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs24', 162)" onmouseover="showTip(event, 'fs24', 162)" class="i">i</span> <span onmouseout="hideTip(event, 'fs35', 163)" onmouseover="showTip(event, 'fs35', 163)" class="i">sum</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs35', 164)" onmouseover="showTip(event, 'fs35', 164)" class="i">sum</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs24', 165)" onmouseover="showTip(event, 'fs24', 165)" class="i">i</span>) <span class="c">// 45</span>
</code></pre></td>
</tr>
</table>
<p>We now have the signature:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">start</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs38', 166)" onmouseover="showTip(event, 'fs38', 166)" class="i">int</span> <span class="k">-></span> <span class="i">stop</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs38', 167)" onmouseover="showTip(event, 'fs38', 167)" class="i">int</span> <span class="k">-></span> <span class="i">init</span><span class="o">:</span><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="i">f</span><span class="o">:</span>(<span onmouseout="hideTip(event, 'fs38', 168)" onmouseover="showTip(event, 'fs38', 168)" class="i">int</span> <span class="k">-></span> <span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">a</span>) <span class="k">-></span> <span class="o">'</span><span class="i">a</span>
</code></pre></td>
</tr>
</table>
<p>We now created a <code>forLoop</code> just with recursion and without any <em>mutable variable</em>. Our loop supports
the creation of any value. The function <code>f</code> just returns the next state (<code>acc</code>) that is used for
the next <em>iteration/recursion</em> and we don't need any <em>mutable variable</em> anymore.</p>
<p>We now can create any type not just <code>int</code>. We could for example build another list from it in
an <em>immutable</em> way.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs45', 169)" onmouseover="showTip(event, 'fs45', 169)" class="i">listOfNumbers</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs39', 170)" onmouseover="showTip(event, 'fs39', 170)" class="f">forLoop</span> <span class="n">0</span> <span class="n">10</span> [] (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs24', 171)" onmouseover="showTip(event, 'fs24', 171)" class="i">i</span> <span onmouseout="hideTip(event, 'fs46', 172)" onmouseover="showTip(event, 'fs46', 172)" class="i">list</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs24', 173)" onmouseover="showTip(event, 'fs24', 173)" class="i">i</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs46', 174)" onmouseover="showTip(event, 'fs46', 174)" class="i">list</span>)
<span class="c">// [9;8;7;6;5;4;3;2;1;0]</span>
</code></pre></td>
</tr>
</table>
<p>Or build a string</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 175)" onmouseover="showTip(event, 'fs47', 175)" class="i">stringofNumbers</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs39', 176)" onmouseover="showTip(event, 'fs39', 176)" class="f">forLoop</span> <span class="n">0</span> <span class="n">10</span> <span class="s">""</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs24', 177)" onmouseover="showTip(event, 'fs24', 177)" class="i">i</span> <span onmouseout="hideTip(event, 'fs48', 178)" onmouseover="showTip(event, 'fs48', 178)" class="i">str</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs48', 179)" onmouseover="showTip(event, 'fs48', 179)" class="i">str</span> <span class="o">+</span> (<span onmouseout="hideTip(event, 'fs49', 180)" onmouseover="showTip(event, 'fs49', 180)" class="f">string</span> <span onmouseout="hideTip(event, 'fs24', 181)" onmouseover="showTip(event, 'fs24', 181)" class="i">i</span>))
<span class="c">// "0123456789"</span>
</code></pre></td>
</tr>
</table>
<p>Or start with a value and just repeatedly call a function on it</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs50', 182)" onmouseover="showTip(event, 'fs50', 182)" class="i">x</span> <span class="o">=</span> <span class="n">100.0</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs51', 183)" onmouseover="showTip(event, 'fs51', 183)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs39', 184)" onmouseover="showTip(event, 'fs39', 184)" class="f">forLoop</span> <span class="n">0</span> <span class="n">5</span> <span onmouseout="hideTip(event, 'fs50', 185)" onmouseover="showTip(event, 'fs50', 185)" class="i">x</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs24', 186)" onmouseover="showTip(event, 'fs24', 186)" class="i">i</span> <span onmouseout="hideTip(event, 'fs52', 187)" onmouseover="showTip(event, 'fs52', 187)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs52', 188)" onmouseover="showTip(event, 'fs52', 188)" class="i">x</span> <span class="o">/</span> <span class="n">2.0</span>)
<span class="c">// 3.125</span>
</code></pre></td>
</tr>
</table>
<h2>Creating an immutable <code>foreach</code></h2>
<p>So far we only looped over numbers. But usually we want to loop over whole <em>data-structures</em>.
In C# we have <code>foreach</code> for this kind of idea. For example we can loop over a list in this way.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> sum <span class="o">=</span> <span class="n">0</span>;
<span class="k">foreach</span> ( <span class="k">var</span> x <span class="k">in</span> list ) {
sum <span class="o">=</span> sum <span class="o">+</span> x;
}
</code></pre></td></tr></table>
<p>We now want to do the same but with an <em>immutable F# list</em> instead, so how do we loop an
<em>immutable list</em>? Actually the only thing we can do with a F# list is either prepend some element
or use pattern matching to extract values from the beginning.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs53', 189)" onmouseover="showTip(event, 'fs53', 189)" class="i">numbers1</span> <span class="o">=</span> [<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>]
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs54', 190)" onmouseover="showTip(event, 'fs54', 190)" class="i">numbers2</span> <span class="o">=</span> <span class="n">1</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs53', 191)" onmouseover="showTip(event, 'fs53', 191)" class="i">numbers1</span> <span class="c">// [1;2;3;4;5]</span>
<span class="k">let</span> (<span onmouseout="hideTip(event, 'fs55', 192)" onmouseover="showTip(event, 'fs55', 192)" class="i">head</span><span class="o">::</span><span onmouseout="hideTip(event, 'fs56', 193)" onmouseover="showTip(event, 'fs56', 193)" class="i">tail</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs54', 194)" onmouseover="showTip(event, 'fs54', 194)" class="i">numbers2</span>
<span onmouseout="hideTip(event, 'fs55', 195)" onmouseover="showTip(event, 'fs55', 195)" class="i">head</span> <span class="c">// 1</span>
<span onmouseout="hideTip(event, 'fs56', 196)" onmouseover="showTip(event, 'fs56', 196)" class="i">tail</span> <span class="c">// [2;3;4;5]</span>
</code></pre></td>
</tr>
</table>
<p>Doing the extraction with a <code>let</code> is usually discouraged because such an operation could fail.
If we have an empty list for example we couldn't extract the first element of a list
(and the code throws an exception). With Pattern matching we can specify multiple cases that we
can check. But as you already can imagine again. This must be recursive again! Because we
repeatedly want to extract one element from <code>tail</code> and we sure don't want to write:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> (<span onmouseout="hideTip(event, 'fs57', 197)" onmouseover="showTip(event, 'fs57', 197)" class="i">head1</span><span class="o">::</span><span onmouseout="hideTip(event, 'fs58', 198)" onmouseover="showTip(event, 'fs58', 198)" class="i">tail1</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs54', 199)" onmouseover="showTip(event, 'fs54', 199)" class="i">numbers2</span> <span class="c">// 1 [2;3;4;5]</span>
<span class="k">let</span> (<span onmouseout="hideTip(event, 'fs59', 200)" onmouseover="showTip(event, 'fs59', 200)" class="i">head2</span><span class="o">::</span><span onmouseout="hideTip(event, 'fs60', 201)" onmouseover="showTip(event, 'fs60', 201)" class="i">tail2</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs58', 202)" onmouseover="showTip(event, 'fs58', 202)" class="i">tail1</span> <span class="c">// 2 [3;4;5]</span>
<span class="k">let</span> (<span onmouseout="hideTip(event, 'fs61', 203)" onmouseover="showTip(event, 'fs61', 203)" class="i">head3</span><span class="o">::</span><span onmouseout="hideTip(event, 'fs62', 204)" onmouseover="showTip(event, 'fs62', 204)" class="i">tail3</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs60', 205)" onmouseover="showTip(event, 'fs60', 205)" class="i">tail2</span> <span class="c">// 3 [4;5]</span>
<span class="c">// and so on ...</span>
</code></pre></td>
</tr>
</table>
<p>And on top, we need an exit condition. We want to end as soon we end up with an empty list for <code>tail</code>.
Now let's do the same stuff we did with our <code>forLoop</code>. We expect some <em>initial value</em> that we can
specify as an <em>accumulator</em>. The <code>f</code> function now just gets the list element and our <em>accumulator</em>.
Once we end up with an empty list, we just return the <em>accumulator</em>. We call this function <code>fold</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs63', 206)" onmouseover="showTip(event, 'fs63', 206)" class="f">fold</span> <span onmouseout="hideTip(event, 'fs64', 207)" onmouseover="showTip(event, 'fs64', 207)" class="f">f</span> (<span onmouseout="hideTip(event, 'fs65', 208)" onmouseover="showTip(event, 'fs65', 208)" class="i">acc</span><span class="o">:</span><span class="o">'</span><span class="i">State</span>) <span onmouseout="hideTip(event, 'fs15', 209)" onmouseover="showTip(event, 'fs15', 209)" class="i">list</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs66', 210)" onmouseover="showTip(event, 'fs66', 210)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs67', 211)" onmouseover="showTip(event, 'fs67', 211)" class="i">remainingList</span> <span onmouseout="hideTip(event, 'fs65', 212)" onmouseover="showTip(event, 'fs65', 212)" class="i">acc</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs67', 213)" onmouseover="showTip(event, 'fs67', 213)" class="i">remainingList</span> <span class="k">with</span>
| [] <span class="k">-></span> <span onmouseout="hideTip(event, 'fs65', 214)" onmouseover="showTip(event, 'fs65', 214)" class="i">acc</span> <span class="c">// We return "acc" when we reached the end of the list</span>
| <span onmouseout="hideTip(event, 'fs68', 215)" onmouseover="showTip(event, 'fs68', 215)" class="i">head</span><span class="o">::</span><span onmouseout="hideTip(event, 'fs69', 216)" onmouseover="showTip(event, 'fs69', 216)" class="i">tail</span> <span class="k">-></span> <span class="c">// extract first element of remainingList</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs70', 217)" onmouseover="showTip(event, 'fs70', 217)" class="i">nextAcc</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs64', 218)" onmouseover="showTip(event, 'fs64', 218)" class="f">f</span> <span onmouseout="hideTip(event, 'fs65', 219)" onmouseover="showTip(event, 'fs65', 219)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs68', 220)" onmouseover="showTip(event, 'fs68', 220)" class="i">head</span> <span class="c">// Compute the next accumulator</span>
<span onmouseout="hideTip(event, 'fs66', 221)" onmouseover="showTip(event, 'fs66', 221)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs69', 222)" onmouseover="showTip(event, 'fs69', 222)" class="i">tail</span> <span onmouseout="hideTip(event, 'fs70', 223)" onmouseover="showTip(event, 'fs70', 223)" class="i">nextAcc</span> <span class="c">// Recurse with remaining list "tail" and "nextAcc"</span>
<span onmouseout="hideTip(event, 'fs66', 224)" onmouseover="showTip(event, 'fs66', 224)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs15', 225)" onmouseover="showTip(event, 'fs15', 225)" class="i">list</span> <span onmouseout="hideTip(event, 'fs65', 226)" onmouseover="showTip(event, 'fs65', 226)" class="i">acc</span>
</code></pre></td>
</tr>
</table>
<p>I also changed the order of the arguments compared to the <code>forEach</code> function. Now <code>f</code> comes first
followed by <code>acc</code> and <code>list</code>. Summing a list of <code>int</code>s can now be written as:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs37', 227)" onmouseover="showTip(event, 'fs37', 227)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs63', 228)" onmouseover="showTip(event, 'fs63', 228)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs71', 229)" onmouseover="showTip(event, 'fs71', 229)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs13', 230)" onmouseover="showTip(event, 'fs13', 230)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs71', 231)" onmouseover="showTip(event, 'fs71', 231)" class="i">acc</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs13', 232)" onmouseover="showTip(event, 'fs13', 232)" class="i">x</span>) <span class="n">0</span> [<span class="n">1</span> <span class="o">..</span> <span class="n">9</span>] <span class="c">// 45</span>
</code></pre></td>
</tr>
</table>
<p>So, what is <code>fold</code> exactly? <code>fold</code> is just the idea of looping through a <em>data-structure</em>
in an <em>immutable way</em>. Instead of accessing a <em>mutable variable</em> that you access and <em>mutate</em> while
you are looping, you provide a function as the <em>loop-body</em> and an <em>initial-accumulator</em>.</p>
<p>In looping you then have access to the current element and a <em>mutable variable</em> that you can
modify. In <code>fold</code> your <code>f</code> function you get the current element and the last state as
function arguments. Instead of <em>mutating</em> a variable outside of a loop. In <code>fold</code> you just
return the new state that will be used for the next recursive call.</p>
<p>Your <em>accumulator</em> will be returned as a result once you traversed all elements of
your data-structure.</p>
<h2>Creating <code>map</code></h2>
<p>Now that we abstracted the recursive looping in it's own function, we don't need to write a
recursive loop function anymore to traverse a list! We just can use <code>fold</code> for this purpose.</p>
<p>A first attempt to build <code>map</code> could look like that.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs72', 233)" onmouseover="showTip(event, 'fs72', 233)" class="f">map</span> <span onmouseout="hideTip(event, 'fs4', 234)" onmouseover="showTip(event, 'fs4', 234)" class="f">f</span> <span onmouseout="hideTip(event, 'fs15', 235)" onmouseover="showTip(event, 'fs15', 235)" class="i">list</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs63', 236)" onmouseover="showTip(event, 'fs63', 236)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs73', 237)" onmouseover="showTip(event, 'fs73', 237)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs7', 238)" onmouseover="showTip(event, 'fs7', 238)" class="i">x</span> <span class="k">-></span> <span class="c">// foreach (var x in list )</span>
(<span onmouseout="hideTip(event, 'fs4', 239)" onmouseover="showTip(event, 'fs4', 239)" class="f">f</span> <span onmouseout="hideTip(event, 'fs7', 240)" onmouseover="showTip(event, 'fs7', 240)" class="i">x</span>) <span class="o">::</span> <span onmouseout="hideTip(event, 'fs73', 241)" onmouseover="showTip(event, 'fs73', 241)" class="i">acc</span> <span class="c">// nextAcc <- (f x) :: acc</span>
) [] <span onmouseout="hideTip(event, 'fs15', 242)" onmouseover="showTip(event, 'fs15', 242)" class="i">list</span> <span class="c">// Start with "[]" as "acc" and go through "list"</span>
<span onmouseout="hideTip(event, 'fs72', 243)" onmouseover="showTip(event, 'fs72', 243)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs13', 244)" onmouseover="showTip(event, 'fs13', 244)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 245)" onmouseover="showTip(event, 'fs13', 245)" class="i">x</span> <span class="o">*</span> <span class="n">2</span>) [<span class="n">0..</span><span class="n">9</span>]
<span class="c">// [18; 16; 14; 12; 10; 8; 6; 4; 2; 0]</span>
</code></pre></td>
</tr>
</table>
<p>But we still have the same problem as in the beginning. The list is reversed because we <em>prepend</em>
and not <em>append</em> elements. As we cannot <em>append</em> we have to provide another solution.</p>
<p>Besides a <code>fold</code> we usually also provide a <code>foldBack</code>. A <code>foldBack</code> just traverses a data-structure
backwards or from <em>right-to-left</em> instead of <em>left-to-right</em>.</p>
<p>But we also cannot easily go through a list backwards, an easy fix to this problem is when we
implement <code>foldBack</code> by first <em>reversing</em> the input list and then use <code>fold</code> on it. After we
have <code>foldBack</code> we can define <code>map</code> with <code>foldBack</code> instead of <code>fold</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// Reverses a List</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs74', 246)" onmouseover="showTip(event, 'fs74', 246)" class="f">rev</span> <span onmouseout="hideTip(event, 'fs15', 247)" onmouseover="showTip(event, 'fs15', 247)" class="i">list</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs63', 248)" onmouseover="showTip(event, 'fs63', 248)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs75', 249)" onmouseover="showTip(event, 'fs75', 249)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs7', 250)" onmouseover="showTip(event, 'fs7', 250)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 251)" onmouseover="showTip(event, 'fs7', 251)" class="i">x</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs75', 252)" onmouseover="showTip(event, 'fs75', 252)" class="i">acc</span>) [] <span onmouseout="hideTip(event, 'fs15', 253)" onmouseover="showTip(event, 'fs15', 253)" class="i">list</span>
<span class="c">// foldBack loops through the list from the end to start</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs76', 254)" onmouseover="showTip(event, 'fs76', 254)" class="f">foldBack</span> <span onmouseout="hideTip(event, 'fs77', 255)" onmouseover="showTip(event, 'fs77', 255)" class="f">f</span> <span onmouseout="hideTip(event, 'fs15', 256)" onmouseover="showTip(event, 'fs15', 256)" class="i">list</span> (<span onmouseout="hideTip(event, 'fs65', 257)" onmouseover="showTip(event, 'fs65', 257)" class="i">acc</span><span class="o">:</span><span class="o">'</span><span class="i">State</span>) <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs63', 258)" onmouseover="showTip(event, 'fs63', 258)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs65', 259)" onmouseover="showTip(event, 'fs65', 259)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs7', 260)" onmouseover="showTip(event, 'fs7', 260)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs77', 261)" onmouseover="showTip(event, 'fs77', 261)" class="f">f</span> <span onmouseout="hideTip(event, 'fs7', 262)" onmouseover="showTip(event, 'fs7', 262)" class="i">x</span> <span onmouseout="hideTip(event, 'fs65', 263)" onmouseover="showTip(event, 'fs65', 263)" class="i">acc</span>) <span onmouseout="hideTip(event, 'fs65', 264)" onmouseover="showTip(event, 'fs65', 264)" class="i">acc</span> (<span onmouseout="hideTip(event, 'fs74', 265)" onmouseover="showTip(event, 'fs74', 265)" class="f">rev</span> <span onmouseout="hideTip(event, 'fs15', 266)" onmouseover="showTip(event, 'fs15', 266)" class="i">list</span>)
<span class="c">// map defined in terms of foldBack</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs72', 267)" onmouseover="showTip(event, 'fs72', 267)" class="f">map</span> <span onmouseout="hideTip(event, 'fs4', 268)" onmouseover="showTip(event, 'fs4', 268)" class="f">f</span> <span onmouseout="hideTip(event, 'fs15', 269)" onmouseover="showTip(event, 'fs15', 269)" class="i">list</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs76', 270)" onmouseover="showTip(event, 'fs76', 270)" class="f">foldBack</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs7', 271)" onmouseover="showTip(event, 'fs7', 271)" class="i">x</span> <span onmouseout="hideTip(event, 'fs73', 272)" onmouseover="showTip(event, 'fs73', 272)" class="i">acc</span> <span class="k">-></span> (<span onmouseout="hideTip(event, 'fs4', 273)" onmouseover="showTip(event, 'fs4', 273)" class="f">f</span> <span onmouseout="hideTip(event, 'fs7', 274)" onmouseover="showTip(event, 'fs7', 274)" class="i">x</span>) <span class="o">::</span> <span onmouseout="hideTip(event, 'fs73', 275)" onmouseover="showTip(event, 'fs73', 275)" class="i">acc</span>) <span onmouseout="hideTip(event, 'fs15', 276)" onmouseover="showTip(event, 'fs15', 276)" class="i">list</span> []
<span class="c">// Now we get the right result</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs78', 277)" onmouseover="showTip(event, 'fs78', 277)" class="i">numbers</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs72', 278)" onmouseover="showTip(event, 'fs72', 278)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs13', 279)" onmouseover="showTip(event, 'fs13', 279)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 280)" onmouseover="showTip(event, 'fs13', 280)" class="i">x</span> <span class="o">*</span> <span class="n">2</span>) [<span class="n">1</span> <span class="o">..</span> <span class="n">9</span>]
<span class="c">// [2; 4; 6; 8; 10; 12; 14; 16; 18]</span>
</code></pre></td>
</tr>
</table>
<p>Probably you wonder why we choose different argument orders for <code>fold</code> and <code>foldBack</code> including the
arguments for the <code>f</code> function. In <code>fold</code> we first have <code>acc</code> then <code>x</code>, in <code>foldBack</code> it is reversed.
<code>x</code> then <code>acc</code>. The reason is, the position of <code>acc</code> <em>resembles</em> the order how we traverse the list.</p>
<p>In <code>fold</code> we go from left to right. We start with the initial <code>acc</code>, we extract the first value
from our list and we somehow <em>combine</em> it with the already present <code>acc</code>. Let's visualize the
steps that code like this do:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs37', 281)" onmouseover="showTip(event, 'fs37', 281)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs63', 282)" onmouseover="showTip(event, 'fs63', 282)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs71', 283)" onmouseover="showTip(event, 'fs71', 283)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs13', 284)" onmouseover="showTip(event, 'fs13', 284)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs71', 285)" onmouseover="showTip(event, 'fs71', 285)" class="i">acc</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs13', 286)" onmouseover="showTip(event, 'fs13', 286)" class="i">x</span>) <span class="n">0</span> [<span class="n">1..</span><span class="n">5</span>]
</code></pre></td>
</tr>
</table>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">acc</span> | <span onmouseout="hideTip(event, 'fs79', 287)" onmouseover="showTip(event, 'fs79', 287)" class="i">list</span> | <span class="i">acc</span> <span class="o">+</span> <span class="i">x</span>
<span class="o">-----------------------------</span>
<span class="n">0</span> | [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>] | <span class="n">0</span> <span class="o">+</span> <span class="n">1</span>
<span class="n">1</span> | [<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>] | <span class="n">1</span> <span class="o">+</span> <span class="n">2</span>
<span class="n">3</span> | [<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>] | <span class="n">3</span> <span class="o">+</span> <span class="n">3</span>
<span class="n">6</span> | [<span class="n">4</span>;<span class="n">5</span>] | <span class="n">6</span> <span class="o">+</span> <span class="n">4</span>
<span class="n">10</span> | [<span class="n">5</span>] | <span class="n">10</span> <span class="o">+</span> <span class="n">5</span>
<span class="n">15</span> | [] | <span class="k">return</span> <span class="k">-></span> <span class="n">15</span>
</code></pre></td>
</tr>
</table>
<p>When we use <code>foldBack</code> we get the same result, but we go from right to left.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs37', 288)" onmouseover="showTip(event, 'fs37', 288)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs76', 289)" onmouseover="showTip(event, 'fs76', 289)" class="f">foldBack</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs13', 290)" onmouseover="showTip(event, 'fs13', 290)" class="i">x</span> <span onmouseout="hideTip(event, 'fs71', 291)" onmouseover="showTip(event, 'fs71', 291)" class="i">acc</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 292)" onmouseover="showTip(event, 'fs13', 292)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs71', 293)" onmouseover="showTip(event, 'fs71', 293)" class="i">acc</span>) [<span class="n">1..</span><span class="n">5</span>] <span class="n">0</span>
</code></pre></td>
</tr>
</table>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs79', 294)" onmouseover="showTip(event, 'fs79', 294)" class="i">list</span> | <span class="i">acc</span> | <span class="i">x</span> <span class="o">+</span> <span class="i">acc</span>
<span class="o">---------------------------</span>
[<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>] | <span class="n">0</span> | <span class="n">5</span> <span class="o">+</span> <span class="n">0</span>
[<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>] | <span class="n">5</span> | <span class="n">4</span> <span class="o">+</span> <span class="n">5</span>
[<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>] | <span class="n">9</span> | <span class="n">3</span> <span class="o">+</span> <span class="n">9</span>
[<span class="n">1</span>;<span class="n">2</span>] | <span class="n">12</span> | <span class="n">2</span> <span class="o">+</span> <span class="n">12</span>
[<span class="n">1</span>] | <span class="n">14</span> | <span class="n">1</span> <span class="o">+</span> <span class="n">14</span>
[] | <span class="n">15</span> | <span class="k">return</span> <span class="k">-></span> <span class="n">15</span>
</code></pre></td>
</tr>
</table>
<p>That's why we use <code>acc x</code> in <code>fold</code> and <code>x acc</code> in <code>foldBack</code>. For summing numbers this
doesn't make any difference, but for other operations like <code>map</code> it does!</p>
<h2><code>length</code>, <code>filter</code>, <code>iter</code>, <code>append</code>, <code>concat</code> and <code>collect</code></h2>
<p>Let's create some more functions. As an exercise you also can try to first implement
those functions yourself.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
<span class="l">19: </span>
<span class="l">20: </span>
<span class="l">21: </span>
<span class="l">22: </span>
<span class="l">23: </span>
<span class="l">24: </span>
<span class="l">25: </span>
<span class="l">26: </span>
<span class="l">27: </span>
<span class="l">28: </span>
<span class="l">29: </span>
<span class="l">30: </span>
<span class="l">31: </span>
<span class="l">32: </span>
<span class="l">33: </span>
<span class="l">34: </span>
<span class="l">35: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// Length</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs80', 295)" onmouseover="showTip(event, 'fs80', 295)" class="f">length</span> <span onmouseout="hideTip(event, 'fs81', 296)" onmouseover="showTip(event, 'fs81', 296)" class="i">xs</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs63', 297)" onmouseover="showTip(event, 'fs63', 297)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs71', 298)" onmouseover="showTip(event, 'fs71', 298)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs7', 299)" onmouseover="showTip(event, 'fs7', 299)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs71', 300)" onmouseover="showTip(event, 'fs71', 300)" class="i">acc</span> <span class="o">+</span> <span class="n">1</span>) <span class="n">0</span> <span onmouseout="hideTip(event, 'fs81', 301)" onmouseover="showTip(event, 'fs81', 301)" class="i">xs</span>
<span onmouseout="hideTip(event, 'fs80', 302)" onmouseover="showTip(event, 'fs80', 302)" class="f">length</span> [<span class="n">1..</span><span class="n">10</span>] <span class="c">// 10</span>
<span class="c">// Filter</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs82', 303)" onmouseover="showTip(event, 'fs82', 303)" class="f">filter</span> <span onmouseout="hideTip(event, 'fs83', 304)" onmouseover="showTip(event, 'fs83', 304)" class="f">predicate</span> <span onmouseout="hideTip(event, 'fs81', 305)" onmouseover="showTip(event, 'fs81', 305)" class="i">xs</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs76', 306)" onmouseover="showTip(event, 'fs76', 306)" class="f">foldBack</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs7', 307)" onmouseover="showTip(event, 'fs7', 307)" class="i">x</span> <span onmouseout="hideTip(event, 'fs75', 308)" onmouseover="showTip(event, 'fs75', 308)" class="i">acc</span> <span class="k">-></span> <span class="k">if</span> <span onmouseout="hideTip(event, 'fs83', 309)" onmouseover="showTip(event, 'fs83', 309)" class="f">predicate</span> <span onmouseout="hideTip(event, 'fs7', 310)" onmouseover="showTip(event, 'fs7', 310)" class="i">x</span> <span class="k">then</span> <span onmouseout="hideTip(event, 'fs7', 311)" onmouseover="showTip(event, 'fs7', 311)" class="i">x</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs75', 312)" onmouseover="showTip(event, 'fs75', 312)" class="i">acc</span> <span class="k">else</span> <span onmouseout="hideTip(event, 'fs75', 313)" onmouseover="showTip(event, 'fs75', 313)" class="i">acc</span>) <span onmouseout="hideTip(event, 'fs81', 314)" onmouseover="showTip(event, 'fs81', 314)" class="i">xs</span> []
<span onmouseout="hideTip(event, 'fs82', 315)" onmouseover="showTip(event, 'fs82', 315)" class="f">filter</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs13', 316)" onmouseover="showTip(event, 'fs13', 316)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 317)" onmouseover="showTip(event, 'fs13', 317)" class="i">x</span> <span class="o">%</span> <span class="n">2</span> <span class="o">=</span> <span class="n">0</span>) [<span class="n">1..</span><span class="n">10</span>] <span class="c">// [2;4;6;8;10]</span>
<span class="c">// Iter</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs84', 318)" onmouseover="showTip(event, 'fs84', 318)" class="f">iter</span> <span onmouseout="hideTip(event, 'fs85', 319)" onmouseover="showTip(event, 'fs85', 319)" class="f">f</span> <span onmouseout="hideTip(event, 'fs81', 320)" onmouseover="showTip(event, 'fs81', 320)" class="i">xs</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs63', 321)" onmouseover="showTip(event, 'fs63', 321)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs86', 322)" onmouseover="showTip(event, 'fs86', 322)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs7', 323)" onmouseover="showTip(event, 'fs7', 323)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs85', 324)" onmouseover="showTip(event, 'fs85', 324)" class="f">f</span> <span onmouseout="hideTip(event, 'fs7', 325)" onmouseover="showTip(event, 'fs7', 325)" class="i">x</span>) () <span onmouseout="hideTip(event, 'fs81', 326)" onmouseover="showTip(event, 'fs81', 326)" class="i">xs</span>
<span onmouseout="hideTip(event, 'fs84', 327)" onmouseover="showTip(event, 'fs84', 327)" class="f">iter</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs13', 328)" onmouseover="showTip(event, 'fs13', 328)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 329)" onmouseover="showTip(event, 'fs18', 329)" class="f">printfn</span> <span class="s">"</span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs13', 330)" onmouseover="showTip(event, 'fs13', 330)" class="i">x</span>) [<span class="n">1..</span><span class="n">5</span>] <span class="c">// Prints numbers 1 to 5 on a line</span>
<span class="c">// Append</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs87', 331)" onmouseover="showTip(event, 'fs87', 331)" class="f">append</span> <span onmouseout="hideTip(event, 'fs81', 332)" onmouseover="showTip(event, 'fs81', 332)" class="i">xs</span> <span onmouseout="hideTip(event, 'fs88', 333)" onmouseover="showTip(event, 'fs88', 333)" class="i">ys</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs76', 334)" onmouseover="showTip(event, 'fs76', 334)" class="f">foldBack</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs7', 335)" onmouseover="showTip(event, 'fs7', 335)" class="i">x</span> <span onmouseout="hideTip(event, 'fs75', 336)" onmouseover="showTip(event, 'fs75', 336)" class="i">acc</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 337)" onmouseover="showTip(event, 'fs7', 337)" class="i">x</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs75', 338)" onmouseover="showTip(event, 'fs75', 338)" class="i">acc</span>) <span onmouseout="hideTip(event, 'fs81', 339)" onmouseover="showTip(event, 'fs81', 339)" class="i">xs</span> <span onmouseout="hideTip(event, 'fs88', 340)" onmouseover="showTip(event, 'fs88', 340)" class="i">ys</span>
<span onmouseout="hideTip(event, 'fs87', 341)" onmouseover="showTip(event, 'fs87', 341)" class="f">append</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>] [<span class="n">4</span>;<span class="n">5</span>;<span class="n">6</span>] <span class="c">// [1;2;3;4;5;6]</span>
<span class="c">// concat</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs89', 342)" onmouseover="showTip(event, 'fs89', 342)" class="f">concat</span> <span onmouseout="hideTip(event, 'fs90', 343)" onmouseover="showTip(event, 'fs90', 343)" class="i">lol</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs63', 344)" onmouseover="showTip(event, 'fs63', 344)" class="f">fold</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs75', 345)" onmouseover="showTip(event, 'fs75', 345)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs91', 346)" onmouseover="showTip(event, 'fs91', 346)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs87', 347)" onmouseover="showTip(event, 'fs87', 347)" class="f">append</span> <span onmouseout="hideTip(event, 'fs75', 348)" onmouseover="showTip(event, 'fs75', 348)" class="i">acc</span> <span onmouseout="hideTip(event, 'fs91', 349)" onmouseover="showTip(event, 'fs91', 349)" class="i">x</span>) [] <span onmouseout="hideTip(event, 'fs90', 350)" onmouseover="showTip(event, 'fs90', 350)" class="i">lol</span>
<span onmouseout="hideTip(event, 'fs89', 351)" onmouseover="showTip(event, 'fs89', 351)" class="f">concat</span> [[<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>]; [<span class="n">4</span>;<span class="n">5</span>;<span class="n">6</span>]; [<span class="n">7</span>;<span class="n">8</span>;<span class="n">9</span>]] <span class="c">// [1;2;3;4;5;6;7;8;9]</span>
<span class="c">// collect</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs92', 352)" onmouseover="showTip(event, 'fs92', 352)" class="f">collect</span> <span onmouseout="hideTip(event, 'fs93', 353)" onmouseover="showTip(event, 'fs93', 353)" class="f">f</span> <span onmouseout="hideTip(event, 'fs81', 354)" onmouseover="showTip(event, 'fs81', 354)" class="i">xs</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs72', 355)" onmouseover="showTip(event, 'fs72', 355)" class="f">map</span> <span onmouseout="hideTip(event, 'fs93', 356)" onmouseover="showTip(event, 'fs93', 356)" class="f">f</span> <span onmouseout="hideTip(event, 'fs81', 357)" onmouseover="showTip(event, 'fs81', 357)" class="i">xs</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs89', 358)" onmouseover="showTip(event, 'fs89', 358)" class="f">concat</span>
<span onmouseout="hideTip(event, 'fs92', 359)" onmouseover="showTip(event, 'fs92', 359)" class="f">collect</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs13', 360)" onmouseover="showTip(event, 'fs13', 360)" class="i">x</span> <span class="k">-></span> [<span onmouseout="hideTip(event, 'fs13', 361)" onmouseover="showTip(event, 'fs13', 361)" class="i">x</span>;<span onmouseout="hideTip(event, 'fs13', 362)" onmouseover="showTip(event, 'fs13', 362)" class="i">x</span>;<span onmouseout="hideTip(event, 'fs13', 363)" onmouseover="showTip(event, 'fs13', 363)" class="i">x</span>]) [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>] <span class="c">// [1;1;1;2;2;2;3;3;3]</span>
</code></pre></td>
</tr>
</table>
<p>From the implementation i think only <code>append</code>, <code>concat</code> and <code>collect</code> are interesting.</p>
<p>In <code>append</code> you see that you don't have to start from an empty list. Appending two list basically
means you prepend the first list to the second list by going backwards through the first list. So
the second list is your starting <em>accumulator</em>.</p>
<p>With <code>append</code> in place, <code>concat</code> becomes easy. As you just repeatedly append two lists to a single
one.</p>
<p>And once you have <code>concat</code>, it is also pretty easy to implement <code>collect</code> through <code>map</code> and <code>concat</code>.</p>
<h2>Summary</h2>
<p>We first started with some loops that modifies <em>mutable variables</em>. In order to get rid of <em>mutable</em>
variables or to work with <em>immutable data-structures</em> we need recursion. Without <em>recursion</em>
it is basically impossible to effectively work with <em>immutable data-structures</em>. But this doesn't mean
we always have to write recursive functions.</p>
<p>We start by implementing a <code>fold</code> function that does the same thing as a <code>foreach</code> loop just in
an <em>immutable</em> way. With <code>fold</code> we abstracted the <em>recursive looping</em> in it's own function.
New functions can now be implemented on top of <code>fold</code> or the function we created with <code>fold</code>.</p>
<p>While <em>recursion</em> is indeed an important aspect of functional programming, as we just need it to
work with <em>immutable data</em>. It doesn't mean we should use <em>recursion</em> all over the place. The use
of <em>recursion</em> is often a sign that we lack abstraction.</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">type ResizeArray<'T> = System.Collections.Generic.List<'T><br /><br />Full name: Microsoft.FSharp.Collections.ResizeArray<_></div>
<div class="tip" id="fs3">val map : f:('a -> 'b) -> oldArray:seq<'a> -> System.Collections.Generic.List<'b><br /><br />Full name: Main.ResizeArray.map</div>
<div class="tip" id="fs4">val f : ('a -> 'b)</div>
<div class="tip" id="fs5">val oldArray : seq<'a></div>
<div class="tip" id="fs6">val newArray : System.Collections.Generic.List<'b></div>
<div class="tip" id="fs7">val x : 'a</div>
<div class="tip" id="fs8">System.Collections.Generic.List.Add(item: 'b) : unit</div>
<div class="tip" id="fs9">val numbers : System.Collections.Generic.List<int><br /><br />Full name: Main.numbers</div>
<div class="tip" id="fs10">Multiple items<br />module ResizeArray<br /><br />from Main<br /><br />--------------------<br />type ResizeArray<'T> = System.Collections.Generic.List<'T><br /><br />Full name: Microsoft.FSharp.Collections.ResizeArray<_></div>
<div class="tip" id="fs11">System.Collections.Generic.List.Add(item: int) : unit</div>
<div class="tip" id="fs12">val squaredNumbers : System.Collections.Generic.List<int><br /><br />Full name: Main.squaredNumbers</div>
<div class="tip" id="fs13">val x : int</div>
<div class="tip" id="fs14">val mapWithImmutableList : f:('a -> 'b) -> list:'a list -> 'b list<br /><br />Full name: Main.mapWithImmutableList</div>
<div class="tip" id="fs15">Multiple items<br />val list : 'a list<br /><br />--------------------<br />type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs16">val mutable acc : 'b list</div>
<div class="tip" id="fs17">val i : int<br /><br />Full name: Main.i</div>
<div class="tip" id="fs18">val printfn : format:Printf.TextWriterFormat<'T> -> 'T<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn</div>
<div class="tip" id="fs19">val i1 : int<br /><br />Full name: Main.i1</div>
<div class="tip" id="fs20">val i2 : int<br /><br />Full name: Main.i2</div>
<div class="tip" id="fs21">val i3 : int<br /><br />Full name: Main.i3</div>
<div class="tip" id="fs22">val calc : int<br /><br />Full name: mutableloopstoimmutability.calc</div>
<div class="tip" id="fs23">val loop : i:int -> 'a<br /><br />Full name: Main.loop</div>
<div class="tip" id="fs24">val i : int</div>
<div class="tip" id="fs25">val loop : i:int -> unit<br /><br />Full name: Main.loop</div>
<div class="tip" id="fs26">val forLoop : i:int -> stop:int -> f:(int -> unit) -> unit<br /><br />Full name: Main.forLoop</div>
<div class="tip" id="fs27">val stop : int</div>
<div class="tip" id="fs28">val f : (int -> unit)</div>
<div class="tip" id="fs29">val forLoop : start:int -> stop:int -> f:(int -> unit) -> unit<br /><br />Full name: Main.forLoop</div>
<div class="tip" id="fs30">val start : int</div>
<div class="tip" id="fs31">val loop : (int -> unit)</div>
<div class="tip" id="fs32">val forLoop : start:int -> stop:int -> f:(int -> int -> int) -> int<br /><br />Full name: Main.forLoop</div>
<div class="tip" id="fs33">val f : (int -> int -> int)</div>
<div class="tip" id="fs34">val loop : (int -> int -> int)</div>
<div class="tip" id="fs35">val sum : int</div>
<div class="tip" id="fs36">val nextSum : int</div>
<div class="tip" id="fs37">val sum : int<br /><br />Full name: Main.sum</div>
<div class="tip" id="fs38">Multiple items<br />val int : value:'T -> int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int<br /><br />--------------------<br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />--------------------<br />type int<'Measure> = int<br /><br />Full name: Microsoft.FSharp.Core.int<_></div>
<div class="tip" id="fs39">val forLoop : start:int -> stop:int -> init:'a -> f:(int -> 'a -> 'a) -> 'a<br /><br />Full name: Main.forLoop</div>
<div class="tip" id="fs40">val init : 'a</div>
<div class="tip" id="fs41">val f : (int -> 'a -> 'a)</div>
<div class="tip" id="fs42">val loop : (int -> 'a -> 'a)</div>
<div class="tip" id="fs43">val acc : 'a</div>
<div class="tip" id="fs44">val nextAcc : 'a</div>
<div class="tip" id="fs45">val listOfNumbers : int list<br /><br />Full name: Main.listOfNumbers</div>
<div class="tip" id="fs46">Multiple items<br />val list : int list<br /><br />--------------------<br />type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs47">val stringofNumbers : string<br /><br />Full name: Main.stringofNumbers</div>
<div class="tip" id="fs48">val str : string</div>
<div class="tip" id="fs49">Multiple items<br />val string : value:'T -> string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string<br /><br />--------------------<br />type string = System.String<br /><br />Full name: Microsoft.FSharp.Core.string</div>
<div class="tip" id="fs50">val x : float<br /><br />Full name: Main.x</div>
<div class="tip" id="fs51">val y : float<br /><br />Full name: Main.y</div>
<div class="tip" id="fs52">val x : float</div>
<div class="tip" id="fs53">val numbers1 : int list<br /><br />Full name: Main.numbers1</div>
<div class="tip" id="fs54">val numbers2 : int list<br /><br />Full name: Main.numbers2</div>
<div class="tip" id="fs55">val head : int<br /><br />Full name: Main.head</div>
<div class="tip" id="fs56">val tail : int list<br /><br />Full name: Main.tail</div>
<div class="tip" id="fs57">val head1 : int<br /><br />Full name: Main.head1</div>
<div class="tip" id="fs58">val tail1 : int list<br /><br />Full name: Main.tail1</div>
<div class="tip" id="fs59">val head2 : int<br /><br />Full name: Main.head2</div>
<div class="tip" id="fs60">val tail2 : int list<br /><br />Full name: Main.tail2</div>
<div class="tip" id="fs61">val head3 : int<br /><br />Full name: Main.head3</div>
<div class="tip" id="fs62">val tail3 : int list<br /><br />Full name: Main.tail3</div>
<div class="tip" id="fs63">val fold : f:('State -> 'a -> 'State) -> acc:'State -> list:'a list -> 'State<br /><br />Full name: Main.fold</div>
<div class="tip" id="fs64">val f : ('State -> 'a -> 'State)</div>
<div class="tip" id="fs65">val acc : 'State</div>
<div class="tip" id="fs66">val loop : ('a list -> 'State -> 'State)</div>
<div class="tip" id="fs67">val remainingList : 'a list</div>
<div class="tip" id="fs68">val head : 'a</div>
<div class="tip" id="fs69">val tail : 'a list</div>
<div class="tip" id="fs70">val nextAcc : 'State</div>
<div class="tip" id="fs71">val acc : int</div>
<div class="tip" id="fs72">val map : f:('a -> 'b) -> list:'a list -> 'b list<br /><br />Full name: Main.map</div>
<div class="tip" id="fs73">val acc : 'b list</div>
<div class="tip" id="fs74">val rev : list:'a list -> 'a list<br /><br />Full name: Main.rev</div>
<div class="tip" id="fs75">val acc : 'a list</div>
<div class="tip" id="fs76">val foldBack : f:('a -> 'State -> 'State) -> list:'a list -> acc:'State -> 'State<br /><br />Full name: Main.foldBack</div>
<div class="tip" id="fs77">val f : ('a -> 'State -> 'State)</div>
<div class="tip" id="fs78">val numbers : int list<br /><br />Full name: Main.numbers</div>
<div class="tip" id="fs79">type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs80">val length : xs:'a list -> int<br /><br />Full name: Main.length</div>
<div class="tip" id="fs81">val xs : 'a list</div>
<div class="tip" id="fs82">val filter : predicate:('a -> bool) -> xs:'a list -> 'a list<br /><br />Full name: Main.filter</div>
<div class="tip" id="fs83">val predicate : ('a -> bool)</div>
<div class="tip" id="fs84">val iter : f:('a -> unit) -> xs:'a list -> unit<br /><br />Full name: Main.iter</div>
<div class="tip" id="fs85">val f : ('a -> unit)</div>
<div class="tip" id="fs86">val acc : unit</div>
<div class="tip" id="fs87">val append : xs:'a list -> ys:'a list -> 'a list<br /><br />Full name: Main.append</div>
<div class="tip" id="fs88">val ys : 'a list</div>
<div class="tip" id="fs89">val concat : lol:'a list list -> 'a list<br /><br />Full name: Main.concat</div>
<div class="tip" id="fs90">val lol : 'a list list</div>
<div class="tip" id="fs91">val x : 'a list</div>
<div class="tip" id="fs92">val collect : f:('a -> 'b list) -> xs:'a list -> 'b list<br /><br />Full name: Main.collect</div>
<div class="tip" id="fs93">val f : ('a -> 'b list)</div>
Understanding bind2016-04-03T00:00:00+00:00https://sidburn.github.io/blog/2016/04/03/understanding-bind<p>In <a href="/blog/2016/03/27/understanding-map">Understanding map</a> we learned that implementing
a <code>map</code> function is what we call a <em>Functor</em>. In <a href="/blog/2016/03/31/applicative-functors">Applicative Functors</a>
we extended that idea with the <code>return</code> and <code>apply</code> function. The next important function in our toolset is
the <code>bind</code> function.</p>
<h2>Monads</h2>
<p>The combination of <code>return</code> and <code>bind</code> is what we call a Monad. But currently
I will not consider this as an introduction to Monads at all. If you heard the <em>Monad</em> term and
search for an introduction to understand what a <em>Monad</em> is you will not find an answer her. If
you already have some basic understanding about the term than this and my two previous blogs
can help to understand the concept. Otherwise if you just try to understand what a <em>Monad</em> is
I recommend the following link to understand the problem:
<a href="http://two-wrongs.com/the-what-are-monads-fallacy">The what are Monads Fallacy</a></p>
<h2>The Problem</h2>
<p>I think it is always good to start with a problem. If we understand a problem first, we usually
have it easier to understand why we are doing something. Currently we have <code>map</code> to upgrade functions with
one argument, with <code>return</code> and <code>apply</code> we could upgrade functions with multiple arguments. So
what is <code>bind</code> supposed to do?</p>
<p>Up to this point we only upgraded functions that had normal unboxed input and output types. We always
faced functions like <code>'a -> 'b</code>, but never functions like <code>'a -> option<'b></code>, <code>'a -> Async<'b></code>
or <code>'a -> list<'b></code>. But in practice, the latter are quite common.</p>
<p>A simple example is a function that tries to parse a <code>string</code> to a <code>float</code>. Because parsing of
a string to a float could fail we usually expect a return type like <code>option<float></code>. Usually we
create a <code>Double</code> extension for this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// Note: .NET System.Double is "float" in F# and "double" in C#.</span>
<span class="c">// .NET System.Single is "float32" in F# and "float" in C#.</span>
<span class="k">type</span> <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="t">Double</span> <span class="k">with</span>
<span class="k">static</span> <span class="k">member</span> <span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="f">tryParse</span> <span onmouseout="hideTip(event, 'fs5', 5)" onmouseover="showTip(event, 'fs5', 5)" class="i">str</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs3', 6)" onmouseover="showTip(event, 'fs3', 6)" class="t">Double</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs6', 7)" onmouseover="showTip(event, 'fs6', 7)" class="f">TryParse</span> <span onmouseout="hideTip(event, 'fs5', 8)" onmouseover="showTip(event, 'fs5', 8)" class="i">str</span> <span class="k">with</span>
| <span class="k">false</span>,_ <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 9)" onmouseover="showTip(event, 'fs7', 9)" class="p">None</span>
| <span class="k">true</span>,<span onmouseout="hideTip(event, 'fs8', 10)" onmouseover="showTip(event, 'fs8', 10)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs9', 11)" onmouseover="showTip(event, 'fs9', 11)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs8', 12)" onmouseover="showTip(event, 'fs8', 12)" class="i">x</span>
</code></pre></td>
</tr>
</table>
<p>We now have a function <code>Double.tryParse</code> with the signature.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs10', 13)" onmouseover="showTip(event, 'fs10', 13)" class="f">string</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 14)" onmouseover="showTip(event, 'fs11', 14)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs12', 15)" onmouseover="showTip(event, 'fs12', 15)" class="i">float</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>I will call such functions <em>Monadic functions</em> from now on. All <em>Monadic functions</em> expect
normal input arguments, but return a boxed type, like <code>option<'a></code>, <code>list<'a></code>, <code>Async<'a></code>
and so on.</p>
<p>The problem with such functions is that we cannot easily upgrade them like other functions. For example,
let's assume we have a <code>option<string></code>, and now we want to pass this value to <code>Double.tryParse</code>.
As <code>tryParse</code> only expects <code>string</code> we could <code>Option.map</code> <code>tryParse</code> so it could work with
a <code>option<string></code>.</p>
<p>But <code>map</code> not only adds a <code>option</code> <em>layer</em> to the input, it also adds it to the output. When we
use <code>Option.map</code> on our <code>Double.tryParse</code> function, we get a function that looks like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs11', 16)" onmouseover="showTip(event, 'fs11', 16)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs10', 17)" onmouseover="showTip(event, 'fs10', 17)" class="i">string</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 18)" onmouseover="showTip(event, 'fs11', 18)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs11', 19)" onmouseover="showTip(event, 'fs11', 19)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs12', 20)" onmouseover="showTip(event, 'fs12', 20)" class="i">float</span><span class="o">></span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>The problem is that our <em>output</em> is wrapped two times in the same layer. Now we have a
<em>option containing an option containing a float</em>. But what we really want is just an <code>option<float></code>.
This is where <code>bind</code> comes into the play. The purpose of <code>bind</code> is to only <em>upgrade</em> the input of a
function because the output of a function already returns an upgraded type. A <code>bind</code> function thus
always have the <em>type-signature</em></p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 21)" onmouseover="showTip(event, 'fs11', 21)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 22)" onmouseover="showTip(event, 'fs11', 22)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 23)" onmouseover="showTip(event, 'fs11', 23)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 24)" onmouseover="showTip(event, 'fs13', 24)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 25)" onmouseover="showTip(event, 'fs13', 25)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs13', 26)" onmouseover="showTip(event, 'fs13', 26)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 27)" onmouseover="showTip(event, 'fs14', 27)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 28)" onmouseover="showTip(event, 'fs14', 28)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 29)" onmouseover="showTip(event, 'fs14', 29)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<h2><code>return</code> once again</h2>
<p>The <code>bind</code> function don't stands on it's own. We also need a <code>return</code> function. But we
already covered this function in <a href="/blog/2016/03/31/applicative-functors">Applicative Functors</a>.</p>
<h2>Implementing <code>bind</code></h2>
<p>We can implement <code>bind</code> in two different ways. It is good to know both as depending on which type we
have, sometimes the one or the other can be easier.</p>
<ol>
<li>
The obvious way. You directly write a <code>bind</code> function that is similar to <code>map</code>, but instead
of wrapping the output, you just return the output of the function as-is.
</li>
<li>
You first write a <code>join</code>, <code>concat</code> or <code>flatten</code> function (The exact name of such a function
usually depends on the type you have). The idea of such a function is to resolve two
boxed types just into a single box. After this you just <code>map</code> and then <code>join</code> the result
to create <code>bind</code>.
</li>
</ol>
<p>The <code>option</code> type has the advantage that both implementations are easy, so let's look at how we could
implement <code>bind</code> for <code>Option</code> in both ways.</p>
<h3>The direct way</h3>
<p>The <em>direct</em> way can sometimes be nearly identical to <code>map</code>. Let's look at the <code>map</code> and <code>bind</code>
implementation side-by-side.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
<span class="l">9: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs15', 30)" onmouseover="showTip(event, 'fs15', 30)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs16', 31)" onmouseover="showTip(event, 'fs16', 31)" class="f">f</span> <span onmouseout="hideTip(event, 'fs17', 32)" onmouseover="showTip(event, 'fs17', 32)" class="i">opt</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs17', 33)" onmouseover="showTip(event, 'fs17', 33)" class="i">opt</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs7', 34)" onmouseover="showTip(event, 'fs7', 34)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 35)" onmouseover="showTip(event, 'fs7', 35)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs9', 36)" onmouseover="showTip(event, 'fs9', 36)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs18', 37)" onmouseover="showTip(event, 'fs18', 37)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs9', 38)" onmouseover="showTip(event, 'fs9', 38)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs16', 39)" onmouseover="showTip(event, 'fs16', 39)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 40)" onmouseover="showTip(event, 'fs18', 40)" class="i">x</span>)
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs19', 41)" onmouseover="showTip(event, 'fs19', 41)" class="f">bindOption</span> <span onmouseout="hideTip(event, 'fs20', 42)" onmouseover="showTip(event, 'fs20', 42)" class="f">f</span> <span onmouseout="hideTip(event, 'fs17', 43)" onmouseover="showTip(event, 'fs17', 43)" class="i">opt</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs17', 44)" onmouseover="showTip(event, 'fs17', 44)" class="i">opt</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs7', 45)" onmouseover="showTip(event, 'fs7', 45)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 46)" onmouseover="showTip(event, 'fs7', 46)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs9', 47)" onmouseover="showTip(event, 'fs9', 47)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs18', 48)" onmouseover="showTip(event, 'fs18', 48)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs20', 49)" onmouseover="showTip(event, 'fs20', 49)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 50)" onmouseover="showTip(event, 'fs18', 50)" class="i">x</span>
</code></pre></td>
</tr>
</table>
<p>As you can see, both functions are nearly identical. The only difference is that we just do <code>f x</code> instead
of <code>Some (f x)</code>. We don't need to wrap the output in a <code>Some</code> because our function <code>f</code> already returns
an <code>option</code>. So we just return it's output directly.</p>
<h3>The <code>join</code> way</h3>
<p>The other way is to first implement a new function that can turn a <code>option<option<'a>></code> just into a
<code>option<'a></code>. That's also quite easy. We first check our outer-most <code>option</code>. If it is <code>None</code>
we just return <code>None</code>. In the <code>Some</code> case we have another option that we directly return.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs21', 51)" onmouseover="showTip(event, 'fs21', 51)" class="f">joinOption</span> <span onmouseout="hideTip(event, 'fs22', 52)" onmouseover="showTip(event, 'fs22', 52)" class="i">opt</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs22', 53)" onmouseover="showTip(event, 'fs22', 53)" class="i">opt</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs7', 54)" onmouseover="showTip(event, 'fs7', 54)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 55)" onmouseover="showTip(event, 'fs7', 55)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs9', 56)" onmouseover="showTip(event, 'fs9', 56)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs23', 57)" onmouseover="showTip(event, 'fs23', 57)" class="i">innerOpt</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs23', 58)" onmouseover="showTip(event, 'fs23', 58)" class="i">innerOpt</span>
</code></pre></td>
</tr>
</table>
<p>Now we create <code>bind</code> by just using <code>map</code> and <code>join</code> the result.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs24', 59)" onmouseover="showTip(event, 'fs24', 59)" class="f">bindOption2</span> <span onmouseout="hideTip(event, 'fs20', 60)" onmouseover="showTip(event, 'fs20', 60)" class="f">f</span> <span onmouseout="hideTip(event, 'fs17', 61)" onmouseover="showTip(event, 'fs17', 61)" class="i">opt</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs21', 62)" onmouseover="showTip(event, 'fs21', 62)" class="f">joinOption</span> (<span onmouseout="hideTip(event, 'fs15', 63)" onmouseover="showTip(event, 'fs15', 63)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs20', 64)" onmouseover="showTip(event, 'fs20', 64)" class="f">f</span> <span onmouseout="hideTip(event, 'fs17', 65)" onmouseover="showTip(event, 'fs17', 65)" class="i">opt</span>)
</code></pre></td>
</tr>
</table>
<h3>Simple usage</h3>
<p>Let's test both functions and compare it with a <code>map</code> call.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs25', 66)" onmouseover="showTip(event, 'fs25', 66)" class="i">input1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 67)" onmouseover="showTip(event, 'fs9', 67)" class="p">Some</span> <span class="s">"abcde"</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs19', 68)" onmouseover="showTip(event, 'fs19', 68)" class="f">bindOption</span> <span onmouseout="hideTip(event, 'fs3', 69)" onmouseover="showTip(event, 'fs3', 69)" class="t">Double</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs26', 70)" onmouseover="showTip(event, 'fs26', 70)" class="f">tryParse</span> <span class="c">// None</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs27', 71)" onmouseover="showTip(event, 'fs27', 71)" class="i">input2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 72)" onmouseover="showTip(event, 'fs9', 72)" class="p">Some</span> <span class="s">"100"</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs24', 73)" onmouseover="showTip(event, 'fs24', 73)" class="f">bindOption2</span> <span onmouseout="hideTip(event, 'fs3', 74)" onmouseover="showTip(event, 'fs3', 74)" class="t">Double</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs26', 75)" onmouseover="showTip(event, 'fs26', 75)" class="f">tryParse</span> <span class="c">// Some 100.0</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs28', 76)" onmouseover="showTip(event, 'fs28', 76)" class="i">input3</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 77)" onmouseover="showTip(event, 'fs9', 77)" class="p">Some</span> <span class="s">"200"</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs15', 78)" onmouseover="showTip(event, 'fs15', 78)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs3', 79)" onmouseover="showTip(event, 'fs3', 79)" class="t">Double</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs26', 80)" onmouseover="showTip(event, 'fs26', 80)" class="f">tryParse</span> <span class="c">// Some (Some 200.0)</span>
</code></pre></td>
</tr>
</table>
<p>As we can see from the signature. <code>input1</code> and <code>input2</code> are just <code>option<float></code>
instead of <code>option<option<float>></code> that a <code>map</code> will return us.</p>
<p>The <code>Option</code> module already contains <code>Option.map</code> and <code>Option.bind</code>, so we don't have to
rewrite those ourselves. As another exercise, let's look at a <code>bind</code> implementation for <code>list</code>.</p>
<h2><code>bind</code> for <code>list</code></h2>
<p>Creating a <code>bind</code> for a <code>list</code> is a case where the first-approach is usually really hard. Let's look
at a <code>map</code> implementation for <code>list</code> first.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs29', 81)" onmouseover="showTip(event, 'fs29', 81)" class="f">mapList</span> <span onmouseout="hideTip(event, 'fs16', 82)" onmouseover="showTip(event, 'fs16', 82)" class="f">f</span> <span onmouseout="hideTip(event, 'fs30', 83)" onmouseover="showTip(event, 'fs30', 83)" class="i">inputList</span> <span class="o">=</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs31', 84)" onmouseover="showTip(event, 'fs31', 84)" class="f">folder</span> <span onmouseout="hideTip(event, 'fs18', 85)" onmouseover="showTip(event, 'fs18', 85)" class="i">x</span> <span onmouseout="hideTip(event, 'fs32', 86)" onmouseover="showTip(event, 'fs32', 86)" class="i">xs</span> <span class="o">=</span>
(<span onmouseout="hideTip(event, 'fs16', 87)" onmouseover="showTip(event, 'fs16', 87)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 88)" onmouseover="showTip(event, 'fs18', 88)" class="i">x</span>) <span class="o">::</span> <span onmouseout="hideTip(event, 'fs32', 89)" onmouseover="showTip(event, 'fs32', 89)" class="i">xs</span>
<span onmouseout="hideTip(event, 'fs33', 90)" onmouseover="showTip(event, 'fs33', 90)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs34', 91)" onmouseover="showTip(event, 'fs34', 91)" class="f">foldBack</span> <span onmouseout="hideTip(event, 'fs31', 92)" onmouseover="showTip(event, 'fs31', 92)" class="f">folder</span> <span onmouseout="hideTip(event, 'fs30', 93)" onmouseover="showTip(event, 'fs30', 93)" class="i">inputList</span> []
</code></pre></td>
</tr>
</table>
<p><code>Option.bind</code> was really easy as we could directly return what the call to <code>f</code> returned. But for a list
this is not possible. Because in a list we call <code>f</code> multiple times for the input list, and the output
of those are collected into a new list.</p>
<p>Because <code>f</code> is a <em>Monadic function</em> in <code>bind</code> it means every call to <code>f</code> will return a list. If
we add a list to another list, we get a list of list as expected <code>list<list<'a>></code>. If we try to
return a single <code>list</code> instead, it means we have to loop over the result of <code>f</code> and add its element
to another list.</p>
<p>Solving that problem inside of <code>bind</code> is hard, because <code>list</code> is an <em>immutable</em> data-structure. With a
<em>mutable</em> list (<code>ResizeArray</code>) this operation would be quite easy, as we just could call <code>f x</code> that
returns a <code>list</code> and loop through it and add it to some other list, but with an <em>immutable</em> list we
cannot just add elements to an existing element.</p>
<p>When we really want to solve it in one-go we could use a mutable list like <code>ResizeArray</code>, otherwise
we have to use two nested <code>fold</code> or <code>foldBack</code> calls. Instead of nesting it and turning it in a complex
function it is usually better to just extract those operation into it's own function. So we create
a <code>concat</code> operation first, that can turn a <code>list<list<'a>></code> just into a single list.</p>
<p>I'm not showing how to implementing <code>concat</code> for <code>list</code>, as the focus is <code>bind</code> not how immutable list
processing works. So for <code>list</code> we usually would prefer just a <code>map</code> and <code>concat</code> implementation for
<code>bind</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs35', 94)" onmouseover="showTip(event, 'fs35', 94)" class="f">bindList</span> <span onmouseout="hideTip(event, 'fs36', 95)" onmouseover="showTip(event, 'fs36', 95)" class="f">f</span> <span onmouseout="hideTip(event, 'fs37', 96)" onmouseover="showTip(event, 'fs37', 96)" class="i">xs</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs33', 97)" onmouseover="showTip(event, 'fs33', 97)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs38', 98)" onmouseover="showTip(event, 'fs38', 98)" class="f">map</span> <span onmouseout="hideTip(event, 'fs36', 99)" onmouseover="showTip(event, 'fs36', 99)" class="f">f</span> <span onmouseout="hideTip(event, 'fs37', 100)" onmouseover="showTip(event, 'fs37', 100)" class="i">xs</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs33', 101)" onmouseover="showTip(event, 'fs33', 101)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs39', 102)" onmouseover="showTip(event, 'fs39', 102)" class="f">concat</span>
</code></pre></td>
</tr>
</table>
<p>As you can see. <code>f</code> in our example now can be a <code>'a -> 'b list</code> function. So it now produces a whole new list
for every input of our starting list, but we still get a single list, not a list of list back.</p>
<p>F# also provides an implementation for this function. But it is named <code>List.collect</code> instead of <code>List.bind</code>.</p>
<h2>An operator for <code>bind</code></h2>
<p>In <a href="/blog/2016/03/31/applicative-functors">Applicative Functors</a> we used <code><!></code> for the <code>map</code> function.
And <code><*></code> for the <code>apply</code> function. We use <code>>>=</code> as an operator for the <code>bind</code> function. But on top of it.
If we write it as an operator we swap the arguments. We expects our type <code>option</code>, <code>list</code>, <code>async</code> on the
left-side and the function on the right-side.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> (<span class="o">></span><span class="o">></span><span class="o">=</span>) <span onmouseout="hideTip(event, 'fs40', 103)" onmouseover="showTip(event, 'fs40', 103)" class="i">m</span> <span onmouseout="hideTip(event, 'fs20', 104)" onmouseover="showTip(event, 'fs20', 104)" class="f">f</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs41', 105)" onmouseover="showTip(event, 'fs41', 105)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs42', 106)" onmouseover="showTip(event, 'fs42', 106)" class="f">bind</span> <span onmouseout="hideTip(event, 'fs20', 107)" onmouseover="showTip(event, 'fs20', 107)" class="f">f</span> <span onmouseout="hideTip(event, 'fs40', 108)" onmouseover="showTip(event, 'fs40', 108)" class="i">m</span>
</code></pre></td>
</tr>
</table>
<h2>Continuation-passing Style</h2>
<p>The reason for this change is that we think of <code>bind</code> as some kind of
<a href="https://en.wikipedia.org/wiki/Continuation-passing_style">Continuation-passing Style</a> programming.
To understand the change, we have to go back at the signature. Up until now i often described <code>map</code>
and <code>apply</code> by the idea to just pass in the first argument. So when we have</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 109)" onmouseover="showTip(event, 'fs11', 109)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 110)" onmouseover="showTip(event, 'fs11', 110)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 111)" onmouseover="showTip(event, 'fs11', 111)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>we see it as a function that just <em>upgrades</em> the input of a function. But we still have a two argument
function here, and the two argument form is how <code>bind</code> is used most often. If we threat it as
a two-argument function we have something like this:</p>
<p>We have a <code>option<'a></code> as an input. And we provide a function <code>'a -> option<'b></code>. As we can see, the input
of <code>f</code> is just <code>'a</code>. So what we get as the input is the <strong>unwrapped</strong> <code>'a</code> that is inside <code>option<'a></code>.</p>
<p>It can help here if we think with piping <code>|></code>. The idea of piping is that we can write the next argument
of a function on the left side. So instead of <code>f x</code> we also can write <code>x |> f</code>. When we use <code>bind</code> with
piping we have something like <code>x |> Option.bind f</code>. We also can rearange the <em>type-signature</em> to reflect
this style of writing</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs11', 112)" onmouseover="showTip(event, 'fs11', 112)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> (<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 113)" onmouseover="showTip(event, 'fs11', 113)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 114)" onmouseover="showTip(event, 'fs11', 114)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>When we use piping with bind, we get something similar to the above. And probably the order becomes
clearer. We start with a boxed value like <code>option<'a></code>, then our <code>bind</code> function somehow extract the
<code>'a</code> from our <code>option<'a></code>, this <code>'a</code> is then passed to the function <code>('a -> option<'b>)</code>. This function
returns an <code>option<'b></code> what is also what <code>bind</code> will then return!</p>
<p>But it is important to understand that there is no guarantee that our function will be called at all!
Look again at the implementation of <code>bind</code> to understand this. <code>bind</code> checks whether we have <code>None</code> or <code>Some</code>.
In the <code>None</code> case it will just return <code>None</code> only in the <code>Some</code> case it will call <code>f x</code> and execute
our function that we passed to <code>bind</code>!</p>
<p>Not only that, the <em>unwrapping</em> of the <code>option</code> is already handled for us by the <code>bind</code> function. So we
can pass a function <code>f</code> to <code>bind</code> that only will be executed if we have <code>Some value</code>.</p>
<p>Let's create an example to understand this idea in more depth. At first we create a function that
prints some text to screen and expect the user to enter a float. We try to parse the input as
<code>float</code> with our <code>Double.tryParse</code> function that returns an <code>option<float></code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs43', 115)" onmouseover="showTip(event, 'fs43', 115)" class="f">getUserInput</span> <span onmouseout="hideTip(event, 'fs44', 116)" onmouseover="showTip(event, 'fs44', 116)" class="i">msg</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs45', 117)" onmouseover="showTip(event, 'fs45', 117)" class="f">printfn</span> <span class="s">"</span><span class="pf">%s</span><span class="s">: "</span> <span onmouseout="hideTip(event, 'fs44', 118)" onmouseover="showTip(event, 'fs44', 118)" class="i">msg</span>
<span onmouseout="hideTip(event, 'fs46', 119)" onmouseover="showTip(event, 'fs46', 119)" class="t">Console</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs47', 120)" onmouseover="showTip(event, 'fs47', 120)" class="f">ReadLine</span>() <span class="o">|></span> <span onmouseout="hideTip(event, 'fs3', 121)" onmouseover="showTip(event, 'fs3', 121)" class="t">Double</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs26', 122)" onmouseover="showTip(event, 'fs26', 122)" class="f">tryParse</span>
</code></pre></td>
</tr>
</table>
<p>Now we sure could write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs48', 123)" onmouseover="showTip(event, 'fs48', 123)" class="i">someInput</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs43', 124)" onmouseover="showTip(event, 'fs43', 124)" class="f">getUserInput</span> <span class="s">"Enter a number"</span>
</code></pre></td>
</tr>
</table>
<p>and <code>someInput</code> would contain an <code>option<float></code>. We now could use that <code>option<float></code> with other
functions. We just could <code>map</code> or <code>apply</code> all other functions that are not compatible with <code>option</code>.</p>
<p>But instead of doing that, let's pass the resulting <code>option<float></code> directly to <code>bind</code>. We then
provide a continuation function to <code>bind</code> that only will be executed if we have <code>Some value</code>.
The advantage is that our <code>f</code> function only sees a <code>float</code>, not a <code>option<float></code>. We now
can do something with that <code>float</code>.</p>
<p>Let's write an example where the user inputs the radius of a circle, and we calculate the
area of that circle.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs49', 125)" onmouseover="showTip(event, 'fs49', 125)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs18', 126)" onmouseover="showTip(event, 'fs18', 126)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 127)" onmouseover="showTip(event, 'fs9', 127)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs18', 128)" onmouseover="showTip(event, 'fs18', 128)" class="i">x</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs50', 129)" onmouseover="showTip(event, 'fs50', 129)" class="f">circleArea</span> <span onmouseout="hideTip(event, 'fs51', 130)" onmouseover="showTip(event, 'fs51', 130)" class="i">r</span> <span class="o">=</span> (<span onmouseout="hideTip(event, 'fs51', 131)" onmouseover="showTip(event, 'fs51', 131)" class="i">r</span> <span class="o">**</span> <span class="n">2.0</span>) <span class="o">*</span> <span onmouseout="hideTip(event, 'fs52', 132)" onmouseover="showTip(event, 'fs52', 132)" class="t">Math</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs53', 133)" onmouseover="showTip(event, 'fs53', 133)" class="i">PI</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs54', 134)" onmouseover="showTip(event, 'fs54', 134)" class="i">area</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs43', 135)" onmouseover="showTip(event, 'fs43', 135)" class="f">getUserInput</span> <span class="s">"Enter radius"</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs41', 136)" onmouseover="showTip(event, 'fs41', 136)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs42', 137)" onmouseover="showTip(event, 'fs42', 137)" class="f">bind</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs55', 138)" onmouseover="showTip(event, 'fs55', 138)" class="i">userInput</span> <span class="k">-></span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs56', 139)" onmouseover="showTip(event, 'fs56', 139)" class="i">area</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs50', 140)" onmouseover="showTip(event, 'fs50', 140)" class="f">circleArea</span> <span onmouseout="hideTip(event, 'fs55', 141)" onmouseover="showTip(event, 'fs55', 141)" class="i">userInput</span>
<span onmouseout="hideTip(event, 'fs49', 142)" onmouseover="showTip(event, 'fs49', 142)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs56', 143)" onmouseover="showTip(event, 'fs56', 143)" class="i">area</span>
)
</code></pre></td>
</tr>
</table>
<p>Let's go through the example step-by-step.</p>
<ol>
<li>
At first we just create a function <code>circleArea</code> that calculates the area from a given radius.
For such a function we just expect <code>float</code> as input. We usually don't expect <code>option<float></code>
or <code>list<float></code> as the input.
</li>
<li>
Then we call <code>getUserInput "Enter radius"</code>. The user will see "Enter radius: " and he must enter
something. The input will be parsed as a <code>float</code>. We will either get <code>Some x</code> back if
the user input was a <code>float</code> or <code>None</code> if the input was not valid.
</li>
<li>
This option is then directly passed to <code>Option.bind</code> as the second argument. We use the Pipe <code>|></code>
here to bring the <code>option</code> to the left-side.
</li>
<li>
The right-side is now a continuation function. If the <code>option</code> passed to <code>bind</code> contains <code>Some x</code>,
that means a valid <code>float</code>, our continuation function is called and <code>bind</code> returns the result
of our continuation function. If the input to <code>bind</code> was <code>None</code>, <code>bind</code> will immediately return <code>None</code>
without executing the continuation function.
</li>
<li>
Look at the type of <code>userInput</code>. It is a <code>float</code> not an <code>option<float></code>. We have a continuation
function that only will be execute if we have a valid <code>float</code>. And we can directly work
with a <code>float</code>.
</li>
<li>
In our Continuation function we use the <code>float</code> to calculate the area of a circle. As
we only have <code>float</code> not an <code>option<float></code> we don't have to <code>map</code> <code>circleArea</code>.
</li>
<li>
As you now can see <code>let area</code> inside our continuation function is now a normal <code>float</code>. But
now we want to return <code>area</code> as the result of our calculation. But <code>bind</code> must return
an <code>option</code> value. So how do we do that? We use our <code>retn</code> (return) function to convert
a normal <code>float</code> into an <code>option<float></code>
</li>
<li>
Our outer <code>area</code> is now a <code>option<float></code> that either is <code>Some</code> and contains the calculated area
for a circle. Or it is <code>None</code>, because the user input could not be parsed.
</li>
</ol>
<p>Currently we don't print the result. So let's print <code>area</code>. As <code>area</code> (outside of the
continuation function) is now a <code>option<float></code> we have to Pattern Match it to see if our computation
was successful or not.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">match</span> <span onmouseout="hideTip(event, 'fs54', 144)" onmouseover="showTip(event, 'fs54', 144)" class="i">area</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs7', 145)" onmouseover="showTip(event, 'fs7', 145)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs45', 146)" onmouseover="showTip(event, 'fs45', 146)" class="f">printfn</span> <span class="s">"User Input was not a valid number"</span>
| <span onmouseout="hideTip(event, 'fs9', 147)" onmouseover="showTip(event, 'fs9', 147)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs56', 148)" onmouseover="showTip(event, 'fs56', 148)" class="i">area</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs45', 149)" onmouseover="showTip(event, 'fs45', 149)" class="f">printfn</span> <span class="s">"The area of a circle is </span><span class="pf">%f</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs56', 150)" onmouseover="showTip(event, 'fs56', 150)" class="i">area</span>
</code></pre></td>
</tr>
</table>
<p>If the user input was <code>10</code> for example, we will see <code>The area of a circle is 314.159265</code>, but if we provide
an invalid input, we just see <code>User Input was not a valid number</code>. In our example we first had a<br />
<code>option</code> value and passed it to <code>Option.bind</code> with <code>|></code>. This happens often, that is why we created
<code>>>=</code> previously.</p>
<p>Let's extend that example. We now ask the user for three inputs. And we will calculate the volume
of a cube.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs57', 151)" onmouseover="showTip(event, 'fs57', 151)" class="i">cubeVolume</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs43', 152)" onmouseover="showTip(event, 'fs43', 152)" class="f">getUserInput</span> <span class="s">"Length X"</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs8', 153)" onmouseover="showTip(event, 'fs8', 153)" class="i">x</span> <span class="k">-></span>
<span onmouseout="hideTip(event, 'fs43', 154)" onmouseover="showTip(event, 'fs43', 154)" class="f">getUserInput</span> <span class="s">"Length Y"</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs58', 155)" onmouseover="showTip(event, 'fs58', 155)" class="i">y</span> <span class="k">-></span>
<span onmouseout="hideTip(event, 'fs43', 156)" onmouseover="showTip(event, 'fs43', 156)" class="f">getUserInput</span> <span class="s">"Length Z"</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs59', 157)" onmouseover="showTip(event, 'fs59', 157)" class="i">z</span> <span class="k">-></span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs60', 158)" onmouseover="showTip(event, 'fs60', 158)" class="i">volume</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 159)" onmouseover="showTip(event, 'fs8', 159)" class="i">x</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs58', 160)" onmouseover="showTip(event, 'fs58', 160)" class="i">y</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs59', 161)" onmouseover="showTip(event, 'fs59', 161)" class="i">z</span>
<span onmouseout="hideTip(event, 'fs49', 162)" onmouseover="showTip(event, 'fs49', 162)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs60', 163)" onmouseover="showTip(event, 'fs60', 163)" class="i">volume</span>
)))
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs57', 164)" onmouseover="showTip(event, 'fs57', 164)" class="i">cubeVolume</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs7', 165)" onmouseover="showTip(event, 'fs7', 165)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs45', 166)" onmouseover="showTip(event, 'fs45', 166)" class="f">printfn</span> <span class="s">"Not all inputs were valid"</span>
| <span onmouseout="hideTip(event, 'fs9', 167)" onmouseover="showTip(event, 'fs9', 167)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs60', 168)" onmouseover="showTip(event, 'fs60', 168)" class="i">volume</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs45', 169)" onmouseover="showTip(event, 'fs45', 169)" class="f">printfn</span> <span class="s">"Volume of cube is: </span><span class="pf">%f</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs60', 170)" onmouseover="showTip(event, 'fs60', 170)" class="i">volume</span>
</code></pre></td>
</tr>
</table>
<p>As we can see now. We ask the user three times to input a number X, Y and Z. If all inputs were valid. We
just calculate the volume with <code>let volume = x * y * z</code>. The important aspect is that all of our values
are always <code>float</code> never <code>option<float></code>, because the <code>bind</code> operation <code>>>=</code> already did the
unwrapping for us.</p>
<p>And probably it now becomes clear why we named our <em>constructor</em> <code>return</code> (retn). Inside of our
continuation functions we never have lifted values. But at the end of our continuation functions we
always must return a lifted value. So <em>lifting</em> and <em>returning</em> is always the last statement we do.</p>
<p>Let's inspect the syntax a little bit deeper. Look at the syntax of a normal <code>let</code>
definition in F#. Usually a <code>let</code> definition contains a name, a equal "=" and a expression that
will be executed. Actually just look at the following two lines and just compare them.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">x</span> <span class="o">=</span> <span class="i">getUserInput</span> <span class="s">"Length X"</span>
<span class="i">getUserInput</span> <span class="s">"Length X"</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span class="i">x</span> <span class="k">-></span>
</code></pre></td>
</tr>
</table>
<p>Do you spot the similarities?</p>
<ol>
<li>Both definition have an expression <code>getUserInput "Length X"</code> this expression will be executed.</li>
<li>In the first example: We only have <code>=</code> for assignment, and we assign the result to <code>let x</code>.</li>
<li>In the second example: We have <code>>>= (fun x</code> as we assign the result of the expression to <code>x</code>.</li>
</ol>
<p>So what is the difference between both?</p>
<p>The first difference is that the statements are just flipped. With <code>let</code> we have something like</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">variable</span> <span class="o">=</span> <span class="i">expression</span>
</code></pre></td>
</tr>
</table>
<p>But with our <code>bind</code> operation we just have</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">expression</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span class="i">variable</span> <span class="k">-></span>
</code></pre></td>
</tr>
</table>
<p>But the more important difference is the result (our variable). In a normal <code>let</code> definition we
will get <code>option<float></code>. But with <code>bind</code>, we just get <code>float</code>. <code>bind</code> decides whether our
continuation function should be called or not.</p>
<h2>Computation Expressions</h2>
<p>The idea of this kind of continuation-passing style is actually really powerful. So powerful that F#
provides a language construct to let it look like normal code. At first, we just create a class
that contains a <code>Bind</code> and <code>Return</code> method that we want to use.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs61', 171)" onmouseover="showTip(event, 'fs61', 171)" class="t">MaybeBuilder</span>() <span class="o">=</span>
<span class="k">member</span> <span onmouseout="hideTip(event, 'fs62', 172)" onmouseover="showTip(event, 'fs62', 172)" class="i">o</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs63', 173)" onmouseover="showTip(event, 'fs63', 173)" class="f">Bind</span>(<span onmouseout="hideTip(event, 'fs64', 174)" onmouseover="showTip(event, 'fs64', 174)" class="i">m</span>,<span onmouseout="hideTip(event, 'fs65', 175)" onmouseover="showTip(event, 'fs65', 175)" class="f">f</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs41', 176)" onmouseover="showTip(event, 'fs41', 176)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs42', 177)" onmouseover="showTip(event, 'fs42', 177)" class="f">bind</span> <span onmouseout="hideTip(event, 'fs65', 178)" onmouseover="showTip(event, 'fs65', 178)" class="f">f</span> <span onmouseout="hideTip(event, 'fs64', 179)" onmouseover="showTip(event, 'fs64', 179)" class="i">m</span>
<span class="k">member</span> <span onmouseout="hideTip(event, 'fs62', 180)" onmouseover="showTip(event, 'fs62', 180)" class="i">o</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs66', 181)" onmouseover="showTip(event, 'fs66', 181)" class="f">Return</span>(<span onmouseout="hideTip(event, 'fs18', 182)" onmouseover="showTip(event, 'fs18', 182)" class="i">x</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 183)" onmouseover="showTip(event, 'fs9', 183)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs18', 184)" onmouseover="showTip(event, 'fs18', 184)" class="i">x</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs67', 185)" onmouseover="showTip(event, 'fs67', 185)" class="i">maybe</span> <span class="o">=</span> <span class="k">new</span> <span onmouseout="hideTip(event, 'fs61', 186)" onmouseover="showTip(event, 'fs61', 186)" class="t">MaybeBuilder</span>()
</code></pre></td>
</tr>
</table>
<p>As you can see. The <code>Bind</code> and <code>Return</code> methods are not special. They are just the functions you already
know! After you created a class you must create an object of this class. That is our <code>maybe</code>. Now you
can use the following special syntax.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs68', 187)" onmouseover="showTip(event, 'fs68', 187)" class="i">cubeVolume2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs67', 188)" onmouseover="showTip(event, 'fs67', 188)" class="i">maybe</span> {
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs8', 189)" onmouseover="showTip(event, 'fs8', 189)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs43', 190)" onmouseover="showTip(event, 'fs43', 190)" class="f">getUserInput</span> <span class="s">"Length X"</span>
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs58', 191)" onmouseover="showTip(event, 'fs58', 191)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs43', 192)" onmouseover="showTip(event, 'fs43', 192)" class="f">getUserInput</span> <span class="s">"Length Y"</span>
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs59', 193)" onmouseover="showTip(event, 'fs59', 193)" class="i">z</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs43', 194)" onmouseover="showTip(event, 'fs43', 194)" class="f">getUserInput</span> <span class="s">"Length Z"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs60', 195)" onmouseover="showTip(event, 'fs60', 195)" class="i">volume</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 196)" onmouseover="showTip(event, 'fs8', 196)" class="i">x</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs58', 197)" onmouseover="showTip(event, 'fs58', 197)" class="i">y</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs59', 198)" onmouseover="showTip(event, 'fs59', 198)" class="i">z</span>
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs60', 199)" onmouseover="showTip(event, 'fs60', 199)" class="i">volume</span>
}
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs68', 200)" onmouseover="showTip(event, 'fs68', 200)" class="i">cubeVolume2</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs7', 201)" onmouseover="showTip(event, 'fs7', 201)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs45', 202)" onmouseover="showTip(event, 'fs45', 202)" class="f">printfn</span> <span class="s">"User entered some invalid number"</span>
| <span onmouseout="hideTip(event, 'fs9', 203)" onmouseover="showTip(event, 'fs9', 203)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs69', 204)" onmouseover="showTip(event, 'fs69', 204)" class="i">vol</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs45', 205)" onmouseover="showTip(event, 'fs45', 205)" class="f">printfn</span> <span class="s">"Cube volume is </span><span class="pf">%f</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs69', 206)" onmouseover="showTip(event, 'fs69', 206)" class="i">vol</span>
</code></pre></td>
</tr>
</table>
<p>So, what happens exactly here? Whenever you use <code>let!</code> <code>Bind</code> is just called. That means,
if you have <code>option<float></code> on the right side. But you use <code>let! x</code>. Then you just get a <code>float</code>.
Every code after <code>let!</code> is automatically converted into a continuation function that is passed to
<code>Bind</code>. The <code>return</code> statement (that is only available inside a computation expression) turns
a normal value into a lifted value. In this example it wraps it inside a <code>option</code>.</p>
<p>You now can write code as <code>option</code> doesn't exists at all. Whenever you have a
function that returns an <code>option</code>, you just must use <code>let!</code> instead of <code>let</code>. The <code>let!</code> call uses
<code>Bind</code> under the hood. You never need to upgrade functions with <code>map</code> or <code>apply</code> as you don't
work with lifted values. You can use all your functions directly.</p>
<p>But it doesn't mean that we just erased <code>option</code>. <code>option</code> is still present, but the handling
of it is done by the <code>bind</code> function. Whenever we have an expression on the right side that for example
returns a <code>None</code> then the computation stops at this point. Why? Because our <code>bind</code> function only calls
the passed in <code>f</code> function (the continuation) in the <code>Some</code> case.</p>
<p>And it overall also means that the result of a <code>maybe { ... }</code> is always an <code>option</code>! Because it
is an <code>option</code> you easily can use functions defined with a <code>maybe { ... }</code> construct in other
<code>maybe { ... }</code> constructs.</p>
<p>On top of it you still get the safety that <code>option</code> provides you, that means at some point you must
check the value. But it is up to you if you just use a generic check that you implemented in <code>bind</code>, or
write your own handling.</p>
<p>What you see here is a basic implementation of the <strong>Maybe Monad</strong>. And it is the implementation of
the second solution I showed in the <a href="/blog/2016/03/20/null-is-evil">null is Evil</a> post.</p>
<h2>Defining <code>map</code> and <code>apply</code> through <code>bind</code></h2>
<p>The combination of <code>return</code> and <code>bind</code> is really powerful. In
<a href="/blog/2016/03/31/applicative-functors">Applicative Functors</a> we already saw that we can
implement <code>map</code> through <code>return</code> and <code>apply</code>. But with <code>return</code> and <code>bind</code> we can easily implement
<code>map</code> and <code>apply</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
<span class="l">19: </span>
<span class="l">20: </span>
<span class="l">21: </span>
<span class="l">22: </span>
<span class="l">23: </span>
<span class="l">24: </span>
<span class="l">25: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// map with bind operator</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs70', 207)" onmouseover="showTip(event, 'fs70', 207)" class="f">map</span> <span onmouseout="hideTip(event, 'fs16', 208)" onmouseover="showTip(event, 'fs16', 208)" class="f">f</span> <span onmouseout="hideTip(event, 'fs17', 209)" onmouseover="showTip(event, 'fs17', 209)" class="i">opt</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs17', 210)" onmouseover="showTip(event, 'fs17', 210)" class="i">opt</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs18', 211)" onmouseover="showTip(event, 'fs18', 211)" class="i">x</span> <span class="k">-></span> <span class="c">// unbox option</span>
<span onmouseout="hideTip(event, 'fs49', 212)" onmouseover="showTip(event, 'fs49', 212)" class="f">retn</span> (<span onmouseout="hideTip(event, 'fs16', 213)" onmouseover="showTip(event, 'fs16', 213)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 214)" onmouseover="showTip(event, 'fs18', 214)" class="i">x</span>) <span class="c">// execute (f x) and box result</span>
)
<span class="c">// map defined with Computation Expression</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs70', 215)" onmouseover="showTip(event, 'fs70', 215)" class="f">map</span> <span onmouseout="hideTip(event, 'fs16', 216)" onmouseover="showTip(event, 'fs16', 216)" class="f">f</span> <span onmouseout="hideTip(event, 'fs17', 217)" onmouseover="showTip(event, 'fs17', 217)" class="i">opt</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs67', 218)" onmouseover="showTip(event, 'fs67', 218)" class="i">maybe</span> {
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs18', 219)" onmouseover="showTip(event, 'fs18', 219)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs17', 220)" onmouseover="showTip(event, 'fs17', 220)" class="i">opt</span> <span class="c">// unbox option</span>
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs16', 221)" onmouseover="showTip(event, 'fs16', 221)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 222)" onmouseover="showTip(event, 'fs18', 222)" class="i">x</span> <span class="c">// execute (f x) and box result</span>
}
<span class="c">// Apply with bind operator</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs71', 223)" onmouseover="showTip(event, 'fs71', 223)" class="f">apply</span> <span onmouseout="hideTip(event, 'fs72', 224)" onmouseover="showTip(event, 'fs72', 224)" class="i">fo</span> <span onmouseout="hideTip(event, 'fs73', 225)" onmouseover="showTip(event, 'fs73', 225)" class="i">xo</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs72', 226)" onmouseover="showTip(event, 'fs72', 226)" class="i">fo</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs16', 227)" onmouseover="showTip(event, 'fs16', 227)" class="f">f</span> <span class="k">-></span> <span class="c">// unbox function</span>
<span onmouseout="hideTip(event, 'fs73', 228)" onmouseover="showTip(event, 'fs73', 228)" class="i">xo</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs18', 229)" onmouseover="showTip(event, 'fs18', 229)" class="i">x</span> <span class="k">-></span> <span class="c">// unbox value</span>
<span onmouseout="hideTip(event, 'fs49', 230)" onmouseover="showTip(event, 'fs49', 230)" class="f">retn</span> (<span onmouseout="hideTip(event, 'fs16', 231)" onmouseover="showTip(event, 'fs16', 231)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 232)" onmouseover="showTip(event, 'fs18', 232)" class="i">x</span>) <span class="c">// execute (f x) and box result</span>
))
<span class="c">// Apply with Computation expression</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs71', 233)" onmouseover="showTip(event, 'fs71', 233)" class="f">apply</span> <span onmouseout="hideTip(event, 'fs72', 234)" onmouseover="showTip(event, 'fs72', 234)" class="i">fo</span> <span onmouseout="hideTip(event, 'fs73', 235)" onmouseover="showTip(event, 'fs73', 235)" class="i">xo</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs67', 236)" onmouseover="showTip(event, 'fs67', 236)" class="i">maybe</span> {
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs16', 237)" onmouseover="showTip(event, 'fs16', 237)" class="f">f</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs72', 238)" onmouseover="showTip(event, 'fs72', 238)" class="i">fo</span> <span class="c">// unbox function</span>
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs18', 239)" onmouseover="showTip(event, 'fs18', 239)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs73', 240)" onmouseover="showTip(event, 'fs73', 240)" class="i">xo</span> <span class="c">// unbox value</span>
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs16', 241)" onmouseover="showTip(event, 'fs16', 241)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 242)" onmouseover="showTip(event, 'fs18', 242)" class="i">x</span> <span class="c">// execute (f x) and box result</span>
}
</code></pre></td>
</tr>
</table>
<p>Because of this we always have an <em>Applicative Functor</em> when we have a <em>Monad</em>.</p>
<h2>Kleisli Composition</h2>
<p>Function composition is the idea to create a new function out of two smaller functions. It
usually works as long we have two function with a matching output and input type.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="o">></span><span class="o">></span> (<span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>)
</code></pre></td>
</tr>
</table>
<p>Because <code>'b</code> is the output of anothers function input, we can directly create a new composed
function that goes from <code>'a</code> to <code>'c</code> <code>'a -> 'c</code>. But this doesn't work for <em>Monadic functions</em>
as they don't have matching input/output.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 243)" onmouseover="showTip(event, 'fs11', 243)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
<span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 244)" onmouseover="showTip(event, 'fs11', 244)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">c</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>These functions cannot be composed because <code>option<'b></code> is not the same as <code>'b</code>. But with our
bind operator <code>>>=</code> we can easily pass boxed values into function that don't expect them. Because
of that we also can create a compose function that directly compose two <em>Monadic functions</em>.
We use the operator <code>>=></code> for this kind of composition. This kind of composition is also named
<em>Kleisli composition</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> (<span class="o">></span><span class="o">></span>) <span onmouseout="hideTip(event, 'fs16', 245)" onmouseover="showTip(event, 'fs16', 245)" class="f">f</span> <span onmouseout="hideTip(event, 'fs74', 246)" onmouseover="showTip(event, 'fs74', 246)" class="f">g</span> <span onmouseout="hideTip(event, 'fs18', 247)" onmouseover="showTip(event, 'fs18', 247)" class="i">x</span> <span class="o">=</span> (<span onmouseout="hideTip(event, 'fs16', 248)" onmouseover="showTip(event, 'fs16', 248)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 249)" onmouseover="showTip(event, 'fs18', 249)" class="i">x</span>) <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 250)" onmouseover="showTip(event, 'fs74', 250)" class="f">g</span> <span class="c">// This is how normal composition is defined</span>
<span class="k">let</span> (<span class="o">></span><span class="o">=></span>) <span onmouseout="hideTip(event, 'fs20', 251)" onmouseover="showTip(event, 'fs20', 251)" class="f">f</span> <span onmouseout="hideTip(event, 'fs75', 252)" onmouseover="showTip(event, 'fs75', 252)" class="f">g</span> <span onmouseout="hideTip(event, 'fs18', 253)" onmouseover="showTip(event, 'fs18', 253)" class="i">x</span> <span class="o">=</span> (<span onmouseout="hideTip(event, 'fs20', 254)" onmouseover="showTip(event, 'fs20', 254)" class="f">f</span> <span onmouseout="hideTip(event, 'fs18', 255)" onmouseover="showTip(event, 'fs18', 255)" class="i">x</span>) <span class="o">></span><span class="o">></span><span class="o">=</span> <span onmouseout="hideTip(event, 'fs75', 256)" onmouseover="showTip(event, 'fs75', 256)" class="f">g</span> <span class="c">// This is Kleisli composition</span>
</code></pre></td>
</tr>
</table>
<p>Now we can compose two <em>Monadic</em> functions directly.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 257)" onmouseover="showTip(event, 'fs11', 257)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>) <span class="o">></span><span class="o">=></span> (<span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 258)" onmouseover="showTip(event, 'fs11', 258)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">c</span><span class="o">></span>)
</code></pre></td>
</tr>
</table>
<p>the result is a new <em>Monadic function</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs11', 259)" onmouseover="showTip(event, 'fs11', 259)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">c</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<h2>Laws</h2>
<p>We already saw Laws for <em>Functors</em> and <em>Applicative Functors</em>. The combination of <code>return</code>
and <code>bind</code> (a Monad) also must satisfy three laws. In the following description I use</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs76', 260)" onmouseover="showTip(event, 'fs76', 260)" class="f">f</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 261)" onmouseover="showTip(event, 'fs3', 261)" class="t">Double</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs26', 262)" onmouseover="showTip(event, 'fs26', 262)" class="f">tryParse</span> <span class="c">// string -> option<float></span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs77', 263)" onmouseover="showTip(event, 'fs77', 263)" class="f">g</span> <span onmouseout="hideTip(event, 'fs8', 264)" onmouseover="showTip(event, 'fs8', 264)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs49', 265)" onmouseover="showTip(event, 'fs49', 265)" class="f">retn</span> (<span onmouseout="hideTip(event, 'fs8', 266)" onmouseover="showTip(event, 'fs8', 266)" class="i">x</span> <span class="o">*</span> <span class="n">2.0</span>) <span class="c">// float -> option<float></span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs78', 267)" onmouseover="showTip(event, 'fs78', 267)" class="i">x</span> <span class="o">=</span> <span class="s">"10"</span> <span class="c">// string -- unboxed value</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs79', 268)" onmouseover="showTip(event, 'fs79', 268)" class="i">m</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs49', 269)" onmouseover="showTip(event, 'fs49', 269)" class="f">retn</span> <span class="s">"10"</span> <span class="c">// option<string> -- a boxed value</span>
</code></pre></td>
</tr>
</table>
<p>But sure, all laws have to work with any function or value combination. But seeing some actual
values makes it easier to understand the laws.</p>
<h3>1. Law: Left identity</h3>
<p>When we <code>return</code> (box) a value and then use <code>bind</code> (that unbox the value) and pass it to a function.
It is the same as directly passing the value to a function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs49', 270)" onmouseover="showTip(event, 'fs49', 270)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs78', 271)" onmouseover="showTip(event, 'fs78', 271)" class="i">x</span> <span class="o">></span><span class="o">></span><span class="o">=</span> <span onmouseout="hideTip(event, 'fs76', 272)" onmouseover="showTip(event, 'fs76', 272)" class="f">f</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs76', 273)" onmouseover="showTip(event, 'fs76', 273)" class="f">f</span> <span onmouseout="hideTip(event, 'fs78', 274)" onmouseover="showTip(event, 'fs78', 274)" class="i">x</span> <span class="c">// (Some 10.0) = (Some 10.0) -> true</span>
</code></pre></td>
</tr>
</table>
<h3>2. Law: Right identity</h3>
<p>Binding a boxed value and returning it, is the same as the boxed value</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs79', 275)" onmouseover="showTip(event, 'fs79', 275)" class="i">m</span> <span class="o">></span><span class="o">></span><span class="o">=</span> <span onmouseout="hideTip(event, 'fs49', 276)" onmouseover="showTip(event, 'fs49', 276)" class="f">retn</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs79', 277)" onmouseover="showTip(event, 'fs79', 277)" class="i">m</span>
</code></pre></td>
</tr>
</table>
<h3>3. Law: Associative</h3>
<p>Order of composing don't play a role. We can pass a value to <code>f</code> and the result to <code>g</code> and
it has to be the same as if we compose <code>f</code> and <code>g</code> first, and pass our value to the composed
function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs80', 278)" onmouseover="showTip(event, 'fs80', 278)" class="i">ax</span> <span class="o">=</span> (<span onmouseout="hideTip(event, 'fs79', 279)" onmouseover="showTip(event, 'fs79', 279)" class="i">m</span> <span class="o">></span><span class="o">></span><span class="o">=</span> <span onmouseout="hideTip(event, 'fs76', 280)" onmouseover="showTip(event, 'fs76', 280)" class="f">f</span>) <span class="o">></span><span class="o">></span><span class="o">=</span> <span onmouseout="hideTip(event, 'fs77', 281)" onmouseover="showTip(event, 'fs77', 281)" class="f">g</span> <span class="c">// Calling f with m then pass result to g</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs81', 282)" onmouseover="showTip(event, 'fs81', 282)" class="i">ay</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs79', 283)" onmouseover="showTip(event, 'fs79', 283)" class="i">m</span> <span class="o">></span><span class="o">></span><span class="o">=</span> (<span onmouseout="hideTip(event, 'fs76', 284)" onmouseover="showTip(event, 'fs76', 284)" class="f">f</span> <span class="o">></span><span class="o">=></span> <span onmouseout="hideTip(event, 'fs77', 285)" onmouseover="showTip(event, 'fs77', 285)" class="f">g</span>) <span class="c">// Compose f and g first, then pass it m</span>
<span onmouseout="hideTip(event, 'fs80', 286)" onmouseover="showTip(event, 'fs80', 286)" class="i">ax</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs81', 287)" onmouseover="showTip(event, 'fs81', 287)" class="i">ay</span> <span class="c">// Must be the same</span>
</code></pre></td>
</tr>
</table>
<h2>Summary</h2>
<p>With <code>map</code>, <code>retn</code>, <code>apply</code> and <code>bind</code> we have four general functions that simplifies working
with <em>boxed</em> types like <code>option</code>, <code>list</code>, <code>Async</code> and so on. Whenever you create a new type you
should consider implementing those functions too. Here is a quick overview of those
functions and when to use them.</p>
<h3><code>map</code></h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>When we interpret it as a "one-argument" function we can add our boxed type <code>M</code> to the input and
output of a function.</p>
<p>Interpreted as a "two-argument" function we can use a boxed value <code>M<'a></code> directly with a function
that can work with the wrapped type <code>'a</code>.</p>
<h3><code>apply</code></h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span><span class="o">></span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>With apply we can work with boxed functions. We get those as a result if we try to <code>map</code> a function
that has more than one argument. Or we just lift a function with <code>return</code>. We can view <code>apply</code> as
<em>Partial Application</em> for <em>boxed</em> function. With every call we can provide the next value to a
function that also is a boxed value. In this way we can turn every argument of a function
to a boxed value. A function like <code>int -> string -> float -> int</code> can thus be turned into</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">M</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs82', 288)" onmouseover="showTip(event, 'fs82', 288)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs10', 289)" onmouseover="showTip(event, 'fs10', 289)" class="i">string</span><span class="o">></span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs12', 290)" onmouseover="showTip(event, 'fs12', 290)" class="i">float</span><span class="o">></span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs82', 291)" onmouseover="showTip(event, 'fs82', 291)" class="i">int</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<h3><code>return</code> or <code>retn</code></h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>It just boxes a <code>'a</code></p>
<h3><code>bind</code></h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>) <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span class="i">M</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>Interpreted as a one-argument function, we can upgrade a function like <code>map</code>. The difference is
that we only upgrade the input, because the function we have already return a boxed value.</p>
<p>Interpreted as a two-argument function, we see it as a form of Continuation passing style. We
often use piping with <code>|></code> to get the value to the <em>left-side</em> and the continuation function on
the <em>right-side</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">m</span> <span class="o">|></span> <span class="i">M</span><span class="o">.</span><span class="i">bind</span> <span class="i">f</span>
</code></pre></td>
</tr>
</table>
<p>On top, we give <code>|> M.bind</code> it's own operator <code>>>=</code></p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">m</span> <span class="o">></span><span class="o">></span><span class="o">=</span> <span class="i">f</span>
</code></pre></td>
</tr>
</table>
<p>This way we have a boxed value <code>M<'a></code>, but our function <code>f</code> only receives an unboxed <code>'a</code>. In this way
we can work with unboxed values and also use any function without explicitly box them. Because
we must return <em>boxed</em> values we usually use <code>return</code> to return/box an unboxed value inside of <code>f</code>.</p>
<p>The syntax of this kind of continuation-passing style can be improved with a <em>Computation Expression</em>.</p>
<h3>Implementations</h3>
<ul>
<li><code>map</code> can be implemented through <code>return</code> and <code>apply</code></li>
<li><code>map</code> can be implemented through <code>return</code> and <code>bind</code></li>
<li><code>apply</code> can be implemented through <code>return</code> and <code>bind</code></li>
<li><code>bind</code> can be implemented through <code>map</code> and some kind of <code>concat</code> operation</li>
</ul>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">namespace System</div>
<div class="tip" id="fs3">type Double =<br />  struct<br />    member CompareTo : value:obj -> int + 1 overload<br />    member Equals : obj:obj -> bool + 1 overload<br />    member GetHashCode : unit -> int<br />    member GetTypeCode : unit -> TypeCode<br />    member ToString : unit -> string + 3 overloads<br />    static val MinValue : float<br />    static val MaxValue : float<br />    static val Epsilon : float<br />    static val NegativeInfinity : float<br />    static val PositiveInfinity : float<br />    ...<br />  end<br /><br />Full name: System.Double</div>
<div class="tip" id="fs4">static member Double.tryParse : str:string -> float option<br /><br />Full name: Main.tryParse</div>
<div class="tip" id="fs5">val str : string</div>
<div class="tip" id="fs6">Double.TryParse(s: string, result: byref<float>) : bool<br />Double.TryParse(s: string, style: Globalization.NumberStyles, provider: IFormatProvider, result: byref<float>) : bool</div>
<div class="tip" id="fs7">union case Option.None: Option<'T></div>
<div class="tip" id="fs8">val x : float</div>
<div class="tip" id="fs9">union case Option.Some: Value: 'T -> Option<'T></div>
<div class="tip" id="fs10">Multiple items<br />val string : value:'T -> string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string<br /><br />--------------------<br />type string = System.String<br /><br />Full name: Microsoft.FSharp.Core.string</div>
<div class="tip" id="fs11">type 'T option = Option<'T><br /><br />Full name: Microsoft.FSharp.Core.option<_></div>
<div class="tip" id="fs12">Multiple items<br />val float : value:'T -> float (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.float<br /><br />--------------------<br />type float = System.Double<br /><br />Full name: Microsoft.FSharp.Core.float<br /><br />--------------------<br />type float<'Measure> = float<br /><br />Full name: Microsoft.FSharp.Core.float<_></div>
<div class="tip" id="fs13">type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs14">Multiple items<br />type Async<br />static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)<br />static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)<br />static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool><br />static member AwaitTask : task:Task -> Async<unit><br />static member AwaitTask : task:Task<'T> -> Async<'T><br />static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool><br />static member CancelDefaultToken : unit -> unit<br />static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>><br />static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T><br />static member Ignore : computation:Async<'T> -> Async<unit><br />static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable><br />static member Parallel : computations:seq<Async<'T>> -> Async<'T []><br />static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T<br />static member Sleep : millisecondsDueTime:int -> Async<unit><br />static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T><br />static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>><br />static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>><br />static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit<br />static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit><br />static member SwitchToNewThread : unit -> Async<unit><br />static member SwitchToThreadPool : unit -> Async<unit><br />static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T><br />static member CancellationToken : Async<CancellationToken><br />static member DefaultCancellationToken : CancellationToken<br /><br />Full name: Microsoft.FSharp.Control.Async<br /><br />--------------------<br />type Async<'T><br /><br />Full name: Microsoft.FSharp.Control.Async<_></div>
<div class="tip" id="fs15">val mapOption : f:('a -> 'b) -> opt:'a option -> 'b option<br /><br />Full name: Main.mapOption</div>
<div class="tip" id="fs16">val f : ('a -> 'b)</div>
<div class="tip" id="fs17">val opt : 'a option</div>
<div class="tip" id="fs18">val x : 'a</div>
<div class="tip" id="fs19">val bindOption : f:('a -> 'b option) -> opt:'a option -> 'b option<br /><br />Full name: Main.bindOption</div>
<div class="tip" id="fs20">val f : ('a -> 'b option)</div>
<div class="tip" id="fs21">val joinOption : opt:'a option option -> 'a option<br /><br />Full name: Main.joinOption</div>
<div class="tip" id="fs22">val opt : 'a option option</div>
<div class="tip" id="fs23">val innerOpt : 'a option</div>
<div class="tip" id="fs24">val bindOption2 : f:('a -> 'b option) -> opt:'a option -> 'b option<br /><br />Full name: Main.bindOption2</div>
<div class="tip" id="fs25">val input1 : float option<br /><br />Full name: Main.input1</div>
<div class="tip" id="fs26">static member Double.tryParse : str:string -> float option</div>
<div class="tip" id="fs27">val input2 : float option<br /><br />Full name: Main.input2</div>
<div class="tip" id="fs28">val input3 : float option option<br /><br />Full name: Main.input3</div>
<div class="tip" id="fs29">val mapList : f:('a -> 'b) -> inputList:'a list -> 'b list<br /><br />Full name: Main.mapList</div>
<div class="tip" id="fs30">val inputList : 'a list</div>
<div class="tip" id="fs31">val folder : ('a -> 'b list -> 'b list)</div>
<div class="tip" id="fs32">val xs : 'b list</div>
<div class="tip" id="fs33">Multiple items<br />module List<br /><br />from Microsoft.FSharp.Collections<br /><br />--------------------<br />type List<'T> =<br />  | ( [] )<br />  | ( :: ) of Head: 'T * Tail: 'T list<br />  interface IEnumerable<br />  interface IEnumerable<'T><br />  member GetSlice : startIndex:int option * endIndex:int option -> 'T list<br />  member Head : 'T<br />  member IsEmpty : bool<br />  member Item : index:int -> 'T with get<br />  member Length : int<br />  member Tail : 'T list<br />  static member Cons : head:'T * tail:'T list -> 'T list<br />  static member Empty : 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List<_></div>
<div class="tip" id="fs34">val foldBack : folder:('T -> 'State -> 'State) -> list:'T list -> state:'State -> 'State<br /><br />Full name: Microsoft.FSharp.Collections.List.foldBack</div>
<div class="tip" id="fs35">val bindList : f:('a -> 'b list) -> xs:'a list -> 'b list<br /><br />Full name: Main.bindList</div>
<div class="tip" id="fs36">val f : ('a -> 'b list)</div>
<div class="tip" id="fs37">val xs : 'a list</div>
<div class="tip" id="fs38">val map : mapping:('T -> 'U) -> list:'T list -> 'U list<br /><br />Full name: Microsoft.FSharp.Collections.List.map</div>
<div class="tip" id="fs39">val concat : lists:seq<'T list> -> 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.concat</div>
<div class="tip" id="fs40">val m : 'a option</div>
<div class="tip" id="fs41">module Option<br /><br />from Microsoft.FSharp.Core</div>
<div class="tip" id="fs42">val bind : binder:('T -> 'U option) -> option:'T option -> 'U option<br /><br />Full name: Microsoft.FSharp.Core.Option.bind</div>
<div class="tip" id="fs43">val getUserInput : msg:string -> float option<br /><br />Full name: Main.getUserInput</div>
<div class="tip" id="fs44">val msg : string</div>
<div class="tip" id="fs45">val printfn : format:Printf.TextWriterFormat<'T> -> 'T<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn</div>
<div class="tip" id="fs46">type Console =<br />  static member BackgroundColor : ConsoleColor with get, set<br />  static member Beep : unit -> unit + 1 overload<br />  static member BufferHeight : int with get, set<br />  static member BufferWidth : int with get, set<br />  static member CapsLock : bool<br />  static member Clear : unit -> unit<br />  static member CursorLeft : int with get, set<br />  static member CursorSize : int with get, set<br />  static member CursorTop : int with get, set<br />  static member CursorVisible : bool with get, set<br />  ...<br /><br />Full name: System.Console</div>
<div class="tip" id="fs47">Console.ReadLine() : string</div>
<div class="tip" id="fs48">val someInput : float option<br /><br />Full name: Main.someInput</div>
<div class="tip" id="fs49">val retn : x:'a -> 'a option<br /><br />Full name: Main.retn</div>
<div class="tip" id="fs50">val circleArea : r:float -> float<br /><br />Full name: Main.circleArea</div>
<div class="tip" id="fs51">val r : float</div>
<div class="tip" id="fs52">type Math =<br />  static val PI : float<br />  static val E : float<br />  static member Abs : value:sbyte -> sbyte + 6 overloads<br />  static member Acos : d:float -> float<br />  static member Asin : d:float -> float<br />  static member Atan : d:float -> float<br />  static member Atan2 : y:float * x:float -> float<br />  static member BigMul : a:int * b:int -> int64<br />  static member Ceiling : d:decimal -> decimal + 1 overload<br />  static member Cos : d:float -> float<br />  ...<br /><br />Full name: System.Math</div>
<div class="tip" id="fs53">field Math.PI = 3.14159265359</div>
<div class="tip" id="fs54">val area : float option<br /><br />Full name: Main.area</div>
<div class="tip" id="fs55">val userInput : float</div>
<div class="tip" id="fs56">val area : float</div>
<div class="tip" id="fs57">val cubeVolume : float option<br /><br />Full name: Main.cubeVolume</div>
<div class="tip" id="fs58">val y : float</div>
<div class="tip" id="fs59">val z : float</div>
<div class="tip" id="fs60">val volume : float</div>
<div class="tip" id="fs61">Multiple items<br />type MaybeBuilder =<br />  new : unit -> MaybeBuilder<br />  member Bind : m:'b option * f:('b -> 'c option) -> 'c option<br />  member Return : x:'a -> 'a option<br /><br />Full name: Main.MaybeBuilder<br /><br />--------------------<br />new : unit -> MaybeBuilder</div>
<div class="tip" id="fs62">val o : MaybeBuilder</div>
<div class="tip" id="fs63">member MaybeBuilder.Bind : m:'b option * f:('b -> 'c option) -> 'c option<br /><br />Full name: Main.MaybeBuilder.Bind</div>
<div class="tip" id="fs64">val m : 'b option</div>
<div class="tip" id="fs65">val f : ('b -> 'c option)</div>
<div class="tip" id="fs66">member MaybeBuilder.Return : x:'a -> 'a option<br /><br />Full name: Main.MaybeBuilder.Return</div>
<div class="tip" id="fs67">val maybe : MaybeBuilder<br /><br />Full name: Main.maybe</div>
<div class="tip" id="fs68">val cubeVolume2 : float option<br /><br />Full name: Main.cubeVolume2</div>
<div class="tip" id="fs69">val vol : float</div>
<div class="tip" id="fs70">val map : f:('a -> 'b) -> opt:'a option -> 'b option<br /><br />Full name: Main.map</div>
<div class="tip" id="fs71">val apply : fo:('a -> 'b) option -> xo:'a option -> 'b option<br /><br />Full name: Main.apply</div>
<div class="tip" id="fs72">val fo : ('a -> 'b) option</div>
<div class="tip" id="fs73">val xo : 'a option</div>
<div class="tip" id="fs74">val g : ('b -> 'c)</div>
<div class="tip" id="fs75">val g : ('b -> 'c option)</div>
<div class="tip" id="fs76">val f : arg00:string -> float option<br /><br />Full name: Main.f</div>
<div class="tip" id="fs77">val g : x:float -> float option<br /><br />Full name: Main.g</div>
<div class="tip" id="fs78">val x : string<br /><br />Full name: Main.x</div>
<div class="tip" id="fs79">val m : string option<br /><br />Full name: Main.m</div>
<div class="tip" id="fs80">val ax : float option<br /><br />Full name: Main.ax</div>
<div class="tip" id="fs81">val ay : float option<br /><br />Full name: Main.ay</div>
<div class="tip" id="fs82">Multiple items<br />val int : value:'T -> int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int<br /><br />--------------------<br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />--------------------<br />type int<'Measure> = int<br /><br />Full name: Microsoft.FSharp.Core.int<_></div>
Applicative Functors2016-03-31T00:00:00+00:00https://sidburn.github.io/blog/2016/03/31/applicative-functors<p>In my previous blog "<a href="/blog/2016/03/27/understanding-map">Understanding map</a>" I
introduced the <code>map</code> function and described that implementing <code>map</code> and fulfilling two laws
we get what we call a <em>Functor</em>. As we already can guess from the title. An
<em>Applicative Functor</em> is some sort of <em>extension</em> to that idea.</p>
<h2>Problem with <code>map</code></h2>
<p>It might be that you have noticed one problem with <code>map</code>. <code>map</code> only can work with
one-argument functions! The definition of <code>map</code> expects a function <code>'a -> 'b</code> as it's
first argument. So we can <strong>upgrade</strong> one-argument functions but what happens
if we want to upgrade two, three or four argument functions?</p>
<h2>Some dummy functions</h2>
<p>Once again we will create some dummy functions with more than one argument to see
how we can work with them.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// int -> int -> int</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="f">mul</span> <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="i">x</span> <span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 5)" onmouseover="showTip(event, 'fs3', 5)" class="i">x</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs4', 6)" onmouseover="showTip(event, 'fs4', 6)" class="i">y</span>
<span class="c">// int -> string -> string</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 7)" onmouseover="showTip(event, 'fs5', 7)" class="f">repeat</span> <span onmouseout="hideTip(event, 'fs6', 8)" onmouseover="showTip(event, 'fs6', 8)" class="i">count</span> (<span onmouseout="hideTip(event, 'fs7', 9)" onmouseover="showTip(event, 'fs7', 9)" class="i">str</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs8', 10)" onmouseover="showTip(event, 'fs8', 10)" class="t">string</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 11)" onmouseover="showTip(event, 'fs9', 11)" class="t">String</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs10', 12)" onmouseover="showTip(event, 'fs10', 12)" class="f">replicate</span> <span onmouseout="hideTip(event, 'fs6', 13)" onmouseover="showTip(event, 'fs6', 13)" class="i">count</span> <span onmouseout="hideTip(event, 'fs7', 14)" onmouseover="showTip(event, 'fs7', 14)" class="i">str</span>
</code></pre></td>
</tr>
</table>
<p>Some simple usage of those:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs2', 15)" onmouseover="showTip(event, 'fs2', 15)" class="f">mul</span> <span class="n">3</span> <span class="n">7</span> <span class="c">// 21</span>
<span onmouseout="hideTip(event, 'fs5', 16)" onmouseover="showTip(event, 'fs5', 16)" class="f">repeat</span> <span class="n">3</span> <span class="s">"abc"</span> <span class="c">// "abcabcabc"</span>
</code></pre></td>
</tr>
</table>
<h2>Currying again</h2>
<p>But wait, didn't we previously said that there doesn't really exists functions with more than
one argument? Are not all functions just one argument functions, and that two/three/four... arguments
function are really just functions that return another function? Yes, it is and that is also the
reason why we can pass any function to <code>map</code>. But probably you will still be irritated. <code>map</code>
has clearly a signature of <code>'a -> 'b</code>. So how can we pass a <code>int -> int -> int</code> function to it?
Shouldn't we need a <code>map</code> function that expects something like <code>'a -> 'b -> 'c</code> as it's first
arguments? Before we answer that question, actually just let's partial apply one of our function
with a <code>map</code> function and let's see what we get.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 17)" onmouseover="showTip(event, 'fs11', 17)" class="f">optionMul</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs12', 18)" onmouseover="showTip(event, 'fs12', 18)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs13', 19)" onmouseover="showTip(event, 'fs13', 19)" class="f">map</span> <span onmouseout="hideTip(event, 'fs2', 20)" onmouseover="showTip(event, 'fs2', 20)" class="f">mul</span>
</code></pre></td>
</tr>
</table>
<p>When we expect the signature of our <code>optionMul</code> function we now get a new function that looks like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 28)" onmouseover="showTip(event, 'fs14', 28)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs15', 29)" onmouseover="showTip(event, 'fs15', 29)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 30)" onmouseover="showTip(event, 'fs14', 30)" class="i">option</span><span class="o"><</span>(<span onmouseout="hideTip(event, 'fs15', 31)" onmouseover="showTip(event, 'fs15', 31)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 32)" onmouseover="showTip(event, 'fs15', 32)" class="i">int</span>)<span class="o">></span>
</code></pre></td>
</tr>
</table>
<h2>What happened?</h2>
<p>So what happened exactly? And why could we pass <code>mul</code> (<code>int -> int -> int</code>) anyway to <code>map</code> that expected
a <code>'a -> 'b</code>? The big answer is, it's all because of currying. As said once before. A definition like
<code>int -> int -> int</code> can be really interpreted as <code>int -> (int -> int)</code>. The braces are actually optional
as <code>-></code> is right-associative. So what is <code>mul</code> really? It is a function taking an <code>int</code>, and returning
<code>int -> int</code>. The important point is. Functions are also just types!</p>
<p>And that is why this function also can be passed as a function that expect <code>'a -> 'b</code>.
The generic <code>'a</code> will be replaced with <code>int</code>, while <code>'b</code> will be replaces with <code>int -> int</code>.</p>
<p>And probably it now makes sense on why we get our result. Remember that what we get back from <code>map</code> is
just the input and output wraped with our type. So when we call <code>Option.map</code> with one argument, we
get a function back with it's input and output wrapped.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 26)" onmouseover="showTip(event, 'fs14', 26)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 27)" onmouseover="showTip(event, 'fs14', 27)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>So when we pass <code>int -> int -> int</code> then we pass <code>int</code> as the type for <code>'a</code> and <code>int -> int</code> for <code>'b</code>.
That's why we get back</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 28)" onmouseover="showTip(event, 'fs14', 28)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs15', 29)" onmouseover="showTip(event, 'fs15', 29)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 30)" onmouseover="showTip(event, 'fs14', 30)" class="i">option</span><span class="o"><</span>(<span onmouseout="hideTip(event, 'fs15', 31)" onmouseover="showTip(event, 'fs15', 31)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 32)" onmouseover="showTip(event, 'fs15', 32)" class="i">int</span>)<span class="o">></span>
</code></pre></td>
</tr>
</table>
<h2>What does <code>option<(int -> int)></code> mean?</h2>
<p>The question that really starts to beg is. What the hell does <code>option<int -> int></code> anyway mean? And how
do we work with such a construct anyway?</p>
<p>Actually the answer is easy, and it the same way unhelpful. The answer is <code>option<int -> int></code> is just an
optional that can contain a function, or not. Just remember what <code>option</code> is about. A <code>option<int></code>
means we either have an <code>int</code> or not. Now we have the same, just for a function!</p>
<p>Even answering on how you can work with it is easy. The same as with any other option! You have to
<em>Pattern match</em> it. The only difference is that instead of for example an <code>int</code> you get a function
that you can execute in the <code>Some</code> case.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs16', 33)" onmouseover="showTip(event, 'fs16', 33)" class="i">seven</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 34)" onmouseover="showTip(event, 'fs11', 34)" class="f">optionMul</span> (<span onmouseout="hideTip(event, 'fs17', 35)" onmouseover="showTip(event, 'fs17', 35)" class="p">Some</span> <span class="n">7</span>) <span class="c">// returns: option<(int -> int)></span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs16', 36)" onmouseover="showTip(event, 'fs16', 36)" class="i">seven</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs18', 37)" onmouseover="showTip(event, 'fs18', 37)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 38)" onmouseover="showTip(event, 'fs19', 38)" class="f">printfn</span> <span class="s">"Nothing to do"</span>
| <span onmouseout="hideTip(event, 'fs17', 39)" onmouseover="showTip(event, 'fs17', 39)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs20', 40)" onmouseover="showTip(event, 'fs20', 40)" class="f">f</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 41)" onmouseover="showTip(event, 'fs19', 41)" class="f">printfn</span> <span class="s">"Executing f: </span><span class="pf">%d</span><span class="s">"</span> (<span onmouseout="hideTip(event, 'fs20', 42)" onmouseover="showTip(event, 'fs20', 42)" class="f">f</span> <span class="n">3</span>)
<span class="c">// prints: Executing f: 21</span>
</code></pre></td>
</tr>
</table>
<p>The bigger problem is that all of this question and answers are currently <em>unhelpful</em> because
their are the wrong question. We really have to start at the beginning and rethink:
<strong>Which result do we expect after upgrading a two-argument function?</strong></p>
<h2>Which result do we expect?</h2>
<p>Let's rethink the purpose of <code>map</code>. <code>map</code> is the idea that we can just <strong>upgrade</strong> an existing
function and add the <code>option</code> handling for us. It just turns a</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs15', 43)" onmouseover="showTip(event, 'fs15', 43)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 44)" onmouseover="showTip(event, 'fs15', 44)" class="i">int</span>
</code></pre></td>
</tr>
</table>
<p>into a</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 45)" onmouseover="showTip(event, 'fs14', 45)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs15', 46)" onmouseover="showTip(event, 'fs15', 46)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 47)" onmouseover="showTip(event, 'fs14', 47)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs15', 48)" onmouseover="showTip(event, 'fs15', 48)" class="i">int</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>So we get a new function that now can work with <code>option</code>. We just <strong>upgraded</strong> the input and output
and added a <code>option</code>. So if we have a function like</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs15', 49)" onmouseover="showTip(event, 'fs15', 49)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 50)" onmouseover="showTip(event, 'fs15', 50)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 51)" onmouseover="showTip(event, 'fs15', 51)" class="i">int</span>
</code></pre></td>
</tr>
</table>
<p>why not just upgrade every element, and turn it into something like this</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 52)" onmouseover="showTip(event, 'fs14', 52)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs15', 53)" onmouseover="showTip(event, 'fs15', 53)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 54)" onmouseover="showTip(event, 'fs14', 54)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs15', 55)" onmouseover="showTip(event, 'fs15', 55)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 56)" onmouseover="showTip(event, 'fs14', 56)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs15', 57)" onmouseover="showTip(event, 'fs15', 57)" class="i">int</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>The question is, how can we achieve that? We sure could start writing a <code>map2</code>, <code>map3</code> or <code>map4</code>
function. But those functions would probably end up in being much the same. Not only that, it also
can get harder and harder to write a function that handles three, four or more <code>option</code> at the
same time. On top of that, it doesn't really feel so much flexible, isn't there some better way
so we can handle functions with arbitrary arguments? Sure there is!</p>
<h2>Introducing <code>apply</code></h2>
<p>The solution to our problem is that we just write a function that can handle the output of
our <code>map</code> function. Let's work with the <code>repeat</code> function this time, and let's also pass in the
first argument.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs21', 58)" onmouseover="showTip(event, 'fs21', 58)" class="i">optionRepeat3</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs12', 59)" onmouseover="showTip(event, 'fs12', 59)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs13', 60)" onmouseover="showTip(event, 'fs13', 60)" class="f">map</span> <span onmouseout="hideTip(event, 'fs5', 61)" onmouseover="showTip(event, 'fs5', 61)" class="f">repeat</span> (<span onmouseout="hideTip(event, 'fs17', 62)" onmouseover="showTip(event, 'fs17', 62)" class="p">Some</span> <span class="n">3</span>)
</code></pre></td>
</tr>
</table>
<p>As we can see we start with a <code>int -> string -> string</code> function. But the interesting thing is, we
ended up with <code>option<(string -> string)></code>. Where is our <code>int</code> argument? We already applied
that argument when we called <code>map</code>. We only need to pass in the remaining arguments.</p>
<p>In some way you can view <code>Option.map</code> as <em>Partial Application</em>. But it does not just <em>Partial Apply</em>
one value to a function, it additional upgrades the input handling of <code>option</code> for us. So the only
thing we need to write is a function that can handle a <code>option<(string -> string)></code> function. But how
do we handle such a function?</p>
<p>There are two ways we can handle this construct.</p>
<ol>
<li>
We write a function that expects the lifted function (<code>option<(string -> string)></code>)
and the next argument <code>string</code>, and we execute our functions inside the <code>option</code>.
</li>
<li>Transform the whole <code>option<(string -> string)></code> just into <code>option<string> -> option<string></code></li>
</ol>
<p>So which one seems easier or more useful? The funny answer is, both operations are the same!</p>
<p>Let's go over the first idea. Should we expect just a <code>string</code> or an <code>option<string></code>? The whole idea
with <code>map</code> so far was that we can apply <code>option</code> values to function that don't support them. So
it makes more sense when we expect a <code>option<string></code>. If we would expect normal values we
wouldn't need to <code>map</code> a function in the first place! So what we need to implement is a function
expecting <code>option<(string -> string)></code> as the first argument, and <code>option<string></code> as the
second argument. What do we return? As we just execute the first argument, we will return
<code>option<string></code>. So overall we get</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 70)" onmouseover="showTip(event, 'fs14', 70)" class="i">option</span><span class="o"><</span>(<span onmouseout="hideTip(event, 'fs8', 71)" onmouseover="showTip(event, 'fs8', 71)" class="i">string</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs8', 72)" onmouseover="showTip(event, 'fs8', 72)" class="i">string</span>)<span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 73)" onmouseover="showTip(event, 'fs14', 73)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs8', 74)" onmouseover="showTip(event, 'fs8', 74)" class="i">string</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 75)" onmouseover="showTip(event, 'fs14', 75)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs8', 76)" onmouseover="showTip(event, 'fs8', 76)" class="i">string</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>Our second idea was that we somehow transform <code>option<(string -> string)></code> (input) to a new function
<code>option<string> -> option<string></code> (output). If we write the output just to a whole function signature,
we also get.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 70)" onmouseover="showTip(event, 'fs14', 70)" class="i">option</span><span class="o"><</span>(<span onmouseout="hideTip(event, 'fs8', 71)" onmouseover="showTip(event, 'fs8', 71)" class="i">string</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs8', 72)" onmouseover="showTip(event, 'fs8', 72)" class="i">string</span>)<span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 73)" onmouseover="showTip(event, 'fs14', 73)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs8', 74)" onmouseover="showTip(event, 'fs8', 74)" class="i">string</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 75)" onmouseover="showTip(event, 'fs14', 75)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs8', 76)" onmouseover="showTip(event, 'fs8', 76)" class="i">string</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>What we see here is "Currying" once again. With Currying it not only can be that we can interpret the
same function differently, we also can come up with different ideas, that in the end is the same
with another idea. This kind of idea can sometimes simplifies the implementation.</p>
<p>For example let's stick with the second idea. We want to transform the input to another function.
But when we write the type-signature of our function that we need to implement, it is just the same
as a two argument function. So we start with</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">apply</span> <span class="i">optionF</span> <span class="i">optionStr</span> <span class="o">=</span>
<span class="o">..</span><span class="o">.</span>
</code></pre></td>
</tr>
</table>
<p>So what we now have is a function as the first argument <code>option<(string -> string)></code> that expects
a <code>string</code>. And we have a <code>option<string></code> as it's second argument. What we now have to do is
unwrap both optionals, and when we have <code>Some function</code> and <code>Some string</code> we can execute our
function with our value. Actually, there exists 4 possible combination. So we write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">apply</span> <span class="i">optionF</span> <span class="i">optionStr</span> <span class="o">=</span>
<span class="k">match</span> <span class="i">optionF</span>,<span class="i">optionStr</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs17', 77)" onmouseover="showTip(event, 'fs17', 77)" class="i">Some</span> <span class="i">f</span>, <span onmouseout="hideTip(event, 'fs17', 78)" onmouseover="showTip(event, 'fs17', 78)" class="i">Some</span> <span class="i">str</span> <span class="k">-></span> <span class="o">??</span>
| <span onmouseout="hideTip(event, 'fs17', 79)" onmouseover="showTip(event, 'fs17', 79)" class="i">Some</span> <span class="i">f</span>, <span onmouseout="hideTip(event, 'fs18', 80)" onmouseover="showTip(event, 'fs18', 80)" class="i">None</span> _ <span class="k">-></span> <span class="o">??</span>
| <span onmouseout="hideTip(event, 'fs18', 81)" onmouseover="showTip(event, 'fs18', 81)" class="i">None</span> _, <span onmouseout="hideTip(event, 'fs17', 82)" onmouseover="showTip(event, 'fs17', 82)" class="i">Some</span> <span class="i">str</span> <span class="k">-></span> <span class="o">??</span>
| <span onmouseout="hideTip(event, 'fs18', 83)" onmouseover="showTip(event, 'fs18', 83)" class="i">None</span> _, <span onmouseout="hideTip(event, 'fs18', 84)" onmouseover="showTip(event, 'fs18', 84)" class="i">None</span> _ <span class="k">-></span> <span class="o">??</span>
</code></pre></td>
</tr>
</table>
<p>So we <em>pattern match</em> both values at once, in our first case we have a function, and
a string, so we can execute the inner function with our passed in value. We must return
an <code>option</code> again, so we end up with</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">| <span onmouseout="hideTip(event, 'fs17', 85)" onmouseover="showTip(event, 'fs17', 85)" class="i">Some</span> <span class="i">f</span>, <span onmouseout="hideTip(event, 'fs17', 86)" onmouseover="showTip(event, 'fs17', 86)" class="i">Some</span> <span class="i">str</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs17', 87)" onmouseover="showTip(event, 'fs17', 87)" class="i">Some</span> (<span class="i">f</span> <span class="i">x</span>)
</code></pre></td>
</tr>
</table>
<p>All other cases are actually the same. What do we do if we don't have a function, or we don't
have a value? Or we don't have both? Well, then we can't execute our function, so all
of the other cases will return <code>None</code> instead.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs22', 88)" onmouseover="showTip(event, 'fs22', 88)" class="f">apply</span> <span onmouseout="hideTip(event, 'fs23', 89)" onmouseover="showTip(event, 'fs23', 89)" class="i">optionF</span> <span onmouseout="hideTip(event, 'fs24', 90)" onmouseover="showTip(event, 'fs24', 90)" class="i">optionStr</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs23', 91)" onmouseover="showTip(event, 'fs23', 91)" class="i">optionF</span>,<span onmouseout="hideTip(event, 'fs24', 92)" onmouseover="showTip(event, 'fs24', 92)" class="i">optionStr</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs17', 93)" onmouseover="showTip(event, 'fs17', 93)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs25', 94)" onmouseover="showTip(event, 'fs25', 94)" class="f">f</span>, <span onmouseout="hideTip(event, 'fs17', 95)" onmouseover="showTip(event, 'fs17', 95)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs26', 96)" onmouseover="showTip(event, 'fs26', 96)" class="i">str</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs17', 97)" onmouseover="showTip(event, 'fs17', 97)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs25', 98)" onmouseover="showTip(event, 'fs25', 98)" class="f">f</span> <span onmouseout="hideTip(event, 'fs26', 99)" onmouseover="showTip(event, 'fs26', 99)" class="i">str</span>)
| <span onmouseout="hideTip(event, 'fs17', 100)" onmouseover="showTip(event, 'fs17', 100)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs25', 101)" onmouseover="showTip(event, 'fs25', 101)" class="f">f</span>, <span onmouseout="hideTip(event, 'fs18', 102)" onmouseover="showTip(event, 'fs18', 102)" class="p">None</span> _ <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 103)" onmouseover="showTip(event, 'fs18', 103)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs18', 104)" onmouseover="showTip(event, 'fs18', 104)" class="p">None</span> _, <span onmouseout="hideTip(event, 'fs17', 105)" onmouseover="showTip(event, 'fs17', 105)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs26', 106)" onmouseover="showTip(event, 'fs26', 106)" class="i">str</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 107)" onmouseover="showTip(event, 'fs18', 107)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs18', 108)" onmouseover="showTip(event, 'fs18', 108)" class="p">None</span> _, <span onmouseout="hideTip(event, 'fs18', 109)" onmouseover="showTip(event, 'fs18', 109)" class="p">None</span> _ <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 110)" onmouseover="showTip(event, 'fs18', 110)" class="p">None</span>
</code></pre></td>
</tr>
</table>
<p>So, now we have written a way we can handle the output of <code>Option.map repeat (Some 3)</code>. Should we now
write a way to handle <code>Option.map mul (Some 3)</code>? When we actually look at the type-signature of our
<code>apply</code> function, it is much more general as we might think. It's type-signature is.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 111)" onmouseover="showTip(event, 'fs14', 111)" class="i">option</span><span class="o"><</span>(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>)<span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 112)" onmouseover="showTip(event, 'fs14', 112)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 113)" onmouseover="showTip(event, 'fs14', 113)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>That's also why I directly named it <code>apply</code> not <code>applyRepeat</code>. If you look over the code it makes
sense. Because <code>optionStr</code> is nowhere used that restricts it to being a <code>string</code>. We just pass
it as the first argument to the inner function. So our second argument just must be the same
as the input type. It might sense to rename the <code>optionStr</code> argument just to <code>optionX</code> instead.</p>
<p>But probably you might notice another similarity. Here is the signature of <code>map</code> and our
<code>apply</code> function side-by-side.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 114)" onmouseover="showTip(event, 'fs14', 114)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 115)" onmouseover="showTip(event, 'fs14', 115)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
<span onmouseout="hideTip(event, 'fs14', 116)" onmouseover="showTip(event, 'fs14', 116)" class="i">option</span><span class="o"><</span>(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>)<span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 117)" onmouseover="showTip(event, 'fs14', 117)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 118)" onmouseover="showTip(event, 'fs14', 118)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>In that sense, we can say. <code>apply</code> does the same as <code>map</code>. The only difference is that
it already expects a <strong>upgraded</strong> function instead. But those two functions now works
nicely together.</p>
<p>Because if we pass a function with more than one argument to <code>map</code> we get something back that
we can pass to <code>apply</code>. By calling <code>map</code> we provided the first <code>option</code> value. And <code>apply</code>
expects the next <code>option</code> value.</p>
<p>Now let's try to use <code>apply</code> with our <code>optionMul</code> function. We first can call <code>OptionMul (Some 7)</code>
that will return us an <code>option<int -> int></code>, the result of this can then be used with <code>apply</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs27', 119)" onmouseover="showTip(event, 'fs27', 119)" class="i">optionMul2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 120)" onmouseover="showTip(event, 'fs11', 120)" class="f">optionMul</span> (<span onmouseout="hideTip(event, 'fs17', 121)" onmouseover="showTip(event, 'fs17', 121)" class="p">Some</span> <span class="n">7</span>) <span class="c">// option<(int -> int)></span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs28', 122)" onmouseover="showTip(event, 'fs28', 122)" class="i">resultMul</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs22', 123)" onmouseover="showTip(event, 'fs22', 123)" class="f">apply</span> <span onmouseout="hideTip(event, 'fs27', 124)" onmouseover="showTip(event, 'fs27', 124)" class="i">optionMul2</span> (<span onmouseout="hideTip(event, 'fs17', 125)" onmouseover="showTip(event, 'fs17', 125)" class="p">Some</span> <span class="n">3</span>) <span class="c">// option<int></span>
</code></pre></td>
</tr>
</table>
<p>We also can write everything in one step, instead of creating the intermediate functions. Not only that,
let's even inline the <code>map</code> call.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs29', 126)" onmouseover="showTip(event, 'fs29', 126)" class="i">resultMul2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs22', 127)" onmouseover="showTip(event, 'fs22', 127)" class="f">apply</span> (<span onmouseout="hideTip(event, 'fs12', 128)" onmouseover="showTip(event, 'fs12', 128)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs13', 129)" onmouseover="showTip(event, 'fs13', 129)" class="f">map</span> <span onmouseout="hideTip(event, 'fs2', 130)" onmouseover="showTip(event, 'fs2', 130)" class="f">mul</span> (<span onmouseout="hideTip(event, 'fs17', 131)" onmouseover="showTip(event, 'fs17', 131)" class="p">Some</span> <span class="n">7</span>)) (<span onmouseout="hideTip(event, 'fs17', 132)" onmouseover="showTip(event, 'fs17', 132)" class="p">Some</span> <span class="n">3</span>)
</code></pre></td>
</tr>
</table>
<p>This doesn't seems very readable, but we will work on that soon. Let's first understand what exactly happens.</p>
<ol>
<li>
<code>Option.map mul (Some 7)</code> is first executed. It will <strong>upgrade</strong> mul and we provide <code>Some 7</code> as
the first argument to the <code>mul</code> function. This will return a <code>option<(int -> int)></code> function.
</li>
<li>
The <code>option<(int -> int)></code> is passed as the first argument to <code>apply</code>, the second argument to apply
is <code>Some 3</code>. This will return just an <code>option<int></code>
</li>
</ol>
<p>Currently we <strong>upgrade</strong> <code>mul</code> and execute <code>mul</code> in one step, because we provide all arguments. But
how can we just <strong>upgrade</strong> <code>mul</code> without executing it? Before we do that, let's look in how we can
make the execution more readable.</p>
<h2>Defining your own Operators</h2>
<p>In F# we can define our own operators. Operators are basically just two argument function. But instead of
writing <code>f x y</code> an operator is written between (infix) two arguments <code>x f y</code>. The value
left of the operator is the first argument, the value right of an operator is the second argument.
So instead of calling <code>Option.map f x</code> let's create an operator for <code>Option.map</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> (<span class="o"><!></span>) <span onmouseout="hideTip(event, 'fs25', 133)" onmouseover="showTip(event, 'fs25', 133)" class="f">f</span> <span onmouseout="hideTip(event, 'fs30', 134)" onmouseover="showTip(event, 'fs30', 134)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs12', 135)" onmouseover="showTip(event, 'fs12', 135)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs13', 136)" onmouseover="showTip(event, 'fs13', 136)" class="f">map</span> <span onmouseout="hideTip(event, 'fs25', 137)" onmouseover="showTip(event, 'fs25', 137)" class="f">f</span> <span onmouseout="hideTip(event, 'fs30', 138)" onmouseover="showTip(event, 'fs30', 138)" class="i">x</span>
</code></pre></td>
</tr>
</table>
<p>We now can use our first improvement. Instead of <code>Option.map mul (Some 7)</code> we now can write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">mul</span> <span class="o"><!></span> (<span onmouseout="hideTip(event, 'fs17', 139)" onmouseover="showTip(event, 'fs17', 139)" class="i">Some</span> <span class="n">7</span>)
</code></pre></td>
</tr>
</table>
<p>Our whole line turns now into</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">apply</span> (<span class="i">mul</span> <span class="o"><!></span> (<span onmouseout="hideTip(event, 'fs17', 140)" onmouseover="showTip(event, 'fs17', 140)" class="i">Some</span> <span class="n">7</span>)) (<span onmouseout="hideTip(event, 'fs17', 141)" onmouseover="showTip(event, 'fs17', 141)" class="i">Some</span> <span class="n">3</span>)
</code></pre></td>
</tr>
</table>
<p>But once again. Writing <code>apply</code> in front looks ugly, so let's also create an operator for our
<code>apply</code> function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> (<span class="o"><*></span>) <span onmouseout="hideTip(event, 'fs31', 142)" onmouseover="showTip(event, 'fs31', 142)" class="i">fo</span> <span onmouseout="hideTip(event, 'fs32', 143)" onmouseover="showTip(event, 'fs32', 143)" class="i">xo</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs22', 144)" onmouseover="showTip(event, 'fs22', 144)" class="f">apply</span> <span onmouseout="hideTip(event, 'fs31', 145)" onmouseover="showTip(event, 'fs31', 145)" class="i">fo</span> <span onmouseout="hideTip(event, 'fs32', 146)" onmouseover="showTip(event, 'fs32', 146)" class="i">xo</span>
</code></pre></td>
</tr>
</table>
<p>We now getting the following line:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs2', 147)" onmouseover="showTip(event, 'fs2', 147)" class="f">mul</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs17', 148)" onmouseover="showTip(event, 'fs17', 148)" class="p">Some</span> <span class="n">7</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs17', 149)" onmouseover="showTip(event, 'fs17', 149)" class="p">Some</span> <span class="n">3</span> <span class="c">// Some 21</span>
</code></pre></td>
</tr>
</table>
<p>The nice thing is now. With <code><!></code> we just can <code>map</code> a function (left-side) and on the right side
we provide an optional value. In this example <code>mul <!> Some 7</code> will return <code>option<(int -> int)></code>
and this is the input to <code><*></code>, because it stands on it's left-side. And we provide <code>Some 3</code>
as the next value.</p>
<p>This is nice because it resembles the normal way how we call a function. Normally we would do</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs2', 150)" onmouseover="showTip(event, 'fs2', 150)" class="f">mul</span> <span class="n">7</span> <span class="n">3</span>
</code></pre></td>
</tr>
</table>
<p>But what happens if we have <code>optional</code> values? We just write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs2', 151)" onmouseover="showTip(event, 'fs2', 151)" class="f">mul</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs17', 152)" onmouseover="showTip(event, 'fs17', 152)" class="p">Some</span> <span class="n">7</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs17', 153)" onmouseover="showTip(event, 'fs17', 153)" class="p">Some</span> <span class="n">3</span>
</code></pre></td>
</tr>
</table>
<p>Sure, normally you wouldn't wrap the values directly, you just would have variables that contain
optionals. So if you have <code>x</code> and <code>y</code> that are just <code>int</code> you can do</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">mul</span> <span class="i">x</span> <span class="i">y</span>
</code></pre></td>
</tr>
</table>
<p>But if your <code>x</code> and <code>y</code> contains <code>option<int></code> instead, you just write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">mul</span> <span class="o"><!></span> <span class="i">x</span> <span class="o"><*></span> <span class="i">y</span>
</code></pre></td>
</tr>
</table>
<p>Probably you will ask, how can we handle functions with three or four arguments. Easy!</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">someFunction</span> <span class="o"><!></span> <span class="i">x</span> <span class="o"><*></span> <span class="i">y</span> <span class="o"><*></span> <span class="i">z</span> <span class="o"><*></span> <span class="i">w</span>
</code></pre></td>
</tr>
</table>
<p>Why does that work? Because once again of currying! If you start with let's say a <code>int -> int -> int -> int</code>
function, Then after the first <code>map</code> you get back <code>option<int -> int -> int></code>. But as we already learned.</p>
<p><code>int -> int -> int</code> is compatible with <code>'a -> 'b</code>. That's the reason why you can pass a <code>option<int -> int -> int></code>
also to a function expecting <code>option<'a -> 'b></code>. What now happens is that your <code>apply</code> will now return
a <code>option<(int -> int)></code>. Or in other words. With <code>apply</code> you <em>Partial Apply</em> one value after another
to a <strong>wrapped</strong> function. Whenever you use <code>apply</code> or <code><*></code> you just provide the next value of the wrapped
function inside <code>option</code>.</p>
<p>But currently, with <code>map</code> and <code>apply</code> we map a function and directly pass values to it. What do we do
if we just want to <strong>upgrade</strong> a function without executing it? With what we have so far, we usually
write some helper functions <code>lift2</code>, <code>lift3</code>, <code>lift4</code> and so on.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs33', 154)" onmouseover="showTip(event, 'fs33', 154)" class="f">lift2</span> <span onmouseout="hideTip(event, 'fs34', 155)" onmouseover="showTip(event, 'fs34', 155)" class="f">f</span> <span onmouseout="hideTip(event, 'fs30', 156)" onmouseover="showTip(event, 'fs30', 156)" class="i">x</span> <span onmouseout="hideTip(event, 'fs35', 157)" onmouseover="showTip(event, 'fs35', 157)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs34', 158)" onmouseover="showTip(event, 'fs34', 158)" class="f">f</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs30', 159)" onmouseover="showTip(event, 'fs30', 159)" class="i">x</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs35', 160)" onmouseover="showTip(event, 'fs35', 160)" class="i">y</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs36', 161)" onmouseover="showTip(event, 'fs36', 161)" class="f">lift3</span> <span onmouseout="hideTip(event, 'fs37', 162)" onmouseover="showTip(event, 'fs37', 162)" class="f">f</span> <span onmouseout="hideTip(event, 'fs30', 163)" onmouseover="showTip(event, 'fs30', 163)" class="i">x</span> <span onmouseout="hideTip(event, 'fs35', 164)" onmouseover="showTip(event, 'fs35', 164)" class="i">y</span> <span onmouseout="hideTip(event, 'fs38', 165)" onmouseover="showTip(event, 'fs38', 165)" class="i">z</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs37', 166)" onmouseover="showTip(event, 'fs37', 166)" class="f">f</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs30', 167)" onmouseover="showTip(event, 'fs30', 167)" class="i">x</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs35', 168)" onmouseover="showTip(event, 'fs35', 168)" class="i">y</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs38', 169)" onmouseover="showTip(event, 'fs38', 169)" class="i">z</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs39', 170)" onmouseover="showTip(event, 'fs39', 170)" class="f">lift4</span> <span onmouseout="hideTip(event, 'fs40', 171)" onmouseover="showTip(event, 'fs40', 171)" class="f">f</span> <span onmouseout="hideTip(event, 'fs30', 172)" onmouseover="showTip(event, 'fs30', 172)" class="i">x</span> <span onmouseout="hideTip(event, 'fs35', 173)" onmouseover="showTip(event, 'fs35', 173)" class="i">y</span> <span onmouseout="hideTip(event, 'fs38', 174)" onmouseover="showTip(event, 'fs38', 174)" class="i">z</span> <span onmouseout="hideTip(event, 'fs41', 175)" onmouseover="showTip(event, 'fs41', 175)" class="i">w</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs40', 176)" onmouseover="showTip(event, 'fs40', 176)" class="f">f</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs30', 177)" onmouseover="showTip(event, 'fs30', 177)" class="i">x</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs35', 178)" onmouseover="showTip(event, 'fs35', 178)" class="i">y</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs38', 179)" onmouseover="showTip(event, 'fs38', 179)" class="i">z</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs41', 180)" onmouseover="showTip(event, 'fs41', 180)" class="i">w</span>
</code></pre></td>
</tr>
</table>
<p>What we now get are the following functions.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 181)" onmouseover="showTip(event, 'fs14', 181)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 182)" onmouseover="showTip(event, 'fs14', 182)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 183)" onmouseover="showTip(event, 'fs14', 183)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">c</span><span class="o">></span>
(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span> <span class="k">-></span> <span class="o">'</span><span class="i">d</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 184)" onmouseover="showTip(event, 'fs14', 184)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 185)" onmouseover="showTip(event, 'fs14', 185)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 186)" onmouseover="showTip(event, 'fs14', 186)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">c</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 187)" onmouseover="showTip(event, 'fs14', 187)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">d</span><span class="o">></span>
(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span> <span class="k">-></span> <span class="o">'</span><span class="i">d</span> <span class="k">-></span> <span class="o">'</span><span class="i">e</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 188)" onmouseover="showTip(event, 'fs14', 188)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 189)" onmouseover="showTip(event, 'fs14', 189)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 190)" onmouseover="showTip(event, 'fs14', 190)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">c</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 191)" onmouseover="showTip(event, 'fs14', 191)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">d</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 192)" onmouseover="showTip(event, 'fs14', 192)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">e</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>Those functions basically do what we first thought of <code>map2</code>, <code>map3</code>, <code>map4</code> and so on. But such functions
are easily implemented with <code>apply</code> in-place. Once again it helps by looking at those function
with Currying in mind. All of those functions makes more sense if we just <em>Partial Apply</em> the first
argument. What you see then is that we turn a two, three or four argument function just
into a new function where every argument should be a <code>option</code>.</p>
<p>Implementing <code>apply</code> is more helpful as we can directly <code>map</code> and <code>apply</code> any function with arbitrary
arguments, without <em>Partial Applying</em> functions. And we still can create easily <code>lift2</code>, <code>lift3</code> or
<code>lift4</code> functions to upgrade functions as a whole.</p>
<p>Some note if it is not obvious. Usually we don't implement a <code>lift1</code> because that is what <code>map</code> does!</p>
<h2>The <code>return</code> function</h2>
<p>Currently we always created all <strong>lifted</strong> values directly. For example if we needed an <code>option<int></code>
we directly wrote <code>Some 7</code> to create it. Let's rethink this process. Let's assume we just
have an int like <code>7</code>, now we want to upgrade the value. <code>Some 7</code> creates an <code>option<int></code> but what
do we do if we want a <code>list<int></code>, <code>Result<int></code> or a <code>Async<int></code>? Sure upgrading an <code>int</code> to
<code>list<int></code> is still easy <code>[7]</code>. But instead of doing it manually, why not create some kind
of <em>constructor</em> that does that for us?</p>
<p>Based on the context such a function is usually called <code>pure</code> or <code>return</code>. Even if <code>return</code> seems
a little bit strange we will pick this one. Later in some other blogs it will become more obvious why
we name it <code>return</code>.</p>
<p>But because <code>pure</code> and <code>return</code> are both reserved words in F#, we have to slightly
change the name. So we just use <code>retn</code>. The <em>type-signature</em> of a <code>retn</code> function always looks like
this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 193)" onmouseover="showTip(event, 'fs14', 193)" class="i">option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span>
<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs42', 194)" onmouseover="showTip(event, 'fs42', 194)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span>
<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="i">Result</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span>
<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs43', 195)" onmouseover="showTip(event, 'fs43', 195)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>It is pretty-easy to implement <code>retn</code> for our option type.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs44', 196)" onmouseover="showTip(event, 'fs44', 196)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs45', 197)" onmouseover="showTip(event, 'fs45', 197)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs17', 198)" onmouseover="showTip(event, 'fs17', 198)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs45', 199)" onmouseover="showTip(event, 'fs45', 199)" class="i">x</span>
</code></pre></td>
</tr>
</table>
<p>Looking at the previous examples we now also could write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs2', 200)" onmouseover="showTip(event, 'fs2', 200)" class="f">mul</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs44', 201)" onmouseover="showTip(event, 'fs44', 201)" class="f">retn</span> <span class="n">7</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 202)" onmouseover="showTip(event, 'fs44', 202)" class="f">retn</span> <span class="n">3</span> <span class="c">// Some 21</span>
</code></pre></td>
</tr>
</table>
<p>This is probably not such a big surprise. But once again we should consider that <code>'a</code> also
could stand for a function. We not only can upgrade values to a type. But also functions.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs44', 203)" onmouseover="showTip(event, 'fs44', 203)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs2', 204)" onmouseover="showTip(event, 'fs2', 204)" class="f">mul</span>
</code></pre></td>
</tr>
</table>
<p>So why do we want to do that? Well we could use <code>map</code> or <code><!></code>. But consider that with <code>map</code>
we <strong>only</strong> can upgrade functions. <code>retn</code> is more basic as it can <strong>upgrade</strong> every value.
While it seems we don't need <code>retn</code> for functions, sometimes we are just interested in just
upgrading a function as raw as possible. The difference becomes more obvious when we compare
both operations.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs44', 205)" onmouseover="showTip(event, 'fs44', 205)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs2', 206)" onmouseover="showTip(event, 'fs2', 206)" class="f">mul</span> <span class="c">// option<int -> int -> int></span>
<span onmouseout="hideTip(event, 'fs12', 207)" onmouseover="showTip(event, 'fs12', 207)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs13', 208)" onmouseover="showTip(event, 'fs13', 208)" class="f">map</span> <span onmouseout="hideTip(event, 'fs2', 209)" onmouseover="showTip(event, 'fs2', 209)" class="f">mul</span> <span class="c">// option<int> -> option<(int -> int)></span>
</code></pre></td>
</tr>
</table>
<p>So with <code>retn</code> we just do the bare minimum to upgrade a value/function. One
interesting aspect is, that we don't need <code>map</code> at all. In fact. We can create <code>map</code>
out of <code>retn</code> and <code>apply</code>! As we can see <code>retn mul</code> returns <code>option<(int -> int -> int)></code>
and we already saw how we can work with such values. We just can use <code>apply</code> to <em>Partial Apply</em>
the first inner value. So overal we also could just write.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs44', 210)" onmouseover="showTip(event, 'fs44', 210)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs2', 211)" onmouseover="showTip(event, 'fs2', 211)" class="f">mul</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 212)" onmouseover="showTip(event, 'fs44', 212)" class="f">retn</span> <span class="n">7</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 213)" onmouseover="showTip(event, 'fs44', 213)" class="f">retn</span> <span class="n">3</span> <span class="c">// Some 21</span>
</code></pre></td>
</tr>
</table>
<p>It basically means. <code>map</code> is the same as <code>retn</code> and <code>apply</code> once! We actually could have
implemented <code>map</code> like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs46', 214)" onmouseover="showTip(event, 'fs46', 214)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs25', 215)" onmouseover="showTip(event, 'fs25', 215)" class="f">f</span> <span onmouseout="hideTip(event, 'fs30', 216)" onmouseover="showTip(event, 'fs30', 216)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 217)" onmouseover="showTip(event, 'fs44', 217)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs25', 218)" onmouseover="showTip(event, 'fs25', 218)" class="f">f</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs30', 219)" onmouseover="showTip(event, 'fs30', 219)" class="i">x</span>
</code></pre></td>
</tr>
</table>
<p><code>retn</code> is just such an easy function that usually it doesn't seems like much value. But
actually that is quite the reason why it's so good. At first how easy it is just depends on the
type you have. But yes, <code>retn</code> is often a very easy implementation. On top of it, it
also can happen that <code>apply</code> is sometimes easier to implement as <code>map</code>. So it is quite
good to know different ways to implement the same function.</p>
<h2>What can we do with all of this?</h2>
<p>Currently we only have written the Applicative Functor for the <code>option</code> type. But you can think
of this extension for every type that you usually also can write a <code>map</code> function for. This
is a general technique not limited to <code>option</code>.</p>
<p>So what can we do now, with all of this? This is actually a solution of the <code>null</code> problem
that I described in <a href="/blog/2016/03/20/null-is-evil">null is Evil</a>. The problem with
<code>null</code> is that everything can be <code>null</code> and you have to add checks everywhere. Replacing
it with <code>option</code> has some advantages, as you only have to check for <code>Some|None</code> if you
also expected a <code>option</code>. So you only need checking where you expect it. But this can be still
to tedious. Often we want to write code and don't bother with <code>null</code> or <code>option</code> at all.
Our <code>mul</code> and <code>repeat</code> functions are such examples. We just expect arguments that are
<code>int</code> and <code>string</code>. But what happens if for some reasons you have option values and you still
want to use them with <code>mul</code> or <code>repeat</code>? Without the idea of our <em>Applicative Functor</em>
we either have to:</p>
<ol>
<li>Unwrap all optionals and do the checking</li>
<li>Write a <code>mul</code> function yourself that expects two <code>option<int></code></li>
</ol>
<p>Both solutions are very tedious and can become very annoying. Like <code>null</code> checking is always
annoying. So you end up with either.</p>
<h3>1. Unwrap all optionals beforehand</h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// Assume we have two optionals from somewhere else</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 220)" onmouseover="showTip(event, 'fs47', 220)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs17', 221)" onmouseover="showTip(event, 'fs17', 221)" class="p">Some</span> <span class="n">3</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs48', 222)" onmouseover="showTip(event, 'fs48', 222)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs17', 223)" onmouseover="showTip(event, 'fs17', 223)" class="p">Some</span> <span class="n">7</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs47', 224)" onmouseover="showTip(event, 'fs47', 224)" class="i">x</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs18', 225)" onmouseover="showTip(event, 'fs18', 225)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 226)" onmouseover="showTip(event, 'fs19', 226)" class="f">printfn</span> <span class="s">"None"</span>
| <span onmouseout="hideTip(event, 'fs17', 227)" onmouseover="showTip(event, 'fs17', 227)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs3', 228)" onmouseover="showTip(event, 'fs3', 228)" class="i">x</span> <span class="k">-></span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs48', 229)" onmouseover="showTip(event, 'fs48', 229)" class="i">y</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs18', 230)" onmouseover="showTip(event, 'fs18', 230)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 231)" onmouseover="showTip(event, 'fs19', 231)" class="f">printfn</span> <span class="s">"None"</span>
| <span onmouseout="hideTip(event, 'fs17', 232)" onmouseover="showTip(event, 'fs17', 232)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs4', 233)" onmouseover="showTip(event, 'fs4', 233)" class="i">y</span> <span class="k">-></span>
<span class="c">// Finally we can use `mul`</span>
<span onmouseout="hideTip(event, 'fs19', 234)" onmouseover="showTip(event, 'fs19', 234)" class="f">printfn</span> <span class="s">"Result: </span><span class="pf">%d</span><span class="s">"</span> (<span onmouseout="hideTip(event, 'fs2', 235)" onmouseover="showTip(event, 'fs2', 235)" class="f">mul</span> <span onmouseout="hideTip(event, 'fs3', 236)" onmouseover="showTip(event, 'fs3', 236)" class="i">x</span> <span onmouseout="hideTip(event, 'fs4', 237)" onmouseover="showTip(event, 'fs4', 237)" class="i">y</span>)
</code></pre></td>
</tr>
</table>
<h3>2. Rewrite a <code>optionMul</code> function</h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs49', 238)" onmouseover="showTip(event, 'fs49', 238)" class="f">optionMul</span> <span onmouseout="hideTip(event, 'fs50', 239)" onmouseover="showTip(event, 'fs50', 239)" class="i">x</span> <span onmouseout="hideTip(event, 'fs51', 240)" onmouseover="showTip(event, 'fs51', 240)" class="i">y</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs50', 241)" onmouseover="showTip(event, 'fs50', 241)" class="i">x</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs18', 242)" onmouseover="showTip(event, 'fs18', 242)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 243)" onmouseover="showTip(event, 'fs18', 243)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs17', 244)" onmouseover="showTip(event, 'fs17', 244)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs3', 245)" onmouseover="showTip(event, 'fs3', 245)" class="i">x</span> <span class="k">-></span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs51', 246)" onmouseover="showTip(event, 'fs51', 246)" class="i">y</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs18', 247)" onmouseover="showTip(event, 'fs18', 247)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 248)" onmouseover="showTip(event, 'fs18', 248)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs17', 249)" onmouseover="showTip(event, 'fs17', 249)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs4', 250)" onmouseover="showTip(event, 'fs4', 250)" class="i">y</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs17', 251)" onmouseover="showTip(event, 'fs17', 251)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs3', 252)" onmouseover="showTip(event, 'fs3', 252)" class="i">x</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs4', 253)" onmouseover="showTip(event, 'fs4', 253)" class="i">y</span>)
</code></pre></td>
</tr>
</table>
<p>Both solutions seems dull. The first solution becomes annoying. Even if we only have to do
add checks for functions/types that are <code>option</code>. It still is an annoying task mostly
because it is a repetitive task. The second solution is even more worse
as we don't have any code-reuse at all. We just have to write the whole function from scratch
again.</p>
<p>The bad part is, that such a function contains more <code>option</code> handling to what it even does.
So with our <em>Applicative Functor</em> we just can write a normal function, that knows nothing about
<code>option</code>, and we later just upgrade it.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs2', 254)" onmouseover="showTip(event, 'fs2', 254)" class="f">mul</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs47', 255)" onmouseover="showTip(event, 'fs47', 255)" class="i">x</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs48', 256)" onmouseover="showTip(event, 'fs48', 256)" class="i">y</span>
<span onmouseout="hideTip(event, 'fs44', 257)" onmouseover="showTip(event, 'fs44', 257)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs2', 258)" onmouseover="showTip(event, 'fs2', 258)" class="f">mul</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs47', 259)" onmouseover="showTip(event, 'fs47', 259)" class="i">x</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs48', 260)" onmouseover="showTip(event, 'fs48', 260)" class="i">y</span>
<span onmouseout="hideTip(event, 'fs33', 261)" onmouseover="showTip(event, 'fs33', 261)" class="f">lift2</span> <span onmouseout="hideTip(event, 'fs2', 262)" onmouseover="showTip(event, 'fs2', 262)" class="f">mul</span> <span onmouseout="hideTip(event, 'fs47', 263)" onmouseover="showTip(event, 'fs47', 263)" class="i">x</span> <span onmouseout="hideTip(event, 'fs48', 264)" onmouseover="showTip(event, 'fs48', 264)" class="i">y</span>
</code></pre></td>
</tr>
</table>
<p>All three ways are identical they lift <code>mul</code> so we can pass <code>option</code> values as arguments.
Sure at some point in your program you probably want or must check the <code>option</code>. But it
is up to you where you do it. You can do your whole computation first, and only later check
once if you got <code>Some value</code> or <code>None</code>. Theoretically it means you can write your whole
program, and it only contains a single <code>option</code> check at the end.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs52', 265)" onmouseover="showTip(event, 'fs52', 265)" class="f">parseInt</span> <span onmouseout="hideTip(event, 'fs7', 266)" onmouseover="showTip(event, 'fs7', 266)" class="i">str</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs53', 267)" onmouseover="showTip(event, 'fs53', 267)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs54', 268)" onmouseover="showTip(event, 'fs54', 268)" class="t">Int32</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs55', 269)" onmouseover="showTip(event, 'fs55', 269)" class="f">TryParse</span> <span onmouseout="hideTip(event, 'fs7', 270)" onmouseover="showTip(event, 'fs7', 270)" class="i">str</span> <span class="k">with</span>
| <span class="k">false</span>,_ <span class="k">-></span> <span onmouseout="hideTip(event, 'fs18', 271)" onmouseover="showTip(event, 'fs18', 271)" class="p">None</span>
| <span class="k">true</span>,<span onmouseout="hideTip(event, 'fs3', 272)" onmouseover="showTip(event, 'fs3', 272)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs17', 273)" onmouseover="showTip(event, 'fs17', 273)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs3', 274)" onmouseover="showTip(event, 'fs3', 274)" class="i">x</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs56', 275)" onmouseover="showTip(event, 'fs56', 275)" class="i">userInput</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs53', 276)" onmouseover="showTip(event, 'fs53', 276)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs57', 277)" onmouseover="showTip(event, 'fs57', 277)" class="t">Console</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs58', 278)" onmouseover="showTip(event, 'fs58', 278)" class="f">ReadLine</span>() <span class="o">|></span> <span onmouseout="hideTip(event, 'fs52', 279)" onmouseover="showTip(event, 'fs52', 279)" class="f">parseInt</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs59', 280)" onmouseover="showTip(event, 'fs59', 280)" class="i">multipliedBy3</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 281)" onmouseover="showTip(event, 'fs2', 281)" class="f">mul</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs56', 282)" onmouseover="showTip(event, 'fs56', 282)" class="i">userInput</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 283)" onmouseover="showTip(event, 'fs44', 283)" class="f">retn</span> <span class="n">3</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs60', 284)" onmouseover="showTip(event, 'fs60', 284)" class="i">repeatedAbc</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 285)" onmouseover="showTip(event, 'fs5', 285)" class="f">repeat</span> <span class="o"><!></span> <span onmouseout="hideTip(event, 'fs59', 286)" onmouseover="showTip(event, 'fs59', 286)" class="i">multipliedBy3</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 287)" onmouseover="showTip(event, 'fs44', 287)" class="f">retn</span> <span class="s">"abc"</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs60', 288)" onmouseover="showTip(event, 'fs60', 288)" class="i">repeatedAbc</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs18', 289)" onmouseover="showTip(event, 'fs18', 289)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 290)" onmouseover="showTip(event, 'fs19', 290)" class="f">printfn</span> <span class="s">"Error: User Input was not an int"</span>
| <span onmouseout="hideTip(event, 'fs17', 291)" onmouseover="showTip(event, 'fs17', 291)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs7', 292)" onmouseover="showTip(event, 'fs7', 292)" class="i">str</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 293)" onmouseover="showTip(event, 'fs19', 293)" class="f">printfn</span> <span class="s">"</span><span class="pf">%s</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs7', 294)" onmouseover="showTip(event, 'fs7', 294)" class="i">str</span>
</code></pre></td>
</tr>
</table>
<p>So if the user input is "3" we will see <code>abcabcabcabcabcabcabcabcabc</code>. If a user don't provide
an input that can be converted to an <code>int</code> we will see: <code>Error: User Input was not an int</code>.</p>
<p>The whole idea is probably why some people don't see the benefit of <code>option</code>. Most
people just see: <em>Okay instead of checking for <code>null</code> I do check for <code>Some</code> or <code>None</code>.
Why is that better?</em></p>
<p>Well, using <code>option</code> already provides some benefits, as you can't
forget the checks, but the real advantage is that they are values on it's own, and you
can write such an <em>Applicative Functor</em> around <code>option</code> that supports upgrading any function
to the <code>option</code> world and do all the checking for you. That's the real benefit of using <code>option</code>.</p>
<h2>Applicative Functor Laws</h2>
<p>In <a href="/blog/2016/03/27/understanding-map">Understanding map</a> we already came across
two laws that <code>map</code> should satisfy. As we now introduced two new functions <code>return</code> (retn)
and <code>apply</code> there also exists some laws they have to satisfy until we can call it a
<em>Applicative Functor</em>.</p>
<h3>1. Rule: Identity</h3>
<p>This basically refers to the first law of a functor. We said that mapping over the <code>id</code>
function should not change the value. Because <code>map</code> can be implemented in terms of
<code>return</code> and <code>apply</code> the same law must be hold.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs17', 295)" onmouseover="showTip(event, 'fs17', 295)" class="i">Some</span> <span class="n">10</span>
<span class="k">let</span> <span class="i">y</span> <span class="o">=</span> <span class="i">retn</span> <span onmouseout="hideTip(event, 'fs61', 296)" onmouseover="showTip(event, 'fs61', 296)" class="i">id</span> <span class="o"><*></span> <span class="i">x</span>
<span class="i">x</span> <span class="o">=</span> <span class="i">y</span> <span class="c">// comparing must be true -- here it will be (Some 10)</span>
</code></pre></td>
</tr>
</table>
<h3>2. Rule: Order of <strong>upgrading</strong></h3>
<p>It shouldn't matter if we first calculate <code>f x</code> and then <code>retn</code>. Or if we <code>retn</code> <code>f</code>
and <code>x</code> separately, and then do the calculation</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">x</span> <span class="o">=</span> <span class="i">retn</span> (<span class="i">mul</span> <span class="n">7</span> <span class="n">3</span>)
<span class="k">let</span> <span class="i">y</span> <span class="o">=</span> <span class="i">retn</span> <span class="i">mul</span> <span class="o"><*></span> <span class="i">retn</span> <span class="n">7</span> <span class="o"><*></span> <span class="i">retn</span> <span class="n">3</span>
<span class="i">x</span> <span class="o">=</span> <span class="i">y</span> <span class="c">// Both must be the same -- here it will be (Some 21)</span>
</code></pre></td>
</tr>
</table>
<h3>3. Rule: Partial Applying</h3>
<p>That one probably needs some more explanation. Usually we can <em>Partial Apply</em> a function
by just omitting values. For example <code>repeat 3</code>. But what is if you want to <em>Partial Apply</em>
the second argument? Here are two solutions in how we can write it.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">repeatAbc</span> <span class="o">=</span> <span class="k">fun</span> <span class="i">x</span> <span class="k">-></span> <span class="i">repeat</span> <span class="i">x</span> <span class="s">"abc"</span>
<span class="k">let</span> <span class="i">repeatAbc</span> <span class="i">x</span> <span class="o">=</span> <span class="i">repeat</span> <span class="i">x</span> <span class="s">"abc"</span>
</code></pre></td>
</tr>
</table>
<p>So after that we can just call <code>repeatAbc 3</code>. The thing is we expect the same results regardless
if we Partial Apply the first or second argument first. As long the arguments are the same,
the result should be the same. The same rule must hold when we additionally lift <code>repeat</code> to an optional.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs62', 297)" onmouseover="showTip(event, 'fs62', 297)" class="i">ax</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 298)" onmouseover="showTip(event, 'fs44', 298)" class="f">retn</span> <span onmouseout="hideTip(event, 'fs5', 299)" onmouseover="showTip(event, 'fs5', 299)" class="f">repeat</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs17', 300)" onmouseover="showTip(event, 'fs17', 300)" class="p">Some</span> <span class="n">3</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs63', 301)" onmouseover="showTip(event, 'fs63', 301)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs62', 302)" onmouseover="showTip(event, 'fs62', 302)" class="i">ax</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 303)" onmouseover="showTip(event, 'fs44', 303)" class="f">retn</span> <span class="s">"abc"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs64', 304)" onmouseover="showTip(event, 'fs64', 304)" class="i">ay</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 305)" onmouseover="showTip(event, 'fs44', 305)" class="f">retn</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs3', 306)" onmouseover="showTip(event, 'fs3', 306)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs5', 307)" onmouseover="showTip(event, 'fs5', 307)" class="f">repeat</span> <span onmouseout="hideTip(event, 'fs3', 308)" onmouseover="showTip(event, 'fs3', 308)" class="i">x</span> <span class="s">"abc"</span>)
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs65', 309)" onmouseover="showTip(event, 'fs65', 309)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs64', 310)" onmouseover="showTip(event, 'fs64', 310)" class="i">ay</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 311)" onmouseover="showTip(event, 'fs44', 311)" class="f">retn</span> <span class="n">3</span>
<span onmouseout="hideTip(event, 'fs63', 312)" onmouseover="showTip(event, 'fs63', 312)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs65', 313)" onmouseover="showTip(event, 'fs65', 313)" class="i">y</span> <span class="c">// Both must be the same -- Here it will be -- Some "abcabcabc"</span>
</code></pre></td>
</tr>
</table>
<h3>4.Rule: Composition</h3>
<p>This rule comes from normal function composition. Let's say we have two functions. One adds "1"
to a value, another one adds "2" to a value. Function Composition says that it doesn't matter
if you execute the first function on a value, and then the second function on the returned
value. Or of you first compose both function and give it the value.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs66', 314)" onmouseover="showTip(event, 'fs66', 314)" class="f">add1</span> <span onmouseout="hideTip(event, 'fs3', 315)" onmouseover="showTip(event, 'fs3', 315)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 316)" onmouseover="showTip(event, 'fs3', 316)" class="i">x</span> <span class="o">+</span> <span class="n">1</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs67', 317)" onmouseover="showTip(event, 'fs67', 317)" class="f">add2</span> <span onmouseout="hideTip(event, 'fs3', 318)" onmouseover="showTip(event, 'fs3', 318)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 319)" onmouseover="showTip(event, 'fs3', 319)" class="i">x</span> <span class="o">+</span> <span class="n">2</span>
<span class="c">// First executing add1, and pass the result to add2</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs68', 320)" onmouseover="showTip(event, 'fs68', 320)" class="i">nx</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs67', 321)" onmouseover="showTip(event, 'fs67', 321)" class="f">add2</span> (<span onmouseout="hideTip(event, 'fs66', 322)" onmouseover="showTip(event, 'fs66', 322)" class="f">add1</span> <span class="n">3</span>) <span class="c">// 6</span>
<span class="c">// First compose add1 and add2 then provide the value</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs69', 323)" onmouseover="showTip(event, 'fs69', 323)" class="i">ny</span> <span class="o">=</span> (<span onmouseout="hideTip(event, 'fs66', 324)" onmouseover="showTip(event, 'fs66', 324)" class="f">add1</span> <span class="o">></span><span class="o">></span> <span onmouseout="hideTip(event, 'fs67', 325)" onmouseover="showTip(event, 'fs67', 325)" class="f">add2</span>) <span class="n">3</span> <span class="c">// 6</span>
<span onmouseout="hideTip(event, 'fs68', 326)" onmouseover="showTip(event, 'fs68', 326)" class="i">nx</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs69', 327)" onmouseover="showTip(event, 'fs69', 327)" class="i">ny</span> <span class="c">// Both must be the same</span>
</code></pre></td>
</tr>
</table>
<p>This makes sense as composing is just executing two functions in sequence and passing the return
value from the first function to the next function. But those law must still hold true if we
lift/box our functions into another type like <code>option</code>.</p>
<p>One note first. Operators are really just functions with two arguments. And they can be lifted too!
Normally we write an operator infix (between two arguments). But we also can write it like a normal
function if we add braces around the operator. Thus both following lines are the same.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">h</span> <span class="o">=</span> <span class="i">f</span> <span class="o">></span><span class="o">></span> <span class="i">g</span>
<span class="k">let</span> <span class="i">h</span> <span class="o">=</span> (<span class="o">></span><span class="o">></span>) <span class="i">f</span> <span class="i">g</span>
</code></pre></td>
</tr>
</table>
<p>The second style of writing can be used to lift an operator. With <code>retn (>>)</code> we can upgrade <code>>></code>.
Normally <code>>></code> would take two functions as arguments, and returns the new composed function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> (<span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>) <span class="k">-></span> (<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="i">c'</span>)
</code></pre></td>
</tr>
</table>
<p>But when we use <code>retn</code> on it, we just can <code>apply</code> our arguments that now also can be
<code>option<'a -> 'b></code>. Instead of <code>retn (>>)</code> and <code>apply</code> twice we also could use <code>lift2</code>
so we would get a compose function that looks like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 328)" onmouseover="showTip(event, 'fs14', 328)" class="i">option</span><span class="o"><</span>(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>)<span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 329)" onmouseover="showTip(event, 'fs14', 329)" class="i">option</span><span class="o"><</span>(<span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>)<span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 330)" onmouseover="showTip(event, 'fs14', 330)" class="i">option</span><span class="o"><</span>(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="i">c'</span>)<span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>With that in mind, our forth rule says, that we also must ensure that composed lifted
functions still behaves the same, as if we just execute both functions directly in sequence.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs70', 331)" onmouseover="showTip(event, 'fs70', 331)" class="i">oadd1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 332)" onmouseover="showTip(event, 'fs44', 332)" class="f">retn</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs3', 333)" onmouseover="showTip(event, 'fs3', 333)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs3', 334)" onmouseover="showTip(event, 'fs3', 334)" class="i">x</span> <span class="o">+</span> <span class="n">1</span>)
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs71', 335)" onmouseover="showTip(event, 'fs71', 335)" class="i">oadd2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 336)" onmouseover="showTip(event, 'fs44', 336)" class="f">retn</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs3', 337)" onmouseover="showTip(event, 'fs3', 337)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs3', 338)" onmouseover="showTip(event, 'fs3', 338)" class="i">x</span> <span class="o">+</span> <span class="n">2</span>)
<span class="c">// First executing oadd1, and pass the result to oadd2</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs72', 339)" onmouseover="showTip(event, 'fs72', 339)" class="i">ox</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs71', 340)" onmouseover="showTip(event, 'fs71', 340)" class="i">oadd2</span> <span class="o"><*></span> (<span onmouseout="hideTip(event, 'fs70', 341)" onmouseover="showTip(event, 'fs70', 341)" class="i">oadd1</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 342)" onmouseover="showTip(event, 'fs44', 342)" class="f">retn</span> <span class="n">3</span>) <span class="c">// Some 6</span>
<span class="c">// First compose oadd1 and oadd2 into a new function, then provide the value</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs73', 343)" onmouseover="showTip(event, 'fs73', 343)" class="i">oy</span> <span class="o">=</span> (<span onmouseout="hideTip(event, 'fs44', 344)" onmouseover="showTip(event, 'fs44', 344)" class="f">retn</span> (<span class="o">></span><span class="o">></span>) <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs70', 345)" onmouseover="showTip(event, 'fs70', 345)" class="i">oadd1</span> <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs71', 346)" onmouseover="showTip(event, 'fs71', 346)" class="i">oadd2</span>) <span class="o"><*></span> <span onmouseout="hideTip(event, 'fs44', 347)" onmouseover="showTip(event, 'fs44', 347)" class="f">retn</span> <span class="n">3</span> <span class="c">// Some 6</span>
<span onmouseout="hideTip(event, 'fs72', 348)" onmouseover="showTip(event, 'fs72', 348)" class="i">ox</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs73', 349)" onmouseover="showTip(event, 'fs73', 349)" class="i">oy</span> <span class="c">// Both must be the same</span>
</code></pre></td>
</tr>
</table>
<h2>Summary</h2>
<p>We started with <code>map</code> as a general function to <em>upgrade/lift/box</em> normal functions into
some other types. But <code>map</code> only handles one argument functions in a way we would expect.
But because we have currying, and there only exists one argument functions anyway, we still
could pass functions with <em>more than one-argument</em> to our <code>map</code> function. But instead of
a value, we get a lifted function back instead. To handle lifted functions we came up
with a <code>apply</code> function.</p>
<p>As we later saw, we basically don't need <code>map</code>. We always can create <code>map</code> in terms of using
<code>retn</code> and <code>apply</code> once. With our <em>Applicative Functor</em> in-place we now can <em>upgrade/lift/box</em>
function with arbitrary arguments. We also can easily create <code>lift2</code>, <code>lift3</code>, ... functions.</p>
<p>With user defined operators like <code><!></code> for <code>map</code> and <code><*></code> for <code>apply</code> we also can easily
<em>upgrade/lift/box</em> functions inline, without the need to save the intermediate functions.</p>
<p>In this introduction we only saw the usuage with the <code>option</code> type. But in general this
idea works also for other types. While the technique how to implement an <em>Applicative Functor</em>
is the same. The meaning of it changes between types. Currently with <code>option</code> we basically
have written a solution to the <a href="/blog/2016/03/20/null-is-evil">null is Evil</a> problem.</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">val mul : x:int -> y:int -> int<br /><br />Full name: Main.mul</div>
<div class="tip" id="fs3">val x : int</div>
<div class="tip" id="fs4">val y : int</div>
<div class="tip" id="fs5">val repeat : count:int -> str:string -> string<br /><br />Full name: Main.repeat</div>
<div class="tip" id="fs6">val count : int</div>
<div class="tip" id="fs7">val str : string</div>
<div class="tip" id="fs8">Multiple items<br />val string : value:'T -> string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string<br /><br />--------------------<br />type string = System.String<br /><br />Full name: Microsoft.FSharp.Core.string</div>
<div class="tip" id="fs9">module String<br /><br />from Microsoft.FSharp.Core</div>
<div class="tip" id="fs10">val replicate : count:int -> str:string -> string<br /><br />Full name: Microsoft.FSharp.Core.String.replicate</div>
<div class="tip" id="fs11">val optionMul : (int option -> (int -> int) option)<br /><br />Full name: Main.optionMul</div>
<div class="tip" id="fs12">module Option<br /><br />from Microsoft.FSharp.Core</div>
<div class="tip" id="fs13">val map : mapping:('T -> 'U) -> option:'T option -> 'U option<br /><br />Full name: Microsoft.FSharp.Core.Option.map</div>
<div class="tip" id="fs14">type 'T option = Option<'T><br /><br />Full name: Microsoft.FSharp.Core.option<_></div>
<div class="tip" id="fs15">Multiple items<br />val int : value:'T -> int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int<br /><br />--------------------<br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />--------------------<br />type int<'Measure> = int<br /><br />Full name: Microsoft.FSharp.Core.int<_></div>
<div class="tip" id="fs16">val seven : (int -> int) option<br /><br />Full name: Main.seven</div>
<div class="tip" id="fs17">union case Option.Some: Value: 'T -> Option<'T></div>
<div class="tip" id="fs18">union case Option.None: Option<'T></div>
<div class="tip" id="fs19">val printfn : format:Printf.TextWriterFormat<'T> -> 'T<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn</div>
<div class="tip" id="fs20">val f : (int -> int)</div>
<div class="tip" id="fs21">val optionRepeat3 : (string -> string) option<br /><br />Full name: Main.optionRepeat3</div>
<div class="tip" id="fs22">val apply : optionF:('a -> 'b) option -> optionStr:'a option -> 'b option<br /><br />Full name: Main.apply</div>
<div class="tip" id="fs23">val optionF : ('a -> 'b) option</div>
<div class="tip" id="fs24">val optionStr : 'a option</div>
<div class="tip" id="fs25">val f : ('a -> 'b)</div>
<div class="tip" id="fs26">val str : 'a</div>
<div class="tip" id="fs27">val optionMul2 : (int -> int) option<br /><br />Full name: Main.optionMul2</div>
<div class="tip" id="fs28">val resultMul : int option<br /><br />Full name: Main.resultMul</div>
<div class="tip" id="fs29">val resultMul2 : int option<br /><br />Full name: Main.resultMul2</div>
<div class="tip" id="fs30">val x : 'a option</div>
<div class="tip" id="fs31">val fo : ('a -> 'b) option</div>
<div class="tip" id="fs32">val xo : 'a option</div>
<div class="tip" id="fs33">val lift2 : f:('a -> 'b -> 'c) -> x:'a option -> y:'b option -> 'c option<br /><br />Full name: Main.lift2</div>
<div class="tip" id="fs34">val f : ('a -> 'b -> 'c)</div>
<div class="tip" id="fs35">val y : 'b option</div>
<div class="tip" id="fs36">val lift3 : f:('a -> 'b -> 'c -> 'd) -> x:'a option -> y:'b option -> z:'c option -> 'd option<br /><br />Full name: Main.lift3</div>
<div class="tip" id="fs37">val f : ('a -> 'b -> 'c -> 'd)</div>
<div class="tip" id="fs38">val z : 'c option</div>
<div class="tip" id="fs39">val lift4 : f:('a -> 'b -> 'c -> 'd -> 'e) -> x:'a option -> y:'b option -> z:'c option -> w:'d option -> 'e option<br /><br />Full name: Main.lift4</div>
<div class="tip" id="fs40">val f : ('a -> 'b -> 'c -> 'd -> 'e)</div>
<div class="tip" id="fs41">val w : 'd option</div>
<div class="tip" id="fs42">type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs43">Multiple items<br />type Async<br />static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)<br />static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)<br />static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool><br />static member AwaitTask : task:Task -> Async<unit><br />static member AwaitTask : task:Task<'T> -> Async<'T><br />static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool><br />static member CancelDefaultToken : unit -> unit<br />static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>><br />static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T><br />static member Ignore : computation:Async<'T> -> Async<unit><br />static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable><br />static member Parallel : computations:seq<Async<'T>> -> Async<'T []><br />static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T<br />static member Sleep : millisecondsDueTime:int -> Async<unit><br />static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T><br />static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>><br />static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>><br />static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit<br />static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit><br />static member SwitchToNewThread : unit -> Async<unit><br />static member SwitchToThreadPool : unit -> Async<unit><br />static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T><br />static member CancellationToken : Async<CancellationToken><br />static member DefaultCancellationToken : CancellationToken<br /><br />Full name: Microsoft.FSharp.Control.Async<br /><br />--------------------<br />type Async<'T><br /><br />Full name: Microsoft.FSharp.Control.Async<_></div>
<div class="tip" id="fs44">val retn : x:'a -> 'a option<br /><br />Full name: Main.retn</div>
<div class="tip" id="fs45">val x : 'a</div>
<div class="tip" id="fs46">val mapOption : f:('a -> 'b) -> x:'a option -> 'b option<br /><br />Full name: Main.mapOption</div>
<div class="tip" id="fs47">val x : int option<br /><br />Full name: Main.x</div>
<div class="tip" id="fs48">val y : int option<br /><br />Full name: Main.y</div>
<div class="tip" id="fs49">val optionMul : x:int option -> y:int option -> int option<br /><br />Full name: Main.optionMul</div>
<div class="tip" id="fs50">val x : int option</div>
<div class="tip" id="fs51">val y : int option</div>
<div class="tip" id="fs52">val parseInt : str:string -> int option<br /><br />Full name: Main.parseInt</div>
<div class="tip" id="fs53">namespace System</div>
<div class="tip" id="fs54">type Int32 =<br />  struct<br />    member CompareTo : value:obj -> int + 1 overload<br />    member Equals : obj:obj -> bool + 1 overload<br />    member GetHashCode : unit -> int<br />    member GetTypeCode : unit -> TypeCode<br />    member ToString : unit -> string + 3 overloads<br />    static val MaxValue : int<br />    static val MinValue : int<br />    static member Parse : s:string -> int + 3 overloads<br />    static member TryParse : s:string * result:int -> bool + 1 overload<br />  end<br /><br />Full name: System.Int32</div>
<div class="tip" id="fs55">System.Int32.TryParse(s: string, result: byref<int>) : bool<br />System.Int32.TryParse(s: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<int>) : bool</div>
<div class="tip" id="fs56">val userInput : int option<br /><br />Full name: Main.userInput</div>
<div class="tip" id="fs57">type Console =<br />  static member BackgroundColor : ConsoleColor with get, set<br />  static member Beep : unit -> unit + 1 overload<br />  static member BufferHeight : int with get, set<br />  static member BufferWidth : int with get, set<br />  static member CapsLock : bool<br />  static member Clear : unit -> unit<br />  static member CursorLeft : int with get, set<br />  static member CursorSize : int with get, set<br />  static member CursorTop : int with get, set<br />  static member CursorVisible : bool with get, set<br />  ...<br /><br />Full name: System.Console</div>
<div class="tip" id="fs58">System.Console.ReadLine() : string</div>
<div class="tip" id="fs59">val multipliedBy3 : int option<br /><br />Full name: Main.multipliedBy3</div>
<div class="tip" id="fs60">val repeatedAbc : string option<br /><br />Full name: Main.repeatedAbc</div>
<div class="tip" id="fs61">val id : x:'T -> 'T<br /><br />Full name: Microsoft.FSharp.Core.Operators.id</div>
<div class="tip" id="fs62">val ax : (string -> string) option<br /><br />Full name: Main.ax</div>
<div class="tip" id="fs63">val x : string option<br /><br />Full name: Main.x</div>
<div class="tip" id="fs64">val ay : (int -> string) option<br /><br />Full name: Main.ay</div>
<div class="tip" id="fs65">val y : string option<br /><br />Full name: Main.y</div>
<div class="tip" id="fs66">val add1 : x:int -> int<br /><br />Full name: Main.add1</div>
<div class="tip" id="fs67">val add2 : x:int -> int<br /><br />Full name: Main.add2</div>
<div class="tip" id="fs68">val nx : int<br /><br />Full name: Main.nx</div>
<div class="tip" id="fs69">val ny : int<br /><br />Full name: Main.ny</div>
<div class="tip" id="fs70">val oadd1 : (int -> int) option<br /><br />Full name: Main.oadd1</div>
<div class="tip" id="fs71">val oadd2 : (int -> int) option<br /><br />Full name: Main.oadd2</div>
<div class="tip" id="fs72">val ox : int option<br /><br />Full name: Main.ox</div>
<div class="tip" id="fs73">val oy : int option<br /><br />Full name: Main.oy</div>
Understanding map2016-03-27T00:00:00+00:00https://sidburn.github.io/blog/2016/03/27/understanding-map<p>One important function in functional programming is the <code>map</code> function. When I learned F# I must
admit that I had some problems first, understanding it. The problem was, I already knew the <code>map</code>
function from dozens of other languages. Or to say it correctly, I mostly learned a wrong explanation
of <code>map</code>.</p>
<p>The typical explanation I'm talking about often goes something like this: <code>map</code> takes a function and
a <code>list</code>. It applies the function to every element in the list, and returns a new <code>list</code>.
You will often see examples like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// F#</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="i">xs</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs5', 5)" onmouseover="showTip(event, 'fs5', 5)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs5', 6)" onmouseover="showTip(event, 'fs5', 6)" class="i">x</span> <span class="o">*</span> <span class="n">2</span>) [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>]
<span class="c">// C#</span>
<span class="i">var</span> <span onmouseout="hideTip(event, 'fs2', 7)" onmouseover="showTip(event, 'fs2', 7)" class="i">xs</span> <span class="o">=</span> <span class="i">Enumerable</span><span class="o">.</span><span class="i">Range</span>(<span class="n">1</span>,<span class="n">5</span>)<span class="o">.</span><span class="i">Select</span>(<span class="i">x</span> <span class="o">=></span> <span class="i">x</span> <span class="o">*</span> <span class="n">2</span>) <span class="c">// Select is `map`</span>
<span class="c">// JavaScript </span>
<span class="i">var</span> <span onmouseout="hideTip(event, 'fs2', 8)" onmouseover="showTip(event, 'fs2', 8)" class="i">xs</span> <span class="o">=</span> [<span class="n">1</span>,<span class="n">2</span>,<span class="n">3</span>,<span class="n">4</span>,<span class="n">5</span>]<span class="o">.</span><span class="i">map</span>(<span class="k">function</span>(<span class="i">x</span>) { <span class="k">return</span> <span class="i">x</span> <span class="o">*</span> <span class="n">2</span> })
</code></pre></td>
</tr>
</table>
<p>All examples start with some kind of array collection that contains the numbers from 1 to 5.
And all of them take a function multiplying the number by two. All of the examples will result in a
new collection containing <code>[2;4;6;8;10]</code>.</p>
<p>While this explanation of <code>map</code> is <em>right</em> for <code>List.map</code>, this is <em>not a right</em> explanation of <code>map</code> in general.
The problem starts when you encounter a functional language, because besides a <code>List.map</code> you will also encounter
things like <code>String.map</code> or <code>Option.map</code>. On top you will also often find the advice that you should provide
a <code>map</code> function for every type you create (if possible). When you have a <code>Result</code> type you should
also provide a <code>Result.map</code>. Also a <code>Async.map</code> is a good idea. So if you only knew <code>map</code> from the idea of
going through a collection you will probably suffer to understand what <code>map</code> is about. If you try to implement
<code>map</code> for yourself, you will probably even wonder what <code>map</code> anyway should do for an arbitrary type? What is
for example the purpose of <code>Async.map</code>?</p>
<p>To explain what <code>map</code> really is about, let's forget about what you already know and start from scratch again.</p>
<h2>Some functions</h2>
<p>Before we look at <code>map</code>, let's create some simple functions. These functions will be used throughout the article.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// Squares a number: int -> int</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs6', 9)" onmouseover="showTip(event, 'fs6', 9)" class="f">square</span> <span onmouseout="hideTip(event, 'fs5', 10)" onmouseover="showTip(event, 'fs5', 10)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 11)" onmouseover="showTip(event, 'fs5', 11)" class="i">x</span> <span class="o">*</span> <span onmouseout="hideTip(event, 'fs5', 12)" onmouseover="showTip(event, 'fs5', 12)" class="i">x</span>
<span class="c">// Add 10 to every number: int -> int</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs7', 13)" onmouseover="showTip(event, 'fs7', 13)" class="f">add10</span> <span onmouseout="hideTip(event, 'fs5', 14)" onmouseover="showTip(event, 'fs5', 14)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 15)" onmouseover="showTip(event, 'fs5', 15)" class="i">x</span> <span class="o">+</span> <span class="n">10</span>
<span class="c">// Returns the length of a string: string -> int</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs8', 16)" onmouseover="showTip(event, 'fs8', 16)" class="f">length</span> (<span onmouseout="hideTip(event, 'fs9', 17)" onmouseover="showTip(event, 'fs9', 17)" class="i">str</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs10', 18)" onmouseover="showTip(event, 'fs10', 18)" class="t">string</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 19)" onmouseover="showTip(event, 'fs9', 19)" class="i">str</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 20)" onmouseover="showTip(event, 'fs11', 20)" class="i">Length</span>
</code></pre></td>
</tr>
</table>
<h2>List.map</h2>
<p>We now assume that we don't have most of the functions from the <code>List</code> module. Especially not <code>List.map</code>. Sooner
or later you will encounter one problem. With our <code>square</code> function we can square an <code>int</code>. But our <code>square</code>
doesn't work at all with a <code>list<int></code>.</p>
<p>So what do you do if you want to apply <code>square</code> to every <code>int</code> <strong>inside</strong> a <code>list</code>? You sure start looping
over the list, and because we are immutable, we build a new list. As for easiness I write very imperative
code with a loop, without recursion or <code>fold</code> or <code>foldBack</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 21)" onmouseover="showTip(event, 'fs12', 21)" class="f">squareList</span> <span onmouseout="hideTip(event, 'fs13', 22)" onmouseover="showTip(event, 'fs13', 22)" class="i">xs</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs14', 23)" onmouseover="showTip(event, 'fs14', 23)" class="v">results</span> <span class="o">=</span> []
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs5', 24)" onmouseover="showTip(event, 'fs5', 24)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs13', 25)" onmouseover="showTip(event, 'fs13', 25)" class="i">xs</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs15', 26)" onmouseover="showTip(event, 'fs15', 26)" class="i">res</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs6', 27)" onmouseover="showTip(event, 'fs6', 27)" class="f">square</span> <span onmouseout="hideTip(event, 'fs5', 28)" onmouseover="showTip(event, 'fs5', 28)" class="i">x</span>
<span onmouseout="hideTip(event, 'fs14', 29)" onmouseover="showTip(event, 'fs14', 29)" class="v">results</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs15', 30)" onmouseover="showTip(event, 'fs15', 30)" class="i">res</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs14', 31)" onmouseover="showTip(event, 'fs14', 31)" class="v">results</span>
<span onmouseout="hideTip(event, 'fs3', 32)" onmouseover="showTip(event, 'fs3', 32)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs16', 33)" onmouseover="showTip(event, 'fs16', 33)" class="f">rev</span> <span onmouseout="hideTip(event, 'fs14', 34)" onmouseover="showTip(event, 'fs14', 34)" class="v">results</span>
</code></pre></td>
</tr>
</table>
<p>So what we now have is a <code>squareList</code> function, this function now takes a <code>list<int></code> as input and returns
a new <code>list<int></code>. Our <code>squareList</code> function basically does the same thing as <code>square</code>, but instead of
<code>int -> int</code> we have <strong>upgraded</strong> it somehow to work with <code>list<int> -> list<int></code> instead.</p>
<p>A final note is the <code>List.rev</code> at the end, if it is unclear why we need it. <code>x :: xs</code> creates a new list,
but it <code>prepends</code> elements. We actually cannot add elements to the end. So when we loop over a list like
<code>[1;2;3;4;5]</code> we will first <code>square</code> 1 and add it to an empty list resulting in <code>[1]</code>. Then we <code>square</code>
2 and the result is added to <code>[1]</code> yielding in <code>[4;1]</code> and so on. That's why we have to reverse the list
at the end when we are done!</p>
<p>Some time later we are faced with the problem that we also want to use our <code>add10</code> function on a <code>list</code>
so we also write a new function for this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs17', 35)" onmouseover="showTip(event, 'fs17', 35)" class="f">add10List</span> <span onmouseout="hideTip(event, 'fs13', 36)" onmouseover="showTip(event, 'fs13', 36)" class="i">xs</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs14', 37)" onmouseover="showTip(event, 'fs14', 37)" class="v">results</span> <span class="o">=</span> []
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs5', 38)" onmouseover="showTip(event, 'fs5', 38)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs13', 39)" onmouseover="showTip(event, 'fs13', 39)" class="i">xs</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs15', 40)" onmouseover="showTip(event, 'fs15', 40)" class="i">res</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs7', 41)" onmouseover="showTip(event, 'fs7', 41)" class="f">add10</span> <span onmouseout="hideTip(event, 'fs5', 42)" onmouseover="showTip(event, 'fs5', 42)" class="i">x</span>
<span onmouseout="hideTip(event, 'fs14', 43)" onmouseover="showTip(event, 'fs14', 43)" class="v">results</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs15', 44)" onmouseover="showTip(event, 'fs15', 44)" class="i">res</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs14', 45)" onmouseover="showTip(event, 'fs14', 45)" class="v">results</span>
<span onmouseout="hideTip(event, 'fs3', 46)" onmouseover="showTip(event, 'fs3', 46)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs16', 47)" onmouseover="showTip(event, 'fs16', 47)" class="f">rev</span> <span onmouseout="hideTip(event, 'fs14', 48)" onmouseover="showTip(event, 'fs14', 48)" class="v">results</span>
</code></pre></td>
</tr>
</table>
<p>Besides that the code is anyway not really nice or functional to begin with, the big problem is that we basically
have written two completely identical functions! The only difference between those two functions is line 4.
The only thing that is different is the function we call to compute <code>res</code>.</p>
<p>Because we like DRY (Don't Repeat Yourself) we do what functional programmers always tell
<em>Parametrize all the things</em>. So instead of directly calling our function, we just expect that the
concrete function to execute for every element is just passed as an argument. Or simply we <em>Abstract</em> those
two functions. <em>Abstracting</em> always means that we put the things that are the same into one function, everything that
is different will be expected as an argument. So what we finally end up with, is our own <code>map</code> function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs18', 49)" onmouseover="showTip(event, 'fs18', 49)" class="f">mapList</span> <span onmouseout="hideTip(event, 'fs19', 50)" onmouseover="showTip(event, 'fs19', 50)" class="f">f</span> <span onmouseout="hideTip(event, 'fs20', 51)" onmouseover="showTip(event, 'fs20', 51)" class="i">xs</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs21', 52)" onmouseover="showTip(event, 'fs21', 52)" class="v">results</span> <span class="o">=</span> []
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs22', 53)" onmouseover="showTip(event, 'fs22', 53)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs20', 54)" onmouseover="showTip(event, 'fs20', 54)" class="i">xs</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs23', 55)" onmouseover="showTip(event, 'fs23', 55)" class="i">mapping</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs19', 56)" onmouseover="showTip(event, 'fs19', 56)" class="f">f</span> <span onmouseout="hideTip(event, 'fs22', 57)" onmouseover="showTip(event, 'fs22', 57)" class="i">x</span>
<span onmouseout="hideTip(event, 'fs21', 58)" onmouseover="showTip(event, 'fs21', 58)" class="v">results</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs23', 59)" onmouseover="showTip(event, 'fs23', 59)" class="i">mapping</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs21', 60)" onmouseover="showTip(event, 'fs21', 60)" class="v">results</span>
<span onmouseout="hideTip(event, 'fs3', 61)" onmouseover="showTip(event, 'fs3', 61)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs16', 62)" onmouseover="showTip(event, 'fs16', 62)" class="f">rev</span> <span onmouseout="hideTip(event, 'fs21', 63)" onmouseover="showTip(event, 'fs21', 63)" class="v">results</span>
</code></pre></td>
</tr>
</table>
<p>We now can use <code>mapList</code> like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs24', 64)" onmouseover="showTip(event, 'fs24', 64)" class="i">listOfsquared</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs18', 65)" onmouseover="showTip(event, 'fs18', 65)" class="f">mapList</span> <span onmouseout="hideTip(event, 'fs6', 66)" onmouseover="showTip(event, 'fs6', 66)" class="f">square</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>] <span class="c">// [1;4;9]</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs25', 67)" onmouseover="showTip(event, 'fs25', 67)" class="i">listOfAdd10</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs18', 68)" onmouseover="showTip(event, 'fs18', 68)" class="f">mapList</span> <span onmouseout="hideTip(event, 'fs7', 69)" onmouseover="showTip(event, 'fs7', 69)" class="f">add10</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>] <span class="c">// [11;12;13]</span>
</code></pre></td>
</tr>
</table>
<p>Currently it doesn't seems like a big difference to other introductions, but let's reconsider what lead to
the idea of creating a <code>map</code> function. The idea was. We have a function <code>int -> int</code>. A <code>list<int></code> contains
<code>int</code> so we could use <code>square</code> or <code>add10</code> on every element. But in order to apply our function to every
element we have to handle the <code>list</code>, and we need to loop through them. Because this process is the same
for every function, we abstract the looping away in it's own function named <code>map</code>.</p>
<p>Before we go even deeper in why this is different from other explanation. Let's first look at the signature
of our <code>mapList</code> function, and let's just remember the signature.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs26', 70)" onmouseover="showTip(event, 'fs26', 70)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs26', 71)" onmouseover="showTip(event, 'fs26', 71)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<h2>Option.map</h2>
<p>Suddenly later when we are programming, we face a new problem. We encounter a <code>option<int></code> value. <code>option<int></code>
contains an <code>int</code>. So because it contains an int, we also could use our <code>square</code> function on the <strong>inner</strong> value.
But sure, now we have to handle <code>option</code>. So what do we do? We can sure unwrap it, and in case of a <code>Some</code> we apply our
function to it. But what do we do in a case of <code>None</code>? Returning some kind of <em>default</em> int doesn't seem to
make sense or like a good idea. So what we will instead do, we just create a new function that will return
an <code>option</code> again. In the case of <code>None</code> we just return <code>None</code> and do nothing.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs27', 72)" onmouseover="showTip(event, 'fs27', 72)" class="f">squareOption</span> <span onmouseout="hideTip(event, 'fs28', 73)" onmouseover="showTip(event, 'fs28', 73)" class="i">opt</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs28', 74)" onmouseover="showTip(event, 'fs28', 74)" class="i">opt</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs29', 75)" onmouseover="showTip(event, 'fs29', 75)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs29', 76)" onmouseover="showTip(event, 'fs29', 76)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs30', 77)" onmouseover="showTip(event, 'fs30', 77)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs31', 78)" onmouseover="showTip(event, 'fs31', 78)" class="i">value</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs30', 79)" onmouseover="showTip(event, 'fs30', 79)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs6', 80)" onmouseover="showTip(event, 'fs6', 80)" class="f">square</span> <span onmouseout="hideTip(event, 'fs31', 81)" onmouseover="showTip(event, 'fs31', 81)" class="i">value</span>)
</code></pre></td>
</tr>
</table>
<p>Like <code>squareList</code> previously we now created a <code>squareOption</code>. It is already interesting to see some common
between all those function. <code>square</code> could simply square an <code>int</code>. <code>squareList</code> could square a <code>list<int></code>
and now <code>squareOption</code> can square an <code>option<int></code>. Let's go further and let's implement <code>add10Option</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs32', 82)" onmouseover="showTip(event, 'fs32', 82)" class="f">add10Option</span> <span onmouseout="hideTip(event, 'fs28', 83)" onmouseover="showTip(event, 'fs28', 83)" class="i">opt</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs28', 84)" onmouseover="showTip(event, 'fs28', 84)" class="i">opt</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs29', 85)" onmouseover="showTip(event, 'fs29', 85)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs29', 86)" onmouseover="showTip(event, 'fs29', 86)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs30', 87)" onmouseover="showTip(event, 'fs30', 87)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs31', 88)" onmouseover="showTip(event, 'fs31', 88)" class="i">value</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs30', 89)" onmouseover="showTip(event, 'fs30', 89)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs7', 90)" onmouseover="showTip(event, 'fs7', 90)" class="f">add10</span> <span onmouseout="hideTip(event, 'fs31', 91)" onmouseover="showTip(event, 'fs31', 91)" class="i">value</span>)
</code></pre></td>
</tr>
</table>
<p>Once again we can see the code duplication. So instead of checking again and again for every <code>option</code>
if it is <code>None</code> or <code>Some</code> and only in the <code>Some</code> case call a function we starting to abstract it!
Instead of calling our function directly, we once again expect it to be passed as an argument. We will
call this abstract function <code>mapOption</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs33', 92)" onmouseover="showTip(event, 'fs33', 92)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs19', 93)" onmouseover="showTip(event, 'fs19', 93)" class="f">f</span> <span onmouseout="hideTip(event, 'fs34', 94)" onmouseover="showTip(event, 'fs34', 94)" class="i">opt</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs34', 95)" onmouseover="showTip(event, 'fs34', 95)" class="i">opt</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs29', 96)" onmouseover="showTip(event, 'fs29', 96)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs29', 97)" onmouseover="showTip(event, 'fs29', 97)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs30', 98)" onmouseover="showTip(event, 'fs30', 98)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs35', 99)" onmouseover="showTip(event, 'fs35', 99)" class="i">value</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs30', 100)" onmouseover="showTip(event, 'fs30', 100)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs19', 101)" onmouseover="showTip(event, 'fs19', 101)" class="f">f</span> <span onmouseout="hideTip(event, 'fs35', 102)" onmouseover="showTip(event, 'fs35', 102)" class="i">value</span>)
</code></pre></td>
</tr>
</table>
<p>We now can use <code>mapOption</code> like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs36', 103)" onmouseover="showTip(event, 'fs36', 103)" class="i">OptionSquare1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs33', 104)" onmouseover="showTip(event, 'fs33', 104)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs6', 105)" onmouseover="showTip(event, 'fs6', 105)" class="f">square</span> (<span onmouseout="hideTip(event, 'fs30', 106)" onmouseover="showTip(event, 'fs30', 106)" class="p">Some</span> <span class="n">5</span>) <span class="c">// Some 25</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs37', 107)" onmouseover="showTip(event, 'fs37', 107)" class="i">OptionSquare2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs33', 108)" onmouseover="showTip(event, 'fs33', 108)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs6', 109)" onmouseover="showTip(event, 'fs6', 109)" class="f">square</span> <span onmouseout="hideTip(event, 'fs29', 110)" onmouseover="showTip(event, 'fs29', 110)" class="p">None</span> <span class="c">// None</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs38', 111)" onmouseover="showTip(event, 'fs38', 111)" class="i">OptionAdd10_1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs33', 112)" onmouseover="showTip(event, 'fs33', 112)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs7', 113)" onmouseover="showTip(event, 'fs7', 113)" class="f">add10</span> (<span onmouseout="hideTip(event, 'fs30', 114)" onmouseover="showTip(event, 'fs30', 114)" class="p">Some</span> <span class="n">5</span>) <span class="c">// Some 15</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs39', 115)" onmouseover="showTip(event, 'fs39', 115)" class="i">OptionAdd10_2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs33', 116)" onmouseover="showTip(event, 'fs33', 116)" class="f">mapOption</span> <span onmouseout="hideTip(event, 'fs7', 117)" onmouseover="showTip(event, 'fs7', 117)" class="f">add10</span> <span onmouseout="hideTip(event, 'fs29', 118)" onmouseover="showTip(event, 'fs29', 118)" class="p">None</span> <span class="c">// None</span>
</code></pre></td>
</tr>
</table>
<p>Let's once again look at the type signature of our <code>mapOption</code></p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs40', 119)" onmouseover="showTip(event, 'fs40', 119)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs41', 120)" onmouseover="showTip(event, 'fs41', 120)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs40', 121)" onmouseover="showTip(event, 'fs40', 121)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs41', 122)" onmouseover="showTip(event, 'fs41', 122)" class="i">int</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>Does this already look familiar?</p>
<h2>The commonalities between <code>List.map</code> and <code>Option.map</code></h2>
<p>Now let's reconsider with what we started. We started with functions like <code>square</code> and <code>add10</code>.
But those function only could work with <code>int</code>. But while we were programming we faced values like
<code>list<int></code> or <code>option<int></code>. To use our functions on those values, we somehow have to <strong>unwrap</strong>
the values. Apply our function to the inner type <code>int</code>, and wrap it up again. <strong>unwraping</strong> is
different for every type. For <code>list</code> it means we loop through a list. For an <code>option</code> it means
we have to check whether it is <code>Some</code> or <code>None</code>. But we still can think of it as some kind of an
<strong>unwrap</strong> function. Because what we do is, at some point in our function we turn an <code>list<int></code> or
an <code>option<int></code> just to in <code>int</code>, so we can use the <code>int</code> with our <code>square</code> or <code>add10</code> function.
But after applying our function we still return the type of what we started. When we started with
a <code>list<int></code> we still have to return a <code>list</code> again. When we started with an <code>option</code> we still
return an <code>option</code> again.</p>
<p>But this is a repetitive task, as this kind of <strong>unwraping</strong> and <strong>re-wraping</strong> is always the same.
It doesn't matter which type we have inside <code>list<></code> or <code>option</code>. And it also doesn't matter
which function we use.</p>
<p>That's why we abstract those idea of <strong>unwrapping</strong>, <strong>applying a function</strong>, <strong>re-wrap</strong> into it's
own function and name it <code>map</code>. To understand this process further let's look again at the type
signatures of our <code>mapList</code> and <code>mapOption</code> function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs26', 123)" onmouseover="showTip(event, 'fs26', 123)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs26', 124)" onmouseover="showTip(event, 'fs26', 124)" class="i">list</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs40', 125)" onmouseover="showTip(event, 'fs40', 125)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs41', 126)" onmouseover="showTip(event, 'fs41', 126)" class="i">int</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs40', 127)" onmouseover="showTip(event, 'fs40', 127)" class="i">option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs41', 128)" onmouseover="showTip(event, 'fs41', 128)" class="i">int</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>This <em>type-signature</em> is the essence of a <code>map</code> function. Every <code>map</code> function has to look like this.
The only part that changes is the <em>wrapping-type</em>. So at this point you could probably already assume
how a <code>map</code> function for <code>Result</code>, <code>Async</code> or <code>Whatever</code> should look like</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span class="i">Result</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span class="i">Result</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs42', 129)" onmouseover="showTip(event, 'fs42', 129)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs42', 130)" onmouseover="showTip(event, 'fs42', 130)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span class="i">Whatever</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span class="i">Whatever</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<h2>Currying and Partial Application</h2>
<p>At this point it is important to talk about Currying. Currying is the idea that there only
exists functions with <strong>one-argument</strong> and they <strong>always</strong> have to return a value. F# is such
a language and does currying automatically.</p>
<p>That is also the very reason why you see multiple <code>-></code> inside a function signature. <code>-></code> is
basically the symbol for a function. On it's left-side is the input of the function, on the right
side is the output. When we look at a signature like</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs10', 131)" onmouseover="showTip(event, 'fs10', 131)" class="i">string</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs41', 132)" onmouseover="showTip(event, 'fs41', 132)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs43', 133)" onmouseover="showTip(event, 'fs43', 133)" class="i">float</span>
</code></pre></td>
</tr>
</table>
<p>We often say it has two arguments, a <code>string</code> and a <code>int</code> and it returns a <code>float</code>. But this isn't
quite correct. What we really have is a function that only has one argument a <code>string</code> and it will
return a <code>int -> float</code>, or in other words. A new function! That is also the reason why functional
languages don't use braces as arguments, it just uses a space. Something like</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">ys</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 134)" onmouseover="showTip(event, 'fs3', 134)" class="i">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 135)" onmouseover="showTip(event, 'fs4', 135)" class="i">map</span> <span class="i">f</span> <span onmouseout="hideTip(event, 'fs2', 136)" onmouseover="showTip(event, 'fs2', 136)" class="i">xs</span>
</code></pre></td>
</tr>
</table>
<p>really means. Execute <code>List.map f</code> this returns a new function, and we immediately pass <code>xs</code> to
that new function. That's also the reason why we can add braces around the function and the <em>first</em>
argument without changing the meaning.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">ys</span> <span class="o">=</span> (<span onmouseout="hideTip(event, 'fs3', 137)" onmouseover="showTip(event, 'fs3', 137)" class="i">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 138)" onmouseover="showTip(event, 'fs4', 138)" class="i">map</span> <span class="i">f</span>) <span onmouseout="hideTip(event, 'fs2', 139)" onmouseover="showTip(event, 'fs2', 139)" class="i">xs</span>
</code></pre></td>
</tr>
</table>
<p>Not only that, we also can extract it, and save the <em>intermediate function</em> as a new value.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">newF</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 140)" onmouseover="showTip(event, 'fs3', 140)" class="i">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 141)" onmouseover="showTip(event, 'fs4', 141)" class="i">map</span> <span class="i">f</span>
<span class="k">let</span> <span class="i">ys</span> <span class="o">=</span> <span class="i">newF</span> <span onmouseout="hideTip(event, 'fs2', 142)" onmouseover="showTip(event, 'fs2', 142)" class="i">xs</span>
</code></pre></td>
</tr>
</table>
<p>The idea to not pass all needed values is what we call <em>Partial Application</em>. The interesting
stuff about all of this is, that with this idea, we can come up with different interpretation
of the same function. And this kind of interpretation is what we can apply to <code>map</code>. Actually we
can view <code>map</code> as a single argument function, or as a two argument functions. Both have some
different meaning. When we interpret <code>map</code> as a single argument function, we now have something like
this</p>
<table>
<thead>
<tr class="header">
<th align="center"><p>Function</p></th>
<th align="center"><p>Input</p></th>
<th align="center"><p>Output</p></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td align="center"><p>List.map</p></td>
<td align="center"><p>'a -> 'b</p></td>
<td align="center"><p>list<'a> -> list<'b></p></td>
</tr>
<tr class="even">
<td align="center"><p>Option.map</p></td>
<td align="center"><p>'a -> 'b</p></td>
<td align="center"><p>option<'a> -> option<'b></p></td>
</tr>
<tr class="odd">
<td align="center"><p>Result.map</p></td>
<td align="center"><p>'a -> 'b</p></td>
<td align="center"><p>Result<'a> -> Result<'b></p></td>
</tr>
<tr class="even">
<td align="center"><p>Async.map</p></td>
<td align="center"><p>'a -> 'b</p></td>
<td align="center"><p>Async<'a> -> Async<'b></p></td>
</tr>
<tr class="odd">
<td align="center"><p>Whatever.map</p></td>
<td align="center"><p>'a -> 'b</p></td>
<td align="center"><p>Whatever<'a> -> Whatever<'b></p></td>
</tr>
</tbody>
</table>
<p>It basically means we can think of <code>map</code> of some kind of function that can <strong>upgrade</strong> a function.
If we pass a <code>int -> string</code> function for example to <code>List.map</code> we get a <code>list<int> -> list<string></code>
function back! If we pass the same function to <code>Async.map</code> we get a <code>Async<int> -> Async<string></code>
function back.</p>
<p>So <code>map</code> is a way to upgrade both sides (input and output) and add a layer to both sides. There are
two reason on why this concept is important.</p>
<ol>
<li>Code-Reuse. If a type supports <code>map</code>, you just can upgrade a function to work with this type.</li>
<li>In your own functions, you don't need to care about the layer itself.</li>
</ol>
<h2>Code Reuse</h2>
<p>So let's look again at our starting functions and just use them with the already built-in <code>List.map</code>
and <code>Option.map</code> functions.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs44', 143)" onmouseover="showTip(event, 'fs44', 143)" class="f">squareL</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 144)" onmouseover="showTip(event, 'fs3', 144)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 145)" onmouseover="showTip(event, 'fs4', 145)" class="f">map</span> <span onmouseout="hideTip(event, 'fs6', 146)" onmouseover="showTip(event, 'fs6', 146)" class="f">square</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs45', 147)" onmouseover="showTip(event, 'fs45', 147)" class="f">add10L</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 148)" onmouseover="showTip(event, 'fs3', 148)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 149)" onmouseover="showTip(event, 'fs4', 149)" class="f">map</span> <span onmouseout="hideTip(event, 'fs7', 150)" onmouseover="showTip(event, 'fs7', 150)" class="f">add10</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs46', 151)" onmouseover="showTip(event, 'fs46', 151)" class="f">lengthL</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 152)" onmouseover="showTip(event, 'fs3', 152)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 153)" onmouseover="showTip(event, 'fs4', 153)" class="f">map</span> <span onmouseout="hideTip(event, 'fs8', 154)" onmouseover="showTip(event, 'fs8', 154)" class="f">length</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 155)" onmouseover="showTip(event, 'fs47', 155)" class="f">squareO</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs48', 156)" onmouseover="showTip(event, 'fs48', 156)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs49', 157)" onmouseover="showTip(event, 'fs49', 157)" class="f">map</span> <span onmouseout="hideTip(event, 'fs6', 158)" onmouseover="showTip(event, 'fs6', 158)" class="f">square</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs50', 159)" onmouseover="showTip(event, 'fs50', 159)" class="f">add10O</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs48', 160)" onmouseover="showTip(event, 'fs48', 160)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs49', 161)" onmouseover="showTip(event, 'fs49', 161)" class="f">map</span> <span onmouseout="hideTip(event, 'fs7', 162)" onmouseover="showTip(event, 'fs7', 162)" class="f">add10</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs51', 163)" onmouseover="showTip(event, 'fs51', 163)" class="f">lengthO</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs48', 164)" onmouseover="showTip(event, 'fs48', 164)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs49', 165)" onmouseover="showTip(event, 'fs49', 165)" class="f">map</span> <span onmouseout="hideTip(event, 'fs8', 166)" onmouseover="showTip(event, 'fs8', 166)" class="f">length</span>
</code></pre></td>
</tr>
</table>
<p>So we just can reuse our three functions. We never have to write special functions that loops
through a list. Or that handles <code>option</code>, <code>Async</code>, <code>Result</code>, we just can <strong>upgrade</strong> any
function we already have written.</p>
<h2>You don't need to care for the layers</h2>
<p>This is probably the biggest advantage, as you don't have to care for the <em>layers</em>. You want
to convert a list of <code>int</code> to a list of <code>string</code>. Just write a function that does <code>int -> string</code>
no List handling, no looping, no recursion. Use <code>List.map</code> and you are done.</p>
<p>And the big advantage. You also can use that function with <code>Option.map</code> to turn it into a function
that works on a <code>option</code> type. If you pass it to <code>Async.map</code> you get a function that can work
on an asynchronous value. You don't need to write code for looping through a list, do pattern
match an option, or write code to handle asynchronicity.</p>
<p>All of this is done for you by the <code>map</code> function!</p>
<h2>Async.map</h2>
<p>Currently F# don't have a built-in <code>Async.map</code> function. So let's create the <code>map</code> function
for <code>Async</code> ourselves.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">module</span> <span onmouseout="hideTip(event, 'fs42', 167)" onmouseover="showTip(event, 'fs42', 167)" class="t">Async</span> <span class="o">=</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs52', 168)" onmouseover="showTip(event, 'fs52', 168)" class="f">map</span> <span onmouseout="hideTip(event, 'fs19', 169)" onmouseover="showTip(event, 'fs19', 169)" class="f">f</span> <span onmouseout="hideTip(event, 'fs53', 170)" onmouseover="showTip(event, 'fs53', 170)" class="i">op</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs54', 171)" onmouseover="showTip(event, 'fs54', 171)" class="i">async</span> {
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs22', 172)" onmouseover="showTip(event, 'fs22', 172)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs53', 173)" onmouseover="showTip(event, 'fs53', 173)" class="i">op</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs55', 174)" onmouseover="showTip(event, 'fs55', 174)" class="i">value</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs19', 175)" onmouseover="showTip(event, 'fs19', 175)" class="f">f</span> <span onmouseout="hideTip(event, 'fs22', 176)" onmouseover="showTip(event, 'fs22', 176)" class="i">x</span>
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs55', 177)" onmouseover="showTip(event, 'fs55', 177)" class="i">value</span>
}
</code></pre></td>
</tr>
</table>
<p>So how do we now that we have to implement it in this way? Because that is what the <em>type-signature</em>
is telling us. We have to write a function with the signature</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span onmouseout="hideTip(event, 'fs42', 178)" onmouseover="showTip(event, 'fs42', 178)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs42', 179)" onmouseover="showTip(event, 'fs42', 179)" class="i">Async</span><span class="o"><</span><span class="o">'</span><span class="i">b</span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<ol>
<li>
That means a function with two arguments. The first arguments is a <em>function</em> <code>'a -> 'b</code>, the second
is an <code>Async<'a></code>, and we have to return an <code>Async<'b></code>.
</li>
<li>Because we have to return an <code>Async</code> we start with <code>async { ... }</code>.</li>
<li>
Now <code>op</code> is an <code>Async<'a></code>, with <code>let! x = op</code> we run the the async operation.
This will <strong>unwrap</strong> our <code>Async<'a></code> and just returns an <code>'a</code>.
</li>
<li>We can pass that <code>'a</code> to our function <code>f</code> that converts <code>'a</code> to an <code>'b</code>.</li>
<li>Once we have a <code>'b</code> we <code>return</code> it. <code>return</code> basically wraps the <code>'b</code> and adds the <code>Async<></code> layer.</li>
</ol>
<h2>Stacking Layers</h2>
<p>The interesting idea is now. We are not restricted to adding a single layer. We can add as much layer
we want and stack them. For example we could have <code>option</code> values that are wrapped inside a <code>list</code> returned
by an <code>Async</code> operation.</p>
<p>To be more concrete. Let's assume we have some kind of async operation that downloads from a website
(The Async layer). This tries to Parse a table on a website that contains numbers (The List Layer).
But because parsing could fail, for example a table entry is not a number, we wrap it in a <code>Option</code>
(The Optional Layer).</p>
<p>Let's write a <em>mock</em> function that returns this kind of data.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs56', 180)" onmouseover="showTip(event, 'fs56', 180)" class="i">downloadPage</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs54', 181)" onmouseover="showTip(event, 'fs54', 181)" class="i">async</span> {
<span class="c">// Simulating Download, wait 1 second</span>
<span class="k">do!</span> <span onmouseout="hideTip(event, 'fs57', 182)" onmouseover="showTip(event, 'fs57', 182)" class="t">Async</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs58', 183)" onmouseover="showTip(event, 'fs58', 183)" class="f">Sleep</span> <span class="n">1000</span>
<span class="c">// A list of optionals list<option<int>></span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs59', 184)" onmouseover="showTip(event, 'fs59', 184)" class="i">numbers</span> <span class="o">=</span> [<span onmouseout="hideTip(event, 'fs30', 185)" onmouseover="showTip(event, 'fs30', 185)" class="p">Some</span> <span class="n">1</span>; <span onmouseout="hideTip(event, 'fs30', 186)" onmouseover="showTip(event, 'fs30', 186)" class="p">Some</span> <span class="n">2</span>; <span onmouseout="hideTip(event, 'fs29', 187)" onmouseover="showTip(event, 'fs29', 187)" class="p">None</span>; <span onmouseout="hideTip(event, 'fs30', 188)" onmouseover="showTip(event, 'fs30', 188)" class="p">Some</span> <span class="n">3</span>; <span onmouseout="hideTip(event, 'fs29', 189)" onmouseover="showTip(event, 'fs29', 189)" class="p">None</span>; <span onmouseout="hideTip(event, 'fs29', 190)" onmouseover="showTip(event, 'fs29', 190)" class="p">None</span>; <span onmouseout="hideTip(event, 'fs30', 191)" onmouseover="showTip(event, 'fs30', 191)" class="p">Some</span> <span class="n">10</span>]
<span class="c">// return it: This adds async<> layer</span>
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs59', 192)" onmouseover="showTip(event, 'fs59', 192)" class="i">numbers</span>
}
</code></pre></td>
</tr>
</table>
<p>What we now have is a <code>Async<list<option<int>>></code>. Puh looks complicated! So what do we now
if we want to square the <code>int</code> inside our <code>Async<List<Option<...>>></code> construct? We just add
one layer after another to <code>square</code>. At first, we do a <code>Option.map</code> on <code>square</code>. The result
of this is a function that we pass to <code>List.map</code> that adds the <code>List</code> layer. And once again
the <code>Async.map</code> finally adds the <code>Async</code> layer.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs60', 193)" onmouseover="showTip(event, 'fs60', 193)" class="f">squaring</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs57', 194)" onmouseover="showTip(event, 'fs57', 194)" class="t">Async</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs52', 195)" onmouseover="showTip(event, 'fs52', 195)" class="f">map</span> (<span onmouseout="hideTip(event, 'fs3', 196)" onmouseover="showTip(event, 'fs3', 196)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 197)" onmouseover="showTip(event, 'fs4', 197)" class="f">map</span> (<span onmouseout="hideTip(event, 'fs48', 198)" onmouseover="showTip(event, 'fs48', 198)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs49', 199)" onmouseover="showTip(event, 'fs49', 199)" class="f">map</span> <span onmouseout="hideTip(event, 'fs6', 200)" onmouseover="showTip(event, 'fs6', 200)" class="f">square</span>))
</code></pre></td>
</tr>
</table>
<p>We now have <code>squaring</code> that has the following signature</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs42', 201)" onmouseover="showTip(event, 'fs42', 201)" class="i">Async</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs3', 202)" onmouseover="showTip(event, 'fs3', 202)" class="i">List</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs48', 203)" onmouseover="showTip(event, 'fs48', 203)" class="i">Option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs41', 204)" onmouseover="showTip(event, 'fs41', 204)" class="i">int</span><span class="o">></span><span class="o">></span><span class="o">></span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs42', 205)" onmouseover="showTip(event, 'fs42', 205)" class="i">Async</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs3', 206)" onmouseover="showTip(event, 'fs3', 206)" class="i">List</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs48', 207)" onmouseover="showTip(event, 'fs48', 207)" class="i">Option</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs41', 208)" onmouseover="showTip(event, 'fs41', 208)" class="i">int</span><span class="o">></span><span class="o">></span><span class="o">></span>
</code></pre></td>
</tr>
</table>
<p>We can now do</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs61', 209)" onmouseover="showTip(event, 'fs61', 209)" class="i">data</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs57', 210)" onmouseover="showTip(event, 'fs57', 210)" class="t">Async</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs62', 211)" onmouseover="showTip(event, 'fs62', 211)" class="f">RunSynchronously</span> (<span onmouseout="hideTip(event, 'fs60', 212)" onmouseover="showTip(event, 'fs60', 212)" class="f">squaring</span> <span onmouseout="hideTip(event, 'fs56', 213)" onmouseover="showTip(event, 'fs56', 213)" class="i">downloadPage</span>)
</code></pre></td>
</tr>
</table>
<p>And <code>data</code> will be <code>[Some 1; Some 4; None; Some 9; None; None; Some 100]</code></p>
<p>All <code>Option</code>, <code>List</code> and <code>Async</code> handling was handled for us. We just <strong>upgraded</strong>
<code>square</code> with the different <code>map</code> functions until it matches our needed signature.</p>
<p>Let's assume we wouldn't have <code>Async.map</code>, <code>List.map</code>, <code>Option.map</code>. We would have needed
to write it like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs63', 214)" onmouseover="showTip(event, 'fs63', 214)" class="f">squaring'</span> <span onmouseout="hideTip(event, 'fs64', 215)" onmouseover="showTip(event, 'fs64', 215)" class="i">input</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs54', 216)" onmouseover="showTip(event, 'fs54', 216)" class="i">async</span> {
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs65', 217)" onmouseover="showTip(event, 'fs65', 217)" class="i">data</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs64', 218)" onmouseover="showTip(event, 'fs64', 218)" class="i">input</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs66', 219)" onmouseover="showTip(event, 'fs66', 219)" class="i">squared</span> <span class="o">=</span> [
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs67', 220)" onmouseover="showTip(event, 'fs67', 220)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs65', 221)" onmouseover="showTip(event, 'fs65', 221)" class="i">data</span> <span class="k">-></span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs67', 222)" onmouseover="showTip(event, 'fs67', 222)" class="i">x</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs29', 223)" onmouseover="showTip(event, 'fs29', 223)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs29', 224)" onmouseover="showTip(event, 'fs29', 224)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs30', 225)" onmouseover="showTip(event, 'fs30', 225)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs31', 226)" onmouseover="showTip(event, 'fs31', 226)" class="i">value</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs30', 227)" onmouseover="showTip(event, 'fs30', 227)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs6', 228)" onmouseover="showTip(event, 'fs6', 228)" class="f">square</span> <span onmouseout="hideTip(event, 'fs31', 229)" onmouseover="showTip(event, 'fs31', 229)" class="i">value</span>)
]
<span class="k">return</span> <span class="i">squared</span>
}
</code></pre></td>
</tr>
</table>
<h2>Functors</h2>
<p>Whenever we have a type with a <code>map</code> function we call it a <em>Functor</em> if the implementation
of <code>map</code> satisfies two laws. Those two laws ensures that <code>map</code> is predictable and don't do
additional stuff we didn't expect.</p>
<h3>1. Law: Mapping <code>id</code></h3>
<p>The first rule says that mapping over the <code>id</code> function must not change the input. The <code>id</code>
function is just a function that returns its input as-is</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs68', 230)" onmouseover="showTip(event, 'fs68', 230)" class="i">id</span> <span class="i">x</span> <span class="o">=</span> <span class="i">x</span>
</code></pre></td>
</tr>
</table>
<p>So when we write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs69', 231)" onmouseover="showTip(event, 'fs69', 231)" class="i">xs</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 232)" onmouseover="showTip(event, 'fs3', 232)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 233)" onmouseover="showTip(event, 'fs4', 233)" class="f">map</span> <span onmouseout="hideTip(event, 'fs68', 234)" onmouseover="showTip(event, 'fs68', 234)" class="f">id</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>]
</code></pre></td>
</tr>
</table>
<p>Then <code>xs</code> still must be <code>[1;2;3;4;5]</code>.</p>
<h3>2. Law: Function composition</h3>
<p>The second rule says that composing two functions and then mapping, should be the same
as mapping over both functions separately.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="c">// 1 solution: compose two functions, and then map</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs70', 235)" onmouseover="showTip(event, 'fs70', 235)" class="f">comp</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs6', 236)" onmouseover="showTip(event, 'fs6', 236)" class="f">square</span> <span class="o">></span><span class="o">></span> <span onmouseout="hideTip(event, 'fs7', 237)" onmouseover="showTip(event, 'fs7', 237)" class="f">add10</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs71', 238)" onmouseover="showTip(event, 'fs71', 238)" class="i">cxs</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 239)" onmouseover="showTip(event, 'fs3', 239)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 240)" onmouseover="showTip(event, 'fs4', 240)" class="f">map</span> <span onmouseout="hideTip(event, 'fs70', 241)" onmouseover="showTip(event, 'fs70', 241)" class="f">comp</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>]
<span class="c">// 2 solution: mapping it two times</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs72', 242)" onmouseover="showTip(event, 'fs72', 242)" class="i">sxs</span> <span class="o">=</span>
[<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>]
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs3', 243)" onmouseover="showTip(event, 'fs3', 243)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 244)" onmouseover="showTip(event, 'fs4', 244)" class="f">map</span> <span onmouseout="hideTip(event, 'fs6', 245)" onmouseover="showTip(event, 'fs6', 245)" class="f">square</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs3', 246)" onmouseover="showTip(event, 'fs3', 246)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 247)" onmouseover="showTip(event, 'fs4', 247)" class="f">map</span> <span onmouseout="hideTip(event, 'fs7', 248)" onmouseover="showTip(event, 'fs7', 248)" class="f">add10</span>
<span onmouseout="hideTip(event, 'fs71', 249)" onmouseover="showTip(event, 'fs71', 249)" class="i">cxs</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs72', 250)" onmouseover="showTip(event, 'fs72', 250)" class="i">sxs</span> <span class="c">// must be the same</span>
</code></pre></td>
</tr>
</table>
<p>It shouldn't matter if we go through the list take one element and then do <code>square</code> and <code>add10</code>
in one-step. Or if we go trough our list two times and do it in two separately steps. Both
<code>cxs</code> and <code>sxs</code> have to return the same result <code>[11;14;19;26;35]</code></p>
<p>Because <code>List.map</code> satisfies both laws, we say that <code>List</code> is a <em>functor</em>.</p>
<h2>Summary</h2>
<p>I hope it is now clear why <code>map</code> is such an important function. Implementing a <code>map</code> function
just means you can <strong>upgrade</strong> already available functions. It opens up a lot of
code reuse as you don't have to write special glue code that handles your type/layer.</p>
<p>It also can make writing new functions easier, as you don't have to care about a layer.
If you find yourself writing a function that has a list as its input and a list as its output
then you are <em>probably</em> doing something wrong! The same goes for every other type.</p>
<p>Not only is it easier to just write a function that don't contain any list/looping/recursion
logic. Such a function is even more reusable.</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">val xs : int list<br /><br />Full name: understandingmap.xs</div>
<div class="tip" id="fs3">Multiple items<br />module List<br /><br />from Microsoft.FSharp.Collections<br /><br />--------------------<br />type List<'T> =<br />  | ( [] )<br />  | ( :: ) of Head: 'T * Tail: 'T list<br />  interface IEnumerable<br />  interface IEnumerable<'T><br />  member GetSlice : startIndex:int option * endIndex:int option -> 'T list<br />  member Head : 'T<br />  member IsEmpty : bool<br />  member Item : index:int -> 'T with get<br />  member Length : int<br />  member Tail : 'T list<br />  static member Cons : head:'T * tail:'T list -> 'T list<br />  static member Empty : 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List<_></div>
<div class="tip" id="fs4">val map : mapping:('T -> 'U) -> list:'T list -> 'U list<br /><br />Full name: Microsoft.FSharp.Collections.List.map</div>
<div class="tip" id="fs5">val x : int</div>
<div class="tip" id="fs6">val square : x:int -> int<br /><br />Full name: Main.square</div>
<div class="tip" id="fs7">val add10 : x:int -> int<br /><br />Full name: Main.add10</div>
<div class="tip" id="fs8">val length : str:string -> int<br /><br />Full name: Main.length</div>
<div class="tip" id="fs9">val str : string</div>
<div class="tip" id="fs10">Multiple items<br />val string : value:'T -> string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string<br /><br />--------------------<br />type string = System.String<br /><br />Full name: Microsoft.FSharp.Core.string</div>
<div class="tip" id="fs11">property System.String.Length: int</div>
<div class="tip" id="fs12">val squareList : xs:seq<int> -> int list<br /><br />Full name: Main.squareList</div>
<div class="tip" id="fs13">val xs : seq<int></div>
<div class="tip" id="fs14">val mutable results : int list</div>
<div class="tip" id="fs15">val res : int</div>
<div class="tip" id="fs16">val rev : list:'T list -> 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.rev</div>
<div class="tip" id="fs17">val add10List : xs:seq<int> -> int list<br /><br />Full name: Main.add10List</div>
<div class="tip" id="fs18">val mapList : f:('a -> 'b) -> xs:seq<'a> -> 'b list<br /><br />Full name: Main.mapList</div>
<div class="tip" id="fs19">val f : ('a -> 'b)</div>
<div class="tip" id="fs20">val xs : seq<'a></div>
<div class="tip" id="fs21">val mutable results : 'b list</div>
<div class="tip" id="fs22">val x : 'a</div>
<div class="tip" id="fs23">val mapping : 'b</div>
<div class="tip" id="fs24">val listOfsquared : int list<br /><br />Full name: Main.listOfsquared</div>
<div class="tip" id="fs25">val listOfAdd10 : int list<br /><br />Full name: Main.listOfAdd10</div>
<div class="tip" id="fs26">type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs27">val squareOption : opt:int option -> int option<br /><br />Full name: Main.squareOption</div>
<div class="tip" id="fs28">val opt : int option</div>
<div class="tip" id="fs29">union case Option.None: Option<'T></div>
<div class="tip" id="fs30">union case Option.Some: Value: 'T -> Option<'T></div>
<div class="tip" id="fs31">val value : int</div>
<div class="tip" id="fs32">val add10Option : opt:int option -> int option<br /><br />Full name: Main.add10Option</div>
<div class="tip" id="fs33">val mapOption : f:('a -> 'b) -> opt:'a option -> 'b option<br /><br />Full name: Main.mapOption</div>
<div class="tip" id="fs34">val opt : 'a option</div>
<div class="tip" id="fs35">val value : 'a</div>
<div class="tip" id="fs36">val OptionSquare1 : int option<br /><br />Full name: Main.OptionSquare1</div>
<div class="tip" id="fs37">val OptionSquare2 : int option<br /><br />Full name: Main.OptionSquare2</div>
<div class="tip" id="fs38">val OptionAdd10_1 : int option<br /><br />Full name: Main.OptionAdd10_1</div>
<div class="tip" id="fs39">val OptionAdd10_2 : int option<br /><br />Full name: Main.OptionAdd10_2</div>
<div class="tip" id="fs40">type 'T option = Option<'T><br /><br />Full name: Microsoft.FSharp.Core.option<_></div>
<div class="tip" id="fs41">Multiple items<br />val int : value:'T -> int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int<br /><br />--------------------<br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />--------------------<br />type int<'Measure> = int<br /><br />Full name: Microsoft.FSharp.Core.int<_></div>
<div class="tip" id="fs42">Multiple items<br />type Async<br />static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)<br />static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)<br />static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool><br />static member AwaitTask : task:Task -> Async<unit><br />static member AwaitTask : task:Task<'T> -> Async<'T><br />static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool><br />static member CancelDefaultToken : unit -> unit<br />static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>><br />static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T><br />static member Ignore : computation:Async<'T> -> Async<unit><br />static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable><br />static member Parallel : computations:seq<Async<'T>> -> Async<'T []><br />static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T<br />static member Sleep : millisecondsDueTime:int -> Async<unit><br />static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T><br />static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>><br />static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>><br />static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit<br />static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit><br />static member SwitchToNewThread : unit -> Async<unit><br />static member SwitchToThreadPool : unit -> Async<unit><br />static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T><br />static member CancellationToken : Async<CancellationToken><br />static member DefaultCancellationToken : CancellationToken<br /><br />Full name: Microsoft.FSharp.Control.Async<br /><br />--------------------<br />type Async<'T><br /><br />Full name: Microsoft.FSharp.Control.Async<_></div>
<div class="tip" id="fs43">Multiple items<br />val float : value:'T -> float (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.float<br /><br />--------------------<br />type float = System.Double<br /><br />Full name: Microsoft.FSharp.Core.float<br /><br />--------------------<br />type float<'Measure> = float<br /><br />Full name: Microsoft.FSharp.Core.float<_></div>
<div class="tip" id="fs44">val squareL : (int list -> int list)<br /><br />Full name: Main.squareL</div>
<div class="tip" id="fs45">val add10L : (int list -> int list)<br /><br />Full name: Main.add10L</div>
<div class="tip" id="fs46">val lengthL : (string list -> int list)<br /><br />Full name: Main.lengthL</div>
<div class="tip" id="fs47">val squareO : (int option -> int option)<br /><br />Full name: Main.squareO</div>
<div class="tip" id="fs48">module Option<br /><br />from Microsoft.FSharp.Core</div>
<div class="tip" id="fs49">val map : mapping:('T -> 'U) -> option:'T option -> 'U option<br /><br />Full name: Microsoft.FSharp.Core.Option.map</div>
<div class="tip" id="fs50">val add10O : (int option -> int option)<br /><br />Full name: Main.add10O</div>
<div class="tip" id="fs51">val lengthO : (string option -> int option)<br /><br />Full name: Main.lengthO</div>
<div class="tip" id="fs52">val map : f:('a -> 'b) -> op:Async<'a> -> Async<'b><br /><br />Full name: Main.Async.map</div>
<div class="tip" id="fs53">val op : Async<'a></div>
<div class="tip" id="fs54">val async : AsyncBuilder<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async</div>
<div class="tip" id="fs55">val value : 'b</div>
<div class="tip" id="fs56">val downloadPage : Async<int option list><br /><br />Full name: Main.downloadPage</div>
<div class="tip" id="fs57">Multiple items<br />module Async<br /><br />from Main<br /><br />--------------------<br />type Async<br />static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)<br />static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)<br />static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool><br />static member AwaitTask : task:Task -> Async<unit><br />static member AwaitTask : task:Task<'T> -> Async<'T><br />static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool><br />static member CancelDefaultToken : unit -> unit<br />static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>><br />static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T><br />static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T><br />static member Ignore : computation:Async<'T> -> Async<unit><br />static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable><br />static member Parallel : computations:seq<Async<'T>> -> Async<'T []><br />static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T<br />static member Sleep : millisecondsDueTime:int -> Async<unit><br />static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T><br />static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>><br />static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>><br />static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit<br />static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit<br />static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit><br />static member SwitchToNewThread : unit -> Async<unit><br />static member SwitchToThreadPool : unit -> Async<unit><br />static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T><br />static member CancellationToken : Async<CancellationToken><br />static member DefaultCancellationToken : CancellationToken<br /><br />Full name: Microsoft.FSharp.Control.Async<br /><br />--------------------<br />type Async<'T><br /><br />Full name: Microsoft.FSharp.Control.Async<_></div>
<div class="tip" id="fs58">static member Async.Sleep : millisecondsDueTime:int -> Async<unit></div>
<div class="tip" id="fs59">val numbers : int option list</div>
<div class="tip" id="fs60">val squaring : (Async<int option list> -> Async<int option list>)<br /><br />Full name: Main.squaring</div>
<div class="tip" id="fs61">val data : int option list<br /><br />Full name: Main.data</div>
<div class="tip" id="fs62">static member Async.RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:System.Threading.CancellationToken -> 'T</div>
<div class="tip" id="fs63">val squaring' : input:Async<#seq<int option>> -> Async<int option list><br /><br />Full name: Main.squaring'</div>
<div class="tip" id="fs64">val input : Async<#seq<int option>></div>
<div class="tip" id="fs65">val data : #seq<int option></div>
<div class="tip" id="fs66">val squared : int option list</div>
<div class="tip" id="fs67">val x : int option</div>
<div class="tip" id="fs68">val id : x:'T -> 'T<br /><br />Full name: Microsoft.FSharp.Core.Operators.id</div>
<div class="tip" id="fs69">val xs : int list<br /><br />Full name: Main.xs</div>
<div class="tip" id="fs70">val comp : (int -> int)<br /><br />Full name: Main.comp</div>
<div class="tip" id="fs71">val cxs : int list<br /><br />Full name: Main.cxs</div>
<div class="tip" id="fs72">val sxs : int list<br /><br />Full name: Main.sxs</div>
Exceptions are Evil2016-03-25T00:00:00+00:00https://sidburn.github.io/blog/2016/03/25/exceptions-are-evil<p>Most people today agree that <code>null</code> is evil, and they try to get rid of them. One technique that
most people prefer is to throw an exception in the case of an error, or if we cannot return a valid
value from a function. The problem is, exceptions are not any kind better than <code>null</code>, and
they don't solve any problem that <code>null</code> introduced.</p>
<p>In my previous post <a href="/blog/2016/03/20/null-is-evil">null is Evil</a> i mentioned seven
problems that <code>null</code> introduced. So let's look if <em>exceptions</em> solve one of those problems.</p>
<h2>1. You cannot see if a function throws an exception</h2>
<p>When you look at the type signature of any function, you just see something like</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">PersonId</span> <span class="k">-></span> <span class="i">Person</span>
</code></pre></td>
</tr>
</table>
<p>The same way that you cannot see that <code>null</code> could be returned. The same way you don't know
if an exception could be thrown or not.</p>
<h2>2. We are not forced to try/catch</h2>
<p>You are not forced to add any kind of <code>try/catch</code>, the same way you are not forced to add
a <code>null</code> check. If you forgot to add your <code>null</code> checks, you end up getting <code>NullReferenceException</code>.
If you forgot to adding <code>try/catch</code> you end up with <code>XYZException</code>. Replacing a <code>NullReferenceException</code>
just with another kind of <code>Exception</code> isn't anyway better.</p>
<h2>3. Every function could throw an Exception</h2>
<p>The big problem of 1. and 2. combined is that you defensively start to check all return values
from a function if it contains <code>null</code>. And you also have to check every argument if it contains
<code>null</code>. This leads to numerous <code>null</code> checking throughout your code. But why do you add those
checks in the first place? Because you want to prevent <code>NullReferenceException</code>. So how is a
function that sometimes returns <code>null</code> that can lead to a <code>NullReferenceException</code> anyhow better
as a function that sometimes throws <code>XYZException</code> directly?</p>
<p>Not only does it not solve the problem at all. You still have to add your checkings. But instead of
<code>null</code> checks throughout your code. You wrap your code in <code>try/catch</code> blocks. Why is checking for
null bad</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">result</span> <span class="o">=</span> <span class="i">SomeFunction</span>()
<span class="k">if</span> <span class="i">result</span> <span class="o"><></span> <span class="k">null</span> <span class="k">then</span>
<span class="c">// Some code if everything was right</span>
<span class="k">else</span>
<span class="c">// Error condition on null</span>
</code></pre></td>
</tr>
</table>
<p>and suddenly wrapping your code in a <code>try/catch</code> anyhow better?</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">try</span>
<span class="k">let</span> <span class="i">result</span> <span class="o">=</span> <span class="i">SomeFunction</span>()
<span class="c">// Some code if everything was right</span>
<span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs1', 1)" onmouseover="showTip(event, 'fs1', 1)" class="i">exn</span> <span class="k">-></span> <span class="c">// Error condition on Exception</span>
</code></pre></td>
</tr>
</table>
<h2>4. We cannot skip the checking</h2>
<p>Probably you would assume that exceptions solve it, but actually, they don't really provide an improvement.
Sure, you don't have to wrap a try/catch block around your code. Exactly the same as you don't have
to write an explicit <code>null</code> check. So what happens in both cases?</p>
<p>In both cases an exception is thrown either a <code>NullReferenceException</code> or probably you throw some other kind of
<code>Exception</code>. Yes, you can catch your <code>Exception</code> further up the stack. The same way as you can catch
a <code>NullReferenceException</code> further up the stack. There is no difference at all here.</p>
<p>But overall, this was not meant with <em>skipping</em>. The idea of <em>skipping</em> was that you can do the null check
at some later point where it makes sense. That doesn't mean only "further up the stack". The idea is that you
pass the whole error as a value around, as you can do with <code>Optional</code>, and additional you are forced
to check the condition of your <code>Optional</code> at compile-time.</p>
<h2>5. and 6. We can pass functions/objects that throws exception around</h2>
<p>At default you don't pass <code>Exception</code> types as values around. You wrap your code in a <code>try/catch</code> and that's
it. You also cannot implicitly pass an <code>Exception</code> as a valid value to a function that expects a <code>Person</code>. With
<code>null</code> you can do that, that's why we have to also add <code>null</code> checks for function arguments.</p>
<p>So it seems we are not affected if we throw exceptions. But that is wrong. An object itself contains <em>methods</em>.
And every method on an object could throw an exception.</p>
<p>With <code>null</code> you have to check every argument if it is <code>null</code>. With <em>exceptions</em> you have to additional add
try/catch blocks if you call a method on an object. Because you pass objects around, and objects have <em>methods</em>
that could throw exceptions when invoked. You end up with the same problem.</p>
<h2>7. Happy Path Coding</h2>
<p>It seems <em>Exceptions</em> solve the problem of Happy-Path coding. But it really does not. Yes, you are not forced to add
a <code>try/catch</code> around every function directly. You just can use one <code>try/catch</code> around the whole code and catch
<strong>any exception</strong>.</p>
<p>Absolutely, and the thing is. <strong>Any exception</strong> also includes <code>NullReferenceException</code>. So if you like to have
<em>exceptions</em>. No problem, just return <code>null</code> from your functions and don't add any <code>null</code> checks.</p>
<h2>Summary</h2>
<p>It seems many people forget about why <code>null</code> is bad. <code>null</code> is bad because <strong>they throw exceptions</strong> when
you try to use them. So using <em>exceptions</em> instead of using <code>null</code> makes nothing better at all. The reason
why we add all those <code>null</code> checks is to <strong>prevent exceptions</strong> to happen. So how can we get rid of that problem
if we choose to directly throw exceptions?</p>
<p>We can't. Throwing <em>exceptions</em> as a solution of getting rid of <em>null</em> is just a Pyrrhic victory. Not only that.
Exceptions in general share the same problems as <code>null</code>.</p>
<p>So what is the alternative? My Post about <a href="/blog/2016/03/20/null-is-evil">null is Evil</a> contains solution
of getting rid of <code>null</code>. The thing is, the same solutions also works for <em>Exceptions</em>!</p>
<div class="tip" id="fs1">type exn = System.Exception<br /><br />Full name: Microsoft.FSharp.Core.exn</div>
Higher-kinded Polymorphism: What is it, why you want it2016-03-24T00:00:00+00:00https://sidburn.github.io/blog/2016/03/24/higher-kinded-polymorphism<p>One aspect of a programming language that is often noted as important is the idea of <em>Polymorphism</em>.
But there doesn't exists just one type of polymorphism. In functional languages <em>Parametric
Polymorphism</em> (aka Generics) is often used. Haskell was the first language that introduced
"Higher-kinded polymorphism". Sadly, F# don't support this kind of polymorphism directly. Actually it
only has partial support for it. So let's look in what it is, and why you want it.</p>
<h2>Polymorphism</h2>
<p>Before we go deeper let's recap what polymorphism is about. Polymorphism is the idea
that you can write code that looks the same. But it can do different things depending on the
concrete type.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="i">x</span> <span class="o">=</span> <span class="n">1</span> <span class="o">+</span> <span class="n">3</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="i">y</span> <span class="o">=</span> <span class="s">"foo"</span> <span class="o">+</span> <span class="s">"bar"</span>
</code></pre></td>
</tr>
</table>
<p>As we see here, we have a polymorphic <code>+</code>. Depending on it's type, it does different things.
It either can add two <code>int</code> or add two <code>string</code>. It is important to note that the types itself
still remain the same. <code>+</code> is polymorphic because it can be used with different types, but every
type can have it's own implementation.</p>
<p>This idea is important because it can greatly help to make code readable. Let's assume we wouldn't
be able to write a polymorphic <code>+</code>, so <code>+</code> always can only operate on a concrete predefined type.
If that would be true, we actually would need different <code>+</code> operators for every type. For example
OCaml doesn't support this kind of polymorphism, so OCaml has two different types for adding
<code>int</code> and <code>float</code></p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip"><code lang="ocaml">let x = a + b // int
let y = a +. b // float
</code></pre></td></tr></table>
<p>So if you want to add a <code>string</code> you need yet again another operator/function. So Polymorphism can
greatly help, because we can create the general concept of <em>add two things</em>. And we can use this
operation with different types.</p>
<h2>Higher-kinded polymorphism</h2>
<p>Now let's assume we want to write a function that just adds two <code>int</code> together. We could just write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="f">add</span> <span onmouseout="hideTip(event, 'fs5', 5)" onmouseover="showTip(event, 'fs5', 5)" class="i">x</span> <span onmouseout="hideTip(event, 'fs6', 6)" onmouseover="showTip(event, 'fs6', 6)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 7)" onmouseover="showTip(event, 'fs5', 7)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs6', 8)" onmouseover="showTip(event, 'fs6', 8)" class="i">y</span>
</code></pre></td>
</tr>
</table>
<p>But when we inspect the type-signature of this function, we get <code>int -> int -> int</code>. The reason for this
is that the type-inference system of the F# compiler defaults to <code>int</code>. But actually the type
can change if we use <code>add</code> with a different type. For example if we write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs7', 9)" onmouseover="showTip(event, 'fs7', 9)" class="f">add</span> <span onmouseout="hideTip(event, 'fs8', 10)" onmouseover="showTip(event, 'fs8', 10)" class="i">x</span> <span onmouseout="hideTip(event, 'fs9', 11)" onmouseover="showTip(event, 'fs9', 11)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 12)" onmouseover="showTip(event, 'fs8', 12)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs9', 13)" onmouseover="showTip(event, 'fs9', 13)" class="i">y</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs10', 14)" onmouseover="showTip(event, 'fs10', 14)" class="i">result</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs7', 15)" onmouseover="showTip(event, 'fs7', 15)" class="f">add</span> <span class="n">1.3</span> <span class="n">2.1</span>
</code></pre></td>
</tr>
</table>
<p>We now have <code>add</code> with the signature <code>float -> float -> float</code>. But it is still important to note that
<code>add</code> now only can work with float. Using it like these</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs7', 16)" onmouseover="showTip(event, 'fs7', 16)" class="f">add</span> <span onmouseout="hideTip(event, 'fs8', 17)" onmouseover="showTip(event, 'fs8', 17)" class="i">x</span> <span onmouseout="hideTip(event, 'fs9', 18)" onmouseover="showTip(event, 'fs9', 18)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 19)" onmouseover="showTip(event, 'fs8', 19)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs9', 20)" onmouseover="showTip(event, 'fs9', 20)" class="i">y</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 21)" onmouseover="showTip(event, 'fs11', 21)" class="i">r1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs7', 22)" onmouseover="showTip(event, 'fs7', 22)" class="f">add</span> <span class="n">1.3</span> <span class="n">2.1</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 23)" onmouseover="showTip(event, 'fs12', 23)" class="i">r2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs7', 24)" onmouseover="showTip(event, 'fs7', 24)" class="f">add</span> <span class="n">3</span> <span class="n">4</span>
</code></pre></td>
</tr>
</table>
<p>will create errors at line 3 saying that <code>3</code> and <code>4</code> was expected to be of type <code>float</code>
but we provided <code>int</code> as a value.</p>
<p>The problem we have is that <code>add</code> itself is not polymorphic at all. But let's consider, why do we have
that behaviour anyway? The only thing we do is add two things together, adding two things together is
polymorphic, so doesn't make it sense that <code>add</code> also should be polymorphic? Well yes, it makes sense,
but this is not what F# does by default. At default it tries to get concrete types or also generic
types. But it cannot automatically create Polymorphic functions that accepts all types that can be
added (+), for instance.</p>
<p>But as said before, F# supports this kind of stuff partly. Indeed we can fix this problem
very easily with the <code>inline</code> keyword.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="k">inline</span> <span onmouseout="hideTip(event, 'fs13', 25)" onmouseover="showTip(event, 'fs13', 25)" class="f">add</span> <span onmouseout="hideTip(event, 'fs14', 26)" onmouseover="showTip(event, 'fs14', 26)" class="i">x</span> <span onmouseout="hideTip(event, 'fs15', 27)" onmouseover="showTip(event, 'fs15', 27)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs14', 28)" onmouseover="showTip(event, 'fs14', 28)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs15', 29)" onmouseover="showTip(event, 'fs15', 29)" class="i">y</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs16', 30)" onmouseover="showTip(event, 'fs16', 30)" class="i">r1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs13', 31)" onmouseover="showTip(event, 'fs13', 31)" class="f">add</span> <span class="n">1.3</span> <span class="n">2.1</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs17', 32)" onmouseover="showTip(event, 'fs17', 32)" class="i">r2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs13', 33)" onmouseover="showTip(event, 'fs13', 33)" class="f">add</span> <span class="n">3</span> <span class="n">4</span>
</code></pre></td>
</tr>
</table>
<p>Now all compiler errors are gone. Let's look at the type-signature of <code>add</code> again.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span> (<span class="i">requires</span> <span class="k">member</span> (<span class="o">+</span>))
</code></pre></td>
</tr>
</table>
<p>What we now have is a function that can take two generic values. But not any kind of generics. Both
generics must support the <code>+</code> operation. It is also important to look at the return types. <code>r1</code> is
of type <code>float</code> while <code>r2</code> is of type <code>int</code>. If you come from a C# background it could probably be that
you are not impressed, but actually such kind of function is not possible to write in C#. In C# you
always have to provide explicit arguments, and you have to write two version of <code>Add</code> if the return
type should remain the same.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">public</span> <span class="k">static</span> <span class="k">int</span> Add(<span class="k">int</span> x, <span class="k">int</span> y) {
<span class="k">return</span> x <span class="o">+</span> y;
}
<span class="k">public</span> <span class="k">static</span> <span class="k">float</span> Add(<span class="k">float</span> x, <span class="k">float</span> y) {
<span class="k">return</span> x <span class="o">+</span> y;
}
</code></pre></td></tr></table>
<p>Actually you cannot write it with a generic type like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">public</span> <span class="k">static</span> <span class="i">T</span> <span class="i">Add</span><span class="o"><</span><span class="i">T</span><span class="o">></span>(<span class="i">T</span> <span onmouseout="hideTip(event, 'fs2', 34)" onmouseover="showTip(event, 'fs2', 34)" class="i">x</span>, <span class="i">T</span> <span onmouseout="hideTip(event, 'fs3', 35)" onmouseover="showTip(event, 'fs3', 35)" class="i">y</span>) {
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs2', 36)" onmouseover="showTip(event, 'fs2', 36)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs3', 37)" onmouseover="showTip(event, 'fs3', 37)" class="i">y</span>;
}
</code></pre></td>
</tr>
</table>
<p>The problem with this code is. You cannot add two generic variables! What you really need is the ability
to say: Allow any type that supports the <code>+</code> operation.</p>
<p>Probably you will say: Okay but i don't need to write the <code>int</code> version. As <code>int</code> can implicitly convert
to <code>float</code>, so the <code>float</code> version also works with <code>int</code>. That might be right, but it is not the same,
your return type will also be <code>float</code> not <code>int</code> anymore. We could argue with <em>floating-point inaccuracy</em>
on why it is not the same, but there is a better way to show the difference. What do you do if your type
supports <code>+</code> but don't support a conversion to <code>float</code>?</p>
<p>Let's assume we have the following <code>Vector3</code> type.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span class="i">Vector3</span> <span class="o">=</span> {<span class="i">X</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs20', 94)" onmouseover="showTip(event, 'fs20', 94)" class="i">float</span>; <span class="i">Y</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs20', 95)" onmouseover="showTip(event, 'fs20', 95)" class="i">float</span>; <span class="i">Z</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs20', 96)" onmouseover="showTip(event, 'fs20', 96)" class="i">float</span>} <span class="k">with</span>
<span class="k">static</span> <span class="k">member</span> <span class="i">create</span> <span onmouseout="hideTip(event, 'fs2', 97)" onmouseover="showTip(event, 'fs2', 97)" class="i">x</span> <span onmouseout="hideTip(event, 'fs3', 98)" onmouseover="showTip(event, 'fs3', 98)" class="i">y</span> <span class="i">z</span> <span class="o">=</span> {<span class="i">X</span><span class="o">=</span><span onmouseout="hideTip(event, 'fs2', 99)" onmouseover="showTip(event, 'fs2', 99)" class="i">x</span>; <span class="i">Y</span><span class="o">=</span><span onmouseout="hideTip(event, 'fs3', 100)" onmouseover="showTip(event, 'fs3', 100)" class="i">y</span>; <span class="i">Z</span><span class="o">=</span><span class="i">z</span>}
<span class="k">static</span> <span class="k">member</span> (<span class="o">+</span>) (<span class="i">a</span>,<span class="i">b</span>) <span class="o">=</span> <span class="i">Vector3</span><span class="o">.</span><span class="i">create</span> (<span class="i">a</span><span class="o">.</span><span class="i">X</span> <span class="o">+</span> <span class="i">b</span><span class="o">.</span><span class="i">X</span>) (<span class="i">a</span><span class="o">.</span><span class="i">Y</span> <span class="o">+</span> <span class="i">b</span><span class="o">.</span><span class="i">Y</span>) (<span class="i">a</span><span class="o">.</span><span class="i">Z</span> <span class="o">+</span> <span class="i">b</span><span class="o">.</span><span class="i">Z</span>)
</code></pre></td>
</tr>
</table>
<p>We now have our own <code>Vector3</code> and implemented <code>+</code> for it. The big advantage is now, that
our <code>Vector3</code> also can be used with our polymorphic <code>add</code> function written in F#. But in C#
you must create a new <code>Add</code> function instead, because we cannot convert a <code>Vector3</code> to a <code>float</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs33', 101)" onmouseover="showTip(event, 'fs33', 101)" class="i">vec1</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs18', 102)" onmouseover="showTip(event, 'fs18', 102)" class="t">Vector3</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 103)" onmouseover="showTip(event, 'fs27', 103)" class="f">create</span> <span class="n">1.0</span> <span class="n">1.0</span> <span class="n">1.0</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs34', 104)" onmouseover="showTip(event, 'fs34', 104)" class="i">vec2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs18', 105)" onmouseover="showTip(event, 'fs18', 105)" class="t">Vector3</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 106)" onmouseover="showTip(event, 'fs27', 106)" class="f">create</span> <span class="n">2.0</span> <span class="n">2.0</span> <span class="n">2.0</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs35', 107)" onmouseover="showTip(event, 'fs35', 107)" class="i">vec3</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs13', 108)" onmouseover="showTip(event, 'fs13', 108)" class="f">add</span> <span onmouseout="hideTip(event, 'fs33', 109)" onmouseover="showTip(event, 'fs33', 109)" class="i">vec1</span> <span onmouseout="hideTip(event, 'fs34', 110)" onmouseover="showTip(event, 'fs34', 110)" class="i">vec2</span>
</code></pre></td>
</tr>
</table>
<p>Now <code>vec3</code> will also be of type <code>Vector3</code> containing <code>{X = 3.0; Y = 3.0; Z = 3.0;}</code>. But probably
now you will say. Okay, but our <code>add</code> function is some kind of silly. We also could use <code>+</code> directly
and we wouldn't have the problem at all. So let's create a more advanced function that does a little
bit more. Let's create an <code>average</code> function.</p>
<p>To start, let's create a non-polymorphic <code>average</code> function that expects a <code>float list</code> as input, and
returns the average.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
<span class="l">9: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs36', 111)" onmouseover="showTip(event, 'fs36', 111)" class="f">averageFloat</span> <span onmouseout="hideTip(event, 'fs37', 112)" onmouseover="showTip(event, 'fs37', 112)" class="i">xs</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs38', 113)" onmouseover="showTip(event, 'fs38', 113)" class="v">amount</span> <span class="o">=</span> <span class="n">0</span> <span class="c">// The amount of values we have</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs39', 114)" onmouseover="showTip(event, 'fs39', 114)" class="v">sum</span> <span class="o">=</span> <span class="n">0.0</span> <span class="c">// Zero for `float`</span>
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs8', 115)" onmouseover="showTip(event, 'fs8', 115)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs37', 116)" onmouseover="showTip(event, 'fs37', 116)" class="i">xs</span> <span class="k">do</span>
<span onmouseout="hideTip(event, 'fs39', 117)" onmouseover="showTip(event, 'fs39', 117)" class="v">sum</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs39', 118)" onmouseover="showTip(event, 'fs39', 118)" class="v">sum</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs8', 119)" onmouseover="showTip(event, 'fs8', 119)" class="i">x</span> <span class="c">// Add for `float`</span>
<span onmouseout="hideTip(event, 'fs38', 120)" onmouseover="showTip(event, 'fs38', 120)" class="v">amount</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs38', 121)" onmouseover="showTip(event, 'fs38', 121)" class="v">amount</span> <span class="o">+</span> <span class="n">1</span>
<span onmouseout="hideTip(event, 'fs39', 122)" onmouseover="showTip(event, 'fs39', 122)" class="v">sum</span> <span class="o">/</span> (<span onmouseout="hideTip(event, 'fs20', 123)" onmouseover="showTip(event, 'fs20', 123)" class="f">float</span> <span onmouseout="hideTip(event, 'fs38', 124)" onmouseover="showTip(event, 'fs38', 124)" class="v">amount</span>) <span class="c">// Divide by int for `float`</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs40', 125)" onmouseover="showTip(event, 'fs40', 125)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs36', 126)" onmouseover="showTip(event, 'fs36', 126)" class="f">averageFloat</span> [<span class="n">1.0</span> <span class="o">..</span> <span class="n">100.0</span>] <span class="c">// 50.5</span>
</code></pre></td>
</tr>
</table>
<p>Sure, we also could solve it more functional with recursion and immutable state, but this is not
the point of the post!</p>
<p>So, the question is, how can we made it more polymorphic? Just adding <code>inline</code> will not help in that
case and made it automatically polymorphic. The problem is already the third line. We write
<code>let mutable sum = 0.0</code>. Or in other words, we create explicitly a <code>float</code> at that point. Another
problem is the last line <code>sum / (float amount)</code>. As here we convert <code>amount</code> an <code>int</code> to a <code>float</code>.</p>
<p>To get this function polymorphic, we need three polymorphic behaviours that every type could implement
on their own. We need.</p>
<ol>
<li>A polymorphic <em>get zero</em></li>
<li>A polymorphic <em>+</em></li>
<li>A polymorphic <em>divide something by an int</em></li>
</ol>
<p>Luckily all three interfaces are already part of the F# language, and we have helper functions for those
operations. A truly polymorphic <code>average</code> would then look like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="k">inline</span> <span onmouseout="hideTip(event, 'fs41', 127)" onmouseover="showTip(event, 'fs41', 127)" class="f">average</span> (<span onmouseout="hideTip(event, 'fs42', 128)" onmouseover="showTip(event, 'fs42', 128)" class="i">xs</span><span class="o">:</span><span class="o">'</span><span class="i">a</span> <span onmouseout="hideTip(event, 'fs43', 129)" onmouseover="showTip(event, 'fs43', 129)" class="t">list</span>) <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs38', 130)" onmouseover="showTip(event, 'fs38', 130)" class="v">amount</span> <span class="o">=</span> <span class="n">0</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs44', 131)" onmouseover="showTip(event, 'fs44', 131)" class="v">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs31', 132)" onmouseover="showTip(event, 'fs31', 132)" class="t">LanguagePrimitives</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs45', 133)" onmouseover="showTip(event, 'fs45', 133)" class="i">GenericZero</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span>
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs46', 134)" onmouseover="showTip(event, 'fs46', 134)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs42', 135)" onmouseover="showTip(event, 'fs42', 135)" class="i">xs</span> <span class="k">do</span>
<span onmouseout="hideTip(event, 'fs44', 136)" onmouseover="showTip(event, 'fs44', 136)" class="v">sum</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs44', 137)" onmouseover="showTip(event, 'fs44', 137)" class="v">sum</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs46', 138)" onmouseover="showTip(event, 'fs46', 138)" class="i">x</span>
<span onmouseout="hideTip(event, 'fs38', 139)" onmouseover="showTip(event, 'fs38', 139)" class="v">amount</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs38', 140)" onmouseover="showTip(event, 'fs38', 140)" class="v">amount</span> <span class="o">+</span> <span class="n">1</span>
<span onmouseout="hideTip(event, 'fs31', 141)" onmouseover="showTip(event, 'fs31', 141)" class="t">LanguagePrimitives</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs32', 142)" onmouseover="showTip(event, 'fs32', 142)" class="f">DivideByInt</span> <span onmouseout="hideTip(event, 'fs44', 143)" onmouseover="showTip(event, 'fs44', 143)" class="v">sum</span> <span onmouseout="hideTip(event, 'fs38', 144)" onmouseover="showTip(event, 'fs38', 144)" class="v">amount</span>
</code></pre></td>
</tr>
</table>
<p>To use our <code>Vector3</code> type with <code>average</code> we have to add the remaining polymorphic <code>Zero</code> and
<code>DivideByInt</code> members.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
<span class="l">9: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs18', 38)" onmouseover="showTip(event, 'fs18', 38)" class="t">Vector3</span> <span class="o">=</span> {<span onmouseout="hideTip(event, 'fs19', 39)" onmouseover="showTip(event, 'fs19', 39)" class="i">X</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs20', 40)" onmouseover="showTip(event, 'fs20', 40)" class="t">float</span>; <span onmouseout="hideTip(event, 'fs21', 41)" onmouseover="showTip(event, 'fs21', 41)" class="i">Y</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs20', 42)" onmouseover="showTip(event, 'fs20', 42)" class="t">float</span>; <span onmouseout="hideTip(event, 'fs22', 43)" onmouseover="showTip(event, 'fs22', 43)" class="i">Z</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs20', 44)" onmouseover="showTip(event, 'fs20', 44)" class="t">float</span>} <span class="k">with</span>
<span class="k">static</span> <span class="k">member</span> <span onmouseout="hideTip(event, 'fs23', 45)" onmouseover="showTip(event, 'fs23', 45)" class="f">create</span> <span onmouseout="hideTip(event, 'fs8', 46)" onmouseover="showTip(event, 'fs8', 46)" class="i">x</span> <span onmouseout="hideTip(event, 'fs9', 47)" onmouseover="showTip(event, 'fs9', 47)" class="i">y</span> <span onmouseout="hideTip(event, 'fs24', 48)" onmouseover="showTip(event, 'fs24', 48)" class="i">z</span> <span class="o">=</span> {<span onmouseout="hideTip(event, 'fs19', 49)" onmouseover="showTip(event, 'fs19', 49)" class="i">X</span><span class="o">=</span><span onmouseout="hideTip(event, 'fs8', 50)" onmouseover="showTip(event, 'fs8', 50)" class="i">x</span>; <span onmouseout="hideTip(event, 'fs21', 51)" onmouseover="showTip(event, 'fs21', 51)" class="i">Y</span><span class="o">=</span><span onmouseout="hideTip(event, 'fs9', 52)" onmouseover="showTip(event, 'fs9', 52)" class="i">y</span>; <span onmouseout="hideTip(event, 'fs22', 53)" onmouseover="showTip(event, 'fs22', 53)" class="i">Z</span><span class="o">=</span><span onmouseout="hideTip(event, 'fs24', 54)" onmouseover="showTip(event, 'fs24', 54)" class="i">z</span>}
<span class="k">static</span> <span class="k">member</span> (<span class="o">+</span>) (<span onmouseout="hideTip(event, 'fs25', 55)" onmouseover="showTip(event, 'fs25', 55)" class="i">a</span>,<span onmouseout="hideTip(event, 'fs26', 56)" onmouseover="showTip(event, 'fs26', 56)" class="i">b</span>) <span class="o">=</span> <span onmouseout="hideTip(event, 'fs18', 57)" onmouseover="showTip(event, 'fs18', 57)" class="t">Vector3</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 58)" onmouseover="showTip(event, 'fs27', 58)" class="f">create</span> (<span onmouseout="hideTip(event, 'fs25', 59)" onmouseover="showTip(event, 'fs25', 59)" class="i">a</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs19', 60)" onmouseover="showTip(event, 'fs19', 60)" class="i">X</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs26', 61)" onmouseover="showTip(event, 'fs26', 61)" class="i">b</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs19', 62)" onmouseover="showTip(event, 'fs19', 62)" class="i">X</span>) (<span onmouseout="hideTip(event, 'fs25', 63)" onmouseover="showTip(event, 'fs25', 63)" class="i">a</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs21', 64)" onmouseover="showTip(event, 'fs21', 64)" class="i">Y</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs26', 65)" onmouseover="showTip(event, 'fs26', 65)" class="i">b</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs21', 66)" onmouseover="showTip(event, 'fs21', 66)" class="i">Y</span>) (<span onmouseout="hideTip(event, 'fs25', 67)" onmouseover="showTip(event, 'fs25', 67)" class="i">a</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs22', 68)" onmouseover="showTip(event, 'fs22', 68)" class="i">Z</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs26', 69)" onmouseover="showTip(event, 'fs26', 69)" class="i">b</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs22', 70)" onmouseover="showTip(event, 'fs22', 70)" class="i">Z</span>)
<span class="k">static</span> <span class="k">member</span> <span onmouseout="hideTip(event, 'fs28', 71)" onmouseover="showTip(event, 'fs28', 71)" class="i">Zero</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs18', 72)" onmouseover="showTip(event, 'fs18', 72)" class="t">Vector3</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 73)" onmouseover="showTip(event, 'fs27', 73)" class="f">create</span> <span class="n">0.0</span> <span class="n">0.0</span> <span class="n">0.0</span>
<span class="k">static</span> <span class="k">member</span> <span onmouseout="hideTip(event, 'fs29', 74)" onmouseover="showTip(event, 'fs29', 74)" class="f">DivideByInt</span>(<span onmouseout="hideTip(event, 'fs25', 75)" onmouseover="showTip(event, 'fs25', 75)" class="i">a</span>,<span onmouseout="hideTip(event, 'fs30', 76)" onmouseover="showTip(event, 'fs30', 76)" class="i">b</span>) <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs18', 77)" onmouseover="showTip(event, 'fs18', 77)" class="t">Vector3</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 78)" onmouseover="showTip(event, 'fs27', 78)" class="f">create</span>
(<span onmouseout="hideTip(event, 'fs31', 79)" onmouseover="showTip(event, 'fs31', 79)" class="t">LanguagePrimitives</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs32', 80)" onmouseover="showTip(event, 'fs32', 80)" class="f">DivideByInt</span> <span onmouseout="hideTip(event, 'fs25', 81)" onmouseover="showTip(event, 'fs25', 81)" class="i">a</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs19', 82)" onmouseover="showTip(event, 'fs19', 82)" class="i">X</span> <span onmouseout="hideTip(event, 'fs30', 83)" onmouseover="showTip(event, 'fs30', 83)" class="i">b</span>)
(<span onmouseout="hideTip(event, 'fs31', 84)" onmouseover="showTip(event, 'fs31', 84)" class="t">LanguagePrimitives</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs32', 85)" onmouseover="showTip(event, 'fs32', 85)" class="f">DivideByInt</span> <span onmouseout="hideTip(event, 'fs25', 86)" onmouseover="showTip(event, 'fs25', 86)" class="i">a</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs21', 87)" onmouseover="showTip(event, 'fs21', 87)" class="i">Y</span> <span onmouseout="hideTip(event, 'fs30', 88)" onmouseover="showTip(event, 'fs30', 88)" class="i">b</span>)
(<span onmouseout="hideTip(event, 'fs31', 89)" onmouseover="showTip(event, 'fs31', 89)" class="t">LanguagePrimitives</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs32', 90)" onmouseover="showTip(event, 'fs32', 90)" class="f">DivideByInt</span> <span onmouseout="hideTip(event, 'fs25', 91)" onmouseover="showTip(event, 'fs25', 91)" class="i">a</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs22', 92)" onmouseover="showTip(event, 'fs22', 92)" class="i">Z</span> <span onmouseout="hideTip(event, 'fs30', 93)" onmouseover="showTip(event, 'fs30', 93)" class="i">b</span>)
</code></pre></td>
</tr>
</table>
<p><code>average</code> is a truly polymorphic function because it can calculate the average of a list
of any type that supports <code>Zero</code>, <code>+</code> and <code>DivideByInt</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 145)" onmouseover="showTip(event, 'fs47', 145)" class="i">floatAverage</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs41', 146)" onmouseover="showTip(event, 'fs41', 146)" class="f">average</span> [<span class="n">2.0</span> <span class="o">..</span> <span class="n">99.0</span>] <span class="c">// 50.5</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs48', 147)" onmouseover="showTip(event, 'fs48', 147)" class="i">vectorAverage</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs41', 148)" onmouseover="showTip(event, 'fs41', 148)" class="f">average</span> [<span onmouseout="hideTip(event, 'fs33', 149)" onmouseover="showTip(event, 'fs33', 149)" class="i">vec1</span>; <span onmouseout="hideTip(event, 'fs34', 150)" onmouseover="showTip(event, 'fs34', 150)" class="i">vec2</span>; <span onmouseout="hideTip(event, 'fs35', 151)" onmouseover="showTip(event, 'fs35', 151)" class="i">vec3</span>; <span onmouseout="hideTip(event, 'fs35', 152)" onmouseover="showTip(event, 'fs35', 152)" class="i">vec3</span>] <span class="c">// {X=2.25;Y=2.25;Z=2.25}</span>
</code></pre></td>
</tr>
</table>
<p>The big advantage is that we only need to write a single <code>average</code> function that can work with
different types. We don't have to create multiple <code>average</code> function each for there own type.
If <code>average</code> itself only uses polymorphic functions, then it means <code>average</code> itself also could
be polymorphic.</p>
<p>But this also means that whenever we create a new type with the correct implementations, we
actually can get a lot of functions for free. Every type that we create that supports <code>+</code>,
<code>Zero</code> and a <code>DivideByInt</code> automatically gets an <code>average</code> function for free!</p>
<p>Or in other words. Higher-kinded polymorphism is about code reuse. By just implementing the
right <em>glue-functions</em> it can be that you get hundreds of already pre-defined functions!</p>
<p>As an example you probably heard that <code>fold</code> and <code>foldBack</code> are very powerful functions,
and just with <code>fold</code> you can implement a lot of other functions like <code>List.filter</code>,
<code>List.collect</code>, <code>List.map</code> and so on. This is interesting as it means, you could theoretically
provide a single polymorphic <code>filter</code> function, and it would work with all types that
implements a <code>fold</code> function. The same is true for all other functions that could be
implemented through <code>fold</code>.</p>
<p>This basically would mean you never have to implement dozens of functions that you see in
the <code>List</code> module. You just need to implement <code>fold</code> and you would get dozens of functions
for free. But currently this is not how it is implemented in F# or how it works. Instead
we have <code>List.filter</code>, <code>Array.filter</code>, <code>Map.filter</code>, <code>Set.filter</code>, <code>Seq.filter</code> and so on.</p>
<p>Or in other words, every type just implements its own <code>filter</code> function, instead that we have
a single implementation of <code>filter</code> that could be used polymorphic across all types. That
also means that if you create your own types you have to implement <code>filter</code> and all
of the other functions by yourself. But with higher-kinded polymorphism you just need
to implement <code>fold</code> for your type, and you would get hundreds of functions for free.</p>
<p>So the big advantage of "higher-kinded polymorphism" is that you get a ton of code reuse.</p>
<h2>Can we solve it with interfaces?</h2>
<p>Probably you will ask: <em>Can we not solve it with an interfaces</em>? The answer is no. You can achieve
something similar, but not the same. Actually there already exists a solution for the <code>fold</code>
example solved with interfaces. It is the <code>IEnumerable<T></code> interface.</p>
<p><code>fold</code> itself is basically just a way to loop over a data-structure. The <code>IEnumerable<T></code> interface
provides the same logic. Once you implement the <code>IEnumerable<T></code> interface that is just a single
method <code>GetEnumerator</code> you also get all of the LINQ Methods for free like <code>Select</code>, <code>Where</code>,
<code>Aggregate</code> and so on. In F# you get the functionality of the <code>Seq</code> module. So what is the
difference?</p>
<p>The difference is that your type changes from whatever you had to <code>IEnumerable<T></code> (C#) <code>Seq<T></code> (F#).
If you have a <code>List<T></code> (C#) and you use <code>Select</code> on it, then you get an <code>IEnumerable<T></code> back.
Or in other words, you loose your original type. If you want to go back to a <code>List<T></code> you have
to convert your <code>IEnumerable<T></code> back to an <code>List<T></code>, <code>T[]</code>, <code>Dictionary<K,V></code> or with whatever you
wanted/started. But with Higher-kinded polymorphism instead you would not only get all
of the additional functions for free, your type also would still remain the same.</p>
<p>This means for example if you use a <code>Set</code> you just can <code>filter</code> it, and directly afterwards you
can use special <code>Set</code> methods only available on <code>Set</code> like <code>Set.intersect</code>, <code>Set.isSubset</code> and others.
If you started with an <code>Array</code> you can use <code>Array.blit</code>, <code>Array.fill</code> and other <code>Array</code> specific
functions and so on.</p>
<p>Actually it is even hard to say that you get any kind of code reuse with an interface. Sure you
can provide methods that turn something into your <code>IFace</code> interface. If you have functions that
only expects <code>IFace</code> objects you now can use all of them.</p>
<p>But that isn't really so special. Sure, after i converted something to a <code>List</code> i also can use all
of the <code>List</code> functions inside the <code>List</code> module, what a surprise!</p>
<h2>Summary</h2>
<p>F# doesn't support higher-kinded polymorphism directly. It has the features to create this kind
of code with re-usability. You also don't need to implement the <code>average</code> function, as F# already
has <code>List.average</code> that is polymorphic in the way I showed here. But overall the language itself
was not build up with this feature in-mind, and it also don't make it easy to create polymorphic
functions in that way.</p>
<p>But it is a really important concept, and I think programing languages should try to focus
more on this kind of polymorphic behaviour. If you are aware of this feature, probably you see the
chance of creating your own polymorphic functions and you gain a lot more code reuse.</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">val x : int<br /><br />Full name: higherkindedpolymorphism.x</div>
<div class="tip" id="fs3">val y : string<br /><br />Full name: higherkindedpolymorphism.y</div>
<div class="tip" id="fs4">val add : x:int -> y:int -> int<br /><br />Full name: higherkindedpolymorphism.add</div>
<div class="tip" id="fs5">val x : int</div>
<div class="tip" id="fs6">val y : int</div>
<div class="tip" id="fs7">val add : x:float -> y:float -> float<br /><br />Full name: higherkindedpolymorphism.add</div>
<div class="tip" id="fs8">val x : float</div>
<div class="tip" id="fs9">val y : float</div>
<div class="tip" id="fs10">val result : float<br /><br />Full name: higherkindedpolymorphism.result</div>
<div class="tip" id="fs11">val r1 : float<br /><br />Full name: higherkindedpolymorphism.r1</div>
<div class="tip" id="fs12">val r2 : float<br /><br />Full name: higherkindedpolymorphism.r2</div>
<div class="tip" id="fs13">val add : x:'a -> y:'b -> 'c (requires member ( + ))<br /><br />Full name: Main.add</div>
<div class="tip" id="fs14">val x : 'a (requires member ( + ))</div>
<div class="tip" id="fs15">val y : 'b (requires member ( + ))</div>
<div class="tip" id="fs16">val r1 : float<br /><br />Full name: Main.r1</div>
<div class="tip" id="fs17">val r2 : int<br /><br />Full name: Main.r2</div>
<div class="tip" id="fs18">type Vector3 =<br />  {X: float;<br />   Y: float;<br />   Z: float;}<br />  static member DivideByInt : a:Vector3 * b:int -> Vector3<br />  static member create : x:float -> y:float -> z:float -> Vector3<br />  static member Zero : Vector3<br />  static member ( + ) : a:Vector3 * b:Vector3 -> Vector3<br /><br />Full name: Main.Vector3</div>
<div class="tip" id="fs19">Vector3.X: float</div>
<div class="tip" id="fs20">Multiple items<br />val float : value:'T -> float (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.float<br /><br />--------------------<br />type float = System.Double<br /><br />Full name: Microsoft.FSharp.Core.float<br /><br />--------------------<br />type float<'Measure> = float<br /><br />Full name: Microsoft.FSharp.Core.float<_></div>
<div class="tip" id="fs21">Vector3.Y: float</div>
<div class="tip" id="fs22">Vector3.Z: float</div>
<div class="tip" id="fs23">static member Vector3.create : x:float -> y:float -> z:float -> Vector3<br /><br />Full name: Main.Vector3.create</div>
<div class="tip" id="fs24">val z : float</div>
<div class="tip" id="fs25">val a : Vector3</div>
<div class="tip" id="fs26">val b : Vector3</div>
<div class="tip" id="fs27">static member Vector3.create : x:float -> y:float -> z:float -> Vector3</div>
<div class="tip" id="fs28">static member Vector3.Zero : Vector3<br /><br />Full name: Main.Vector3.Zero</div>
<div class="tip" id="fs29">static member Vector3.DivideByInt : a:Vector3 * b:int -> Vector3<br /><br />Full name: Main.Vector3.DivideByInt</div>
<div class="tip" id="fs30">val b : int</div>
<div class="tip" id="fs31">module LanguagePrimitives<br /><br />from Microsoft.FSharp.Core</div>
<div class="tip" id="fs32">val DivideByInt : x:'T -> y:int -> 'T (requires member DivideByInt)<br /><br />Full name: Microsoft.FSharp.Core.LanguagePrimitives.DivideByInt</div>
<div class="tip" id="fs33">val vec1 : Vector3<br /><br />Full name: Main.vec1</div>
<div class="tip" id="fs34">val vec2 : Vector3<br /><br />Full name: Main.vec2</div>
<div class="tip" id="fs35">val vec3 : Vector3<br /><br />Full name: Main.vec3</div>
<div class="tip" id="fs36">val averageFloat : xs:seq<float> -> float<br /><br />Full name: Main.averageFloat</div>
<div class="tip" id="fs37">val xs : seq<float></div>
<div class="tip" id="fs38">val mutable amount : int</div>
<div class="tip" id="fs39">val mutable sum : float</div>
<div class="tip" id="fs40">val x : float<br /><br />Full name: Main.x</div>
<div class="tip" id="fs41">val average : xs:'a list -> 'a (requires member get_Zero and member ( + ) and member DivideByInt)<br /><br />Full name: Main.average</div>
<div class="tip" id="fs42">val xs : 'a list (requires member get_Zero and member ( + ) and member DivideByInt)</div>
<div class="tip" id="fs43">type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs44">val mutable sum : 'a (requires member get_Zero and member ( + ) and member DivideByInt)</div>
<div class="tip" id="fs45">val GenericZero<'T (requires member get_Zero)> : 'T (requires member get_Zero)<br /><br />Full name: Microsoft.FSharp.Core.LanguagePrimitives.GenericZero</div>
<div class="tip" id="fs46">val x : 'a (requires member get_Zero and member ( + ) and member DivideByInt)</div>
<div class="tip" id="fs47">val floatAverage : float<br /><br />Full name: Main.floatAverage</div>
<div class="tip" id="fs48">val vectorAverage : Vector3<br /><br />Full name: Main.vectorAverage</div>
null is Evil2016-03-20T00:00:00+00:00https://sidburn.github.io/blog/2016/03/20/null-is-evil<p>Tony Hoare once said: <em>I call it my billion-dollar mistake. It was the invention of the null
reference in 1965.</em> So, why did he added "null" in the first place? Why was it such a big
mistake. And if it is such a big mistake, what are the alternatives?</p>
<h2>The purpose of null</h2>
<p>To understand why it was a mistake, let's look why it was even added in the first place. Let's
assume we have a simple function expecting a <code>PersonId</code> that returns a <code>Person</code> object. We would
have a function with the following function signature.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">PersonId</span> <span class="k">-></span> <span class="i">Person</span>
</code></pre></td>
</tr>
</table>
<p>Implementing such a function means, we always have to return a <code>Person</code>. But what happens if we
are not able to return a <code>Person</code>? What should we return instead? And there can be a multitude of
reasons why that could be the case. A database could not contain a <code>Person</code> with your provided
<code>PersonId</code>. Also an error could have happened while trying to retrieve data. So overall we have
two kinds of problems that could happen.</p>
<ol>
<li>The passed in value was invalid, or in other words, there doesn't exists a <code>Person</code> for the provided input</li>
<li>Some kind of error happened that prevents us returning a <code>Person</code> object.</li>
</ol>
<p>So how do we solve that problem? Hoare's answer was the invention of the <em>null-reference</em>. A
<em>null-reference</em> is compatible with any other type. So instead of returning a <code>Person</code> we just
could return a <code>null</code> instead.</p>
<p>Our client code calling our function just need to check whether it is <code>null</code> or not. As easy as
this sound, this easiness is exactly what leads to numerous errors and problems.</p>
<p>As a first note. Some people will probably tell, that for <em>errors</em> we should throw an exception
instead. Actually I leave the discussion for <em>exception</em> for another blog post. The important thing
is more that you could return a <code>null</code> in the error case. Some functions/libraries do that, and
there is no way you can prevent that. You just have to deal with it, whether you like it or not.</p>
<h2>The problems with null</h2>
<p>Now that we understand why we have null. Let's create a list of problems that the implementation
of <em>null</em> causes.</p>
<p>The first problem is, we cannot see if a function could return <code>null</code> or not. We could just
have written code like this (C#)</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> person <span class="o">=</span> Person.FetchById(<span class="n">10</span>);
Console.WriteLine(<span class="k">string</span>.Format(<span class="s">"Name of Person is {0}"</span>, person.Name));
</code></pre></td></tr></table>
<p>The problem is that <code>Person.FetchById()</code> sometimes returns a <em>null-reference</em>. But we could use
it just like a valid <code>Person</code>. But using it just like that, means that sometimes our code will throw a
<code>NullReferenceException</code>. Because sometimes, we don't have a <code>Person</code>.</p>
<p>To be safe, we have to explicitly check if <code>Person.FetchById()</code> returns <code>null</code> or not. This results in
code like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> person <span class="o">=</span> Person.FetchById(<span class="n">10</span>);
<span class="k">if</span> ( person <span class="o">=</span><span class="o">=</span> <span class="k">null</span> ) {
Console.WriteLine(<span class="s">"No Person with ID 10"</span>);
}
<span class="k">else</span> {
Console.WriteLine(<span class="k">string</span>.Format(<span class="s">"Name of Person is {0}"</span>, person.Name));
}
</code></pre></td></tr></table>
<p>The big problem is that we cannot see from a function type signature that it could return <code>null</code> or
not. That means, we have to check <strong>every</strong> function call in our system explicitly because it could
potentially return <code>null</code>.</p>
<p>This explicit checking of <code>null</code> for every function is sure bother some. So what do we do? Sure, we don't
do that checking on every function. We only check those function that we know they could return a <code>null</code>.
Or in other words. We probably rely on <em>documentation</em>. Because we all know that <em>documentation</em> is always
correct, never has mistakes, and everyone who writes documentation always adds the information if
a function call could return <code>null</code> or not. And sure, we as programmers always re-check the whole documentation
for every Class, Method or Function once we updated a library to ensure that the behaviour of all functions
still remains the same!</p>
<p>Jokes aside, sure we don't do that. Not doing that doesn't mean we are bad programmers. The problem is
that doing such kind of things is just silly. Instead of us humans, the language/compiler should do
such kinds of checks for us. We cannot solve the problem with <em>documentation</em>. The burden of checking
should be leveraged to the language/compiler instead of us humans. Sure we humans are those who have
to program what happens at some places if we have a <code>null</code> or not. But our language should notify us
at compile-time where we have forgotten such checks. We only should add those check where it is really
needed, and the language should notify us where we have forgotten them.</p>
<p>But we don't even have covered all problems yet! We also can pass <code>null</code> to other functions. We can
do that because <code>null</code> is technically just a value. So we also could do stuff like that.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> person <span class="o">=</span> Person.FetchById(<span class="n">10</span>);
DoSomethingWithPerson(person);
</code></pre></td></tr></table>
<p>It basically means, we not only have to check <code>null</code> from every function that we call. We also have to
add <code>null</code> checks to every function we write, because someone could provide us a <code>null</code> value even
if we don't want them. Not doing the checking can actually lead to the problem that somewhere
else, probably even in code we don't have written, we get a <code>NullReferenceException</code>.</p>
<p>And the last problem is a so called <em>Happy path-coding</em>. Usually we mean it negative that someone
just writes code for the <em>Happy-Path</em> expecting that everything works correctly. And as soon there
is some problem, our program blows up and crashes. This leads to very buggy programs. So what we
actually really want is sure we want to code like "Happ-Path", we want to cover as much possible
errors as possible. But we don't want to include some kind of checking and validation throughout
our whole code, nearly at every line, after every function call.</p>
<p>Usually what we want is just write code as if there are no errors (Happy-Path). And only at the end of a
chain we want to check if some-kind of error happened, or probably at selected points inside our chain.
So ideally we want that we are forced to check, but only at specific places where we explicitly want it.
But <code>null</code> doesn't provide that. We sure can leave the checks, but then our program will be buggy. As a
result we often add so much <code>null</code> checks that our language also could have forced us to write them always
and otherwise return a error. It probably seems impossible how we can get both. Forcing us to check
and gain the safeness to not forget it anywhere, but still only doing the checks when we really want it.</p>
<p>So as a summary, we have the following problems with <code>null</code>.</p>
<ol>
<li>We cannot see if a function returns <code>null</code> or not</li>
<li>We are not forced to add <code>null</code> checks, this can lead to <code>NullReferenceException</code></li>
<li>Because every function could return <code>null</code> we also have to check every function</li>
<li>We cannot <em>skip</em> the checking and do it at some later point</li>
<li>
We can pass <code>null</code> as valid values. And because we are not forced to check for <code>null</code>, this
can throw <code>NullReferenceException</code> at some other places.
</li>
<li>We also have to check every function argument for <code>null</code></li>
<li>It destroys <em>Happy Path-coding</em></li>
</ol>
<h2>Optionals</h2>
<p>Actually retro-fixing <em>null</em> in a language is nearly impossible. There exists often some kind of <em>hack-ish</em>
ways on how to fix it. But it usually feels not natural, or it doesn't fix all problems. So let's look at
F# that does not support <code>null</code> <em>directly</em>. So how do we write a functions that sometimes can return an
absence of a value?</p>
<p>The answer is, it is not possible. We actually cannot write a function that sometimes returns <code>Person</code>
or not. What we really have to do is return another type instead. What we really need to return is an
<code>Option</code> instead. An <code>Option</code> is just a data-type on its own. But an Option can either be <code>Some value</code>
or <code>None</code>. You can compare it to a <code>bool</code> that is either <code>true</code> or <code>false</code>. The only difference is that in
the case of <code>true</code> or <code>Some</code> it can carry an additional value with it. Option is already part of F#
but you could easily define it yourself like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="i">Option</span><span class="o"><</span><span class="o">'</span><span class="i">a</span><span class="o">></span> <span class="o">=</span>
| <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="i">None</span>
| <span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="i">Some</span> <span class="k">of</span> <span class="o">'</span><span class="i">a</span>
</code></pre></td>
</tr>
</table>
<p>Or to say it otherwise. It is just a <em>generic</em> type. That either could be <code>None</code> or <code>Some 'a</code>. With this
kind of idea we now can create types like <code>Option<int></code>, <code>Option<Person></code>, <code>Option<Foo></code>, ... and so on.
There is also an alternative style for writing a generic type <code>int person</code>, <code>Person option</code>, <code>Foo option</code>.
We will use this style, because this is also the style how it is often shown by the IDE (like Visual Studio).
Also note that the <code>Option</code> type itself defined in F# uses a small letter <code>option</code> instead of <code>Option</code>.</p>
<p>So what we really have is not a function <code>PersonId -> Person</code> we really have:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">PersonId</span> <span class="k">-></span> <span class="i">Person</span> <span onmouseout="hideTip(event, 'fs5', 5)" onmouseover="showTip(event, 'fs5', 5)" class="i">option</span>
</code></pre></td>
</tr>
</table>
<p>Or in other words. A function taking a <code>PersonId</code> that returns an <code>option</code> that either can
contain a <code>Person</code> or don't contain anything. The first improvement is now that we can see
clearly which functions can return a value or not. We don't have to rely on documentation
anymore. Code itself is the best documentation at all! So lets assume we want to
print the Name of a person, what do we have to write now?</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">person</span> <span class="o">=</span> <span class="i">Person</span><span class="o">.</span><span class="i">fetchById</span> <span class="n">10</span>
<span class="k">match</span> <span class="i">person</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs3', 16)" onmouseover="showTip(event, 'fs3', 16)" class="i">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs6', 17)" onmouseover="showTip(event, 'fs6', 17)" class="i">printfn</span> <span class="s">"No Person with Id 10"</span>
| <span onmouseout="hideTip(event, 'fs4', 18)" onmouseover="showTip(event, 'fs4', 18)" class="i">Some</span> <span class="i">person</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs6', 19)" onmouseover="showTip(event, 'fs6', 19)" class="i">printfn</span> <span class="s">"Name of Person is %s"</span> <span class="i">person</span><span class="o">.</span><span class="i">Name</span>
</code></pre></td>
</tr>
</table>
<p>At first, this doesn't look like an improvement over the <code>if</code> checking. We still have to check for
either <code>Some</code> or <code>None</code>. So why is that better?</p>
<ol>
<li>
The important point is, not every function returns an <code>option</code>. You only have to add this check if
a function returns an optional.
</li>
<li>You are <em>forced</em> by the language at <em>compile-time</em> to add the checks if a function returns an <code>option</code>.</li>
</ol>
<p>You cannot write code like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">person</span> <span class="o">=</span> <span class="i">Person</span><span class="o">.</span><span class="i">fetchById</span> <span class="n">10</span>
<span onmouseout="hideTip(event, 'fs6', 10)" onmouseover="showTip(event, 'fs6', 10)" class="i">printfn</span> <span class="s">"Name of person is %s"</span> <span class="i">person</span><span class="o">.</span><span class="i">Name</span>
</code></pre></td>
</tr>
</table>
<p>This will give you a <em>compile-time error</em>. Because <code>person</code> is of type <code>option</code> and <code>option</code> don't
contain a field <code>Name</code>. It basically means, you cannot create <code>NullReferenceException</code> because you cannot
forget to add the checking. And you only have to really check those functions that could return an option.</p>
<p>Actually that eliminates all problems we have, but let's go over the problems once more to describe
why they are eliminated.</p>
<h3>1: We can identify functions returning <em>Nothing</em></h3>
<p>It is just part of the function signature.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs7', 11)" onmouseover="showTip(event, 'fs7', 11)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 12)" onmouseover="showTip(event, 'fs7', 12)" class="i">int</span> <span onmouseout="hideTip(event, 'fs5', 13)" onmouseover="showTip(event, 'fs5', 13)" class="i">option</span>
</code></pre></td>
</tr>
</table>
<p>it can return an <code>int</code> or not</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs7', 14)" onmouseover="showTip(event, 'fs7', 14)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 15)" onmouseover="showTip(event, 'fs7', 15)" class="i">int</span>
</code></pre></td>
</tr>
</table>
<p>This will always return an <code>int</code></p>
<h3>2: We must check</h3>
<p>We cannot access a value directly. <code>option</code> is a type on its own. If we want to get the inner value
we have to <em>Pattern Match</em> against an optional.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">person</span> <span class="o">=</span> <span class="i">Person</span><span class="o">.</span><span class="i">fetchById</span> <span class="n">10</span>
<span class="k">match</span> <span class="i">person</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs3', 16)" onmouseover="showTip(event, 'fs3', 16)" class="i">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs6', 17)" onmouseover="showTip(event, 'fs6', 17)" class="i">printfn</span> <span class="s">"No Person with Id 10"</span>
| <span onmouseout="hideTip(event, 'fs4', 18)" onmouseover="showTip(event, 'fs4', 18)" class="i">Some</span> <span class="i">person</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs6', 19)" onmouseover="showTip(event, 'fs6', 19)" class="i">printfn</span> <span class="s">"Name of Person is %s"</span> <span class="i">person</span><span class="o">.</span><span class="i">Name</span>
</code></pre></td>
</tr>
</table>
<p>Runtime <code>NullReferenceException</code> are not possible anymore</p>
<h3>3: Not every function returns <code>option</code></h3>
<p>That means we only need to <em>Pattern Match</em> those function that return an <code>option</code>. Functions
that don't return <code>option</code> also cannot be Pattern Matched! If we would Pattern Match against
a value that is not an <code>option</code> we get an error. Once again, everything happens already at
compile-time. That means you can see the error already in your IDE.</p>
<h3>4: We can skip the checking</h3>
<p><code>option</code> is just a type like any other. That means you can return an option from your function.
But you also can pass <code>option</code> as a value around. The important thing is, you only need to do
the checking once you also need the value inside of the <code>option</code>. But note that you cannot pass
a <code>int option</code> to a function expecting a <code>int</code>. Both are different types. If a function expects
<code>int</code> you must unwrap the value inside the <code>option</code>. Well that isn't quite correct, because
you can automate this process, but we will look later at this in more detail.</p>
<h3>5 and 6: Passing <code>option</code></h3>
<p>We can pass <code>option</code> as a valid value. But only to those function that expects a <code>option</code>. We
cannot implicitly pass it. And a function expecting an <code>option</code> as a value also must <em>Pattern Match</em>
the argument.</p>
<p>So it cannot happen that values sometimes are <code>option</code> or not. Either they are, and we must check. Or
we don't have to check at all.</p>
<h2>Happy Path-Coding</h2>
<p>Happy Path-Coding needs some further explanations. Previously i said that F# don't support <code>null</code>
but this isn't quite right. F# runs on the .NET platform, and the runtime supports the concept
of <code>null</code>. From F# we can call any code that was written for example in C#. So we have to add
<code>null</code> checks for data-types, functions and so on that where not directly written in F#.</p>
<p>To deal with functions that returns <code>null</code> we often write wrappers and turn the result into an <code>option</code>.
For example the <code>Int32.TryParse</code> function is a good candidate to show the idea.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 23)" onmouseover="showTip(event, 'fs11', 23)" class="f">tryParse</span> (<span onmouseout="hideTip(event, 'fs12', 24)" onmouseover="showTip(event, 'fs12', 24)" class="i">str</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs13', 25)" onmouseover="showTip(event, 'fs13', 25)" class="t">string</span>) <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs8', 26)" onmouseover="showTip(event, 'fs8', 26)" class="t">Int32</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs14', 27)" onmouseover="showTip(event, 'fs14', 27)" class="f">TryParse</span> <span onmouseout="hideTip(event, 'fs12', 28)" onmouseover="showTip(event, 'fs12', 28)" class="i">str</span> <span class="k">with</span>
| <span class="k">false</span>,_ <span class="k">-></span> <span onmouseout="hideTip(event, 'fs3', 29)" onmouseover="showTip(event, 'fs3', 29)" class="p">None</span>
| <span class="k">true</span>,<span onmouseout="hideTip(event, 'fs15', 30)" onmouseover="showTip(event, 'fs15', 30)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs4', 31)" onmouseover="showTip(event, 'fs4', 31)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs15', 32)" onmouseover="showTip(event, 'fs15', 32)" class="i">x</span>
</code></pre></td>
</tr>
</table>
<p>We now created a <code>tryParse</code> function. When we look at the signature we see <code>string -> int option</code>. Or
in other words. A function that can return an <code>int</code> or not. Let's assume we now parse three strings.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs16', 33)" onmouseover="showTip(event, 'fs16', 33)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 34)" onmouseover="showTip(event, 'fs11', 34)" class="f">tryParse</span> <span class="s">"10"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs17', 35)" onmouseover="showTip(event, 'fs17', 35)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 36)" onmouseover="showTip(event, 'fs11', 36)" class="f">tryParse</span> <span class="s">"20"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs18', 37)" onmouseover="showTip(event, 'fs18', 37)" class="i">z</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 38)" onmouseover="showTip(event, 'fs11', 38)" class="f">tryParse</span> <span class="s">"30"</span>
</code></pre></td>
</tr>
</table>
<p>and now we want to add them together. Ideally in a <em>Happy-Path</em> coding we could directly write.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">result</span> <span class="o">=</span> <span class="i">x</span> <span class="o">+</span> <span class="i">y</span> <span class="o">+</span> <span class="i">z</span>
</code></pre></td>
</tr>
</table>
<p>But the problem is that <code>x</code>, <code>y</code> and <code>z</code> are <code>int optional</code>. So we cannot add <code>optional</code> values.
We first have to unwrap them. And it makes sense that we cannot do it. What for example should the
the result be if some of the parsing failed? Should it just add those that where valid? Should
the whole <em>computation</em> be aborted as soon one was invalid? Let's stick for the last one. As soon
one is invalid, the whole computation should be invalid. Or in our case now. We now have to <em>Pattern
Match</em> every variable, check if it is <code>Some value</code>. If true, we check the next variable, if <code>None</code>
the whole computations returns <code>None</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs19', 39)" onmouseover="showTip(event, 'fs19', 39)" class="i">result</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs16', 40)" onmouseover="showTip(event, 'fs16', 40)" class="i">x</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs3', 41)" onmouseover="showTip(event, 'fs3', 41)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs3', 42)" onmouseover="showTip(event, 'fs3', 42)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs4', 43)" onmouseover="showTip(event, 'fs4', 43)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs20', 44)" onmouseover="showTip(event, 'fs20', 44)" class="i">extractedX</span> <span class="k">-></span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs17', 45)" onmouseover="showTip(event, 'fs17', 45)" class="i">y</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs3', 46)" onmouseover="showTip(event, 'fs3', 46)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs3', 47)" onmouseover="showTip(event, 'fs3', 47)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs4', 48)" onmouseover="showTip(event, 'fs4', 48)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs21', 49)" onmouseover="showTip(event, 'fs21', 49)" class="i">extractedY</span> <span class="k">-></span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs18', 50)" onmouseover="showTip(event, 'fs18', 50)" class="i">z</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs3', 51)" onmouseover="showTip(event, 'fs3', 51)" class="p">None</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs3', 52)" onmouseover="showTip(event, 'fs3', 52)" class="p">None</span>
| <span onmouseout="hideTip(event, 'fs4', 53)" onmouseover="showTip(event, 'fs4', 53)" class="p">Some</span> <span onmouseout="hideTip(event, 'fs22', 54)" onmouseover="showTip(event, 'fs22', 54)" class="i">extractedZ</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs4', 55)" onmouseover="showTip(event, 'fs4', 55)" class="p">Some</span> (<span onmouseout="hideTip(event, 'fs20', 56)" onmouseover="showTip(event, 'fs20', 56)" class="i">extractedX</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs21', 57)" onmouseover="showTip(event, 'fs21', 57)" class="i">extractedY</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs22', 58)" onmouseover="showTip(event, 'fs22', 58)" class="i">extractedZ</span>)
</code></pre></td>
</tr>
</table>
<p>Man, that is some ugly code! We have the benefit that we are forced to check, we cannot have
<code>NullReferenceException</code> and all of the other benefits. Also <code>result</code> is now an <code>int option</code>. And
it makes sense. As soon one of <code>x</code>, <code>y</code> or <code>z</code> was not a valid <code>int</code>, also <code>return</code> would be <code>None</code>.
But it seems we have lost any kind of our <em>Happy-Path</em> coding. Because now we have to check every value
directly. Isn't there some way to be as close to <code>let result = x + y + z</code>, so if every value was <code>Some</code>
it does it calculation, and otherwise it just returns <code>None</code>? So instead of checking every value directly
we just want to work with the values as they would be normal non-optional values? But as soon one value
is <code>None</code> just everything is <code>None</code>? The answer is. Yes, there is a way to achieve that!</p>
<p>But at this point i will not show how to build the solution for yourself. And actually there even exists
two solutions to solve it. Either way through a so called <em>Applicative Functor</em> or the <em>Maybe Monad</em>.
So let's look how both solution would look like.</p>
<h3>Applicative Functor</h3>
<p>The approach with an <em>applicative functor</em> works that we can <em>upgrade</em> any kind of functions. Let's
first create a function that added our three variables together.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs38', 104)" onmouseover="showTip(event, 'fs38', 104)" class="f">addThree</span> <span onmouseout="hideTip(event, 'fs39', 105)" onmouseover="showTip(event, 'fs39', 105)" class="i">a</span> <span onmouseout="hideTip(event, 'fs40', 106)" onmouseover="showTip(event, 'fs40', 106)" class="i">b</span> <span onmouseout="hideTip(event, 'fs41', 107)" onmouseover="showTip(event, 'fs41', 107)" class="i">c</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs39', 108)" onmouseover="showTip(event, 'fs39', 108)" class="i">a</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs40', 109)" onmouseover="showTip(event, 'fs40', 109)" class="i">b</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs41', 110)" onmouseover="showTip(event, 'fs41', 110)" class="i">c</span>
</code></pre></td>
</tr>
</table>
<p>Now we have a function with the function signature</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs7', 111)" onmouseover="showTip(event, 'fs7', 111)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 112)" onmouseover="showTip(event, 'fs7', 112)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 113)" onmouseover="showTip(event, 'fs7', 113)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 114)" onmouseover="showTip(event, 'fs7', 114)" class="i">int</span>
</code></pre></td>
</tr>
</table>
<p>Or in other words, a function taking three <code>int</code> as an argument, and returning an <code>int</code>. But as learned
so far we could not just call.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">result</span> <span class="o">=</span> <span class="i">addThree</span> <span class="i">x</span> <span class="i">y</span> <span class="i">z</span>
</code></pre></td>
</tr>
</table>
<p>Because or <code>x</code>, <code>y</code> and <code>z</code> are <code>int optional</code>. So with an <em>Applicative Functor</em> we could <em>upgrade</em> our
<em>addThree</em> function. So we could do something like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs42', 115)" onmouseover="showTip(event, 'fs42', 115)" class="f">addThreeOptionals</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs43', 116)" onmouseover="showTip(event, 'fs43', 116)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs32', 117)" onmouseover="showTip(event, 'fs32', 117)" class="f">lift3</span> <span onmouseout="hideTip(event, 'fs38', 118)" onmouseover="showTip(event, 'fs38', 118)" class="f">addThree</span>
</code></pre></td>
</tr>
</table>
<p>So we have a function <code>Option.lift3</code>. We can pass any three argument function to it and what we get
back is a new three argument function that now could be <code>optional</code>. When we expect the signature
of our <code>addThreeOptionals</code> function (You can hover over <code>addThreeOptionals</code> if you don't know yet)
we now see <code>addThreeOptionals</code> has the following signature.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs7', 119)" onmouseover="showTip(event, 'fs7', 119)" class="i">int</span> <span class="i">optional</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 120)" onmouseover="showTip(event, 'fs7', 120)" class="i">int</span> <span class="i">optional</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 121)" onmouseover="showTip(event, 'fs7', 121)" class="i">int</span> <span class="i">optional</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs7', 122)" onmouseover="showTip(event, 'fs7', 122)" class="i">int</span> <span class="i">optional</span>
</code></pre></td>
</tr>
</table>
<p>Or in other words. We now have a function taking three arguments, sum then only when all of them
are <code>Some</code>, and returning another <code>int optional</code> as a result. What we now can do is just write.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs44', 123)" onmouseover="showTip(event, 'fs44', 123)" class="i">resultWithA</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs42', 124)" onmouseover="showTip(event, 'fs42', 124)" class="f">addThreeOptionals</span> <span onmouseout="hideTip(event, 'fs16', 125)" onmouseover="showTip(event, 'fs16', 125)" class="i">x</span> <span onmouseout="hideTip(event, 'fs17', 126)" onmouseover="showTip(event, 'fs17', 126)" class="i">y</span> <span onmouseout="hideTip(event, 'fs18', 127)" onmouseover="showTip(event, 'fs18', 127)" class="i">z</span> <span class="c">// Some 60</span>
</code></pre></td>
</tr>
</table>
<p>But as soon as we have an optional in it, we just get a <code>None</code> overall back.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs45', 128)" onmouseover="showTip(event, 'fs45', 128)" class="i">w</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 129)" onmouseover="showTip(event, 'fs11', 129)" class="f">tryParse</span> <span class="s">"hallo"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs46', 130)" onmouseover="showTip(event, 'fs46', 130)" class="i">ax</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs42', 131)" onmouseover="showTip(event, 'fs42', 131)" class="f">addThreeOptionals</span> <span onmouseout="hideTip(event, 'fs16', 132)" onmouseover="showTip(event, 'fs16', 132)" class="i">x</span> <span onmouseout="hideTip(event, 'fs17', 133)" onmouseover="showTip(event, 'fs17', 133)" class="i">y</span> <span onmouseout="hideTip(event, 'fs45', 134)" onmouseover="showTip(event, 'fs45', 134)" class="i">w</span> <span class="c">// None</span>
</code></pre></td>
</tr>
</table>
<p>But we are not forced to create an intermediate function like <code>addThreeOptionals</code>. We also could
have written.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 135)" onmouseover="showTip(event, 'fs47', 135)" class="i">bx</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs43', 136)" onmouseover="showTip(event, 'fs43', 136)" class="t">Option</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs32', 137)" onmouseover="showTip(event, 'fs32', 137)" class="f">lift3</span> <span onmouseout="hideTip(event, 'fs38', 138)" onmouseover="showTip(event, 'fs38', 138)" class="f">addThree</span> <span onmouseout="hideTip(event, 'fs16', 139)" onmouseover="showTip(event, 'fs16', 139)" class="i">x</span> <span onmouseout="hideTip(event, 'fs17', 140)" onmouseover="showTip(event, 'fs17', 140)" class="i">y</span> <span onmouseout="hideTip(event, 'fs18', 141)" onmouseover="showTip(event, 'fs18', 141)" class="i">z</span>
</code></pre></td>
</tr>
</table>
<p>It just means, you can just write any kind of function, and you never have to care if they are <code>option</code>
or not. You always can assume that you have a valid value. If your function should also be able to work
with <code>optional</code>, you just pass your function to <code>Option.lift1</code>, <code>Option.lift2</code>, <code>Option.lift3</code> and so
on to <em>upgrade</em> your function. So you just can stay on the Happy-Path as long as you wish!</p>
<p>But all of your functions will return <code>option</code> now. So at some point in your application you have
to check whether your computation was successful or not. But it is up to you where you do it or
where it makes sense to check it. So instead of checking <code>x</code>, <code>y</code> and <code>z</code> directly, you just can work
with the values, directly add them but if you want to print the result of your <code>addThreeOptionals</code>
function. You have to Pattern Match.</p>
<h3>Maybe Monad</h3>
<p>Another solution is the so called <em>Maybe Monad</em>. F# supports a feature named <em>Computation Expression</em>
that are syntactic sugar for this kind of computations. Let's just look how our code could look like
with a <em>Maybe Monad</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs56', 158)" onmouseover="showTip(event, 'fs56', 158)" class="i">resultWithMaybeA</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs55', 159)" onmouseover="showTip(event, 'fs55', 159)" class="i">maybe</span> {
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs15', 160)" onmouseover="showTip(event, 'fs15', 160)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 161)" onmouseover="showTip(event, 'fs11', 161)" class="f">tryParse</span> <span class="s">"10"</span>
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs57', 162)" onmouseover="showTip(event, 'fs57', 162)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 163)" onmouseover="showTip(event, 'fs11', 163)" class="f">tryParse</span> <span class="s">"20"</span>
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs58', 164)" onmouseover="showTip(event, 'fs58', 164)" class="i">z</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 165)" onmouseover="showTip(event, 'fs11', 165)" class="f">tryParse</span> <span class="s">"30"</span>
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs15', 166)" onmouseover="showTip(event, 'fs15', 166)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs57', 167)" onmouseover="showTip(event, 'fs57', 167)" class="i">y</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs58', 168)" onmouseover="showTip(event, 'fs58', 168)" class="i">z</span>
}
</code></pre></td>
</tr>
</table>
<p>As you see, we just can wrap our code inside a <code>maybe { ... }</code>. What you now see is a special
syntax only available in a <em>Computation Expression</em>. You can write <code>let!</code> instead of just <code>let</code>.
A <code>let!</code> basically does the <em>unwrapping</em> of a value for you.</p>
<p>Remember that <code>tryParse</code> actually returned an <code>int option</code>. But if you hover over <code>x</code> it is
just an <code>int</code>. <code>let!</code> basically can turn a <code>int option</code> to an ordinary <code>int</code> for you. So you
can work with the result of <code>tryParse</code> just as if it is a normal value. But
overall <code>resultWithMaybeA</code> is still an <code>int optional</code>. In those case it will be <code>Some 60</code>.</p>
<p>If you would have written.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs59', 169)" onmouseover="showTip(event, 'fs59', 169)" class="i">resultWithMaybeB</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs55', 170)" onmouseover="showTip(event, 'fs55', 170)" class="i">maybe</span> {
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs15', 171)" onmouseover="showTip(event, 'fs15', 171)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 172)" onmouseover="showTip(event, 'fs11', 172)" class="f">tryParse</span> <span class="s">"10"</span>
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs57', 173)" onmouseover="showTip(event, 'fs57', 173)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 174)" onmouseover="showTip(event, 'fs11', 174)" class="f">tryParse</span> <span class="s">"hallo"</span>
<span class="k">let!</span> <span onmouseout="hideTip(event, 'fs58', 175)" onmouseover="showTip(event, 'fs58', 175)" class="i">z</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs11', 176)" onmouseover="showTip(event, 'fs11', 176)" class="f">tryParse</span> <span class="s">"30"</span>
<span class="k">return</span> <span onmouseout="hideTip(event, 'fs15', 177)" onmouseover="showTip(event, 'fs15', 177)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs57', 178)" onmouseover="showTip(event, 'fs57', 178)" class="i">y</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs58', 179)" onmouseover="showTip(event, 'fs58', 179)" class="i">z</span>
}
</code></pre></td>
</tr>
</table>
<p><code>resultWithMaybeB</code> would be <code>None</code>. This is because <code>tryParse "hallo"</code> would result in <code>None</code>. And this
will abort the <code>maybe</code> construct at this point, and it would overall just return <code>None</code>.</p>
<h2>Summary</h2>
<p><code>null</code> is evil, because you have to add a lot of checking to get it right, a language like C# don't
support you in trying to find all places where you forgot or have to add checking to get a correct
program.</p>
<p>Optionals solve the problem as you already get forced to check for <code>None</code> at compile-time. And
you only need to do it at places where an Optional could be returned. With the idea of
an <em>Applicative Functor</em> or the <em>Maybe Monad</em> you can still write code at places where you don't
want to add explicit checking, without losing the benefits of optionals.</p>
<p>In some future blogs I will show you in more detail how <em>Applicative Functors</em> and the <em>Maybe Monad</em>
works. So you can build your own constructs !</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">module Option<br /><br />from Microsoft.FSharp.Core</div>
<div class="tip" id="fs3">union case Option.None: Option<'T></div>
<div class="tip" id="fs4">union case Option.Some: Value: 'T -> Option<'T></div>
<div class="tip" id="fs5">type 'T option = Option<'T><br /><br />Full name: Microsoft.FSharp.Core.option<_></div>
<div class="tip" id="fs6">val printfn : format:Printf.TextWriterFormat<'T> -> 'T<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn</div>
<div class="tip" id="fs7">Multiple items<br />val int : value:'T -> int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int<br /><br />--------------------<br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />--------------------<br />type int<'Measure> = int<br /><br />Full name: Microsoft.FSharp.Core.int<_></div>
<div class="tip" id="fs8">type Int32 = System.Int32<br /><br />Full name: Main.Int32</div>
<div class="tip" id="fs9">namespace System</div>
<div class="tip" id="fs10">type Int32 =<br />  struct<br />    member CompareTo : value:obj -> int + 1 overload<br />    member Equals : obj:obj -> bool + 1 overload<br />    member GetHashCode : unit -> int<br />    member GetTypeCode : unit -> TypeCode<br />    member ToString : unit -> string + 3 overloads<br />    static val MaxValue : int<br />    static val MinValue : int<br />    static member Parse : s:string -> int + 3 overloads<br />    static member TryParse : s:string * result:int -> bool + 1 overload<br />  end<br /><br />Full name: System.Int32</div>
<div class="tip" id="fs11">val tryParse : str:string -> int option<br /><br />Full name: Main.tryParse</div>
<div class="tip" id="fs12">val str : string</div>
<div class="tip" id="fs13">Multiple items<br />val string : value:'T -> string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string<br /><br />--------------------<br />type string = System.String<br /><br />Full name: Microsoft.FSharp.Core.string</div>
<div class="tip" id="fs14">System.Int32.TryParse(s: string, result: byref<int>) : bool<br />System.Int32.TryParse(s: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider, result: byref<int>) : bool</div>
<div class="tip" id="fs15">val x : int</div>
<div class="tip" id="fs16">val x : int option<br /><br />Full name: Main.x</div>
<div class="tip" id="fs17">val y : int option<br /><br />Full name: Main.y</div>
<div class="tip" id="fs18">val z : int option<br /><br />Full name: Main.z</div>
<div class="tip" id="fs19">val result : int option<br /><br />Full name: Main.result</div>
<div class="tip" id="fs20">val extractedX : int</div>
<div class="tip" id="fs21">val extractedY : int</div>
<div class="tip" id="fs22">val extractedZ : int</div>
<div class="tip" id="fs23">val apply : xf:('a -> 'b) option -> xx:'a option -> 'b option<br /><br />Full name: Main.Option.apply</div>
<div class="tip" id="fs24">val xf : ('a -> 'b) option</div>
<div class="tip" id="fs25">val xx : 'a option</div>
<div class="tip" id="fs26">val f : ('a -> 'b)</div>
<div class="tip" id="fs27">val x : 'a</div>
<div class="tip" id="fs28">val lift2 : f:('a -> 'b -> 'c) -> x:'a option -> y:'b option -> 'c option<br /><br />Full name: Main.Option.lift2</div>
<div class="tip" id="fs29">val f : ('a -> 'b -> 'c)</div>
<div class="tip" id="fs30">val x : 'a option</div>
<div class="tip" id="fs31">val y : 'b option</div>
<div class="tip" id="fs32">val lift3 : f:('a -> 'b -> 'c -> 'd) -> x:'a option -> y:'b option -> z:'c option -> 'd option<br /><br />Full name: Main.Option.lift3</div>
<div class="tip" id="fs33">val f : ('a -> 'b -> 'c -> 'd)</div>
<div class="tip" id="fs34">val z : 'c option</div>
<div class="tip" id="fs35">val lift4 : f:('a -> 'b -> 'c -> 'd -> 'e) -> x:'a option -> y:'b option -> z:'c option -> w:'d option -> 'e option<br /><br />Full name: Main.Option.lift4</div>
<div class="tip" id="fs36">val f : ('a -> 'b -> 'c -> 'd -> 'e)</div>
<div class="tip" id="fs37">val w : 'd option</div>
<div class="tip" id="fs38">val addThree : a:int -> b:int -> c:int -> int<br /><br />Full name: Main.addThree</div>
<div class="tip" id="fs39">val a : int</div>
<div class="tip" id="fs40">val b : int</div>
<div class="tip" id="fs41">val c : int</div>
<div class="tip" id="fs42">val addThreeOptionals : (int option -> int option -> int option -> int option)<br /><br />Full name: Main.addThreeOptionals</div>
<div class="tip" id="fs43">Multiple items<br />module Option<br /><br />from Main<br /><br />--------------------<br />module Option<br /><br />from Microsoft.FSharp.Core</div>
<div class="tip" id="fs44">val resultWithA : int option<br /><br />Full name: Main.resultWithA</div>
<div class="tip" id="fs45">val w : int option<br /><br />Full name: Main.w</div>
<div class="tip" id="fs46">val ax : int option<br /><br />Full name: Main.ax</div>
<div class="tip" id="fs47">val bx : int option<br /><br />Full name: Main.bx</div>
<div class="tip" id="fs48">Multiple items<br />type MaybeBuilder =<br />  new : unit -> MaybeBuilder<br />  member Bind : m:'b option * f:('b -> 'c option) -> 'c option<br />  member Return : x:'a -> 'a option<br /><br />Full name: Main.MaybeBuilder<br /><br />--------------------<br />new : unit -> MaybeBuilder</div>
<div class="tip" id="fs49">val o : MaybeBuilder</div>
<div class="tip" id="fs50">member MaybeBuilder.Bind : m:'b option * f:('b -> 'c option) -> 'c option<br /><br />Full name: Main.MaybeBuilder.Bind</div>
<div class="tip" id="fs51">val m : 'b option</div>
<div class="tip" id="fs52">val f : ('b -> 'c option)</div>
<div class="tip" id="fs53">val bind : binder:('T -> 'U option) -> option:'T option -> 'U option<br /><br />Full name: Microsoft.FSharp.Core.Option.bind</div>
<div class="tip" id="fs54">member MaybeBuilder.Return : x:'a -> 'a option<br /><br />Full name: Main.MaybeBuilder.Return</div>
<div class="tip" id="fs55">val maybe : MaybeBuilder<br /><br />Full name: Main.maybe</div>
<div class="tip" id="fs56">val resultWithMaybeA : int option<br /><br />Full name: Main.resultWithMaybeA</div>
<div class="tip" id="fs57">val y : int</div>
<div class="tip" id="fs58">val z : int</div>
<div class="tip" id="fs59">val resultWithMaybeB : int option<br /><br />Full name: Main.resultWithMaybeB</div>
Understanding Immutability and Pure Functions (for OOP)2016-03-14T00:00:00+00:00https://sidburn.github.io/blog/2016/03/14/immutability-and-pure-functions<p>One important concept in functional programming is immutability. But also in
object-oriented programming immutability and so called <em>immutable objects</em> getting
more attention. The problem that I see especially from object-oriented programmers
are really bad explanations. A lot of explanation I had see described it like this:
<em>Just create a class and make all fields readonly (final or const) and
you have an immutable object</em>.</p>
<p>Explanations like these are <strong>horrible</strong>. Such explanations are so simplified that I
would even call them <em>wrong</em>. So why are they so horrible? Because they don't really
explain anything at all. A programmer new to this concept will just immediately
think: <em>Uhm, but I want to change things! I want to add data to an array, I want to
modify things. I want to do some kind of calculations. I don't want to have static non
changing things. Immutability sounds not practical at all!</em></p>
<p>So let's see what immutability really means.</p>
<h2>Immutability in a Nutshell</h2>
<p>A much more useful explanation is to say that <em>immutability</em> is not about <em>forbidding change</em>
at all. Instead <em>immutability</em> is more on <strong>how</strong> to <em>handle change</em>. Immutability
is not about forbidding some kind of operations. You still can add an element to
an array, the difference is that you just do it differently.</p>
<p>In an mutable world you would directly add your element to an array. In an immutable
world you create a new array with your added element instead. The key concept is to
understand that instead of modifying something you create something <em>new</em> with your
change applied.</p>
<p>Once you understand it is more about creating <em>new</em> things with your changes applied,
the question that arise is more: <em>Why should that be better?</em></p>
<h2>About OO</h2>
<p>Before we go into all kinds of explanations we first have to address OO programming. At first,
talking about immutability and OO at the same time is actually a bad idea. The problem is
that immutability doesn't really fit in the OO world. Because of that we should first focus
on immutability and how it works in a functional language. This will be several magnitudes
easier. Once we understand it there, we go back to the OO world and look how everything
fits in the OO world.</p>
<p>So why does <em>immutability</em> not directly fit in the OO world? Because <em>immutability</em> is solely
about data-structures. <em>Immutability</em> is the core idea that data cannot be changed. Functions
take <em>immutable data</em> and they return <em>immutable data</em>.</p>
<p>The problem is that in object-orientation you usually don't create data-structures. You
encapsulate and hide data instead. Data-access is often even viewed as <em>bad</em>. Often you got told
to create methods instead of providing access to data. This and other things are the reason
why it is hard to <em>get</em> the concept of immutability especially as an OO programmer. We will later
talk about this problem in more depth. For the moment we will put objects aside.</p>
<h2>Immutability is about data</h2>
<p>So Immutability really means that data itself cannot be changed. But as stated previously, instead
of modifying data itself we call functions that then can return new immutable data. Let's look at
some immutable data-structures.</p>
<h3><code>int</code> is immutable</h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="i">x</span> <span class="o">=</span> <span class="n">5</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="i">y</span> <span class="o">=</span> <span class="n">10</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="i">z</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 5)" onmouseover="showTip(event, 'fs2', 5)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs3', 6)" onmouseover="showTip(event, 'fs3', 6)" class="i">y</span> <span class="c">// 15</span>
</code></pre></td>
</tr>
</table>
<p>You actually should be familiar with this because it even feels natural that <code>int</code> is immutable. You
have a lot of operations like <code>+</code>, <code>-</code>,<code>*</code>, <code>*</code>, and some more in the <code>Math</code> class. All of those
operations take some number, do some kind of operation with it and return something new instead.</p>
<p><code>x</code> stays the same, instead <code>+</code> takes two arguments, and produces a new result. We can actually
treat <code>+</code> just as a function that takes two <code>int</code> and produces a whole new <code>int</code>. As a result
we get <code>z</code> that is <code>15</code>. We wouldn't expect that <code>x</code> or <code>y</code> also get modified at all.</p>
<h3><code>string</code> is immutable</h3>
<p>Using <code>int</code> to get the feeling of the concept is easy, but it is sometimes hard how this concept
works with more complex types. Additional <code>int</code> is in most languages some kind of special <em>primitive</em>
type or a so called <em>value type</em>. So we threat them anyway as some kind of <em>special</em>.</p>
<p>So let's look at <code>string</code>. <code>string</code> is usually a <em>reference type</em> in most languages like any
other class. But at least in Java or C#, they are still immutable.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 7)" onmouseover="showTip(event, 'fs5', 7)" class="i">a</span> <span class="o">=</span> <span class="s">"foo"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs6', 8)" onmouseover="showTip(event, 'fs6', 8)" class="i">b</span> <span class="o">=</span> <span class="s">"bar"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs7', 9)" onmouseover="showTip(event, 'fs7', 9)" class="i">c</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 10)" onmouseover="showTip(event, 'fs5', 10)" class="i">a</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs6', 11)" onmouseover="showTip(event, 'fs6', 11)" class="i">b</span> <span class="c">// "foobar"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs8', 12)" onmouseover="showTip(event, 'fs8', 12)" class="i">foo1</span> <span class="o">=</span> <span class="s">"foo1"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs9', 13)" onmouseover="showTip(event, 'fs9', 13)" class="i">foo2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 14)" onmouseover="showTip(event, 'fs8', 14)" class="i">foo1</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs10', 15)" onmouseover="showTip(event, 'fs10', 15)" class="f">Replace</span>(<span class="s">'1'</span>, <span class="s">'2'</span>)
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 16)" onmouseover="showTip(event, 'fs11', 16)" class="i">foo</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs9', 17)" onmouseover="showTip(event, 'fs9', 17)" class="i">foo2</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs12', 18)" onmouseover="showTip(event, 'fs12', 18)" class="f">Remove</span>(<span class="n">3</span>,<span class="n">1</span>)
</code></pre></td>
</tr>
</table>
<p>In this examples we even already see a little bit of OO, because we call methods that <code>string</code> provides.
But looking at the examples we still see that also <code>string</code> behaves much like <code>int</code>. If we add
two strings together we don't modify a string. Instead we create a whole new string instead.</p>
<p>We can observe the same with our method calls. Calling <code>foo1.Replace('1', '2')</code> doesn't change <code>foo1</code>
instead we get a new string back with our change applied.</p>
<h3><code>list</code> is immutable</h3>
<p>So let's look into a more advanced immutable data-type a <code>list</code> in F#. (This is not
<code>System.Collections.Generic.List<T></code>).</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs13', 19)" onmouseover="showTip(event, 'fs13', 19)" class="i">data</span> <span class="o">=</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>]
</code></pre></td>
</tr>
</table>
<p>Usually we want operation for List, for example we want to add elements. In F# we could write something
like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs14', 20)" onmouseover="showTip(event, 'fs14', 20)" class="i">data2</span> <span class="o">=</span> <span class="n">0</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs13', 21)" onmouseover="showTip(event, 'fs13', 21)" class="i">data</span>
</code></pre></td>
</tr>
</table>
<p>In the same spirit like <code>+</code> we have <code>::</code> for adding an element to the top of a list. But instead
of modifying the list itself, we get a new list back. It is now important to note that now we have
two lists. <code>data</code> now contains <code>[1;2;3;4;5]</code> and <code>data2</code> contains <code>[0;1;2;3;4;5]</code>.</p>
<p>From the examples so far we actually can see a <em>pattern</em>. All of our functions take some arguments.
But they always <em>return</em> us something new with our wanted modification applied. That alone means
we can often identify mutation by looking at the function signature. Functions without a return
value that just return <em>unit</em> or similar <em>void</em> in C# <em>often</em> mutate data. This alone is
not a proof, but a very high indicator.</p>
<p>So, let's assume we want to do some more real-world stuff with our list. Let's assume we want to multiply
each element in an <code>int list</code>. Usually in imperative languages like C# you can see something like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">for</span> (<span class="k">int</span> i=<span class="n">0</span>; i<array.Count<span class="n">-1</span>; i+<span class="o">+</span>) {
array[i] <span class="o">=</span> array[i] <span class="o">*</span> <span class="n">2</span>
}
</code></pre></td></tr></table>
<p>but in an immutable world we would create a whole new list with our change applied. Instead of
direct looping we use functions instead. So for example we have <code>List.map</code> that does this kind of
operation for us.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs13', 22)" onmouseover="showTip(event, 'fs13', 22)" class="i">data</span> <span class="o">=</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>;<span class="n">5</span>]
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs14', 23)" onmouseover="showTip(event, 'fs14', 23)" class="i">data2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs15', 24)" onmouseover="showTip(event, 'fs15', 24)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs16', 25)" onmouseover="showTip(event, 'fs16', 25)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs17', 26)" onmouseover="showTip(event, 'fs17', 26)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs17', 27)" onmouseover="showTip(event, 'fs17', 27)" class="i">x</span> <span class="o">*</span> <span class="n">2</span>) <span onmouseout="hideTip(event, 'fs13', 28)" onmouseover="showTip(event, 'fs13', 28)" class="i">data</span>
</code></pre></td>
</tr>
</table>
<p>After executing we once again have two lists. <code>data</code> that still contains <code>[1;2;3;4;5]</code> and
<code>data2</code> that now contains <code>[2;4;6;8;10]</code>.</p>
<h3>Records are immutable</h3>
<p>Let's create another more advanced example. Let's create a <code>Person</code> type that represents a Person
in a database.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs21', 32)" onmouseover="showTip(event, 'fs21', 32)" class="t">Person</span> <span class="o">=</span> {
<span onmouseout="hideTip(event, 'fs22', 33)" onmouseover="showTip(event, 'fs22', 33)" class="i">Id</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs23', 34)" onmouseover="showTip(event, 'fs23', 34)" class="t">int</span>
<span onmouseout="hideTip(event, 'fs24', 35)" onmouseover="showTip(event, 'fs24', 35)" class="i">Name</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs25', 36)" onmouseover="showTip(event, 'fs25', 36)" class="t">string</span>
<span onmouseout="hideTip(event, 'fs26', 37)" onmouseover="showTip(event, 'fs26', 37)" class="i">Birthday</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs18', 38)" onmouseover="showTip(event, 'fs18', 38)" class="t">DateTime</span>
<span onmouseout="hideTip(event, 'fs27', 39)" onmouseover="showTip(event, 'fs27', 39)" class="i">Likes</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs25', 40)" onmouseover="showTip(event, 'fs25', 40)" class="t">string</span> <span onmouseout="hideTip(event, 'fs28', 41)" onmouseover="showTip(event, 'fs28', 41)" class="t">list</span>
}
</code></pre></td>
</tr>
</table>
<p>We now could create a Person like this</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs29', 42)" onmouseover="showTip(event, 'fs29', 42)" class="i">me</span> <span class="o">=</span> {
<span class="i">Id</span> <span class="o">=</span> <span class="n">1</span>
<span class="i">Name</span> <span class="o">=</span> <span class="s">"David Raab"</span>
<span class="i">Birthday</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs18', 43)" onmouseover="showTip(event, 'fs18', 43)" class="t">DateTime</span>(<span class="n">1983</span>, <span class="n">02</span>, <span class="n">19</span>)
<span class="i">Likes</span> <span class="o">=</span> [<span class="s">"Pizza"</span>]
}
</code></pre></td>
</tr>
</table>
<p>This is a record in F#, and like all other data-types it is also <em>immutable</em> by default.
So now let's assume we want to change some parts.I like "dark chocolate" and "tea" so
let's add them. Because we cannot change our data, we have to create a new record instead.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs30', 44)" onmouseover="showTip(event, 'fs30', 44)" class="i">me2</span> <span class="o">=</span> {
<span class="i">Id</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs29', 45)" onmouseover="showTip(event, 'fs29', 45)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs22', 46)" onmouseover="showTip(event, 'fs22', 46)" class="i">Id</span>
<span class="i">Name</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs29', 47)" onmouseover="showTip(event, 'fs29', 47)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs24', 48)" onmouseover="showTip(event, 'fs24', 48)" class="i">Name</span>
<span class="i">Birthday</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs29', 49)" onmouseover="showTip(event, 'fs29', 49)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs26', 50)" onmouseover="showTip(event, 'fs26', 50)" class="i">Birthday</span>
<span class="i">Likes</span> <span class="o">=</span> <span class="s">"Tea"</span> <span class="o">::</span> <span class="s">"Dark Chocolate"</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs29', 51)" onmouseover="showTip(event, 'fs29', 51)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 52)" onmouseover="showTip(event, 'fs27', 52)" class="i">Likes</span>
}
</code></pre></td>
</tr>
</table>
<p>What we now have are two separate variables. <code>me</code> still represents</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">{
<span class="i">Id</span> <span class="o">=</span> <span class="n">1</span>
<span class="i">Name</span> <span class="o">=</span> <span class="s">"David Raab"</span>
<span class="i">Birthday</span> <span class="o">=</span> <span class="n">19.02</span><span class="o">.</span><span class="n">1983</span> <span class="n">00</span><span class="o">:</span><span class="n">00</span><span class="o">:</span><span class="n">00</span>
<span class="i">Likes</span> <span class="o">=</span> [<span class="s">"Pizza"</span>]
}
</code></pre></td>
</tr>
</table>
<p>while <code>me2</code> represents</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">{
<span class="i">Id</span> <span class="o">=</span> <span class="n">1</span>
<span class="i">Name</span> <span class="o">=</span> <span class="s">"David Raab"</span>
<span class="i">Birthday</span> <span class="o">=</span> <span class="n">19.02</span><span class="o">.</span><span class="n">1983</span> <span class="n">00</span><span class="o">:</span><span class="n">00</span><span class="o">:</span><span class="n">00</span>
<span class="i">Likes</span> <span class="o">=</span> [<span class="s">"Tea"</span>; <span class="s">"Dark Chocolate"</span>; <span class="s">"Pizza"</span>]
}
</code></pre></td>
</tr>
</table>
<p>Such a <em>copy & update</em> operation for records is quite common so F# provides a built-in
language construct for it. We also could have written.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">me2</span> <span class="o">=</span> {<span class="i">me</span> <span class="k">with</span> <span class="i">Likes</span> <span class="o">=</span> <span class="s">"Tea"</span> <span class="o">::</span> <span class="s">"Dark Chocolate"</span> <span class="o">::</span> <span class="i">me</span><span class="o">.</span><span class="i">Likes</span>}
</code></pre></td>
</tr>
</table>
<p>So <em>immutability</em> is about data that cannot be changed. But when we want to change something
we usually call a function that can create something new for us. Let's actually simplify
our example even more. Let's create a <code>addLike</code> function instead of using the <code>copy & update</code>
mechanism all over our code.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs31', 53)" onmouseover="showTip(event, 'fs31', 53)" class="f">addLike</span> <span onmouseout="hideTip(event, 'fs32', 54)" onmouseover="showTip(event, 'fs32', 54)" class="i">likes</span> <span onmouseout="hideTip(event, 'fs33', 55)" onmouseover="showTip(event, 'fs33', 55)" class="i">person</span> <span class="o">=</span> {<span onmouseout="hideTip(event, 'fs33', 56)" onmouseover="showTip(event, 'fs33', 56)" class="i">person</span> <span class="k">with</span> <span class="i">Likes</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs32', 57)" onmouseover="showTip(event, 'fs32', 57)" class="i">likes</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs33', 58)" onmouseover="showTip(event, 'fs33', 58)" class="i">person</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 59)" onmouseover="showTip(event, 'fs27', 59)" class="i">Likes</span>}
</code></pre></td>
</tr>
</table>
<p>What we now have is a function that takes two arguments. A <code>string</code> <code>likes</code> that we want to add
and a <code>Person</code> record as its second argument. The function will then return a <em>new</em> <code>Person</code>
record. Now we also could add our Elements by using <code>addLike</code> instead.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs30', 60)" onmouseover="showTip(event, 'fs30', 60)" class="i">me2</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs31', 61)" onmouseover="showTip(event, 'fs31', 61)" class="f">addLike</span> <span class="s">"Dark Chocolate"</span> <span onmouseout="hideTip(event, 'fs29', 62)" onmouseover="showTip(event, 'fs29', 62)" class="i">me</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs34', 63)" onmouseover="showTip(event, 'fs34', 63)" class="i">me3</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs31', 64)" onmouseover="showTip(event, 'fs31', 64)" class="f">addLike</span> <span class="s">"Tea"</span> <span onmouseout="hideTip(event, 'fs30', 65)" onmouseover="showTip(event, 'fs30', 65)" class="i">me2</span>
</code></pre></td>
</tr>
</table>
<p>In this example we call <code>addLike</code> with <code>Dark Chocolate</code> and <code>me</code>. And we get a new <code>Person</code> back
with our change applied. Then we use <code>addLike</code> on <code>me2</code> to create our final <code>me3</code>.</p>
<p>It can feel a little awkward to create a lot of intermediate variables, but we can get rid of them
by chaining functions with <code>|></code>. So we also could have written it like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs30', 66)" onmouseover="showTip(event, 'fs30', 66)" class="i">me2</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs29', 67)" onmouseover="showTip(event, 'fs29', 67)" class="i">me</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs31', 68)" onmouseover="showTip(event, 'fs31', 68)" class="f">addLike</span> <span class="s">"Dark Chocolate"</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs31', 69)" onmouseover="showTip(event, 'fs31', 69)" class="f">addLike</span> <span class="s">"Tea"</span>
</code></pre></td>
</tr>
</table>
<p>Here <code>me</code> is <em>piped-into</em> <code>addLike "Dark Chocolate"</code>. This will result in a new <code>Person</code> record
that then is once again <em>piped-into</em> <code>addLike "Tea"</code>. In object-oriented programming we could
achieve something similar if we have a <code>Person</code> class with a method <code>AddLike</code> that returns a
new <code>Person</code> object, instead of modifying some <code>private</code> fields. in C# this would result into
something like this</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> me<span class="n">2</span> <span class="o">=</span>
me
.AddLike(<span class="s">"Dark Chocolate"</span>)
.AddLike(<span class="s">"Tea"</span>);
</code></pre></td></tr></table>
<p>This is similar to <a href="https://en.wikipedia.org/wiki/Fluent_interface">Fluent Interfaces</a>.
But the important point is that <code>me</code> as an object don't get modified. <code>AddLike</code> would return
a whole new <code>Person</code> object with your operation applied. Because it is once again a <code>Person</code>
you can chain methods. You also can get a <em>fluent-interface</em> by just returning <em>this</em> after
each modification. It would look the same. But in the end <code>me</code> and <code>me2</code> would be references
to the same object, and <code>me</code> would be changed.</p>
<h2>Pure functions</h2>
<p>In a <em>functional-only</em> language we could probably stop at this point. <em>Data</em> and <em>functions</em>
are clearly separated, immutability is only about <em>data</em> that does not change. The big problem
arises if a language also supports classes. Because a class is about <em>hiding data</em>
and additionally contains <em>functions</em>, it introduces a lot of complexity. To understand
the reason of this complexity, we first need to talk about <em>pure</em> and <em>impure</em> functions on
its own.</p>
<h3>Side-effects</h3>
<p><em>Pure</em> functions are only those functions that don't have any kind of side-effects. So
what exactly is a <em>side-effect</em>? A simple explanation would be: <em>A function only can
depend on its input</em>. Calling a function with the same input, <em>always</em> has to produce the
same output. No matter how often, or at what time you call it. We can view <code>+</code> as a pure function.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">x</span> <span class="o">=</span> <span class="n">3</span> <span class="o">+</span> <span class="n">5</span>
</code></pre></td>
</tr>
</table>
<p>No matter how often or at what time we execute the above statement, <code>x</code> should always be <code>8</code>.
If at some point it is <em>possible</em> that it could return something different, we would have
an <em>impure</em> function.</p>
<p>In this example it seems even natural that we don't want any <em>impure</em> function. A <code>3 + 5</code>
that sometimes could return something different sounds horrible. But the truth is, we
often face <em>impure</em> functions and we usually also want them. Examples of <em>impure</em> functions are.</p>
<ol>
<li>Getting a random number</li>
<li>Getting the current system time</li>
<li>Getting the user input</li>
<li>Reading data from a file</li>
<li>Reading data from a network</li>
</ol>
<p>To deeper understand why they are impure. Which arguments would a function have that returns
a random number? Usually we would say: <em>Such a function don't need any input</em>. And that is a problem.
It means, whenever we call a function with no input. It always have to return the same output.
So it just means, we cannot return <em>random numbers</em>, because otherwise that statement wouldn't be
true. That's is also true for the other functions. We cannot for example implement a
<code>readFile "file.txt"</code> function that returns the content of <code>"file.txt"</code>. Because that content
could change every time. And whenever the content of the file changes. <code>readFile "file.txt"</code> would
return something different.</p>
<p>But currently we only only know half of the truth. Because a <em>function</em> still can be impure even
following the above rule. There is even a second rule that a <em>pure function</em> have to fulfil:
<em>We always can replace a pure function call with the value it produces, without that it yields any
change to the program</em>.</p>
<p>That means. Whenever we see <code>3 + 5</code>, we also could replace that calculations with <code>8</code>. Or if
we see <code>readFile "file.txt"</code> we could replace all calls to <code>readFile "file.txt"</code> by the value
that the first function call would produce. This also explains better why a <code>readFile "file.txt"</code>
would be impure. If we call <code>readFile</code> and some time later once again, we would assume that it
returns the new current state of the file. It also could yield an error if the function in the
mean time was deleted. The point is, we expect that the function can return something
different every time we call it.</p>
<p>But this kind of description also eliminates some additional behaviour.</p>
<ol>
<li>We cannot print something to a console</li>
<li>We cannot write to a file/database</li>
<li>We cannot send data over network</li>
</ol>
<p>Let's assume we have <code>someFunciton 5</code> that always will return <code>10</code> but also prints something
to the console. We couldn't replace all calls to <code>someFunction 5</code> just with <code>10</code> because otherwise
we lose all log statements in our console.</p>
<p>Thinking over it, we could ask the question. Can we even write any useful program without
side-effects? The answer is no. That is the reason why Erik Meijer often say:
<em>We all love side-effects</em>. But that doesn't mean we want side-effects happens all
over our code in every function. If a statement like <code>3 + 5</code> could yield <code>10</code> that would
probably drive a lot of people crazy, me too. We want side-effects but we want to somehow
control them. We want to minimize side-effects as much as possible.</p>
<p>So how do we do that? By letting pure functions return immutable data!</p>
<h3>(Im)mutability and (im)pure functions</h3>
<p>One interesting aspect is that both concepts are completely orthogonal. That means, we can have
any combination of those. We can have pure functions that take mutable or immutable data, and return
mutable or immutable data. And we can have impure functions that take and return mutable or immutable
data. The thing is, mutability or immutability doesn't change whether a function is pure or not. This
is important to understand that both concepts don't relate to each other. Let's for example look
again at the above impure functions.</p>
<ul>
<li>A random number generator returns an immutable int/float</li>
<li>A function returning the current time can return an immutable <code>DateTime</code></li>
<li>A function that returns the user input returns an immutable string</li>
<li>Reading a file or from a socket can also return an immutable string</li>
<li>A function that prints something to the console takes an immutable string</li>
<li>Sending/Serialization of data over network can take an immutable data-structure</li>
</ul>
<p>At this point, I cannot stress further how important it is to understand that immutability
is all about data, not about functions or behaviour. We will see later why this is so important!</p>
<h3>Pure functions with side-effects</h3>
<p>The last important point is that we can have pure-functions even if they have some kind of
side-effects. A typical example of this is a function that has internal caching with a mutable
variable.</p>
<p>We could come to the conclusion that this is an impure function as another variable as a
side-effects gets changed. But actually, such a function fulfil all rules we have above. Even
the fact that it mutates some variable. It doesn't really matter, as such a function will still
always return the exact same results to its input. And we always also could replace the function
call with its output.</p>
<p>This is important because people all to often try to look at implementations, but the implementation
itself shouldn't matter at all. The only thing that should matter is how a function behaves. If
a function behaves like a pure function it is a pure function. The same is also true for
mutability. A lot of people try hard to get rid of mutability, sometimes that can lead to
bad performance or in general can make the code harder to understand. For example it is also
fine to have a function with internal mutable state. As long as that function behaves like a pure
function and even gets/returns immutable data, it is absolutely fine to have mutable local variables.</p>
<p>I would even state that this is a big advantage of F#! For example a lot
of the functions from the <code>List</code> module turn a List into a mutable array, do some work on it, and
turn it back into an immutable list. And overall we don't care that it does that. As long as we
use a function and it behaves like a pure function returning immutable data, we are fine with it.</p>
<h2>Benefits of Immutability</h2>
<p>To shorten the example. Let's assume everything is mutable and a <em>reference-type</em> and it also
applies to numbers. Saying that, lets look at the following code.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">x</span> <span class="o">=</span> <span class="n">5</span>
<span class="i">someFunction</span> <span class="i">x</span>
<span class="k">let</span> <span class="i">y</span> <span class="o">=</span> <span class="i">x</span> <span class="o">+</span> <span class="n">3</span>
</code></pre></td>
</tr>
</table>
<p>What value is <code>y</code> now? The answer is, we don't know! <code>someFunction</code> could have changed <code>x</code> to
some other value without that we are aware of it. So after our function did run, we cannot
know what <code>x</code> is, so we don't know what <code>y</code> is. But what does that overall mean?</p>
<p>Usually we are told that functions, or also classes, methods should be treated as <em>block-boxes</em>.
So we should never have to look at how something is implemented. But the thing is, as long we
have mutable data, that concept cannot work. Because as long we have mutable data it means that
a function could do more as documented. We actually can never be sure that <code>x</code> don't get changed
until we look at how <code>someFunction</code> is implemented. Lets look at another problem.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">if</span> <span class="i">value</span><span class="o">.</span><span class="i">isValid</span> <span class="k">then</span>
<span class="i">someFunction</span> <span class="i">x</span>
<span class="k">if</span> <span class="i">value</span><span class="o">.</span><span class="i">isValid</span> <span class="k">then</span>
<span class="o">..</span><span class="o">.</span>
<span class="o">..</span><span class="o">.</span>
</code></pre></td>
</tr>
</table>
<p>So what is the problem here? We are actually accessing <code>value.isValid</code> when it is <code>true</code>
we enter the code. Once again we have <code>someFunction</code> using <code>value</code>. But wait, why do we now
re-check <code>value.isValid</code>? It could <em>probably</em> be that the programmer in charge was drunk, but
wait, can we be sure that the <code>value.isValid</code> is still true? In fact, as long as we have
mutability the answer is <em>no</em>.</p>
<p>The problem is we don't see the scope of our variables. It could be that our
<code>someFunction</code> also has access to our <code>value</code> and modifies it. This sounds like a
horrible programming-style but it is not so uncommon as you think. Did you ever had an
array of objects, and returned an object from this array? If <em>yes</em>, you are open to such kind
of errors. Because you have two functions that still can access the same object used at
multiple places. And in fact we don't even need an array. Looking at object-oriented languages
like C# nearly <em>everything</em> is actually a reference-type. <em>Objects</em> itself never get copied,
only references are copied, and the only thing you pass around are references. But hat
also means that every function could hold a reference to some data and directly change
it whenever it wants to!</p>
<p>So shortly, we cannot know if <code>value</code> still contains the same data. It already could have changed
multiple times. This kind of possibility even raises with <em>multi-threaded</em> code. And
I'm not talking about <em>thread-safety</em> or <em>race-conditions</em> here. <code>value</code> could be thread-safe
and still changed in the mean time. The thing is, mutability basically makes any kind of code
hard or nearly completely unpredictable.</p>
<p>The problem is, this kind of problem grows the bigger our program becomes. Multi-threading
also increase that kind of problems by several magnitudes. And this is the overall problem.
With more code we anyway face problems of designing and maintaining programs. Mutability
just can create hard to track errors. It can become insanely hard to reason about some
kind of code if at every blink of an eye every value can be changed at any time. Immutability
overall can make code easier to read and maintain.</p>
<p>We also can gain other benefits out of it, like easy do/undo systems, backtracking in recursive
functions for free, and a lot of other stuff.</p>
<h2>Disadvantages of Immutability</h2>
<p>Nothing in the world really just have only benefits. Everything in the world has its advantages and
its disadvantages. So what are the disadvantages of immutability?</p>
<p>Mainly it is performance.
Some people think that <em>copying</em> is the often problem or <em>memory</em>, but that isn't true. For example
let's look at the list example. A lot of people assume that by adding an element to a list a whole
list itself has to be copied. But that isn't true at all. For example adding an element to the top
is an <em>O(1)</em> operation. It only can be made so efficient <em>because</em> of immutability. An immutable list
is really just a data-structure that contains an element and a reference to another list.</p>
<p>That's why adding/removing from the top is efficient, instead of adding/removing at the end like
many people knew it from types like <code>List<T></code> in C#. The only reason why you could safely reference
another list is because of immutability. With mutable data this wouldn't be possible as
a list can change. So sharing data with immutable data is very safe. That's also the reason
why you probably hear often that immutability works better with multi-threaded system. Or
functional languages have advantages with multi-threaded systems. It is because immutable data
are preferred and used in such languages.</p>
<p>But it doesn't change that there sometimes exists a problem where this is still a bottleneck
or the culprit to performance problems. The problem with immutable-data is that you have to build
them incrementally. A List with 1 Million elements is really build just as</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">x</span> <span class="o">=</span> <span class="n">1</span> <span class="o">::</span> <span class="n">2</span> <span class="o">::</span> <span class="n">3</span> <span class="o">::</span> <span class="n">4</span> <span class="o">::</span> <span class="o">..</span><span class="o">.</span> <span class="o">::</span> []
</code></pre></td>
</tr>
</table>
<p>or in other words. a lot of copy and create options. Sure a compiler or a runtime could have
some optimization. F# probably have them for lists, but that overall doesn't change that
immutability can sometimes lead to such problems. That is also the very reason why we have
a <code>StringBuilder</code>.</p>
<p>Also a <code>String</code> is immutable but concatenating a lot of strings can create a lot of garbage
throw-away objects. A <code>StringBuilder</code> can actually close that bridge. A <code>StringBuilder</code> uses
a mutable string, and once you are done, you can get an immutable <code>string</code> back.</p>
<p>Other problems can arise that some problems or algorithms can be hard to implement with
immutability. I just want to point again at what was said for <em>pure</em> functions. If you encounter
such problems you always can convert some kind of data to some kind of mutable data. Do your
operation, and convert it back to a immutable data-type.</p>
<p>So it is still important to understand that not everything is shiny and automatically better.
Immutability can sometime have it's own problems, but there exists solutions for it.</p>
<h2>Immutability and OO</h2>
<p>Finally, we now have every knowledge to talk about immutability in object-oriented programming
and why it is so damn hard. First, let's reconsider what an object is.</p>
<p>The fundamental thing
of object-oriented programming is to hide data and instead provide methods that do
some stuff. We even have rules like <em>Law-of-Demeter</em> or <em>Tell don't ask</em> that express it.
An object is not about asking it form some data, we usually just call a method to
tell it that it should <em>do</em> something.</p>
<p>Or in other words. Objects are just collection of functions. And here starts the problem. We
actually learned that immutability has nothing to-do with functions at all! Immutability is
about data not functions! Functions sure can be <em>pure</em> or <em>impure</em> but once again, we also
learned that it doesn't matter at all for immutability. In fact we even consider it as good
if we have side-effects that returns immutable data. That is how to solve the problem of
side-effects. But just having data is usually discouraged in OO. OO has even it's own term
for it. It is named the <em>Anemic Domain Model</em> to express if we have classes that just contains
data.</p>
<p>So, if object-oriented programming don't try to use data explicitly, if we only have objects
that provides us functions (methods) to call. How on earth can we even talk about
<em>immutable objects</em>? What should that thing even be? Does it even makes sense to talk
about <em>immutable objects</em>? If we only provide methods, doesn't it make more sense to talk
about <em>pure</em> and <em>impure objects</em> instead?</p>
<p>To better see the problem, let's look at at the Random class.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs35', 70)" onmouseover="showTip(event, 'fs35', 70)" class="i">rng</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs19', 71)" onmouseover="showTip(event, 'fs19', 71)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs36', 72)" onmouseover="showTip(event, 'fs36', 72)" class="t">Random</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs37', 73)" onmouseover="showTip(event, 'fs37', 73)" class="i">random</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs35', 74)" onmouseover="showTip(event, 'fs35', 74)" class="i">rng</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs38', 75)" onmouseover="showTip(event, 'fs38', 75)" class="f">Next</span>();
</code></pre></td>
</tr>
</table>
<p>Do we consider <code>rng</code> to be immutable or not? Let's look what we have. Besides the usual
method inherited from <code>object</code> we only have three additional methods. <code>Next</code>, <code>NextDouble</code> and
<code>NextBytes</code>. <code>rng</code> don't have any data or additional properties. We can call <code>Next</code> and
we get an immutable <code>int</code> back. Besides that we cannot see any difference at all that <code>rng</code>
itself changed at all! From the outside it looks like an immutable object!</p>
<p>Sure we have knowledge on how a random class works. Usually we have an internal private field
that holds the last generated number, with this the next number will be created when we call
<code>Next</code>. But the point is, we cannot see that. Theoretically the implementation could also
use no mutable field at all. It could just use the current time to generate a random number
instead. So that <code>Next</code> is impure, but don't have any mutable field.</p>
<p>From the outside the only thing we could say is that <code>Random</code> has three <em>impure</em> functions.
And the object itself looks like immutable. We cannot see that any changes at all happens!</p>
<p>So do we consider <code>Random</code> immutable or not? Actually if you really expect an answer, there
isn't really one. Sure we could look at the implementation of it, but that is really bad,
we shouldn't needed to look at some kind of implementation to determine if something is immutable
or not. And as already explained above, it is anyway not a good idea. We should view something
as immutable or pure by looking at how it behaves, not how it is implemented.</p>
<p>So, now we are in a dilemma, how do we solve it? One thing we could do is to broaden the view of
what an immutable object is. So we only consider something as immutable only if it has pure
functions. As soon as we have one impure function on an object, we have to think that there
exists a possibility that a private property could be modified.</p>
<p>Let's look at another example that I saw some time ago. Someone provided a class like this</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs39', 76)" onmouseover="showTip(event, 'fs39', 76)" class="t">MutableSite</span>(<span onmouseout="hideTip(event, 'fs40', 77)" onmouseover="showTip(event, 'fs40', 77)" class="i">url</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 78)" onmouseover="showTip(event, 'fs25', 78)" class="t">string</span>) <span class="o">=</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Url</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs40', 79)" onmouseover="showTip(event, 'fs40', 79)" class="i">url</span>
<span class="k">member</span> <span class="k">val</span> <span class="v">Text</span> <span class="o">=</span> <span class="s">""</span> <span class="k">with</span> <span class="i">get</span>,<span onmouseout="hideTip(event, 'fs41', 80)" onmouseover="showTip(event, 'fs41', 80)" class="i">set</span>
<span class="k">member</span> <span onmouseout="hideTip(event, 'fs42', 81)" onmouseover="showTip(event, 'fs42', 81)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs43', 82)" onmouseover="showTip(event, 'fs43', 82)" class="f">Download</span>() <span class="o">=</span>
<span class="k">use</span> <span onmouseout="hideTip(event, 'fs44', 83)" onmouseover="showTip(event, 'fs44', 83)" class="i">wc</span> <span class="o">=</span> <span class="k">new</span> <span onmouseout="hideTip(event, 'fs19', 84)" onmouseover="showTip(event, 'fs19', 84)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs45', 85)" onmouseover="showTip(event, 'fs45', 85)" class="i">Net</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs46', 86)" onmouseover="showTip(event, 'fs46', 86)" class="t">WebClient</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 87)" onmouseover="showTip(event, 'fs47', 87)" class="i">content</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 88)" onmouseover="showTip(event, 'fs44', 88)" class="i">wc</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs48', 89)" onmouseover="showTip(event, 'fs48', 89)" class="f">DownloadString</span>(<span onmouseout="hideTip(event, 'fs42', 90)" onmouseover="showTip(event, 'fs42', 90)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs49', 91)" onmouseover="showTip(event, 'fs49', 91)" class="i">Url</span>)
<span onmouseout="hideTip(event, 'fs42', 92)" onmouseover="showTip(event, 'fs42', 92)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs50', 93)" onmouseover="showTip(event, 'fs50', 93)" class="i">Text</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs47', 94)" onmouseover="showTip(event, 'fs47', 94)" class="i">content</span>
</code></pre></td>
</tr>
</table>
<p>So, we have obviously a mutable object, right? We have an mutable <code>Text</code>. To fetch the current
site we call <code>Download</code> that mutates <code>Text</code>. So let's look how that person made it immutable.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs51', 95)" onmouseover="showTip(event, 'fs51', 95)" class="t">ImmutableSite</span>(<span onmouseout="hideTip(event, 'fs40', 96)" onmouseover="showTip(event, 'fs40', 96)" class="i">url</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 97)" onmouseover="showTip(event, 'fs25', 97)" class="t">string</span>) <span class="o">=</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Url</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs40', 98)" onmouseover="showTip(event, 'fs40', 98)" class="i">url</span>
<span class="k">member</span> <span onmouseout="hideTip(event, 'fs52', 99)" onmouseover="showTip(event, 'fs52', 99)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs53', 100)" onmouseover="showTip(event, 'fs53', 100)" class="f">Text</span>() <span class="o">=</span>
<span class="k">use</span> <span onmouseout="hideTip(event, 'fs44', 101)" onmouseover="showTip(event, 'fs44', 101)" class="i">wc</span> <span class="o">=</span> <span class="k">new</span> <span onmouseout="hideTip(event, 'fs19', 102)" onmouseover="showTip(event, 'fs19', 102)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs45', 103)" onmouseover="showTip(event, 'fs45', 103)" class="i">Net</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs46', 104)" onmouseover="showTip(event, 'fs46', 104)" class="t">WebClient</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 105)" onmouseover="showTip(event, 'fs47', 105)" class="i">content</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 106)" onmouseover="showTip(event, 'fs44', 106)" class="i">wc</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs48', 107)" onmouseover="showTip(event, 'fs48', 107)" class="f">DownloadString</span>(<span onmouseout="hideTip(event, 'fs52', 108)" onmouseover="showTip(event, 'fs52', 108)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs54', 109)" onmouseover="showTip(event, 'fs54', 109)" class="i">Url</span>)
<span onmouseout="hideTip(event, 'fs47', 110)" onmouseover="showTip(event, 'fs47', 110)" class="i">content</span>
</code></pre></td>
</tr>
</table>
<p>So, he just eliminated the <code>Text</code> field. Instead he created a <code>Text</code> method that would
directly download the site and return the content. Obviously he thought that now he
had an immutable class. And actually that things is just silly. Both version don't
differ at all!</p>
<p>What is the difference between a <code>Text</code> field that always can return another string after
we called <code>Download</code>, or a <code>Text</code> method that directly return a new string whenever
we call the method? There is no difference at all between both version. The problem
is that <code>Text</code> always can return something different. If it
is either a mutable field or an impure method doesn't matter at all! Actually it even could
also just be a property that could do this kind of stuff, so it doesn't even look any different
to a normal mutable field instead of a method call.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs55', 111)" onmouseover="showTip(event, 'fs55', 111)" class="t">SiteWithProperty</span>(<span onmouseout="hideTip(event, 'fs40', 112)" onmouseover="showTip(event, 'fs40', 112)" class="i">url</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 113)" onmouseover="showTip(event, 'fs25', 113)" class="t">string</span>) <span class="o">=</span>
<span class="k">member</span> <span onmouseout="hideTip(event, 'fs56', 114)" onmouseover="showTip(event, 'fs56', 114)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs57', 115)" onmouseover="showTip(event, 'fs57', 115)" class="i">Url</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs40', 116)" onmouseover="showTip(event, 'fs40', 116)" class="i">url</span>
<span class="k">member</span> <span onmouseout="hideTip(event, 'fs56', 117)" onmouseover="showTip(event, 'fs56', 117)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs58', 118)" onmouseover="showTip(event, 'fs58', 118)" class="i">Text</span>
<span class="k">with</span> <span class="i">get</span>() <span class="o">=</span>
<span class="k">use</span> <span onmouseout="hideTip(event, 'fs44', 119)" onmouseover="showTip(event, 'fs44', 119)" class="i">wc</span> <span class="o">=</span> <span class="k">new</span> <span onmouseout="hideTip(event, 'fs19', 120)" onmouseover="showTip(event, 'fs19', 120)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs45', 121)" onmouseover="showTip(event, 'fs45', 121)" class="i">Net</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs46', 122)" onmouseover="showTip(event, 'fs46', 122)" class="t">WebClient</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 123)" onmouseover="showTip(event, 'fs47', 123)" class="i">content</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 124)" onmouseover="showTip(event, 'fs44', 124)" class="i">wc</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs48', 125)" onmouseover="showTip(event, 'fs48', 125)" class="f">DownloadString</span>(<span onmouseout="hideTip(event, 'fs56', 126)" onmouseover="showTip(event, 'fs56', 126)" class="i">this</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs59', 127)" onmouseover="showTip(event, 'fs59', 127)" class="i">Url</span>)
<span onmouseout="hideTip(event, 'fs47', 128)" onmouseover="showTip(event, 'fs47', 128)" class="i">content</span>
</code></pre></td>
</tr>
</table>
<p>The thing is, he thought he made any improvement just because he eliminated a mutable field,
but actually that change don't matter at all. Whether you
have a <code>Text</code> field that can change, a <code>Text</code> property that changes, or a <code>Text</code> method,
in the end, <code>Text</code> always can return something different if you try to access it. So it
improves nothing at all. We don't get any <em>benefits</em> at all that we should get
by imposing immutability.</p>
<p>This example just shows how hard it is to reason about immutable objects. The problem is
the combination of functions and data in one container like a class. And there is even another
problem. Actually it is just fine to have <em>impure functions</em> that return immutable data. But
how do we do that if we consider <em>impure functions</em> on an object as bad?</p>
<p>Actually in functional programming we don't have that problem at all. As every function stands on
its own. Sure we group them in Modules, but it doesn't mean a function is part of some kind
of structure. We can reason about every function separately. We can have pure and impure functions.
And none of those changes the fact that we have immutable data. But in a class you combine
functions with some kind of data in one container, the result is that we have to view an object
as mutable as soon as it provides an impure method. The reason is that it behaves exactly
like a mutable field would do.</p>
<p>So how do we create our impure functions in object-oriented programming? As we learned,
we just need them to do anything useful. Just eliminating all kind of impure functions
doesn't help us to solve any problems. The only way out of it is if you write static methods
for impure functions. In this way you can separate impure functions from pure functions
and an object could be considered as pure/immutable as long it only has pure methods.
So let's consider how a good immutable object should look like.</p>
<h2>How to Design immutable objects</h2>
<ol>
<li>
An immutable class don't have <em>hidden</em> (<code>private</code>) fields. <code>private</code> in the sense of hidden fields
not exposed to the user. Sure a class can have <code>private</code> fields for its data. But a class always
have to provide access to the data through a <em>readonly getter</em>. If you have <em>hidden</em> fields not
exposed to the user, we cannot be sure that an object is <em>immutable</em> at all.
</li>
<li>
A class should only contain <em>pure functions</em> (methods). We don't knew if an impure function
modifies probably some hidden field or not. And it also doesn't matter. As soon we have a method
that can return something different on every call we also cannot view it as <em>immutable</em>. If
a field got changed alongside it or not doesn't matter at all. We judge <em>immutability</em> on how
it behaves, not in how it is implemented. Because functions and data are mixed together in a class.
We have to view every <em>impure method</em> as a violation against <em>immutability</em>.
</li>
<li>
All <em>impure</em> functions should be static methods on a class, or extracted into it's own class.
Let's look at <code>DateTime</code> as an example. For example we have <code>DateTime.Now</code> or <code>DateTime.Today</code>. Those
are impure properties as they always return a different <code>DateTime</code> whenever we call it. But once we
have a <code>DateTime</code> object we only have <em>pure methods</em> operating on it. All data are accessible
through getters. All methods are <em>pure</em>.
</li>
<li>
As we learned at the beginning, immutability is not about forbidding change, so an immutable
objects should have a lot of methods that gives us easy ways to create new objects with our needed
modification. If you don't provide them, it will probably painful to work with your objects. You
can look again at <code>DateTime</code>. We have rich ways like <code>Add</code>, <code>AddDays</code>, <code>AddHours</code>, <code>AddMinutes</code> to
create new DateTime objects. All of those methods return a new <code>DateTime</code> instead of mutating a field.
</li>
</ol>
<p>So let's reconsider the <code>Site</code> class above. How should an immutable <code>Site</code> class looks like?</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span class="i">SiteImmutable</span>(<span class="i">url</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 129)" onmouseover="showTip(event, 'fs25', 129)" class="i">string</span>, <span class="i">content</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 130)" onmouseover="showTip(event, 'fs25', 130)" class="i">string</span>, <span class="i">size</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs23', 131)" onmouseover="showTip(event, 'fs23', 131)" class="i">int</span>) <span class="o">=</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Url</span> <span class="o">=</span> <span class="i">url</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Content</span> <span class="o">=</span> <span class="i">content</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Size</span> <span class="o">=</span> <span class="i">size</span>
<span class="k">static</span> <span class="k">member</span> <span class="i">Download</span>(<span class="i">url</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 132)" onmouseover="showTip(event, 'fs25', 132)" class="i">string</span>) <span class="o">=</span>
<span class="k">use</span> <span class="i">wc</span> <span class="o">=</span> <span class="k">new</span> <span onmouseout="hideTip(event, 'fs19', 133)" onmouseover="showTip(event, 'fs19', 133)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs45', 134)" onmouseover="showTip(event, 'fs45', 134)" class="i">Net</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs46', 135)" onmouseover="showTip(event, 'fs46', 135)" class="i">WebClient</span>()
<span class="k">let</span> <span class="i">content</span> <span class="o">=</span> <span class="i">wc</span><span class="o">.</span><span class="i">DownloadString</span>(<span class="i">url</span>)
<span class="i">SiteImmutable</span>(<span class="i">url</span>, <span class="i">content</span>, <span class="i">content</span><span class="o">.</span><span class="i">Length</span>)
</code></pre></td>
</tr>
</table>
<p>So what we really have is a class with our immutable fields. Our member fields
cannot be changed later as they are immutable. Our class constructor has to be pure, the
same as all methods. The creation of our immutable object is handled by a <em>static impure method</em>
<code>let site = SiteImmutable.Download("http://example.org")</code></p>
<p>Let's for example consider we later want an <code>Update</code> method, so we can re-fetch the <code>content</code> of a
<code>site</code>. Instead of providing an <em>impure</em> <code>Update</code> method we have to provide an <em>impure static method</em>
that does this for us.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs60', 136)" onmouseover="showTip(event, 'fs60', 136)" class="t">SiteImmutable</span>(<span onmouseout="hideTip(event, 'fs40', 137)" onmouseover="showTip(event, 'fs40', 137)" class="i">url</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 138)" onmouseover="showTip(event, 'fs25', 138)" class="t">string</span>, <span onmouseout="hideTip(event, 'fs47', 139)" onmouseover="showTip(event, 'fs47', 139)" class="i">content</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 140)" onmouseover="showTip(event, 'fs25', 140)" class="t">string</span>, <span onmouseout="hideTip(event, 'fs61', 141)" onmouseover="showTip(event, 'fs61', 141)" class="i">size</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs23', 142)" onmouseover="showTip(event, 'fs23', 142)" class="t">int</span>) <span class="o">=</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Url</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs40', 143)" onmouseover="showTip(event, 'fs40', 143)" class="i">url</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Content</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs47', 144)" onmouseover="showTip(event, 'fs47', 144)" class="i">content</span>
<span class="k">member</span> <span class="k">val</span> <span class="i">Size</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs61', 145)" onmouseover="showTip(event, 'fs61', 145)" class="i">size</span>
<span class="k">static</span> <span class="k">member</span> <span onmouseout="hideTip(event, 'fs62', 146)" onmouseover="showTip(event, 'fs62', 146)" class="f">Download</span>(<span onmouseout="hideTip(event, 'fs40', 147)" onmouseover="showTip(event, 'fs40', 147)" class="i">url</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs25', 148)" onmouseover="showTip(event, 'fs25', 148)" class="t">string</span>) <span class="o">=</span>
<span class="k">use</span> <span onmouseout="hideTip(event, 'fs44', 149)" onmouseover="showTip(event, 'fs44', 149)" class="i">wc</span> <span class="o">=</span> <span class="k">new</span> <span onmouseout="hideTip(event, 'fs19', 150)" onmouseover="showTip(event, 'fs19', 150)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs45', 151)" onmouseover="showTip(event, 'fs45', 151)" class="i">Net</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs46', 152)" onmouseover="showTip(event, 'fs46', 152)" class="t">WebClient</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 153)" onmouseover="showTip(event, 'fs47', 153)" class="i">content</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 154)" onmouseover="showTip(event, 'fs44', 154)" class="i">wc</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs48', 155)" onmouseover="showTip(event, 'fs48', 155)" class="f">DownloadString</span>(<span onmouseout="hideTip(event, 'fs40', 156)" onmouseover="showTip(event, 'fs40', 156)" class="i">url</span>)
<span onmouseout="hideTip(event, 'fs60', 157)" onmouseover="showTip(event, 'fs60', 157)" class="t">SiteImmutable</span>(<span onmouseout="hideTip(event, 'fs40', 158)" onmouseover="showTip(event, 'fs40', 158)" class="i">url</span>, <span onmouseout="hideTip(event, 'fs47', 159)" onmouseover="showTip(event, 'fs47', 159)" class="i">content</span>, <span onmouseout="hideTip(event, 'fs47', 160)" onmouseover="showTip(event, 'fs47', 160)" class="i">content</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs63', 161)" onmouseover="showTip(event, 'fs63', 161)" class="i">Length</span>)
<span class="k">static</span> <span class="k">member</span> <span onmouseout="hideTip(event, 'fs64', 162)" onmouseover="showTip(event, 'fs64', 162)" class="f">Update</span>(<span onmouseout="hideTip(event, 'fs65', 163)" onmouseover="showTip(event, 'fs65', 163)" class="i">site</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs60', 164)" onmouseover="showTip(event, 'fs60', 164)" class="t">SiteImmutable</span>) <span class="o">=</span>
<span class="k">use</span> <span onmouseout="hideTip(event, 'fs44', 165)" onmouseover="showTip(event, 'fs44', 165)" class="i">wc</span> <span class="o">=</span> <span class="k">new</span> <span onmouseout="hideTip(event, 'fs19', 166)" onmouseover="showTip(event, 'fs19', 166)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs45', 167)" onmouseover="showTip(event, 'fs45', 167)" class="i">Net</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs46', 168)" onmouseover="showTip(event, 'fs46', 168)" class="t">WebClient</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs47', 169)" onmouseover="showTip(event, 'fs47', 169)" class="i">content</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs44', 170)" onmouseover="showTip(event, 'fs44', 170)" class="i">wc</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs48', 171)" onmouseover="showTip(event, 'fs48', 171)" class="f">DownloadString</span>(<span onmouseout="hideTip(event, 'fs65', 172)" onmouseover="showTip(event, 'fs65', 172)" class="i">site</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs66', 173)" onmouseover="showTip(event, 'fs66', 173)" class="i">Url</span>)
<span onmouseout="hideTip(event, 'fs60', 174)" onmouseover="showTip(event, 'fs60', 174)" class="t">SiteImmutable</span>(<span onmouseout="hideTip(event, 'fs65', 175)" onmouseover="showTip(event, 'fs65', 175)" class="i">site</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs66', 176)" onmouseover="showTip(event, 'fs66', 176)" class="i">Url</span>, <span onmouseout="hideTip(event, 'fs47', 177)" onmouseover="showTip(event, 'fs47', 177)" class="i">content</span>, <span onmouseout="hideTip(event, 'fs47', 178)" onmouseover="showTip(event, 'fs47', 178)" class="i">content</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs63', 179)" onmouseover="showTip(event, 'fs63', 179)" class="i">Length</span>)
</code></pre></td>
</tr>
</table>
<p>So if a user wants to update the content of an object he can do something like this</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs67', 180)" onmouseover="showTip(event, 'fs67', 180)" class="i">site</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs60', 181)" onmouseover="showTip(event, 'fs60', 181)" class="t">SiteImmutable</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs68', 182)" onmouseover="showTip(event, 'fs68', 182)" class="f">Download</span>(<span class="s">"http://example.org"</span>);
<span class="c">// Later...</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs69', 183)" onmouseover="showTip(event, 'fs69', 183)" class="i">updatedSite</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs60', 184)" onmouseover="showTip(event, 'fs60', 184)" class="t">SiteImmutable</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs70', 185)" onmouseover="showTip(event, 'fs70', 185)" class="f">Update</span>(<span onmouseout="hideTip(event, 'fs67', 186)" onmouseover="showTip(event, 'fs67', 186)" class="i">site</span>)
</code></pre></td>
</tr>
</table>
<h2>Conclusion</h2>
<p>Immutability itself is actually an easy concept. The problem starts when we don't separate
data and functions clearly from each other like OO programming does it. To really embrace
immutability in OOP you have to forget a lot of stuff you were taught that should be good. Create
pure data-objects as much as possible. Don't implement <em>impure</em> methods on such data-objects.
Instead create <em>impure static methods</em>. Those should be as small as possible with as
little logic possible. They should return an immutable data-objects as soon as possible.</p>
<p>A good place for <em>impure functions</em> are <em>static methods</em> or either create special
<em>impure/mutable</em> objects instead. But don't try to implement a lot of logic for them,
provide methods to convert an mutable object to an immutable object. <code>StringBuilder</code>
is a good example for an mutable object that fixes the performance problems for creating
complex strings. Once you are done you convert a <code>StringBuilder</code> instance to an
immutable <code>string</code>.</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">val x : int<br /><br />Full name: Main.x</div>
<div class="tip" id="fs3">val y : int<br /><br />Full name: Main.y</div>
<div class="tip" id="fs4">val z : int<br /><br />Full name: Main.z</div>
<div class="tip" id="fs5">val a : string<br /><br />Full name: Main.a</div>
<div class="tip" id="fs6">val b : string<br /><br />Full name: Main.b</div>
<div class="tip" id="fs7">val c : string<br /><br />Full name: Main.c</div>
<div class="tip" id="fs8">val foo1 : string<br /><br />Full name: Main.foo1</div>
<div class="tip" id="fs9">val foo2 : string<br /><br />Full name: Main.foo2</div>
<div class="tip" id="fs10">System.String.Replace(oldValue: string, newValue: string) : string<br />System.String.Replace(oldChar: char, newChar: char) : string</div>
<div class="tip" id="fs11">val foo : string<br /><br />Full name: Main.foo</div>
<div class="tip" id="fs12">System.String.Remove(startIndex: int) : string<br />System.String.Remove(startIndex: int, count: int) : string</div>
<div class="tip" id="fs13">val data : int list<br /><br />Full name: immutabilityandpurefunctions.data</div>
<div class="tip" id="fs14">val data2 : int list<br /><br />Full name: immutabilityandpurefunctions.data2</div>
<div class="tip" id="fs15">Multiple items<br />module List<br /><br />from Microsoft.FSharp.Collections<br /><br />--------------------<br />type List<'T> =<br />  | ( [] )<br />  | ( :: ) of Head: 'T * Tail: 'T list<br />  interface IEnumerable<br />  interface IEnumerable<'T><br />  member GetSlice : startIndex:int option * endIndex:int option -> 'T list<br />  member Head : 'T<br />  member IsEmpty : bool<br />  member Item : index:int -> 'T with get<br />  member Length : int<br />  member Tail : 'T list<br />  static member Cons : head:'T * tail:'T list -> 'T list<br />  static member Empty : 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List<_></div>
<div class="tip" id="fs16">val map : mapping:('T -> 'U) -> list:'T list -> 'U list<br /><br />Full name: Microsoft.FSharp.Collections.List.map</div>
<div class="tip" id="fs17">val x : int</div>
<div class="tip" id="fs18">type DateTime = System.DateTime<br /><br />Full name: Main.DateTime</div>
<div class="tip" id="fs19">namespace System</div>
<div class="tip" id="fs20">Multiple items<br />type DateTime =<br />  struct<br />    new : ticks:int64 -> DateTime + 10 overloads<br />    member Add : value:TimeSpan -> DateTime<br />    member AddDays : value:float -> DateTime<br />    member AddHours : value:float -> DateTime<br />    member AddMilliseconds : value:float -> DateTime<br />    member AddMinutes : value:float -> DateTime<br />    member AddMonths : months:int -> DateTime<br />    member AddSeconds : value:float -> DateTime<br />    member AddTicks : value:int64 -> DateTime<br />    member AddYears : value:int -> DateTime<br />    ...<br />  end<br /><br />Full name: System.DateTime<br /><br />--------------------<br />System.DateTime()<br />   <em>(+0 other overloads)</em><br />System.DateTime(ticks: int64) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(ticks: int64, kind: System.DateTimeKind) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, calendar: System.Globalization.Calendar) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: System.DateTimeKind) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: System.Globalization.Calendar) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: System.DateTimeKind) : unit<br />   <em>(+0 other overloads)</em></div>
<div class="tip" id="fs21">type Person =<br />  {Id: int;<br />   Name: string;<br />   Birthday: DateTime;<br />   Likes: string list;}<br /><br />Full name: Main.Person</div>
<div class="tip" id="fs22">Person.Id: int</div>
<div class="tip" id="fs23">Multiple items<br />val int : value:'T -> int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int<br /><br />--------------------<br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />--------------------<br />type int<'Measure> = int<br /><br />Full name: Microsoft.FSharp.Core.int<_></div>
<div class="tip" id="fs24">Person.Name: string</div>
<div class="tip" id="fs25">Multiple items<br />val string : value:'T -> string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string<br /><br />--------------------<br />type string = System.String<br /><br />Full name: Microsoft.FSharp.Core.string</div>
<div class="tip" id="fs26">Person.Birthday: DateTime</div>
<div class="tip" id="fs27">Person.Likes: string list</div>
<div class="tip" id="fs28">type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs29">val me : Person<br /><br />Full name: Main.me</div>
<div class="tip" id="fs30">val me2 : Person<br /><br />Full name: Main.me2</div>
<div class="tip" id="fs31">val addLike : likes:string -> person:Person -> Person<br /><br />Full name: Main.addLike</div>
<div class="tip" id="fs32">val likes : string</div>
<div class="tip" id="fs33">val person : Person</div>
<div class="tip" id="fs34">val me3 : Person<br /><br />Full name: Main.me3</div>
<div class="tip" id="fs35">val rng : System.Random<br /><br />Full name: Main.rng</div>
<div class="tip" id="fs36">Multiple items<br />type Random =<br />  new : unit -> Random + 1 overload<br />  member Next : unit -> int + 2 overloads<br />  member NextBytes : buffer:byte[] -> unit<br />  member NextDouble : unit -> float<br /><br />Full name: System.Random<br /><br />--------------------<br />System.Random() : unit<br />System.Random(Seed: int) : unit</div>
<div class="tip" id="fs37">val random : int<br /><br />Full name: Main.random</div>
<div class="tip" id="fs38">System.Random.Next() : int<br />System.Random.Next(maxValue: int) : int<br />System.Random.Next(minValue: int, maxValue: int) : int</div>
<div class="tip" id="fs39">Multiple items<br />type MutableSite =<br />  new : url:string -> MutableSite<br />  member Download : unit -> unit<br />  member Text : string<br />  member Url : string<br />  member Text : string with set<br /><br />Full name: Main.MutableSite<br /><br />--------------------<br />new : url:string -> MutableSite</div>
<div class="tip" id="fs40">val url : string</div>
<div class="tip" id="fs41">val set : elements:seq<'T> -> Set<'T> (requires comparison)<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set</div>
<div class="tip" id="fs42">val this : MutableSite</div>
<div class="tip" id="fs43">member MutableSite.Download : unit -> unit<br /><br />Full name: Main.MutableSite.Download</div>
<div class="tip" id="fs44">val wc : System.Net.WebClient</div>
<div class="tip" id="fs45">namespace System.Net</div>
<div class="tip" id="fs46">Multiple items<br />type WebClient =<br />  inherit Component<br />  new : unit -> WebClient<br />  member BaseAddress : string with get, set<br />  member CachePolicy : RequestCachePolicy with get, set<br />  member CancelAsync : unit -> unit<br />  member Credentials : ICredentials with get, set<br />  member DownloadData : address:string -> byte[] + 1 overload<br />  member DownloadDataAsync : address:Uri -> unit + 1 overload<br />  member DownloadFile : address:string * fileName:string -> unit + 1 overload<br />  member DownloadFileAsync : address:Uri * fileName:string -> unit + 1 overload<br />  member DownloadString : address:string -> string + 1 overload<br />  ...<br /><br />Full name: System.Net.WebClient<br /><br />--------------------<br />System.Net.WebClient() : unit</div>
<div class="tip" id="fs47">val content : string</div>
<div class="tip" id="fs48">System.Net.WebClient.DownloadString(address: System.Uri) : string<br />System.Net.WebClient.DownloadString(address: string) : string</div>
<div class="tip" id="fs49">property MutableSite.Url: string</div>
<div class="tip" id="fs50">property MutableSite.Text: string</div>
<div class="tip" id="fs51">Multiple items<br />type ImmutableSite =<br />  new : url:string -> ImmutableSite<br />  member Text : unit -> string<br />  member Url : string<br /><br />Full name: Main.ImmutableSite<br /><br />--------------------<br />new : url:string -> ImmutableSite</div>
<div class="tip" id="fs52">val this : ImmutableSite</div>
<div class="tip" id="fs53">member ImmutableSite.Text : unit -> string<br /><br />Full name: Main.ImmutableSite.Text</div>
<div class="tip" id="fs54">property ImmutableSite.Url: string</div>
<div class="tip" id="fs55">Multiple items<br />type SiteWithProperty =<br />  new : url:string -> SiteWithProperty<br />  member Text : string<br />  member Url : string<br /><br />Full name: Main.SiteWithProperty<br /><br />--------------------<br />new : url:string -> SiteWithProperty</div>
<div class="tip" id="fs56">val this : SiteWithProperty</div>
<div class="tip" id="fs57">member SiteWithProperty.Url : string<br /><br />Full name: Main.SiteWithProperty.Url</div>
<div class="tip" id="fs58">member SiteWithProperty.Text : string<br /><br />Full name: Main.SiteWithProperty.Text</div>
<div class="tip" id="fs59">property SiteWithProperty.Url: string</div>
<div class="tip" id="fs60">Multiple items<br />type SiteImmutable =<br />  new : url:string * content:string * size:int -> SiteImmutable<br />  member Content : string<br />  member Size : int<br />  member Url : string<br />  static member Download : url:string -> SiteImmutable<br />  static member Update : site:SiteImmutable -> SiteImmutable<br /><br />Full name: Main.SiteImmutable<br /><br />--------------------<br />new : url:string * content:string * size:int -> SiteImmutable</div>
<div class="tip" id="fs61">val size : int</div>
<div class="tip" id="fs62">static member SiteImmutable.Download : url:string -> SiteImmutable<br /><br />Full name: Main.SiteImmutable.Download</div>
<div class="tip" id="fs63">property System.String.Length: int</div>
<div class="tip" id="fs64">static member SiteImmutable.Update : site:SiteImmutable -> SiteImmutable<br /><br />Full name: Main.SiteImmutable.Update</div>
<div class="tip" id="fs65">val site : SiteImmutable</div>
<div class="tip" id="fs66">property SiteImmutable.Url: string</div>
<div class="tip" id="fs67">val site : SiteImmutable<br /><br />Full name: Main.site</div>
<div class="tip" id="fs68">static member SiteImmutable.Download : url:string -> SiteImmutable</div>
<div class="tip" id="fs69">val updatedSite : SiteImmutable<br /><br />Full name: Main.updatedSite</div>
<div class="tip" id="fs70">static member SiteImmutable.Update : site:SiteImmutable -> SiteImmutable</div>
Introduction to F#2016-03-10T00:00:00+00:00https://sidburn.github.io/blog/2016/03/10/introduction-in-fsharp<p>When I remember the first time I looked at functional(-first) languages like F#, ML, Haskell and others.
The typical reaction that I had, and I always see from other people is: This is unreadable, it
must be hard to read, it feels complicated and hard.</p>
<p>After spending some time in F# I cannot agree to that at all anymore. Often the syntax
itself is easier (for example compared to C#), shorter and in my opinion more readable.
The problem is more over that most functional languages shares a syntax that is completely
different compared to languages like C, C++, C#, Java, JavaScript and other more mainstream
languages. The problem is more that it is just unfamiliar.</p>
<p>In this post I want you to give a quick overview over the most common and important concepts.
With this overview it should be easy to understand the most basic part to read
and understand functional code.</p>
<p>For better understanding I will provide some C# to F# code examples.</p>
<h2>Variables</h2>
<h3>Definition C#</h3>
<p>Variables are an important concept, in C# you can define variables in two ways. First with an
explicit type. You can optionally initialize it with a value.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">int</span> num <span class="o">=</span> <span class="n">33</span>;
<span class="k">string</span> name <span class="o">=</span> <span class="s">"Hello"</span>;
Person person;
</code></pre></td></tr></table>
<p>The second way is to use the <code>var</code> keyword. It uses <em>type-inference</em> to automatically determine the
type of a variable. You are also forced to specify a value in this way.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> num <span class="o">=</span> <span class="n">33</span>;
<span class="k">var</span> name <span class="o">=</span> <span class="s">"Hello"</span>;
<span class="k">var</span> person <span class="o">=</span> <span class="k">new</span> Person(<span class="s">"foo"</span>);
</code></pre></td></tr></table>
<h3>Definition in F#</h3>
<p>In F# we usually only use the second form of definition. But instead of <code>var</code> we write <code>let</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 13)" onmouseover="showTip(event, 'fs11', 13)" class="i">num</span> <span class="o">=</span> <span class="n">33</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 14)" onmouseover="showTip(event, 'fs12', 14)" class="i">name</span> <span class="o">=</span> <span class="s">"Hello"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs13', 15)" onmouseover="showTip(event, 'fs13', 15)" class="i">person</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 16)" onmouseover="showTip(event, 'fs8', 16)" class="t">Person</span>(<span class="s">"foo"</span>)
</code></pre></td>
</tr>
</table>
<p>We already can see some important differences.</p>
<ol>
<li>Semicolons are not needed to end/separate commands.</li>
<li>We don't have to specify <code>new</code> to create an object.</li>
</ol>
<p>We still can add <em>type-annotations</em> if we want.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs11', 17)" onmouseover="showTip(event, 'fs11', 17)" class="i">num</span> <span class="o">:</span> <span onmouseout="hideTip(event, 'fs14', 18)" onmouseover="showTip(event, 'fs14', 18)" class="t">int</span> <span class="o">=</span> <span class="n">33</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 19)" onmouseover="showTip(event, 'fs12', 19)" class="i">name</span> <span class="o">:</span> <span onmouseout="hideTip(event, 'fs15', 20)" onmouseover="showTip(event, 'fs15', 20)" class="t">string</span> <span class="o">=</span> <span class="s">"Hello"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs13', 21)" onmouseover="showTip(event, 'fs13', 21)" class="i">person</span> <span class="o">:</span> <span onmouseout="hideTip(event, 'fs8', 22)" onmouseover="showTip(event, 'fs8', 22)" class="t">Person</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 23)" onmouseover="showTip(event, 'fs8', 23)" class="t">Person</span>(<span class="s">"foo"</span>)
</code></pre></td>
</tr>
</table>
<h2>(Im)mutability</h2>
<h3>(Im)mutability in C#</h3>
<p>One important difference is that every variable in C# is <em>mutable</em> by default. This
means you can change a variable at any time you want</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp">num <span class="o">=</span> <span class="n">66</span>;
name <span class="o">+</span><span class="o">=</span> <span class="s">" World!"</span>;
person <span class="o">=</span> <span class="k">new</span> Person(<span class="s">"bar"</span>);
</code></pre></td></tr></table>
<p>In C# you otherwise only can create immutable class fields with the <code>readonly</code> keyword.
You cannot create immutable <em>local-variables</em>.</p>
<h3>(Im)mutability in F#</h3>
<p>In F# on the other hand, everything is immutable by default. You cannot change a variable by default.
If you want to create a mutable variable you have to mark a variable as <code>mutable</code></p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs16', 24)" onmouseover="showTip(event, 'fs16', 24)" class="v">num</span> <span class="o">=</span> <span class="n">33</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs17', 25)" onmouseover="showTip(event, 'fs17', 25)" class="v">name</span> <span class="o">=</span> <span class="s">"Hello"</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs18', 26)" onmouseover="showTip(event, 'fs18', 26)" class="v">person</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs8', 27)" onmouseover="showTip(event, 'fs8', 27)" class="t">Person</span>(<span class="s">"foo"</span>)
</code></pre></td>
</tr>
</table>
<p>You change the content of a variable with <code><-</code> instead of <code>=</code>. Equal is only used to specify or comparison.
There is no operator like <code>+=</code> in F#. F# doesn't try to make mutability convenient.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs16', 28)" onmouseover="showTip(event, 'fs16', 28)" class="v">num</span> <span class="o"><-</span> <span class="n">66</span>
<span onmouseout="hideTip(event, 'fs17', 29)" onmouseover="showTip(event, 'fs17', 29)" class="v">name</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs17', 30)" onmouseover="showTip(event, 'fs17', 30)" class="v">name</span> <span class="o">+</span> <span class="s">" World!"</span>
<span onmouseout="hideTip(event, 'fs18', 31)" onmouseover="showTip(event, 'fs18', 31)" class="v">person</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs8', 32)" onmouseover="showTip(event, 'fs8', 32)" class="t">Person</span>(<span class="s">"bar"</span>)
</code></pre></td>
</tr>
</table>
<h2>Functions / Static Methods</h2>
<h3>Definition in C#</h3>
<p>In C# you define <em>static methods</em> as part of a <em>class</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">public</span> <span class="k">static</span> <span class="k">class</span> MyOperations {
<span class="k">public</span> <span class="k">static</span> Add(<span class="k">int</span> x, <span class="k">int</span> y) {
<span class="k">return</span> x <span class="o">+</span> y;
}
}
</code></pre></td></tr></table>
<h3>Definition in F#</h3>
<p>In F# you put functions inside modules.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">module</span> <span class="t">MyOperations</span> <span class="o">=</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs19', 33)" onmouseover="showTip(event, 'fs19', 33)" class="f">add</span> <span onmouseout="hideTip(event, 'fs20', 34)" onmouseover="showTip(event, 'fs20', 34)" class="i">x</span> <span onmouseout="hideTip(event, 'fs21', 35)" onmouseover="showTip(event, 'fs21', 35)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs20', 36)" onmouseover="showTip(event, 'fs20', 36)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs21', 37)" onmouseover="showTip(event, 'fs21', 37)" class="i">y</span>
</code></pre></td>
</tr>
</table>
<p>We can see once again some important differences.</p>
<ol>
<li>You also use <code>let</code> for the definition of a function</li>
<li>Arguments <code>x</code> and <code>y</code> will just be separated by spaces instead of <code>(x, y)</code></li>
<li><em>Type-inference</em> also works for functions.</li>
<li>There doesn't exists a <code>return</code> keyword. The last <em>expression</em> is automatically returned as a value.</li>
</ol>
<p>You also can add explicit <em>type-annotations</em>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">module</span> <span onmouseout="hideTip(event, 'fs22', 38)" onmouseover="showTip(event, 'fs22', 38)" class="i">MyOperations</span> <span class="o">=</span>
<span class="k">let</span> <span class="i">add</span> (<span class="i">x</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs14', 39)" onmouseover="showTip(event, 'fs14', 39)" class="i">int</span>) (<span class="i">y</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs14', 40)" onmouseover="showTip(event, 'fs14', 40)" class="i">int</span>) <span class="o">:</span> <span onmouseout="hideTip(event, 'fs14', 41)" onmouseover="showTip(event, 'fs14', 41)" class="i">int</span> <span class="o">=</span> <span class="i">x</span> <span class="o">+</span> <span class="i">y</span>
</code></pre></td>
</tr>
</table>
<h3>Calling functions in C#</h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> result <span class="o">=</span> MyOperations.Add(<span class="n">5</span>, <span class="n">10</span>);
</code></pre></td></tr></table>
<h3>Calling functions in F#</h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs23', 42)" onmouseover="showTip(event, 'fs23', 42)" class="i">result</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs22', 43)" onmouseover="showTip(event, 'fs22', 43)" class="t">MyOperations</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs19', 44)" onmouseover="showTip(event, 'fs19', 44)" class="f">add</span> <span class="n">5</span> <span class="n">10</span>
</code></pre></td>
</tr>
</table>
<p>The only difference is that you don't use braces and commas to separate the arguments. You
just provide the arguments as-is.</p>
<h2>Generics</h2>
<p>One important concept that you will see more often in F# (compared to C#) is the usage of generics.
Because <em>type-inference</em> also works with functions. F# often automatically generalize a function
with generic arguments, instead of specific-types. And overall generics are more important in
functional languages.</p>
<h3>Generics in C#</h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">public</span> <span class="k">static</span> T SomeFunction<T>(T input) {
<span class="c">// Some code</span>
}
</code></pre></td></tr></table>
<h3>Generics in F#</h3>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs24', 45)" onmouseover="showTip(event, 'fs24', 45)" class="f">someFunction</span> (<span onmouseout="hideTip(event, 'fs25', 46)" onmouseover="showTip(event, 'fs25', 46)" class="i">input</span><span class="o">:</span><span class="o">'</span><span class="i">a</span>) <span class="o">=</span> <span class="c">// Some code</span>
</code></pre></td>
</tr>
</table>
<p>Generics in F# are just annotated like normal types. The only difference is that all of them start
with an apostrophe. Instead of <code>T</code>, <code>TIn</code>, <code>TOut</code> and so on, as often used in C#, in F# they will
be just letters <code>'a</code>, <code>'b</code>, <code>'c</code> ...</p>
<p>As stated previously. You also don't need to annotate generics. If you have written a generic function,
F# will automatically infer a generic type for you. So overall you also could just write.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs26', 47)" onmouseover="showTip(event, 'fs26', 47)" class="f">someFunction</span> <span onmouseout="hideTip(event, 'fs27', 48)" onmouseover="showTip(event, 'fs27', 48)" class="i">input</span> <span class="o">=</span> <span class="c">// Some code</span>
</code></pre></td>
</tr>
</table>
<h2>Data-Types</h2>
<p>Other than object-oriented languages the key concept of <em>functional programming</em> is a separation
between <em>data</em> and <em>behaviour</em>. In <em>OO</em> programming we use <em>classes</em>. Classes can contain
public/private fields to save data, and provide methods for working with this data.</p>
<p>In a <em>functional-language</em> instead we usually define our data-types as separate immutable data.
We then provide (pure) functions that gets immutable data as input, and generate some new data
as output. Because working with data is so important, a functional language offers more than just
classes to define data-types. Besides classes we can use <em>tuples</em>, <em>records</em> and
<em>discriminated unions</em>.</p>
<h3>Tuples in C#</h3>
<p>Tuples are also present in C#. There already exists as a <code>Tuple</code> class. But working with them
is not so convenient as in F#. Anyway let's quickly look at how you use them.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">var</span> position <span class="o">=</span> Tuple.Create(<span class="n">3</span>, <span class="n">4</span>, <span class="n">5</span>); <span class="c">// The type is: Tuple<int,int,int></span>
<span class="k">var</span> x <span class="o">=</span> position.Item<span class="n">1</span>; <span class="c">// 3</span>
<span class="k">var</span> y <span class="o">=</span> position.Item<span class="n">2</span>; <span class="c">// 4</span>
<span class="k">var</span> z <span class="o">=</span> position.Item<span class="n">3</span>; <span class="c">// 5</span>
</code></pre></td></tr></table>
<p>Tuples are a good way for intermediate types. If you easily want to pass some values as
<em>one unit</em> to a function. But more often they are used as a result. So you can easily return
multiple different values from a function.</p>
<h3>Tuples in F#</h3>
<p>Working with Tuples is much easier in F#</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs28', 49)" onmouseover="showTip(event, 'fs28', 49)" class="i">position</span> <span class="o">=</span> <span class="n">3</span>,<span class="n">4</span>,<span class="n">5</span> <span class="c">// The type is: int * int * int</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs29', 50)" onmouseover="showTip(event, 'fs29', 50)" class="i">x</span>,<span onmouseout="hideTip(event, 'fs30', 51)" onmouseover="showTip(event, 'fs30', 51)" class="i">y</span>,<span onmouseout="hideTip(event, 'fs31', 52)" onmouseover="showTip(event, 'fs31', 52)" class="i">z</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs28', 53)" onmouseover="showTip(event, 'fs28', 53)" class="i">position</span>
</code></pre></td>
</tr>
</table>
<p>You create Tuples just by separating values with a comma. You can extract a Tuple with
a <code>let</code> definition. This way you can easily create a function that return multiple data
at once. Tuples don't must contain the same types.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs32', 54)" onmouseover="showTip(event, 'fs32', 54)" class="f">someFunction</span> <span onmouseout="hideTip(event, 'fs20', 55)" onmouseover="showTip(event, 'fs20', 55)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs20', 56)" onmouseover="showTip(event, 'fs20', 56)" class="i">x</span>, <span onmouseout="hideTip(event, 'fs20', 57)" onmouseover="showTip(event, 'fs20', 57)" class="i">x</span><span class="o">*</span><span class="n">2</span>
</code></pre></td>
</tr>
</table>
<p>This function for example returns a Tuple with two elements. The input itself, and the input
multiplied by Two.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs33', 58)" onmouseover="showTip(event, 'fs33', 58)" class="i">result</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs32', 59)" onmouseover="showTip(event, 'fs32', 59)" class="f">someFunction</span> <span class="n">10</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs29', 60)" onmouseover="showTip(event, 'fs29', 60)" class="i">x</span>, <span onmouseout="hideTip(event, 'fs30', 61)" onmouseover="showTip(event, 'fs30', 61)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs33', 62)" onmouseover="showTip(event, 'fs33', 62)" class="i">result</span>
</code></pre></td>
</tr>
</table>
<p>We also can write it in one line</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs29', 63)" onmouseover="showTip(event, 'fs29', 63)" class="i">x</span>,<span onmouseout="hideTip(event, 'fs30', 64)" onmouseover="showTip(event, 'fs30', 64)" class="i">y</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs32', 65)" onmouseover="showTip(event, 'fs32', 65)" class="f">someFunction</span> <span class="n">10</span>
</code></pre></td>
</tr>
</table>
<p>Other than C#, tuples have its own type signature. Instead of a Generic Class like <code>Tuple<int,int,int></code>
a tuple is built into the language itself. They will be represented as <code>int * int * int</code> as a type.
<code>int * float * string * Person</code> would be a four element tuple (quadruple) that contains an <code>int</code> a <code>float</code>
a <code>string</code> and a <code>Person</code> in that <strong>exact</strong> order.</p>
<h3>Records in F#</h3>
<p>Working with tuples is good for intermediate function, for example if you create Pipelines like you
see them with LINQ in C#. They are also good for grouping two or three elements, but as soon you have
have more elements, they are unhandy to work with. An alternative to this is a Record type. If
you know JavaScript you can compare them just to an object. Or a hash in Perl. The only difference
is that they are static typed. So you must define a type beforehand.</p>
<p>Records are planned as a feature in C# 7.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
<span class="l">19: </span>
<span class="l">20: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs34', 66)" onmouseover="showTip(event, 'fs34', 66)" class="t">Human</span> <span class="o">=</span> {
<span onmouseout="hideTip(event, 'fs35', 67)" onmouseover="showTip(event, 'fs35', 67)" class="i">Id</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs14', 68)" onmouseover="showTip(event, 'fs14', 68)" class="t">int</span>
<span onmouseout="hideTip(event, 'fs36', 69)" onmouseover="showTip(event, 'fs36', 69)" class="i">FirstName</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs15', 70)" onmouseover="showTip(event, 'fs15', 70)" class="t">string</span>
<span onmouseout="hideTip(event, 'fs37', 71)" onmouseover="showTip(event, 'fs37', 71)" class="i">LastName</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs15', 72)" onmouseover="showTip(event, 'fs15', 72)" class="t">string</span>
<span onmouseout="hideTip(event, 'fs38', 73)" onmouseover="showTip(event, 'fs38', 73)" class="i">Born</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs2', 74)" onmouseover="showTip(event, 'fs2', 74)" class="t">DateTime</span>
}
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs39', 75)" onmouseover="showTip(event, 'fs39', 75)" class="i">me</span> <span class="o">=</span> {
<span class="i">Id</span> <span class="o">=</span> <span class="n">1</span>
<span class="i">FirstName</span> <span class="o">=</span> <span class="s">"David"</span>
<span class="i">LastName</span> <span class="o">=</span> <span class="s">"Rab"</span>
<span class="i">Born</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 76)" onmouseover="showTip(event, 'fs2', 76)" class="t">DateTime</span>(<span class="n">1983</span>, <span class="n">02</span>, <span class="n">19</span>)
}
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs40', 77)" onmouseover="showTip(event, 'fs40', 77)" class="i">age</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 78)" onmouseover="showTip(event, 'fs2', 78)" class="t">DateTime</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs41', 79)" onmouseover="showTip(event, 'fs41', 79)" class="i">Today</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs42', 80)" onmouseover="showTip(event, 'fs42', 80)" class="i">Year</span> <span class="o">-</span> <span onmouseout="hideTip(event, 'fs39', 81)" onmouseover="showTip(event, 'fs39', 81)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs38', 82)" onmouseover="showTip(event, 'fs38', 82)" class="i">Born</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs42', 83)" onmouseover="showTip(event, 'fs42', 83)" class="i">Year</span>
<span onmouseout="hideTip(event, 'fs43', 84)" onmouseover="showTip(event, 'fs43', 84)" class="f">printfn</span> <span class="s">"</span><span class="pf">%s</span><span class="s"> </span><span class="pf">%s</span><span class="s"> is currently </span><span class="pf">%d</span><span class="s"> years old"</span> <span onmouseout="hideTip(event, 'fs39', 85)" onmouseover="showTip(event, 'fs39', 85)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs36', 86)" onmouseover="showTip(event, 'fs36', 86)" class="i">FirstName</span> <span onmouseout="hideTip(event, 'fs39', 87)" onmouseover="showTip(event, 'fs39', 87)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs37', 88)" onmouseover="showTip(event, 'fs37', 88)" class="i">LastName</span> <span onmouseout="hideTip(event, 'fs40', 89)" onmouseover="showTip(event, 'fs40', 89)" class="i">age</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs44', 90)" onmouseover="showTip(event, 'fs44', 90)" class="i">newMe</span> <span class="o">=</span> {<span onmouseout="hideTip(event, 'fs39', 91)" onmouseover="showTip(event, 'fs39', 91)" class="i">me</span> <span class="k">with</span> <span class="i">LastName</span> <span class="o">=</span> <span class="s">"Raab"</span>}
<span onmouseout="hideTip(event, 'fs43', 92)" onmouseover="showTip(event, 'fs43', 92)" class="f">printfn</span> <span class="s">"</span><span class="pf">%s</span><span class="s"> </span><span class="pf">%s</span><span class="s"> is currently </span><span class="pf">%d</span><span class="s"> years old"</span> <span onmouseout="hideTip(event, 'fs39', 93)" onmouseover="showTip(event, 'fs39', 93)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs36', 94)" onmouseover="showTip(event, 'fs36', 94)" class="i">FirstName</span> <span onmouseout="hideTip(event, 'fs39', 95)" onmouseover="showTip(event, 'fs39', 95)" class="i">me</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs37', 96)" onmouseover="showTip(event, 'fs37', 96)" class="i">LastName</span> <span onmouseout="hideTip(event, 'fs40', 97)" onmouseover="showTip(event, 'fs40', 97)" class="i">age</span>
<span onmouseout="hideTip(event, 'fs43', 98)" onmouseover="showTip(event, 'fs43', 98)" class="f">printfn</span> <span class="s">"</span><span class="pf">%s</span><span class="s"> </span><span class="pf">%s</span><span class="s"> is currently </span><span class="pf">%d</span><span class="s"> years old"</span> <span onmouseout="hideTip(event, 'fs44', 99)" onmouseover="showTip(event, 'fs44', 99)" class="i">newMe</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs36', 100)" onmouseover="showTip(event, 'fs36', 100)" class="i">FirstName</span> <span onmouseout="hideTip(event, 'fs44', 101)" onmouseover="showTip(event, 'fs44', 101)" class="i">newMe</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs37', 102)" onmouseover="showTip(event, 'fs37', 102)" class="i">LastName</span> <span onmouseout="hideTip(event, 'fs40', 103)" onmouseover="showTip(event, 'fs40', 103)" class="i">age</span>
</code></pre></td>
</tr>
</table>
<p>This code will produce the output:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip"><code lang="console">David Rab is currently 33 years old
David Rab is currently 33 years old
David Raab is currently 33 years old
</code></pre></td></tr></table>
<p>Defining a Record needs explicit type annotations. Creating
a Record is pretty easy. You just use the <code>{ ... }</code> syntax. This is nearly identical to JavaScript.
As <em>functional-languages</em> prefer <em>immutability</em> a Record type itself is also <em>immutable</em> by default.
It also has default equality and comparison implementations.</p>
<p>There exists a special <em>copy and update</em> operation. It is <code>{record with newField = newValue }</code>. You
also can set multiple fields at once. As seen in the example. This creates a new record and doesn't
modify the old record.</p>
<p>You can access member of a record with a dot. Records also can be deeply nested, so
you can create hierarchical data-structures.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
<span class="l">19: </span>
<span class="l">20: </span>
<span class="l">21: </span>
<span class="l">22: </span>
<span class="l">23: </span>
<span class="l">24: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs45', 104)" onmouseover="showTip(event, 'fs45', 104)" class="t">Attributes</span> <span class="o">=</span> {
<span onmouseout="hideTip(event, 'fs46', 105)" onmouseover="showTip(event, 'fs46', 105)" class="i">Strength</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs14', 106)" onmouseover="showTip(event, 'fs14', 106)" class="t">int</span>
<span onmouseout="hideTip(event, 'fs47', 107)" onmouseover="showTip(event, 'fs47', 107)" class="i">Dexterity</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs14', 108)" onmouseover="showTip(event, 'fs14', 108)" class="t">int</span>
<span onmouseout="hideTip(event, 'fs48', 109)" onmouseover="showTip(event, 'fs48', 109)" class="i">Intelligence</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs14', 110)" onmouseover="showTip(event, 'fs14', 110)" class="t">int</span>
<span onmouseout="hideTip(event, 'fs49', 111)" onmouseover="showTip(event, 'fs49', 111)" class="i">Vitality</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs14', 112)" onmouseover="showTip(event, 'fs14', 112)" class="t">int</span>
}
<span class="k">type</span> <span onmouseout="hideTip(event, 'fs50', 113)" onmouseover="showTip(event, 'fs50', 113)" class="t">CaharacterSheet</span> <span class="o">=</span> {
<span onmouseout="hideTip(event, 'fs51', 114)" onmouseover="showTip(event, 'fs51', 114)" class="i">Name</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs15', 115)" onmouseover="showTip(event, 'fs15', 115)" class="t">string</span>
<span onmouseout="hideTip(event, 'fs52', 116)" onmouseover="showTip(event, 'fs52', 116)" class="i">Attribute</span><span class="o">:</span> <span onmouseout="hideTip(event, 'fs45', 117)" onmouseover="showTip(event, 'fs45', 117)" class="t">Attributes</span>
}
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs53', 118)" onmouseover="showTip(event, 'fs53', 118)" class="i">warrior</span> <span class="o">=</span> {
<span class="i">Name</span> <span class="o">=</span> <span class="s">"Conan"</span>
<span class="i">Attribute</span> <span class="o">=</span>
{
<span class="i">Strength</span> <span class="o">=</span> <span class="n">1000</span>
<span class="i">Dexterity</span> <span class="o">=</span> <span class="n">200</span>
<span class="i">Intelligence</span> <span class="o">=</span> <span class="n">3</span>
<span class="i">Vitality</span> <span class="o">=</span> <span class="n">1000</span>
}
}
<span onmouseout="hideTip(event, 'fs43', 119)" onmouseover="showTip(event, 'fs43', 119)" class="f">printfn</span> <span class="s">"</span><span class="pf">%s</span><span class="s"> was a Warrior with Strength of </span><span class="pf">%d</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs53', 120)" onmouseover="showTip(event, 'fs53', 120)" class="i">warrior</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs51', 121)" onmouseover="showTip(event, 'fs51', 121)" class="i">Name</span> <span onmouseout="hideTip(event, 'fs53', 122)" onmouseover="showTip(event, 'fs53', 122)" class="i">warrior</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs52', 123)" onmouseover="showTip(event, 'fs52', 123)" class="i">Attribute</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs46', 124)" onmouseover="showTip(event, 'fs46', 124)" class="i">Strength</span>
</code></pre></td>
</tr>
</table>
<h3>Discriminated Unions in F#</h3>
<p>A Discriminated Union (DU) also doesn't currently exists in C#, but they are also planed as a feature for C# 7.
A DU is important as they provide a <em>OR</em> type. When you look at classes, tuples or records all of them are
basically <em>AND</em> types. All of those types group some data-together, but you always have all of them
at the same time. But what happens if you want to express some kind of <em>Either A or B</em>? The closest
thing you can get are <em>enums</em> in C#, but <em>enums</em> cannot contain additional values for each case.</p>
<p>DU are important, because if a language supports both kinds, we also say that it has an
<em>Algebraic type-system</em>. Let's assume we have a shopping system, and we want to express that a
user can pay with different methods.</p>
<ol>
<li><strong>Cash</strong> -- No additional data needed</li>
<li><strong>PayPal</strong> -- We need the email address</li>
<li><strong>CreditCard</strong> -- We need the credit card number</li>
</ol>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs54', 125)" onmouseover="showTip(event, 'fs54', 125)" class="t">Payment</span> <span class="o">=</span>
| <span onmouseout="hideTip(event, 'fs55', 126)" onmouseover="showTip(event, 'fs55', 126)" class="p">Cash</span>
| <span onmouseout="hideTip(event, 'fs56', 127)" onmouseover="showTip(event, 'fs56', 127)" class="p">PayPal</span> <span class="k">of</span> <span onmouseout="hideTip(event, 'fs15', 128)" onmouseover="showTip(event, 'fs15', 128)" class="t">string</span>
| <span onmouseout="hideTip(event, 'fs57', 129)" onmouseover="showTip(event, 'fs57', 129)" class="p">CreditCard</span> <span class="k">of</span> <span onmouseout="hideTip(event, 'fs15', 130)" onmouseover="showTip(event, 'fs15', 130)" class="t">string</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs58', 131)" onmouseover="showTip(event, 'fs58', 131)" class="f">inform</span> <span onmouseout="hideTip(event, 'fs59', 132)" onmouseover="showTip(event, 'fs59', 132)" class="i">payment</span> <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs59', 133)" onmouseover="showTip(event, 'fs59', 133)" class="i">payment</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs55', 134)" onmouseover="showTip(event, 'fs55', 134)" class="p">Cash</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs43', 135)" onmouseover="showTip(event, 'fs43', 135)" class="f">printfn</span> <span class="s">"User payed cash"</span>
| <span onmouseout="hideTip(event, 'fs56', 136)" onmouseover="showTip(event, 'fs56', 136)" class="p">PayPal</span> <span onmouseout="hideTip(event, 'fs60', 137)" onmouseover="showTip(event, 'fs60', 137)" class="i">email</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs43', 138)" onmouseover="showTip(event, 'fs43', 138)" class="f">printfn</span> <span class="s">"User payed with PayPal. Email: </span><span class="pf">%s</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs60', 139)" onmouseover="showTip(event, 'fs60', 139)" class="i">email</span>
| <span onmouseout="hideTip(event, 'fs57', 140)" onmouseover="showTip(event, 'fs57', 140)" class="p">CreditCard</span> <span onmouseout="hideTip(event, 'fs61', 141)" onmouseover="showTip(event, 'fs61', 141)" class="i">no</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs43', 142)" onmouseover="showTip(event, 'fs43', 142)" class="f">printfn</span> <span class="s">"User payed with CC. No: </span><span class="pf">%s</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs61', 143)" onmouseover="showTip(event, 'fs61', 143)" class="i">no</span>
<span onmouseout="hideTip(event, 'fs58', 144)" onmouseover="showTip(event, 'fs58', 144)" class="f">inform</span> <span onmouseout="hideTip(event, 'fs55', 145)" onmouseover="showTip(event, 'fs55', 145)" class="p">Cash</span>
<span onmouseout="hideTip(event, 'fs58', 146)" onmouseover="showTip(event, 'fs58', 146)" class="f">inform</span> (<span onmouseout="hideTip(event, 'fs56', 147)" onmouseover="showTip(event, 'fs56', 147)" class="p">PayPal</span> <span class="s">"foo@example.com"</span>)
<span onmouseout="hideTip(event, 'fs58', 148)" onmouseover="showTip(event, 'fs58', 148)" class="f">inform</span> (<span onmouseout="hideTip(event, 'fs57', 149)" onmouseover="showTip(event, 'fs57', 149)" class="p">CreditCard</span> <span class="s">"123456789"</span>)
</code></pre></td>
</tr>
</table>
<p>The above code will produce an output like</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip"><code lang="console">User payed cash
User payed with PayPal. Email: foo@example.com
User payed with CC. No: 123456789
</code></pre></td></tr></table>
<p>Here <code>inform</code> is a function with one argument <code>payment</code>. Still note that we don't need any kind of
<em>type-annotation</em>. We use <em>pattern matching</em> on payment. Just the fact that we use <code>Cash</code>, <code>PayPal</code>
and <code>CreditCard</code> the F# Compiler can automatically infer that the argument has to be of type <code>Payment</code>.</p>
<p><em>Pattern matching</em> is a kind of <em>switch</em> statement but more powerful, because it not only matches on
the different cases, you also can extract the additional values that are carried within each case.</p>
<p>Also note the syntax <code>inform (PayPal "foo@example.com")</code> We need the braces here not for invocations.
We need them for grouping. This is probably one source of confusion for people coming from C-style
languages. If we wouldn't use the braces and write something like <code>inform PayPal "foo@example.com"</code>
we would try to invoke the <code>inform</code> function with two arguments. The first argument would be <code>PayPal</code>
and the second argument would be <code>"foo@exmaple.com"</code>. That would fail because <code>inform</code> is not a two
argument function. We first need to create a value. That is just done with <code>PayPal "foo@example.com"</code>
and we want the result to pass to our function. That is why we need to add braces around our call.</p>
<p>This is comparable to just simple maths. <code>3 + 4 * 5</code> would yield in <code>23</code>. If we otherwise write
<code>(3 + 4) * 5</code> we would get <code>35</code>. Braces are just grouping constructs! This becomes more important
if we have something like these.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">someFunction</span> (<span class="i">Foo</span> <span class="i">x</span>) (<span class="i">Bar</span> <span class="i">z</span>)
</code></pre></td>
</tr>
</table>
<p>This would be a Function call with two arguments. The first argument is the result of <code>Foo x</code>, the
second argument would be the Result of <code>Bar z</code>. Coming from a C-style language people often try to read it as</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp">someFunction(Foo x)
</code></pre></td></tr></table>
<p>as a single function invocation with one argument, and they see a trailing <code>(Bar z)</code> and they don't know
what it stands for. Actually converting such a function call to C# would result in something like this</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp">someFunction(<span class="k">new</span> Foo(x), <span class="k">new</span> Bar(z));
</code></pre></td></tr></table>
<p>The big advantage of Discriminated Unions is that each case can contain objects, tuples, records or
other discriminated unions as values. It even can contain itself as an element. In this way you
can easily build recursive data-structures.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
<span class="l">19: </span>
<span class="l">20: </span>
<span class="l">21: </span>
<span class="l">22: </span>
<span class="l">23: </span>
<span class="l">24: </span>
<span class="l">25: </span>
<span class="l">26: </span>
<span class="l">27: </span>
<span class="l">28: </span>
<span class="l">29: </span>
<span class="l">30: </span>
<span class="l">31: </span>
<span class="l">32: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">type</span> <span onmouseout="hideTip(event, 'fs62', 150)" onmouseover="showTip(event, 'fs62', 150)" class="t">Markdown</span> <span class="o">=</span>
| <span onmouseout="hideTip(event, 'fs63', 151)" onmouseover="showTip(event, 'fs63', 151)" class="p">NewLine</span>
| <span onmouseout="hideTip(event, 'fs64', 152)" onmouseover="showTip(event, 'fs64', 152)" class="p">Literal</span> <span class="k">of</span> <span onmouseout="hideTip(event, 'fs15', 153)" onmouseover="showTip(event, 'fs15', 153)" class="t">string</span>
| <span onmouseout="hideTip(event, 'fs65', 154)" onmouseover="showTip(event, 'fs65', 154)" class="p">Bold</span> <span class="k">of</span> <span onmouseout="hideTip(event, 'fs15', 155)" onmouseover="showTip(event, 'fs15', 155)" class="t">string</span>
| <span onmouseout="hideTip(event, 'fs66', 156)" onmouseover="showTip(event, 'fs66', 156)" class="p">InlineCode</span> <span class="k">of</span> <span onmouseout="hideTip(event, 'fs15', 157)" onmouseover="showTip(event, 'fs15', 157)" class="t">string</span>
| <span onmouseout="hideTip(event, 'fs67', 158)" onmouseover="showTip(event, 'fs67', 158)" class="p">Block</span> <span class="k">of</span> <span onmouseout="hideTip(event, 'fs62', 159)" onmouseover="showTip(event, 'fs62', 159)" class="t">Markdown</span> <span onmouseout="hideTip(event, 'fs68', 160)" onmouseover="showTip(event, 'fs68', 160)" class="t">list</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs69', 161)" onmouseover="showTip(event, 'fs69', 161)" class="i">document</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs67', 162)" onmouseover="showTip(event, 'fs67', 162)" class="p">Block</span> [
<span onmouseout="hideTip(event, 'fs64', 163)" onmouseover="showTip(event, 'fs64', 163)" class="p">Literal</span> <span class="s">"Hello"</span>; <span onmouseout="hideTip(event, 'fs65', 164)" onmouseover="showTip(event, 'fs65', 164)" class="p">Bold</span> <span class="s">"World!"</span>; <span onmouseout="hideTip(event, 'fs63', 165)" onmouseover="showTip(event, 'fs63', 165)" class="p">NewLine</span>
<span onmouseout="hideTip(event, 'fs64', 166)" onmouseover="showTip(event, 'fs64', 166)" class="p">Literal</span> <span class="s">"InlineCode of"</span>; <span onmouseout="hideTip(event, 'fs66', 167)" onmouseover="showTip(event, 'fs66', 167)" class="p">InlineCode</span> <span class="s">"let sum x y = x + y"</span>; <span onmouseout="hideTip(event, 'fs63', 168)" onmouseover="showTip(event, 'fs63', 168)" class="p">NewLine</span>
<span onmouseout="hideTip(event, 'fs67', 169)" onmouseover="showTip(event, 'fs67', 169)" class="p">Block</span> [
<span onmouseout="hideTip(event, 'fs64', 170)" onmouseover="showTip(event, 'fs64', 170)" class="p">Literal</span> <span class="s">"This is the end"</span>
]
]
<span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs70', 171)" onmouseover="showTip(event, 'fs70', 171)" class="f">produceHtml</span> <span onmouseout="hideTip(event, 'fs71', 172)" onmouseover="showTip(event, 'fs71', 172)" class="i">markdown</span> (<span onmouseout="hideTip(event, 'fs72', 173)" onmouseover="showTip(event, 'fs72', 173)" class="i">sb</span><span class="o">:</span><span onmouseout="hideTip(event, 'fs5', 174)" onmouseover="showTip(event, 'fs5', 174)" class="t">StringBuilder</span>) <span class="o">=</span>
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs71', 175)" onmouseover="showTip(event, 'fs71', 175)" class="i">markdown</span> <span class="k">with</span>
| <span onmouseout="hideTip(event, 'fs63', 176)" onmouseover="showTip(event, 'fs63', 176)" class="p">NewLine</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs72', 177)" onmouseover="showTip(event, 'fs72', 177)" class="i">sb</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs73', 178)" onmouseover="showTip(event, 'fs73', 178)" class="f">Append</span>(<span class="s">"<br/>"</span>) <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 179)" onmouseover="showTip(event, 'fs74', 179)" class="f">ignore</span>
| <span onmouseout="hideTip(event, 'fs64', 180)" onmouseover="showTip(event, 'fs64', 180)" class="p">Literal</span> <span onmouseout="hideTip(event, 'fs75', 181)" onmouseover="showTip(event, 'fs75', 181)" class="i">str</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs72', 182)" onmouseover="showTip(event, 'fs72', 182)" class="i">sb</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs73', 183)" onmouseover="showTip(event, 'fs73', 183)" class="f">Append</span>(<span onmouseout="hideTip(event, 'fs75', 184)" onmouseover="showTip(event, 'fs75', 184)" class="i">str</span>) <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 185)" onmouseover="showTip(event, 'fs74', 185)" class="f">ignore</span>
| <span onmouseout="hideTip(event, 'fs65', 186)" onmouseover="showTip(event, 'fs65', 186)" class="p">Bold</span> <span onmouseout="hideTip(event, 'fs75', 187)" onmouseover="showTip(event, 'fs75', 187)" class="i">str</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs72', 188)" onmouseover="showTip(event, 'fs72', 188)" class="i">sb</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs76', 189)" onmouseover="showTip(event, 'fs76', 189)" class="f">AppendFormat</span>(<span class="s">"<strong>{0}</strong>"</span>, <span onmouseout="hideTip(event, 'fs75', 190)" onmouseover="showTip(event, 'fs75', 190)" class="i">str</span>) <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 191)" onmouseover="showTip(event, 'fs74', 191)" class="f">ignore</span>
| <span onmouseout="hideTip(event, 'fs66', 192)" onmouseover="showTip(event, 'fs66', 192)" class="p">InlineCode</span> <span onmouseout="hideTip(event, 'fs77', 193)" onmouseover="showTip(event, 'fs77', 193)" class="i">code</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs72', 194)" onmouseover="showTip(event, 'fs72', 194)" class="i">sb</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs76', 195)" onmouseover="showTip(event, 'fs76', 195)" class="f">AppendFormat</span>(<span class="s">"<code>{0}</code>"</span>, <span onmouseout="hideTip(event, 'fs77', 196)" onmouseover="showTip(event, 'fs77', 196)" class="i">code</span>) <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 197)" onmouseover="showTip(event, 'fs74', 197)" class="f">ignore</span>
| <span onmouseout="hideTip(event, 'fs67', 198)" onmouseover="showTip(event, 'fs67', 198)" class="p">Block</span> <span onmouseout="hideTip(event, 'fs78', 199)" onmouseover="showTip(event, 'fs78', 199)" class="i">markdown</span> <span class="k">-></span>
<span onmouseout="hideTip(event, 'fs72', 200)" onmouseover="showTip(event, 'fs72', 200)" class="i">sb</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs73', 201)" onmouseover="showTip(event, 'fs73', 201)" class="f">Append</span>(<span class="s">"<p>"</span>) <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 202)" onmouseover="showTip(event, 'fs74', 202)" class="f">ignore</span>
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs79', 203)" onmouseover="showTip(event, 'fs79', 203)" class="i">x</span> <span class="k">in</span> <span onmouseout="hideTip(event, 'fs78', 204)" onmouseover="showTip(event, 'fs78', 204)" class="i">markdown</span> <span class="k">do</span>
<span onmouseout="hideTip(event, 'fs70', 205)" onmouseover="showTip(event, 'fs70', 205)" class="f">produceHtml</span> <span onmouseout="hideTip(event, 'fs79', 206)" onmouseover="showTip(event, 'fs79', 206)" class="i">x</span> <span onmouseout="hideTip(event, 'fs72', 207)" onmouseover="showTip(event, 'fs72', 207)" class="i">sb</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 208)" onmouseover="showTip(event, 'fs74', 208)" class="f">ignore</span>
<span onmouseout="hideTip(event, 'fs72', 209)" onmouseover="showTip(event, 'fs72', 209)" class="i">sb</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs73', 210)" onmouseover="showTip(event, 'fs73', 210)" class="f">Append</span>(<span class="s">"</p>"</span>) <span class="o">|></span> <span onmouseout="hideTip(event, 'fs74', 211)" onmouseover="showTip(event, 'fs74', 211)" class="f">ignore</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs80', 212)" onmouseover="showTip(event, 'fs80', 212)" class="i">html</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 213)" onmouseover="showTip(event, 'fs5', 213)" class="t">StringBuilder</span>()
<span onmouseout="hideTip(event, 'fs70', 214)" onmouseover="showTip(event, 'fs70', 214)" class="f">produceHtml</span> <span onmouseout="hideTip(event, 'fs69', 215)" onmouseover="showTip(event, 'fs69', 215)" class="i">document</span> <span onmouseout="hideTip(event, 'fs80', 216)" onmouseover="showTip(event, 'fs80', 216)" class="i">html</span>
<span onmouseout="hideTip(event, 'fs43', 217)" onmouseover="showTip(event, 'fs43', 217)" class="f">printfn</span> <span class="s">"</span><span class="pf">%s</span><span class="s">"</span> (<span onmouseout="hideTip(event, 'fs80', 218)" onmouseover="showTip(event, 'fs80', 218)" class="i">html</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs81', 219)" onmouseover="showTip(event, 'fs81', 219)" class="f">ToString</span>())
</code></pre></td>
</tr>
</table>
<p>Running the above code will produce us the following output</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip"><code lang="console"><p>Hello<strong>World!</strong><br/>InlineCode of<code>let sum x y = x + y</code><br/><p>This is the end</p></p>
</code></pre></td></tr></table>
<p>So we can easily create hierarchical data-structures, and with Pattern Matching we can easily write recursive
function to traverse them.</p>
<h3>List in F#</h3>
<p>The example above already introduced lists. Otherwise a list in F# is different to the C# <code>List<T></code> type.
In C# you create a mutable <code>List<T></code> object and you can directly <code>Add</code> items to. In F# on the other hand you
create lists just with the syntax <code>[ ... ]</code> (Like in JavaScript). Otherwise elements get separated by <code>;</code>
instead of <code>,</code>. This is often a source of confusion, because both styles are allowed but they mean something
different.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs82', 220)" onmouseover="showTip(event, 'fs82', 220)" class="i">data</span> <span class="o">=</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>]
</code></pre></td>
</tr>
</table>
<p>This is a List of <code>int</code>. And it contains four elements.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs83', 221)" onmouseover="showTip(event, 'fs83', 221)" class="i">data</span> <span class="o">=</span> [<span class="n">1</span>,<span class="n">2</span>,<span class="n">3</span>,<span class="n">4</span>]
</code></pre></td>
</tr>
</table>
<p>This is a List of a Tuple <code>int * int * int * int</code> and it contains a single element. Remember <code>,</code> is
for creating Tuples!</p>
<p>Additional lists in F# are also immutable. They also provide default implementations of equality, comparison
and so on. If you want to add elements to a list you have to create a new list. This can be easily done with
<code>::</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs82', 222)" onmouseover="showTip(event, 'fs82', 222)" class="i">data</span> <span class="o">=</span> [<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>]
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs84', 223)" onmouseover="showTip(event, 'fs84', 223)" class="i">oneMore</span> <span class="o">=</span> <span class="n">5</span> <span class="o">::</span> <span onmouseout="hideTip(event, 'fs82', 224)" onmouseover="showTip(event, 'fs82', 224)" class="i">data</span>
</code></pre></td>
</tr>
</table>
<p><code>oneMore</code> is now</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">[<span class="n">5</span>;<span class="n">1</span>;<span class="n">2</span>;<span class="n">3</span>;<span class="n">4</span>]
</code></pre></td>
</tr>
</table>
<p>note that <code>data</code> is unchanged and is still a four element list. The way how lists are build (<em>immutable</em>
and as <em>linked-list</em>) means adding and removing from the beginning is an efficient operation <em>O(1)</em>.</p>
<p>There are various functions inside the <code>List</code> module to transform lists itself. With <code>[|1;2;3|]</code>
we also can create <em>mutable fixed-size array</em>. There also exists a <code>Array</code> Module with nearly the same
functions as in the <code>List</code> module.</p>
<h2>Composition and Piping</h2>
<p>The last concepts we look at in our introduction is the concept of <em>Composition</em> and <em>Piping</em>. Both
are very important in functional languages, as more complex logic is achieved by composing of functions.
Compose ability is actually pretty easy. Let's assume we have a function that takes an <code>int</code> as its input
and a <code>string</code> as its output. In C# we would usually define such a <em>method interface</em> in that way.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">string</span> SomeMethod(<span class="k">int</span> x);
</code></pre></td></tr></table>
<p>This could be for example part of an <code>interface</code> definition in C#. In F# we would define such an interface
just as</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 225)" onmouseover="showTip(event, 'fs14', 225)" class="f">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 226)" onmouseover="showTip(event, 'fs15', 226)" class="i">string</span>
</code></pre></td>
</tr>
</table>
<p>This definition means. A function that has an <code>int</code> as an input, and will return a <code>string</code>. Note that
we don't specify a function name. Every function itself is actually an interface of its own. Something
like this also exists in C#. Usually expressed as either <code>Action</code> or <code>Func</code>. We also could have written.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp">Func<<span class="k">int</span>,<span class="k">string</span>>
</code></pre></td></tr></table>
<p>In C# <code>Action</code> and <code>Func</code> types are usually used in Methods if we want to expect a function as an argument.
In C# you need <code>Action</code> to describe function with a <code>void</code> return value.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">Func</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs14', 227)" onmouseover="showTip(event, 'fs14', 227)" class="i">int</span>,<span onmouseout="hideTip(event, 'fs15', 228)" onmouseover="showTip(event, 'fs15', 228)" class="i">string</span><span class="o">></span>
<span onmouseout="hideTip(event, 'fs15', 229)" onmouseover="showTip(event, 'fs15', 229)" class="i">string</span> <span class="i">SomeFunction</span>(<span onmouseout="hideTip(event, 'fs14', 230)" onmouseover="showTip(event, 'fs14', 230)" class="i">int</span> <span class="i">x</span>)
</code></pre></td>
</tr>
</table>
<p>And Action means</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="i">Action</span><span class="o"><</span><span onmouseout="hideTip(event, 'fs14', 231)" onmouseover="showTip(event, 'fs14', 231)" class="i">int</span>,<span onmouseout="hideTip(event, 'fs15', 232)" onmouseover="showTip(event, 'fs15', 232)" class="i">string</span><span class="o">></span>
<span class="k">void</span> <span class="i">SomeFunction</span>(<span onmouseout="hideTip(event, 'fs14', 233)" onmouseover="showTip(event, 'fs14', 233)" class="i">int</span> <span class="i">x</span>, <span onmouseout="hideTip(event, 'fs15', 234)" onmouseover="showTip(event, 'fs15', 234)" class="i">string</span> <span class="i">y</span>)
</code></pre></td>
</tr>
</table>
<p>In F# we just have a sepcial type named <code>unit</code> to express <em>Nothing</em>. So we can write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs14', 235)" onmouseover="showTip(event, 'fs14', 235)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 236)" onmouseover="showTip(event, 'fs15', 236)" class="i">string</span>
<span onmouseout="hideTip(event, 'fs14', 237)" onmouseover="showTip(event, 'fs14', 237)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs85', 238)" onmouseover="showTip(event, 'fs85', 238)" class="i">unit</span>
<span onmouseout="hideTip(event, 'fs14', 239)" onmouseover="showTip(event, 'fs14', 239)" class="i">int</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs15', 240)" onmouseover="showTip(event, 'fs15', 240)" class="i">string</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs85', 241)" onmouseover="showTip(event, 'fs85', 241)" class="i">unit</span>
</code></pre></td>
</tr>
</table>
<p>The Last line can be read as. A function with two arguments <code>int</code> and <code>string</code> and it will
return <code>unit</code> (Nothing).</p>
<p>Now let's assume we have two functions with the following signatures</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs15', 242)" onmouseover="showTip(event, 'fs15', 242)" class="i">string</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 243)" onmouseover="showTip(event, 'fs14', 243)" class="i">int</span> <span onmouseout="hideTip(event, 'fs68', 244)" onmouseover="showTip(event, 'fs68', 244)" class="i">list</span>
<span onmouseout="hideTip(event, 'fs14', 245)" onmouseover="showTip(event, 'fs14', 245)" class="i">int</span> <span onmouseout="hideTip(event, 'fs68', 246)" onmouseover="showTip(event, 'fs68', 246)" class="i">list</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 247)" onmouseover="showTip(event, 'fs14', 247)" class="i">int</span>
</code></pre></td>
</tr>
</table>
<p>So we have a function that has a <code>string</code> as it's input, and a <code>int list</code> (List of int) as its
output. Our second functions takes a <code>int list</code> as its input, and will produce just a <code>int</code>
as its output. Looking at those signatures we now can compose them. Even if we don't now what
those functions do. We just know that the output of the first function can be directly given
as the input of the second function.</p>
<p>We can directly create a function with a <code>string</code> input returning an <code>int</code>.
This kind of idea is what we name <em>composing</em>. In F# we have a special operator for this
kind of composition. The <code>>></code> operator.</p>
<p>But let's work step by step to it. Let's assume we have a <code>parseInts</code> function
that takes a string, splits a string on ',' and parses every number as an <code>int</code>
and returns <code>int list</code>. The signature would be <code>string -> int list</code>.</p>
<p>We then have another function <code>sumList</code> that just takes a <code>int list</code> and sums all
numbers together returning an <code>int</code>. We could use those two functions like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs101', 274)" onmouseover="showTip(event, 'fs101', 274)" class="i">nums</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs91', 275)" onmouseover="showTip(event, 'fs91', 275)" class="f">parseInts</span> <span class="s">"1,2,3,4,5"</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs102', 276)" onmouseover="showTip(event, 'fs102', 276)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs98', 277)" onmouseover="showTip(event, 'fs98', 277)" class="f">sumList</span> <span onmouseout="hideTip(event, 'fs101', 278)" onmouseover="showTip(event, 'fs101', 278)" class="i">nums</span> <span class="c">// 15</span>
</code></pre></td>
</tr>
</table>
<p>We also could create a new function that combines these two steps into a new function</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs103', 279)" onmouseover="showTip(event, 'fs103', 279)" class="f">strToSum</span> <span onmouseout="hideTip(event, 'fs104', 280)" onmouseover="showTip(event, 'fs104', 280)" class="i">stringList</span> <span class="o">=</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs105', 281)" onmouseover="showTip(event, 'fs105', 281)" class="i">nums</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs91', 282)" onmouseover="showTip(event, 'fs91', 282)" class="f">parseInts</span> <span onmouseout="hideTip(event, 'fs104', 283)" onmouseover="showTip(event, 'fs104', 283)" class="i">stringList</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs106', 284)" onmouseover="showTip(event, 'fs106', 284)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs98', 285)" onmouseover="showTip(event, 'fs98', 285)" class="f">sumList</span> <span onmouseout="hideTip(event, 'fs105', 286)" onmouseover="showTip(event, 'fs105', 286)" class="i">nums</span>
<span onmouseout="hideTip(event, 'fs106', 287)" onmouseover="showTip(event, 'fs106', 287)" class="i">sum</span>
</code></pre></td>
</tr>
</table>
<p>We now have a function <code>strToSum</code> that goes directly from <code>string -> int</code></p>
<p>But these kind of operation is actually pretty generic. As this kind of composing works for
any kind of function with any kind of type. In general we can say. When we have two functions.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>
<span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>
</code></pre></td>
</tr>
</table>
<p>we can compose those two into a new function</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>
</code></pre></td>
</tr>
</table>
<p>So let's write a <code>compose</code> function that does that kind of stuff for us.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs107', 288)" onmouseover="showTip(event, 'fs107', 288)" class="f">compose</span> <span onmouseout="hideTip(event, 'fs108', 289)" onmouseover="showTip(event, 'fs108', 289)" class="f">f</span> <span onmouseout="hideTip(event, 'fs109', 290)" onmouseover="showTip(event, 'fs109', 290)" class="f">g</span> <span onmouseout="hideTip(event, 'fs110', 291)" onmouseover="showTip(event, 'fs110', 291)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs109', 292)" onmouseover="showTip(event, 'fs109', 292)" class="f">g</span> (<span onmouseout="hideTip(event, 'fs108', 293)" onmouseover="showTip(event, 'fs108', 293)" class="f">f</span> <span onmouseout="hideTip(event, 'fs110', 294)" onmouseover="showTip(event, 'fs110', 294)" class="i">x</span>)
</code></pre></td>
</tr>
</table>
<p>So let's look at the implementation. We have a function <code>compose</code> with three arguments. <code>f</code>
is expected to be a function. The same is true for <code>g</code>. <code>x</code> is just some kind of value. What we
first do is</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span class="i">f</span> <span class="i">x</span>)
</code></pre></td>
</tr>
</table>
<p>meaning we will call our <code>f</code> function with the <code>x</code> value. The Result of that is passed to the <code>g</code>
function. The result of the <code>g</code> function is then returned as a value. We also could have written it
like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span class="i">compose</span> <span class="i">f</span> <span class="i">g</span> <span class="i">x</span> <span class="o">=</span>
<span class="k">let</span> <span class="i">y</span> <span class="o">=</span> <span class="i">f</span> <span class="i">x</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs111', 295)" onmouseover="showTip(event, 'fs111', 295)" class="i">z</span> <span class="o">=</span> <span class="i">g</span> <span class="i">y</span>
<span onmouseout="hideTip(event, 'fs111', 296)" onmouseover="showTip(event, 'fs111', 296)" class="i">z</span>
</code></pre></td>
</tr>
</table>
<p>The F# compiler automatically infers that <code>f</code> and <code>g</code> are functions.
Just by using it like <code>f x</code> or <code>g y</code> the compiler knows that <code>f</code> and <code>g</code> must be
functions with a single argument.</p>
<p>But what kind of types do we have here? The answer is, they are generic. When we look at the type
signature that the compiler created for us, it looks some kind of scary first. We have.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">val</span> <span class="i">compose</span> <span class="o">:</span> <span class="i">f</span><span class="o">:</span>(<span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">b</span>) <span class="k">-></span> <span class="i">g</span><span class="o">:</span>(<span class="o">'</span><span class="i">b</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>) <span class="k">-></span> <span class="i">x</span><span class="o">:</span><span class="o">'</span><span class="i">a</span> <span class="k">-></span> <span class="o">'</span><span class="i">c</span>
</code></pre></td>
</tr>
</table>
<p>Let's go over it step-by-step</p>
<table>
<thead>
<tr class="header">
<th align="center"><p>Argument</p></th>
<th align="center"><p>Signature</p></th>
<th align="left"><p>Meaning</p></th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td align="center"><p>f</p></td>
<td align="center"><p>('a -> 'b)</p></td>
<td align="left"><p>A function that goes from 'a to 'b</p></td>
</tr>
<tr class="even">
<td align="center"><p>g</p></td>
<td align="center"><p>('b -> 'c)</p></td>
<td align="left"><p>A function that goes from 'b to 'c</p></td>
</tr>
<tr class="odd">
<td align="center"><p>x</p></td>
<td align="center"><p>'a</p></td>
<td align="left"><p>A value of type 'a</p></td>
</tr>
<tr class="even">
<td align="center"></td>
<td align="center"><p>'c</p></td>
<td align="left"><p>It will return 'c</p></td>
</tr>
</tbody>
</table>
<p>Just by looking at the types we can examine what the function does. We have <code>'a</code> as a value and two
functions. And we need to return a <code>'c</code>. So how do we get a <code>'c</code>?</p>
<p>At first the only thing that function can do is pass the <code>x</code> value (a <code>'a</code>) into the <code>f</code> function. That will
return a <code>'b</code> value. After we have a <code>'b</code> value it only can pass that value into the <code>g</code> function.
Finally this returns a <code>'c</code> that the <code>compose</code> function then returns.</p>
<p>We now could use <code>compose</code> like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs102', 297)" onmouseover="showTip(event, 'fs102', 297)" class="i">sum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs107', 298)" onmouseover="showTip(event, 'fs107', 298)" class="f">compose</span> <span onmouseout="hideTip(event, 'fs91', 299)" onmouseover="showTip(event, 'fs91', 299)" class="f">parseInts</span> <span onmouseout="hideTip(event, 'fs98', 300)" onmouseover="showTip(event, 'fs98', 300)" class="f">sumList</span> <span class="s">"1,2,3,4,5"</span> <span class="c">// 15</span>
</code></pre></td>
</tr>
</table>
<p>Here we now call <code>compose</code> with three arguments. We provide the <code>parseInts</code> function itself as a value.
We then provide the <code>sumList</code> function as a the second argument. And our third argument is our <code>"1,2,3,4,5"</code>
string.</p>
<p>The last thing we can do now. F# supports <em>omitting</em> arguments from a function call. If you <em>omit</em> a value, you
get a function back with the remaining arguments. Currently our <code>compose</code> function is a three arguments
function. So what happens if we just provide the first two functions as arguments? We get a function back
that is still waiting for the last third argument.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs112', 301)" onmouseover="showTip(event, 'fs112', 301)" class="f">strToSum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs107', 302)" onmouseover="showTip(event, 'fs107', 302)" class="f">compose</span> <span onmouseout="hideTip(event, 'fs91', 303)" onmouseover="showTip(event, 'fs91', 303)" class="f">parseInts</span> <span onmouseout="hideTip(event, 'fs98', 304)" onmouseover="showTip(event, 'fs98', 304)" class="f">sumList</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs113', 305)" onmouseover="showTip(event, 'fs113', 305)" class="i">result</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs112', 306)" onmouseover="showTip(event, 'fs112', 306)" class="f">strToSum</span> <span class="s">"1,2,3,4,5"</span> <span class="c">// 15</span>
</code></pre></td>
</tr>
</table>
<p>This kind of composing is so common that we have a special operator <code>>></code> for this. So all we really need to
do is put >> between two functions, and we get a new function back! So what we are doing is</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp">(<span onmouseout="hideTip(event, 'fs15', 307)" onmouseover="showTip(event, 'fs15', 307)" class="i">string</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 308)" onmouseover="showTip(event, 'fs14', 308)" class="i">int</span> <span onmouseout="hideTip(event, 'fs68', 309)" onmouseover="showTip(event, 'fs68', 309)" class="i">list</span>) <span class="o">></span><span class="o">></span> (<span onmouseout="hideTip(event, 'fs14', 310)" onmouseover="showTip(event, 'fs14', 310)" class="i">int</span> <span onmouseout="hideTip(event, 'fs68', 311)" onmouseover="showTip(event, 'fs68', 311)" class="i">list</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs14', 312)" onmouseover="showTip(event, 'fs14', 312)" class="i">int</span>)
</code></pre></td>
</tr>
</table>
<p>and we just get a <code>string -> int</code> back.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs112', 313)" onmouseover="showTip(event, 'fs112', 313)" class="f">strToSum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs91', 314)" onmouseover="showTip(event, 'fs91', 314)" class="f">parseInts</span> <span class="o">></span><span class="o">></span> <span onmouseout="hideTip(event, 'fs98', 315)" onmouseover="showTip(event, 'fs98', 315)" class="f">sumList</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs113', 316)" onmouseover="showTip(event, 'fs113', 316)" class="i">result</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs112', 317)" onmouseover="showTip(event, 'fs112', 317)" class="f">strToSum</span> <span class="s">"1,2,3,4,5"</span>
</code></pre></td>
</tr>
</table>
<p>So we can easily create new functions out of smaller functions. This is the essence of <em>functional programming</em>.
We have <em>immutable data-types</em> that gets transformed from one type to another. And we compose functions
together to create new functions. Note that we also could create such a <code>compose</code> function in C#.
But because of a lack of some features in C#, such a function is less practical as it seems.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">public</span> <span class="k">static</span> Func<A, C> Compose<A, B, C>(Func<A, B> f, Func<B, C> g) {
<span class="k">return</span> input <span class="o">=</span><span class="o">></span> g(f(input));
}
</code></pre></td></tr></table>
<p>But it is can help to understand what <em>composition</em> means.</p>
<p>The remaining part is now <em>Piping</em> that is used more often in F#. Piping can be compared with Linux/Bash
Pipes. For example in Bash you can do stuff like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip"><code lang="console">cat file.txt | grep "foo" | sort
</code></pre></td></tr></table>
<p>It basically means that it prints out the file <em>file.txt</em> line by line. The output is passed into <code>grep "foo"</code>
that only shows the line that contains a <code>foo</code>. And that output is finally sorted by <code>sort</code>. F# has the operator
<code>|></code> to provide such a functionality. <code>|></code> just means, pass the value on the left to the function on the right.
So instead of</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span onmouseout="hideTip(event, 'fs112', 318)" onmouseover="showTip(event, 'fs112', 318)" class="f">strToSum</span> <span class="s">"1,2,3,4,5"</span>
</code></pre></td>
</tr>
</table>
<p>We also could write</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="s">"1,2,3,4,5"</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs112', 319)" onmouseover="showTip(event, 'fs112', 319)" class="f">strToSum</span>
</code></pre></td>
</tr>
</table>
<p>Having this kind of Piping means we also could have written <code>strToSum</code> like this</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs114', 320)" onmouseover="showTip(event, 'fs114', 320)" class="f">strToStum</span> <span onmouseout="hideTip(event, 'fs115', 321)" onmouseover="showTip(event, 'fs115', 321)" class="i">x</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs115', 322)" onmouseover="showTip(event, 'fs115', 322)" class="i">x</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs91', 323)" onmouseover="showTip(event, 'fs91', 323)" class="f">parseInts</span> <span class="o">|></span> <span onmouseout="hideTip(event, 'fs98', 324)" onmouseover="showTip(event, 'fs98', 324)" class="f">sumList</span>
</code></pre></td>
</tr>
</table>
<p>instead of</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs112', 325)" onmouseover="showTip(event, 'fs112', 325)" class="f">strToSum</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs91', 326)" onmouseover="showTip(event, 'fs91', 326)" class="f">parseInts</span> <span class="o">></span><span class="o">></span> <span onmouseout="hideTip(event, 'fs98', 327)" onmouseover="showTip(event, 'fs98', 327)" class="f">sumList</span>
</code></pre></td>
</tr>
</table>
<p>Both styles means the same. In the <code>|></code> we just provide the input argument explcitily. <code>x |> parseInts |> sumList</code>
also can be read as. Take argument <code>x</code> and pass it to the <code>parseInts</code> function. The result of <code>parseInts</code> is then
passed into the <code>sumList</code> function. This kind of style is often what you see with <code>List</code> manipulations.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
<span class="l">9: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs116', 328)" onmouseover="showTip(event, 'fs116', 328)" class="f">numbers</span> <span onmouseout="hideTip(event, 'fs99', 329)" onmouseover="showTip(event, 'fs99', 329)" class="i">xs</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs99', 330)" onmouseover="showTip(event, 'fs99', 330)" class="i">xs</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs96', 331)" onmouseover="showTip(event, 'fs96', 331)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs117', 332)" onmouseover="showTip(event, 'fs117', 332)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs20', 333)" onmouseover="showTip(event, 'fs20', 333)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs20', 334)" onmouseover="showTip(event, 'fs20', 334)" class="i">x</span> <span class="o">+</span> <span class="n">3</span>) <span class="c">// Add +3 to every element</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs96', 335)" onmouseover="showTip(event, 'fs96', 335)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs117', 336)" onmouseover="showTip(event, 'fs117', 336)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs20', 337)" onmouseover="showTip(event, 'fs20', 337)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs20', 338)" onmouseover="showTip(event, 'fs20', 338)" class="i">x</span> <span class="o">*</span> <span class="n">2</span>) <span class="c">// Multiply every element by 2</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs96', 339)" onmouseover="showTip(event, 'fs96', 339)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs118', 340)" onmouseover="showTip(event, 'fs118', 340)" class="f">filter</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs20', 341)" onmouseover="showTip(event, 'fs20', 341)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs20', 342)" onmouseover="showTip(event, 'fs20', 342)" class="i">x</span> <span class="o">%</span> <span class="n">2</span> <span class="o">=</span> <span class="n">0</span>) <span class="c">// Only pick even elements</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs96', 343)" onmouseover="showTip(event, 'fs96', 343)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs118', 344)" onmouseover="showTip(event, 'fs118', 344)" class="f">filter</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs20', 345)" onmouseover="showTip(event, 'fs20', 345)" class="i">x</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs20', 346)" onmouseover="showTip(event, 'fs20', 346)" class="i">x</span> <span class="o">></span> <span class="n">10</span>) <span class="c">// Only pick elements greater than 10</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs96', 347)" onmouseover="showTip(event, 'fs96', 347)" class="t">List</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs119', 348)" onmouseover="showTip(event, 'fs119', 348)" class="f">take</span> <span class="n">10</span> <span class="c">// Only take 10 Elements</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs120', 349)" onmouseover="showTip(event, 'fs120', 349)" class="i">result</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs116', 350)" onmouseover="showTip(event, 'fs116', 350)" class="f">numbers</span> [<span class="n">1..</span><span class="n">100</span>] <span class="c">// [12; 14; 16; 18; 20; 22; 24; 26; 28; 30]</span>
</code></pre></td>
</tr>
</table>
<p>This style of composing is also what you see with LINQ in C# or Java 8 Stream interface. The above
code could also be implemented in this way with C# LINQ feature.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="csharp"><span class="k">public</span> <span class="k">static</span> IEnumerable<<span class="k">int</span>> Numbers(IEnumerable<<span class="k">int</span>> xs) {
<span class="k">return</span> xs
.Select(x <span class="o">=</span><span class="o">></span> x <span class="o">+</span> <span class="n">3</span>)
.Select(x <span class="o">=</span><span class="o">></span> x <span class="o">*</span> <span class="n">2</span>)
.Where(x <span class="o">=</span><span class="o">></span> x <span class="o">%</span> <span class="n">2</span> <span class="o">=</span><span class="o">=</span> <span class="n">0</span>)
.Where(x <span class="o">=</span><span class="o">></span> x <span class="o">></span> <span class="n">10</span>)
.Take(<span class="n">10</span>);
}
<span class="k">var</span> result <span class="o">=</span> Numbers(Enumerable.Range(<span class="n">1</span>,<span class="n">100</span>));
</code></pre></td></tr></table>
<h2>Final Note</h2>
<p>I covered quite a lot of topics. But I hope that now <em>functional languages</em> looks less scary to you. By understanding
all of the topics you basically already made a big step in understanding F# in general.</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">type DateTime = System.DateTime<br /><br />Full name: Main.DateTime</div>
<div class="tip" id="fs3">namespace System</div>
<div class="tip" id="fs4">Multiple items<br />type DateTime =<br />  struct<br />    new : ticks:int64 -> DateTime + 10 overloads<br />    member Add : value:TimeSpan -> DateTime<br />    member AddDays : value:float -> DateTime<br />    member AddHours : value:float -> DateTime<br />    member AddMilliseconds : value:float -> DateTime<br />    member AddMinutes : value:float -> DateTime<br />    member AddMonths : months:int -> DateTime<br />    member AddSeconds : value:float -> DateTime<br />    member AddTicks : value:int64 -> DateTime<br />    member AddYears : value:int -> DateTime<br />    ...<br />  end<br /><br />Full name: System.DateTime<br /><br />--------------------<br />System.DateTime()<br />   <em>(+0 other overloads)</em><br />System.DateTime(ticks: int64) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(ticks: int64, kind: System.DateTimeKind) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, calendar: System.Globalization.Calendar) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: System.DateTimeKind) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: System.Globalization.Calendar) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit<br />   <em>(+0 other overloads)</em><br />System.DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: System.DateTimeKind) : unit<br />   <em>(+0 other overloads)</em></div>
<div class="tip" id="fs5">type StringBuilder = System.Text.StringBuilder<br /><br />Full name: Main.StringBuilder</div>
<div class="tip" id="fs6">namespace System.Text</div>
<div class="tip" id="fs7">Multiple items<br />type StringBuilder =<br />  new : unit -> StringBuilder + 5 overloads<br />  member Append : value:string -> StringBuilder + 18 overloads<br />  member AppendFormat : format:string * arg0:obj -> StringBuilder + 4 overloads<br />  member AppendLine : unit -> StringBuilder + 1 overload<br />  member Capacity : int with get, set<br />  member Chars : int -> char with get, set<br />  member Clear : unit -> StringBuilder<br />  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit<br />  member EnsureCapacity : capacity:int -> int<br />  member Equals : sb:StringBuilder -> bool<br />  ...<br /><br />Full name: System.Text.StringBuilder<br /><br />--------------------<br />System.Text.StringBuilder() : unit<br />System.Text.StringBuilder(capacity: int) : unit<br />System.Text.StringBuilder(value: string) : unit<br />System.Text.StringBuilder(value: string, capacity: int) : unit<br />System.Text.StringBuilder(capacity: int, maxCapacity: int) : unit<br />System.Text.StringBuilder(value: string, startIndex: int, length: int, capacity: int) : unit</div>
<div class="tip" id="fs8">Multiple items<br />type Person =<br />  new : name:string -> Person<br />  member Name : string<br />  member Name : string with set<br /><br />Full name: Main.Person<br /><br />--------------------<br />new : name:string -> Person</div>
<div class="tip" id="fs9">val name : string</div>
<div class="tip" id="fs10">val set : elements:seq<'T> -> Set<'T> (requires comparison)<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.set</div>
<div class="tip" id="fs11">val num : int<br /><br />Full name: Main.num</div>
<div class="tip" id="fs12">val name : string<br /><br />Full name: Main.name</div>
<div class="tip" id="fs13">val person : Person<br /><br />Full name: Main.person</div>
<div class="tip" id="fs14">Multiple items<br />val int : value:'T -> int (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.int<br /><br />--------------------<br />type int = int32<br /><br />Full name: Microsoft.FSharp.Core.int<br /><br />--------------------<br />type int<'Measure> = int<br /><br />Full name: Microsoft.FSharp.Core.int<_></div>
<div class="tip" id="fs15">Multiple items<br />val string : value:'T -> string<br /><br />Full name: Microsoft.FSharp.Core.Operators.string<br /><br />--------------------<br />type string = System.String<br /><br />Full name: Microsoft.FSharp.Core.string</div>
<div class="tip" id="fs16">val mutable num : int<br /><br />Full name: Main.num</div>
<div class="tip" id="fs17">val mutable name : string<br /><br />Full name: Main.name</div>
<div class="tip" id="fs18">val mutable person : Person<br /><br />Full name: Main.person</div>
<div class="tip" id="fs19">val add : x:int -> y:int -> int<br /><br />Full name: introductioninfsharp.MyOperations.add</div>
<div class="tip" id="fs20">val x : int</div>
<div class="tip" id="fs21">val y : int</div>
<div class="tip" id="fs22">module MyOperations<br /><br />from introductioninfsharp</div>
<div class="tip" id="fs23">val result : int<br /><br />Full name: introductioninfsharp.result</div>
<div class="tip" id="fs24">val someFunction : input:'a -> 'a0<br /><br />Full name: introductioninfsharp.someFunction</div>
<div class="tip" id="fs25">val input : 'a</div>
<div class="tip" id="fs26">val someFunction : ('b -> int -> int)</div>
<div class="tip" id="fs27">val input : 'b</div>
<div class="tip" id="fs28">val position : int * int * int<br /><br />Full name: Main.position</div>
<div class="tip" id="fs29">val x : int<br /><br />Full name: Main.x</div>
<div class="tip" id="fs30">val y : int<br /><br />Full name: Main.y</div>
<div class="tip" id="fs31">val z : int<br /><br />Full name: Main.z</div>
<div class="tip" id="fs32">val someFunction : x:int -> int * int<br /><br />Full name: Main.someFunction</div>
<div class="tip" id="fs33">val result : int * int<br /><br />Full name: Main.result</div>
<div class="tip" id="fs34">type Human =<br />  {Id: int;<br />   FirstName: string;<br />   LastName: string;<br />   Born: DateTime;}<br /><br />Full name: Main.Human</div>
<div class="tip" id="fs35">Human.Id: int</div>
<div class="tip" id="fs36">Human.FirstName: string</div>
<div class="tip" id="fs37">Human.LastName: string</div>
<div class="tip" id="fs38">Human.Born: DateTime</div>
<div class="tip" id="fs39">val me : Human<br /><br />Full name: Main.me</div>
<div class="tip" id="fs40">val age : int<br /><br />Full name: Main.age</div>
<div class="tip" id="fs41">property System.DateTime.Today: System.DateTime</div>
<div class="tip" id="fs42">property System.DateTime.Year: int</div>
<div class="tip" id="fs43">val printfn : format:Printf.TextWriterFormat<'T> -> 'T<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn</div>
<div class="tip" id="fs44">val newMe : Human<br /><br />Full name: Main.newMe</div>
<div class="tip" id="fs45">type Attributes =<br />  {Strength: int;<br />   Dexterity: int;<br />   Intelligence: int;<br />   Vitality: int;}<br /><br />Full name: Main.Attributes</div>
<div class="tip" id="fs46">Attributes.Strength: int</div>
<div class="tip" id="fs47">Attributes.Dexterity: int</div>
<div class="tip" id="fs48">Attributes.Intelligence: int</div>
<div class="tip" id="fs49">Attributes.Vitality: int</div>
<div class="tip" id="fs50">type CaharacterSheet =<br />  {Name: string;<br />   Attribute: Attributes;}<br /><br />Full name: Main.CaharacterSheet</div>
<div class="tip" id="fs51">CaharacterSheet.Name: string</div>
<div class="tip" id="fs52">CaharacterSheet.Attribute: Attributes</div>
<div class="tip" id="fs53">val warrior : CaharacterSheet<br /><br />Full name: Main.warrior</div>
<div class="tip" id="fs54">type Payment =<br />  | Cash<br />  | PayPal of string<br />  | CreditCard of string<br /><br />Full name: Main.Payment</div>
<div class="tip" id="fs55">union case Payment.Cash: Payment</div>
<div class="tip" id="fs56">union case Payment.PayPal: string -> Payment</div>
<div class="tip" id="fs57">union case Payment.CreditCard: string -> Payment</div>
<div class="tip" id="fs58">val inform : payment:Payment -> unit<br /><br />Full name: Main.inform</div>
<div class="tip" id="fs59">val payment : Payment</div>
<div class="tip" id="fs60">val email : string</div>
<div class="tip" id="fs61">val no : string</div>
<div class="tip" id="fs62">type Markdown =<br />  | NewLine<br />  | Literal of string<br />  | Bold of string<br />  | InlineCode of string<br />  | Block of Markdown list<br /><br />Full name: Main.Markdown</div>
<div class="tip" id="fs63">union case Markdown.NewLine: Markdown</div>
<div class="tip" id="fs64">Multiple items<br />union case Markdown.Literal: string -> Markdown<br /><br />--------------------<br />type LiteralAttribute =<br />  inherit Attribute<br />  new : unit -> LiteralAttribute<br /><br />Full name: Microsoft.FSharp.Core.LiteralAttribute<br /><br />--------------------<br />new : unit -> LiteralAttribute</div>
<div class="tip" id="fs65">union case Markdown.Bold: string -> Markdown</div>
<div class="tip" id="fs66">union case Markdown.InlineCode: string -> Markdown</div>
<div class="tip" id="fs67">union case Markdown.Block: Markdown list -> Markdown</div>
<div class="tip" id="fs68">type 'T list = List<'T><br /><br />Full name: Microsoft.FSharp.Collections.list<_></div>
<div class="tip" id="fs69">val document : Markdown<br /><br />Full name: Main.document</div>
<div class="tip" id="fs70">val produceHtml : markdown:Markdown -> sb:StringBuilder -> unit<br /><br />Full name: Main.produceHtml</div>
<div class="tip" id="fs71">val markdown : Markdown</div>
<div class="tip" id="fs72">val sb : StringBuilder</div>
<div class="tip" id="fs73">System.Text.StringBuilder.Append(value: char []) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: obj) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: uint64) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: uint32) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: uint16) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: decimal) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: float) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: float32) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: int64) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em><br />System.Text.StringBuilder.Append(value: int) : System.Text.StringBuilder<br />   <em>(+0 other overloads)</em></div>
<div class="tip" id="fs74">val ignore : value:'T -> unit<br /><br />Full name: Microsoft.FSharp.Core.Operators.ignore</div>
<div class="tip" id="fs75">val str : string</div>
<div class="tip" id="fs76">System.Text.StringBuilder.AppendFormat(format: string, [<System.ParamArray>] args: obj []) : System.Text.StringBuilder<br />System.Text.StringBuilder.AppendFormat(format: string, arg0: obj) : System.Text.StringBuilder<br />System.Text.StringBuilder.AppendFormat(provider: System.IFormatProvider, format: string, [<System.ParamArray>] args: obj []) : System.Text.StringBuilder<br />System.Text.StringBuilder.AppendFormat(format: string, arg0: obj, arg1: obj) : System.Text.StringBuilder<br />System.Text.StringBuilder.AppendFormat(format: string, arg0: obj, arg1: obj, arg2: obj) : System.Text.StringBuilder</div>
<div class="tip" id="fs77">val code : string</div>
<div class="tip" id="fs78">val markdown : Markdown list</div>
<div class="tip" id="fs79">val x : Markdown</div>
<div class="tip" id="fs80">val html : System.Text.StringBuilder<br /><br />Full name: Main.html</div>
<div class="tip" id="fs81">System.Text.StringBuilder.ToString() : string<br />System.Text.StringBuilder.ToString(startIndex: int, length: int) : string</div>
<div class="tip" id="fs82">val data : int list</div>
<div class="tip" id="fs83">val data : (int * int * int * int) list</div>
<div class="tip" id="fs84">val oneMore : int list</div>
<div class="tip" id="fs85">type unit = Unit<br /><br />Full name: Microsoft.FSharp.Core.unit</div>
<div class="tip" id="fs86">Multiple items<br />module String<br /><br />from Microsoft.FSharp.Core<br /><br />--------------------<br />type String = System.String<br /><br />Full name: Main.String</div>
<div class="tip" id="fs87">Multiple items<br />type String =<br />  new : value:char -> string + 7 overloads<br />  member Chars : int -> char<br />  member Clone : unit -> obj<br />  member CompareTo : value:obj -> int + 1 overload<br />  member Contains : value:string -> bool<br />  member CopyTo : sourceIndex:int * destination:char[] * destinationIndex:int * count:int -> unit<br />  member EndsWith : value:string -> bool + 2 overloads<br />  member Equals : obj:obj -> bool + 2 overloads<br />  member GetEnumerator : unit -> CharEnumerator<br />  member GetHashCode : unit -> int<br />  ...<br /><br />Full name: System.String<br /><br />--------------------<br />System.String(value: nativeptr<char>) : unit<br />System.String(value: nativeptr<sbyte>) : unit<br />System.String(value: char []) : unit<br />System.String(c: char, count: int) : unit<br />System.String(value: nativeptr<char>, startIndex: int, length: int) : unit<br />System.String(value: nativeptr<sbyte>, startIndex: int, length: int) : unit<br />System.String(value: char [], startIndex: int, length: int) : unit<br />System.String(value: nativeptr<sbyte>, startIndex: int, length: int, enc: System.Text.Encoding) : unit</div>
<div class="tip" id="fs88">val parseInt : str:string -> int<br /><br />Full name: Main.parseInt</div>
<div class="tip" id="fs89">type Int32 =<br />  struct<br />    member CompareTo : value:obj -> int + 1 overload<br />    member Equals : obj:obj -> bool + 1 overload<br />    member GetHashCode : unit -> int<br />    member GetTypeCode : unit -> TypeCode<br />    member ToString : unit -> string + 3 overloads<br />    static val MaxValue : int<br />    static val MinValue : int<br />    static member Parse : s:string -> int + 3 overloads<br />    static member TryParse : s:string * result:int -> bool + 1 overload<br />  end<br /><br />Full name: System.Int32</div>
<div class="tip" id="fs90">System.Int32.Parse(s: string) : int<br />System.Int32.Parse(s: string, provider: System.IFormatProvider) : int<br />System.Int32.Parse(s: string, style: System.Globalization.NumberStyles) : int<br />System.Int32.Parse(s: string, style: System.Globalization.NumberStyles, provider: System.IFormatProvider) : int</div>
<div class="tip" id="fs91">val parseInts : str:String -> int list<br /><br />Full name: Main.parseInts</div>
<div class="tip" id="fs92">val str : String</div>
<div class="tip" id="fs93">System.String.Split([<System.ParamArray>] separator: char []) : string []<br />System.String.Split(separator: string [], options: System.StringSplitOptions) : string []<br />System.String.Split(separator: char [], options: System.StringSplitOptions) : string []<br />System.String.Split(separator: char [], count: int) : string []<br />System.String.Split(separator: string [], count: int, options: System.StringSplitOptions) : string []<br />System.String.Split(separator: char [], count: int, options: System.StringSplitOptions) : string []</div>
<div class="tip" id="fs94">module Array<br /><br />from Microsoft.FSharp.Collections</div>
<div class="tip" id="fs95">val map : mapping:('T -> 'U) -> array:'T [] -> 'U []<br /><br />Full name: Microsoft.FSharp.Collections.Array.map</div>
<div class="tip" id="fs96">Multiple items<br />module List<br /><br />from Microsoft.FSharp.Collections<br /><br />--------------------<br />type List<'T> =<br />  | ( [] )<br />  | ( :: ) of Head: 'T * Tail: 'T list<br />  interface IEnumerable<br />  interface IEnumerable<'T><br />  member GetSlice : startIndex:int option * endIndex:int option -> 'T list<br />  member Head : 'T<br />  member IsEmpty : bool<br />  member Item : index:int -> 'T with get<br />  member Length : int<br />  member Tail : 'T list<br />  static member Cons : head:'T * tail:'T list -> 'T list<br />  static member Empty : 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List<_></div>
<div class="tip" id="fs97">val ofArray : array:'T [] -> 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.ofArray</div>
<div class="tip" id="fs98">val sumList : xs:int list -> int<br /><br />Full name: Main.sumList</div>
<div class="tip" id="fs99">val xs : int list</div>
<div class="tip" id="fs100">val sum : list:'T list -> 'T (requires member ( + ) and member get_Zero)<br /><br />Full name: Microsoft.FSharp.Collections.List.sum</div>
<div class="tip" id="fs101">val nums : int list<br /><br />Full name: Main.nums</div>
<div class="tip" id="fs102">val sum : int<br /><br />Full name: Main.sum</div>
<div class="tip" id="fs103">val strToSum : stringList:String -> int<br /><br />Full name: Main.strToSum</div>
<div class="tip" id="fs104">val stringList : String</div>
<div class="tip" id="fs105">val nums : int list</div>
<div class="tip" id="fs106">val sum : int</div>
<div class="tip" id="fs107">val compose : f:('a -> 'b) -> g:('b -> 'c) -> x:'a -> 'c<br /><br />Full name: Main.compose</div>
<div class="tip" id="fs108">val f : ('a -> 'b)</div>
<div class="tip" id="fs109">val g : ('b -> 'c)</div>
<div class="tip" id="fs110">val x : 'a</div>
<div class="tip" id="fs111">val z : 'a</div>
<div class="tip" id="fs112">val strToSum : (String -> int)<br /><br />Full name: Main.strToSum</div>
<div class="tip" id="fs113">val result : int<br /><br />Full name: Main.result</div>
<div class="tip" id="fs114">val strToStum : x:String -> int<br /><br />Full name: Main.strToStum</div>
<div class="tip" id="fs115">val x : String</div>
<div class="tip" id="fs116">val numbers : xs:int list -> int list<br /><br />Full name: Main.numbers</div>
<div class="tip" id="fs117">val map : mapping:('T -> 'U) -> list:'T list -> 'U list<br /><br />Full name: Microsoft.FSharp.Collections.List.map</div>
<div class="tip" id="fs118">val filter : predicate:('T -> bool) -> list:'T list -> 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.filter</div>
<div class="tip" id="fs119">val take : count:int -> list:'T list -> 'T list<br /><br />Full name: Microsoft.FSharp.Collections.List.take</div>
<div class="tip" id="fs120">val result : int list<br /><br />Full name: Main.result</div>
Applying Structured Programming2016-03-09T01:00:00+00:00https://sidburn.github.io/blog/2016/03/09/applying-structured-programming<p>In my previous post about <a href="/blog/2016/03/09/structured-programming">Structured Programming</a> I
talked about that basic looping constructs, <code>fold</code> and so on are basically just still to powerful.
In the sense of readability we should try to eliminate them with more specific ones. In this post
i go through a <em>toy example</em> to show the various ways on how to refactor some code.</p>
<h2>The Toy Example</h2>
<p>Recently I had some conversation about code in a game and providing some kind of
<em>critical hit-chance</em> in a game. The typical way on how to achieve that is actually easy. Let's
assume that every attack of an player has a 16% chance to be critical. We only need to generate
a random number between 0 and 99 (or 0 to 1) and test if that number is lower than 16 (or 0.16).</p>
<p>Let's assume we want to test if that really is true. We would just generate some random numbers.
Test if that number is a critical hit. And either increase a <em>critical hit</em> variable or some
<em>normal hit</em> variable. After 1000 tries we just calculate the average and see if
we really have around 16% or around 160 hits.</p>
<h2>Solution 1</h2>
<p>Some very imperative code in F# could look like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 2)" onmouseover="showTip(event, 'fs2', 2)" class="i">rng</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 3)" onmouseover="showTip(event, 'fs3', 3)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 4)" onmouseover="showTip(event, 'fs4', 4)" class="t">Random</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 5)" onmouseover="showTip(event, 'fs5', 5)" class="f">calculateChance</span> <span onmouseout="hideTip(event, 'fs6', 6)" onmouseover="showTip(event, 'fs6', 6)" class="i">chance</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs7', 7)" onmouseover="showTip(event, 'fs7', 7)" class="v">criticalHit</span> <span class="o">=</span> <span class="n">0</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs8', 8)" onmouseover="showTip(event, 'fs8', 8)" class="v">normalHit</span> <span class="o">=</span> <span class="n">0</span>
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs9', 9)" onmouseover="showTip(event, 'fs9', 9)" class="i">i</span> <span class="k">in</span> <span class="n">1</span> <span class="o">..</span> <span class="n">1000</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs10', 10)" onmouseover="showTip(event, 'fs10', 10)" class="i">random</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 11)" onmouseover="showTip(event, 'fs2', 11)" class="i">rng</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 12)" onmouseover="showTip(event, 'fs11', 12)" class="f">Next</span>(<span class="n">0</span>, <span class="n">100</span>)
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs10', 13)" onmouseover="showTip(event, 'fs10', 13)" class="i">random</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs6', 14)" onmouseover="showTip(event, 'fs6', 14)" class="i">chance</span> <span class="k">then</span>
<span onmouseout="hideTip(event, 'fs7', 15)" onmouseover="showTip(event, 'fs7', 15)" class="v">criticalHit</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs7', 16)" onmouseover="showTip(event, 'fs7', 16)" class="v">criticalHit</span> <span class="o">+</span> <span class="n">1</span>
<span class="k">else</span>
<span onmouseout="hideTip(event, 'fs8', 17)" onmouseover="showTip(event, 'fs8', 17)" class="v">normalHit</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs8', 18)" onmouseover="showTip(event, 'fs8', 18)" class="v">normalHit</span> <span class="o">+</span> <span class="n">1</span>
<span onmouseout="hideTip(event, 'fs7', 19)" onmouseover="showTip(event, 'fs7', 19)" class="v">criticalHit</span>, <span onmouseout="hideTip(event, 'fs8', 20)" onmouseover="showTip(event, 'fs8', 20)" class="v">normalHit</span>
</code></pre></td>
</tr>
</table>
<p>Testing our code would look something like this.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 21)" onmouseover="showTip(event, 'fs12', 21)" class="f">percentage</span> <span onmouseout="hideTip(event, 'fs13', 22)" onmouseover="showTip(event, 'fs13', 22)" class="i">x</span> <span onmouseout="hideTip(event, 'fs14', 23)" onmouseover="showTip(event, 'fs14', 23)" class="i">y</span> <span class="o">=</span> <span class="n">100.0</span> <span class="o">/</span> (<span onmouseout="hideTip(event, 'fs13', 24)" onmouseover="showTip(event, 'fs13', 24)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs14', 25)" onmouseover="showTip(event, 'fs14', 25)" class="i">y</span>) <span class="o">*</span> <span onmouseout="hideTip(event, 'fs13', 26)" onmouseover="showTip(event, 'fs13', 26)" class="i">x</span>
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs9', 27)" onmouseover="showTip(event, 'fs9', 27)" class="i">i</span> <span class="k">in</span> <span class="n">1..</span><span class="n">10</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs15', 28)" onmouseover="showTip(event, 'fs15', 28)" class="i">crit</span>,<span onmouseout="hideTip(event, 'fs16', 29)" onmouseover="showTip(event, 'fs16', 29)" class="i">normal</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 30)" onmouseover="showTip(event, 'fs5', 30)" class="f">calculateChance</span> <span class="n">16</span>
<span onmouseout="hideTip(event, 'fs17', 31)" onmouseover="showTip(event, 'fs17', 31)" class="f">printfn</span> <span class="s">"Crit: </span><span class="pf">%d</span><span class="s"> Normal: </span><span class="pf">%d</span><span class="s"> Percentage: </span><span class="pf">%f</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs15', 32)" onmouseover="showTip(event, 'fs15', 32)" class="i">crit</span> <span onmouseout="hideTip(event, 'fs16', 33)" onmouseover="showTip(event, 'fs16', 33)" class="i">normal</span> (<span onmouseout="hideTip(event, 'fs12', 34)" onmouseover="showTip(event, 'fs12', 34)" class="f">percentage</span> (<span onmouseout="hideTip(event, 'fs18', 35)" onmouseover="showTip(event, 'fs18', 35)" class="f">float</span> <span onmouseout="hideTip(event, 'fs15', 36)" onmouseover="showTip(event, 'fs15', 36)" class="i">crit</span>) (<span onmouseout="hideTip(event, 'fs18', 37)" onmouseover="showTip(event, 'fs18', 37)" class="f">float</span> <span onmouseout="hideTip(event, 'fs16', 38)" onmouseover="showTip(event, 'fs16', 38)" class="i">normal</span>))
</code></pre></td>
</tr>
</table>
<p>We now getting a result like this:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip"><code lang="console">Crit: 1585 Normal: 8415 Percentage: 15.850000
Crit: 1638 Normal: 8362 Percentage: 16.380000
Crit: 1616 Normal: 8384 Percentage: 16.160000
Crit: 1603 Normal: 8397 Percentage: 16.030000
Crit: 1624 Normal: 8376 Percentage: 16.240000
Crit: 1667 Normal: 8333 Percentage: 16.670000
Crit: 1617 Normal: 8383 Percentage: 16.170000
Crit: 1639 Normal: 8361 Percentage: 16.390000
Crit: 1653 Normal: 8347 Percentage: 16.530000
Crit: 1613 Normal: 8387 Percentage: 16.130000
</code></pre></td></tr></table>
<p>Actually we now have proven that the idea works, as around 16% of our attacks are now critical.
But now let's actually look if we can improve our <code>calculateChance</code> function. As stated in the
beginning. It is a toy example, so we usually wouldn't waste any time in improving this particular
function. But by going through a toy example it can help to get the general concept on
how to improve code.</p>
<h2>Solution 2</h2>
<p>In functional programming mutable variables are actually a little bit frowned upon. So let's try
to eliminate our mutable variables by replacing our loop with recursion. Actually recursion is in that
sense just looping and you can turn any kind of loop into recursion. The difference between looping
and recursion is just what is explicit and what is implicit.</p>
<p>In Looping we implicitly move to the next step, and we can explicitly break/abort a loop. In recursion
we implicitly abort, and we have to explicitly move to the next step, by calling our function recursively.</p>
<p>Mutable variables outside of a loop turn into function parameters. This way we can turn any kind of
loop into a recursive function and eliminate mutable variables all together.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 39)" onmouseover="showTip(event, 'fs5', 39)" class="f">calculateChance</span> <span onmouseout="hideTip(event, 'fs6', 40)" onmouseover="showTip(event, 'fs6', 40)" class="i">chance</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">rec</span> <span onmouseout="hideTip(event, 'fs19', 41)" onmouseover="showTip(event, 'fs19', 41)" class="f">loop</span> <span onmouseout="hideTip(event, 'fs20', 42)" onmouseover="showTip(event, 'fs20', 42)" class="i">count</span> <span onmouseout="hideTip(event, 'fs21', 43)" onmouseover="showTip(event, 'fs21', 43)" class="i">criticalHit</span> <span onmouseout="hideTip(event, 'fs22', 44)" onmouseover="showTip(event, 'fs22', 44)" class="i">normalHit</span> <span class="o">=</span>
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs20', 45)" onmouseover="showTip(event, 'fs20', 45)" class="i">count</span> <span class="o"><</span> <span class="n">1000</span> <span class="k">then</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs10', 46)" onmouseover="showTip(event, 'fs10', 46)" class="i">random</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 47)" onmouseover="showTip(event, 'fs2', 47)" class="i">rng</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 48)" onmouseover="showTip(event, 'fs11', 48)" class="f">Next</span>(<span class="n">0</span>,<span class="n">100</span>)
<span class="k">match</span> <span onmouseout="hideTip(event, 'fs10', 49)" onmouseover="showTip(event, 'fs10', 49)" class="i">random</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs6', 50)" onmouseover="showTip(event, 'fs6', 50)" class="i">chance</span> <span class="k">with</span>
| <span class="k">false</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 51)" onmouseover="showTip(event, 'fs19', 51)" class="f">loop</span> (<span onmouseout="hideTip(event, 'fs20', 52)" onmouseover="showTip(event, 'fs20', 52)" class="i">count</span><span class="o">+</span><span class="n">1</span>) <span onmouseout="hideTip(event, 'fs21', 53)" onmouseover="showTip(event, 'fs21', 53)" class="i">criticalHit</span> (<span onmouseout="hideTip(event, 'fs22', 54)" onmouseover="showTip(event, 'fs22', 54)" class="i">normalHit</span><span class="o">+</span><span class="n">1</span>)
| <span class="k">true</span> <span class="k">-></span> <span onmouseout="hideTip(event, 'fs19', 55)" onmouseover="showTip(event, 'fs19', 55)" class="f">loop</span> (<span onmouseout="hideTip(event, 'fs20', 56)" onmouseover="showTip(event, 'fs20', 56)" class="i">count</span><span class="o">+</span><span class="n">1</span>) (<span onmouseout="hideTip(event, 'fs21', 57)" onmouseover="showTip(event, 'fs21', 57)" class="i">criticalHit</span><span class="o">+</span><span class="n">1</span>) <span onmouseout="hideTip(event, 'fs22', 58)" onmouseover="showTip(event, 'fs22', 58)" class="i">normalHit</span>
<span class="k">else</span>
<span onmouseout="hideTip(event, 'fs21', 59)" onmouseover="showTip(event, 'fs21', 59)" class="i">criticalHit</span>, <span onmouseout="hideTip(event, 'fs22', 60)" onmouseover="showTip(event, 'fs22', 60)" class="i">normalHit</span>
<span onmouseout="hideTip(event, 'fs19', 61)" onmouseover="showTip(event, 'fs19', 61)" class="f">loop</span> <span class="n">0</span> <span class="n">0</span> <span class="n">0</span>
</code></pre></td>
</tr>
</table>
<p>We now eliminated all mutable variables and now provided an inner recursive function that replaces
our loop. On top of it i replaced the inner <code>if</code> check on <code>random < chance</code> with pattern-matching.
This way it is easier to see the difference.</p>
<p>Either in both ways we will call <code>loop</code> again, but with an increment <code>count</code>. If <code>random < change</code>
is <code>false</code> we have a normal hit, so we increase <code>normalHit</code> by one, otherwise we increase <code>criticalHit</code>
by one.</p>
<p>We continue our recursive call as long we have <code>count < 1000</code>. But as soon that condition is <code>false</code>
we end up with just <code>criticalHit, normalHit</code> that will return both variables as a tuple.</p>
<p>The question overall is. Is that version better as <em>Solution 1</em>?</p>
<p>Well it depends. We eliminated the mutable variables, but actually at least I am someone that
has nothing against mutable variables in a limited scope. If you are a programmer that primarily
uses an imperative language and are used to looping then you will probably prefer Solution 1. If you
are in the state of learning <em>functional programing</em> you should try to replace looping
constructs in this kind of way to get used to it. This is especially important for the later Solutions
we will look at. If you are used to this, like me, you will probably not find the recursive version
any harder to understand as the looping example.</p>
<p>So what is with Structured Programming? Did we replace a powerful construct with a less powerful
construct? At that moment, no we didn't. Recursion is just as much powerful as looping. The funny
part. The compiler will turn such kind of tail-recursion into a loop when compiled. That's also
the reason why functional programmers names such inner recursive functions just <code>loop</code>.</p>
<p>So was our transformation into <em>Solution 2</em> wasteful? Not really, that now leads to <em>Solution 3</em></p>
<h2>Solution 3</h2>
<p>Once we have eliminated all kinds of mutable variables we end up with a recursive function that
just loops. Our function takes some additional variables like <code>count</code>, <code>criticalHit</code> and <code>normalHit</code>
as it's state. What we really have is a looping construct with just an accumulator. But wait. That's
exactly what <code>fold</code> is about! The question that starts to beg is. Can we replace <em>Solution 2</em> somehow
by using a <code>fold</code>?</p>
<p>The answer is <em>yes</em>. But which kind of <code>fold</code> do we need? Or in other words, over what exactly do
we loop? We don't loop over a data-structure like an <code>Array</code> or <code>List</code>. So what is it that
we are looping over?</p>
<p>When we examine our code we could say we loop over <code>count</code>. But that isn't true. Our
<code>count</code> is just there so we know when to end the looping. We really are looping over the
<code>rng.Next(0,100)</code> call. We only need the <code>count</code> because that is an infinite sequence.
But that actually answers our question. Let's create a <code>seq</code> that just returns an
infinite sequence of random numbers.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 62)" onmouseover="showTip(event, 'fs2', 62)" class="i">rng</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 63)" onmouseover="showTip(event, 'fs3', 63)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 64)" onmouseover="showTip(event, 'fs4', 64)" class="t">Random</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs23', 65)" onmouseover="showTip(event, 'fs23', 65)" class="f">randomSeq</span> <span onmouseout="hideTip(event, 'fs24', 66)" onmouseover="showTip(event, 'fs24', 66)" class="i">min</span> <span onmouseout="hideTip(event, 'fs25', 67)" onmouseover="showTip(event, 'fs25', 67)" class="i">max</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs26', 68)" onmouseover="showTip(event, 'fs26', 68)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 69)" onmouseover="showTip(event, 'fs27', 69)" class="f">initInfinite</span> (<span class="k">fun</span> _ <span class="k">-></span> <span onmouseout="hideTip(event, 'fs2', 70)" onmouseover="showTip(event, 'fs2', 70)" class="i">rng</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 71)" onmouseover="showTip(event, 'fs11', 71)" class="f">Next</span>(<span onmouseout="hideTip(event, 'fs24', 72)" onmouseover="showTip(event, 'fs24', 72)" class="i">min</span>, <span onmouseout="hideTip(event, 'fs25', 73)" onmouseover="showTip(event, 'fs25', 73)" class="i">max</span>))
</code></pre></td>
</tr>
</table>
<p>Note that I'm defining <code>rng</code> outside the function. Instantiating a <code>System.Random</code> inside the function
and calling <code>randomSeq</code> in short time-interval would otherwise lead to a RNG with the same seed.
Once we have our Random Sequence it also becomes clearer what our <code>count</code> was before. We just <code>take</code>
the amount of randoms we need from our infinite sequence. After that, we only need to transform what is
left into a <code>fold</code> call.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
<span class="l">6: </span>
<span class="l">7: </span>
<span class="l">8: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 74)" onmouseover="showTip(event, 'fs5', 74)" class="f">calculateChance</span> <span onmouseout="hideTip(event, 'fs6', 75)" onmouseover="showTip(event, 'fs6', 75)" class="i">chance</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs23', 76)" onmouseover="showTip(event, 'fs23', 76)" class="f">randomSeq</span> <span class="n">0</span> <span class="n">100</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 77)" onmouseover="showTip(event, 'fs26', 77)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs28', 78)" onmouseover="showTip(event, 'fs28', 78)" class="f">take</span> <span class="n">1000</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 79)" onmouseover="showTip(event, 'fs26', 79)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs29', 80)" onmouseover="showTip(event, 'fs29', 80)" class="f">fold</span> (<span class="k">fun</span> (<span onmouseout="hideTip(event, 'fs21', 81)" onmouseover="showTip(event, 'fs21', 81)" class="i">criticalHit</span>,<span onmouseout="hideTip(event, 'fs22', 82)" onmouseover="showTip(event, 'fs22', 82)" class="i">normalHit</span>) <span onmouseout="hideTip(event, 'fs10', 83)" onmouseover="showTip(event, 'fs10', 83)" class="i">random</span> <span class="k">-></span>
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs10', 84)" onmouseover="showTip(event, 'fs10', 84)" class="i">random</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs6', 85)" onmouseover="showTip(event, 'fs6', 85)" class="i">chance</span>
<span class="k">then</span> (<span onmouseout="hideTip(event, 'fs21', 86)" onmouseover="showTip(event, 'fs21', 86)" class="i">criticalHit</span><span class="o">+</span><span class="n">1</span>),<span onmouseout="hideTip(event, 'fs22', 87)" onmouseover="showTip(event, 'fs22', 87)" class="i">normalHit</span>
<span class="k">else</span> <span onmouseout="hideTip(event, 'fs21', 88)" onmouseover="showTip(event, 'fs21', 88)" class="i">criticalHit</span>,(<span onmouseout="hideTip(event, 'fs22', 89)" onmouseover="showTip(event, 'fs22', 89)" class="i">normalHit</span><span class="o">+</span><span class="n">1</span>)
) (<span class="n">0</span>,<span class="n">0</span>)
</code></pre></td>
</tr>
</table>
<p>Looking at the current Solution i think we made our first improvements to our code. At first we
created a <code>randomSeq</code>. A sequence out of random can be helpful in many other places. <code>Seq.take 1000</code>
makes it clear that we just fetch <code>1000</code> random numbers from it. And after having those we use <code>fold</code>.</p>
<p>Now, our <code>fold</code> only contains the real logic. It just checks whether our random is a criticalHit or not
and we create our new state from it.</p>
<p>But as stated before. <code>fold</code> is still something that we consider as <em>powerful</em>, is there a way to also
eliminate <code>fold</code>?</p>
<h2>Solution 4</h2>
<p>We actually can eliminate <code>fold</code>. But for that we need to go and look back at what we are actually
doing. What we really was interested in was the percentage if we really get the right amount of
<em>critical-hits</em> this way. What we really need is to split it into two parts. We need some function
that test whether we have a critical hit or not. We could turn it into <code>true</code> and <code>false</code> values.
But later we need to turn those somehow into a formula to calculate the average.</p>
<p>But by thinking separetely about it we easily can recognise that we can easily achive both things in
one step. By just turning a critical-hit into <code>1.0</code> and a normal hit into <code>0.0</code>. By calculating the
average we would automatically get a percentage that ranges bewteen <code>0.0</code> and <code>1.0</code>. We could multiply it by
<code>100.0</code> or we also could use <code>100.0</code> and <code>0.0</code> instead of <code>1.0</code> and <code>0.0</code>.</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
<span class="l">5: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs30', 90)" onmouseover="showTip(event, 'fs30', 90)" class="f">calculateChance</span> <span onmouseout="hideTip(event, 'fs6', 91)" onmouseover="showTip(event, 'fs6', 91)" class="i">chance</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs23', 92)" onmouseover="showTip(event, 'fs23', 92)" class="f">randomSeq</span> <span class="n">0</span> <span class="n">100</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 93)" onmouseover="showTip(event, 'fs26', 93)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs28', 94)" onmouseover="showTip(event, 'fs28', 94)" class="f">take</span> <span class="n">1000</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 95)" onmouseover="showTip(event, 'fs26', 95)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs31', 96)" onmouseover="showTip(event, 'fs31', 96)" class="f">map</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs32', 97)" onmouseover="showTip(event, 'fs32', 97)" class="i">x</span> <span class="k">-></span> <span class="k">if</span> <span onmouseout="hideTip(event, 'fs32', 98)" onmouseover="showTip(event, 'fs32', 98)" class="i">x</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs6', 99)" onmouseover="showTip(event, 'fs6', 99)" class="i">chance</span> <span class="k">then</span> <span class="n">100.0</span> <span class="k">else</span> <span class="n">0.0</span>)
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 100)" onmouseover="showTip(event, 'fs26', 100)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs33', 101)" onmouseover="showTip(event, 'fs33', 101)" class="f">average</span>
</code></pre></td>
</tr>
</table>
<p>And as a final note. We can replace a call to <code>map</code> followed by <code>average</code> with <code>averageBy</code></p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l">1: </span>
<span class="l">2: </span>
<span class="l">3: </span>
<span class="l">4: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs30', 102)" onmouseover="showTip(event, 'fs30', 102)" class="f">calculateChance</span> <span onmouseout="hideTip(event, 'fs6', 103)" onmouseover="showTip(event, 'fs6', 103)" class="i">chance</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs23', 104)" onmouseover="showTip(event, 'fs23', 104)" class="f">randomSeq</span> <span class="n">0</span> <span class="n">100</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 105)" onmouseover="showTip(event, 'fs26', 105)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs28', 106)" onmouseover="showTip(event, 'fs28', 106)" class="f">take</span> <span class="n">1000</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 107)" onmouseover="showTip(event, 'fs26', 107)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs34', 108)" onmouseover="showTip(event, 'fs34', 108)" class="f">averageBy</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs32', 109)" onmouseover="showTip(event, 'fs32', 109)" class="i">x</span> <span class="k">-></span> <span class="k">if</span> <span onmouseout="hideTip(event, 'fs32', 110)" onmouseover="showTip(event, 'fs32', 110)" class="i">x</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs6', 111)" onmouseover="showTip(event, 'fs6', 111)" class="i">chance</span> <span class="k">then</span> <span class="n">100.0</span> <span class="k">else</span> <span class="n">0.0</span>)
</code></pre></td>
</tr>
</table>
<h2>Conclusion</h2>
<p>When we compare the final code with what we started I think we have reached a good refactoring.</p>
<p>We started with:</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
<span class="l">12: </span>
<span class="l">13: </span>
<span class="l">14: </span>
<span class="l">15: </span>
<span class="l">16: </span>
<span class="l">17: </span>
<span class="l">18: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 112)" onmouseover="showTip(event, 'fs2', 112)" class="i">rng</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 113)" onmouseover="showTip(event, 'fs3', 113)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 114)" onmouseover="showTip(event, 'fs4', 114)" class="t">Random</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs5', 115)" onmouseover="showTip(event, 'fs5', 115)" class="f">calculateChance</span> <span onmouseout="hideTip(event, 'fs6', 116)" onmouseover="showTip(event, 'fs6', 116)" class="i">chance</span> <span class="o">=</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs7', 117)" onmouseover="showTip(event, 'fs7', 117)" class="v">criticalHit</span> <span class="o">=</span> <span class="n">0</span>
<span class="k">let</span> <span class="k">mutable</span> <span onmouseout="hideTip(event, 'fs8', 118)" onmouseover="showTip(event, 'fs8', 118)" class="v">normalHit</span> <span class="o">=</span> <span class="n">0</span>
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs9', 119)" onmouseover="showTip(event, 'fs9', 119)" class="i">i</span> <span class="k">in</span> <span class="n">1</span> <span class="o">..</span> <span class="n">1000</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs10', 120)" onmouseover="showTip(event, 'fs10', 120)" class="i">random</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs2', 121)" onmouseover="showTip(event, 'fs2', 121)" class="i">rng</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 122)" onmouseover="showTip(event, 'fs11', 122)" class="f">Next</span>(<span class="n">0</span>, <span class="n">100</span>)
<span class="k">if</span> <span onmouseout="hideTip(event, 'fs10', 123)" onmouseover="showTip(event, 'fs10', 123)" class="i">random</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs6', 124)" onmouseover="showTip(event, 'fs6', 124)" class="i">chance</span> <span class="k">then</span>
<span onmouseout="hideTip(event, 'fs7', 125)" onmouseover="showTip(event, 'fs7', 125)" class="v">criticalHit</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs7', 126)" onmouseover="showTip(event, 'fs7', 126)" class="v">criticalHit</span> <span class="o">+</span> <span class="n">1</span>
<span class="k">else</span>
<span onmouseout="hideTip(event, 'fs8', 127)" onmouseover="showTip(event, 'fs8', 127)" class="v">normalHit</span> <span class="o"><-</span> <span onmouseout="hideTip(event, 'fs8', 128)" onmouseover="showTip(event, 'fs8', 128)" class="v">normalHit</span> <span class="o">+</span> <span class="n">1</span>
<span onmouseout="hideTip(event, 'fs7', 129)" onmouseover="showTip(event, 'fs7', 129)" class="v">criticalHit</span>, <span onmouseout="hideTip(event, 'fs8', 130)" onmouseover="showTip(event, 'fs8', 130)" class="v">normalHit</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs12', 131)" onmouseover="showTip(event, 'fs12', 131)" class="f">percentage</span> <span onmouseout="hideTip(event, 'fs13', 132)" onmouseover="showTip(event, 'fs13', 132)" class="i">x</span> <span onmouseout="hideTip(event, 'fs14', 133)" onmouseover="showTip(event, 'fs14', 133)" class="i">y</span> <span class="o">=</span> <span class="n">100.0</span> <span class="o">/</span> (<span onmouseout="hideTip(event, 'fs13', 134)" onmouseover="showTip(event, 'fs13', 134)" class="i">x</span> <span class="o">+</span> <span onmouseout="hideTip(event, 'fs14', 135)" onmouseover="showTip(event, 'fs14', 135)" class="i">y</span>) <span class="o">*</span> <span onmouseout="hideTip(event, 'fs13', 136)" onmouseover="showTip(event, 'fs13', 136)" class="i">x</span>
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs9', 137)" onmouseover="showTip(event, 'fs9', 137)" class="i">i</span> <span class="k">in</span> <span class="n">1..</span><span class="n">10</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs15', 138)" onmouseover="showTip(event, 'fs15', 138)" class="i">crit</span>,<span onmouseout="hideTip(event, 'fs16', 139)" onmouseover="showTip(event, 'fs16', 139)" class="i">normal</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs5', 140)" onmouseover="showTip(event, 'fs5', 140)" class="f">calculateChance</span> <span class="n">16</span>
<span onmouseout="hideTip(event, 'fs17', 141)" onmouseover="showTip(event, 'fs17', 141)" class="f">printfn</span> <span class="s">"Crit: </span><span class="pf">%d</span><span class="s"> Normal: </span><span class="pf">%d</span><span class="s"> Percentage: </span><span class="pf">%f</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs15', 142)" onmouseover="showTip(event, 'fs15', 142)" class="i">crit</span> <span onmouseout="hideTip(event, 'fs16', 143)" onmouseover="showTip(event, 'fs16', 143)" class="i">normal</span> (<span onmouseout="hideTip(event, 'fs12', 144)" onmouseover="showTip(event, 'fs12', 144)" class="f">percentage</span> (<span onmouseout="hideTip(event, 'fs18', 145)" onmouseover="showTip(event, 'fs18', 145)" class="f">float</span> <span onmouseout="hideTip(event, 'fs15', 146)" onmouseover="showTip(event, 'fs15', 146)" class="i">crit</span>) (<span onmouseout="hideTip(event, 'fs18', 147)" onmouseover="showTip(event, 'fs18', 147)" class="f">float</span> <span onmouseout="hideTip(event, 'fs16', 148)" onmouseover="showTip(event, 'fs16', 148)" class="i">normal</span>))
</code></pre></td>
</tr>
</table>
<p>End we ended with</p>
<table class="pre"><tr><td class="lines"><pre class="fssnip"><span class="l"> 1: </span>
<span class="l"> 2: </span>
<span class="l"> 3: </span>
<span class="l"> 4: </span>
<span class="l"> 5: </span>
<span class="l"> 6: </span>
<span class="l"> 7: </span>
<span class="l"> 8: </span>
<span class="l"> 9: </span>
<span class="l">10: </span>
<span class="l">11: </span>
</pre></td>
<td class="snippet"><pre class="fssnip highlighted"><code lang="fsharp"><span class="k">let</span> <span onmouseout="hideTip(event, 'fs2', 149)" onmouseover="showTip(event, 'fs2', 149)" class="i">rng</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs3', 150)" onmouseover="showTip(event, 'fs3', 150)" class="i">System</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs4', 151)" onmouseover="showTip(event, 'fs4', 151)" class="t">Random</span>()
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs23', 152)" onmouseover="showTip(event, 'fs23', 152)" class="f">randomSeq</span> <span onmouseout="hideTip(event, 'fs24', 153)" onmouseover="showTip(event, 'fs24', 153)" class="i">min</span> <span onmouseout="hideTip(event, 'fs25', 154)" onmouseover="showTip(event, 'fs25', 154)" class="i">max</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs26', 155)" onmouseover="showTip(event, 'fs26', 155)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs27', 156)" onmouseover="showTip(event, 'fs27', 156)" class="f">initInfinite</span> (<span class="k">fun</span> _ <span class="k">-></span> <span onmouseout="hideTip(event, 'fs2', 157)" onmouseover="showTip(event, 'fs2', 157)" class="i">rng</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs11', 158)" onmouseover="showTip(event, 'fs11', 158)" class="f">Next</span>(<span onmouseout="hideTip(event, 'fs24', 159)" onmouseover="showTip(event, 'fs24', 159)" class="i">min</span>, <span onmouseout="hideTip(event, 'fs25', 160)" onmouseover="showTip(event, 'fs25', 160)" class="i">max</span>))
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs30', 161)" onmouseover="showTip(event, 'fs30', 161)" class="f">calculateChance</span> <span onmouseout="hideTip(event, 'fs6', 162)" onmouseover="showTip(event, 'fs6', 162)" class="i">chance</span> <span class="o">=</span>
<span onmouseout="hideTip(event, 'fs23', 163)" onmouseover="showTip(event, 'fs23', 163)" class="f">randomSeq</span> <span class="n">0</span> <span class="n">100</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 164)" onmouseover="showTip(event, 'fs26', 164)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs28', 165)" onmouseover="showTip(event, 'fs28', 165)" class="f">take</span> <span class="n">1000</span>
<span class="o">|></span> <span onmouseout="hideTip(event, 'fs26', 166)" onmouseover="showTip(event, 'fs26', 166)" class="t">Seq</span><span class="o">.</span><span onmouseout="hideTip(event, 'fs34', 167)" onmouseover="showTip(event, 'fs34', 167)" class="f">averageBy</span> (<span class="k">fun</span> <span onmouseout="hideTip(event, 'fs32', 168)" onmouseover="showTip(event, 'fs32', 168)" class="i">x</span> <span class="k">-></span> <span class="k">if</span> <span onmouseout="hideTip(event, 'fs32', 169)" onmouseover="showTip(event, 'fs32', 169)" class="i">x</span> <span class="o"><</span> <span onmouseout="hideTip(event, 'fs6', 170)" onmouseover="showTip(event, 'fs6', 170)" class="i">chance</span> <span class="k">then</span> <span class="n">100.0</span> <span class="k">else</span> <span class="n">0.0</span>)
<span class="k">for</span> <span onmouseout="hideTip(event, 'fs9', 171)" onmouseover="showTip(event, 'fs9', 171)" class="i">i</span> <span class="k">in</span> <span class="n">1..</span><span class="n">10</span> <span class="k">do</span>
<span class="k">let</span> <span onmouseout="hideTip(event, 'fs35', 172)" onmouseover="showTip(event, 'fs35', 172)" class="i">percentage</span> <span class="o">=</span> <span onmouseout="hideTip(event, 'fs30', 173)" onmouseover="showTip(event, 'fs30', 173)" class="f">calculateChance</span> <span class="n">16</span>
<span onmouseout="hideTip(event, 'fs17', 174)" onmouseover="showTip(event, 'fs17', 174)" class="f">printfn</span> <span class="s">"Percentage: </span><span class="pf">%f</span><span class="s">"</span> <span onmouseout="hideTip(event, 'fs35', 175)" onmouseover="showTip(event, 'fs35', 175)" class="i">percentage</span>
</code></pre></td>
</tr>
</table>
<p>From a code perspective we didn't write more code. We even reduced the line count number.
By rewriting we created a reusable <code>randomSeq</code> sequence that can provide
us an infinite stream of random numbers. I also find the logic easier to understand.</p>
<ol>
<li>Initialize a <code>randomSeq</code> that return numbers from 0 to 99</li>
<li>Take 1000 of those numbers</li>
<li>Map them to <code>100.0</code> if it smaller than <code>chance</code> or <code>0.0</code> and calculate the average from those numbers.</li>
</ol>
<p>As stated in the beginning. It was a toy program with what we started but overall we can see the ways
in how we can continuously improve our code.</p>
<p>I don't think that just turning a loop in itself into
a recursive function as you see in <em>Solution 2</em> provides much benefit. But doing such a thing
can help to later turn it into a <code>fold</code> call. You also can move directly from <em>Solution 1</em> to
<em>Solution 3</em>. But doing the intermediate Step can greatly help if you are not used in doing this kind
of things.</p>
<p>Once you have a <code>fold</code> in it you can further think in how you can eliminate it. If there
exists other functions that can replace a <code>fold</code> use them instead! But what happens if you don't
find other more specific function as <code>fold</code>? Well just use it, it is there to be used. But if you
found similarities between multiple different lambda functions that you pass into <code>fold</code>, you should
look into how you can abstract the lambda into a reusable function.</p>
<div class="tip" id="fs1">module Main</div>
<div class="tip" id="fs2">val rng : System.Random<br /><br />Full name: Main.rng</div>
<div class="tip" id="fs3">namespace System</div>
<div class="tip" id="fs4">Multiple items<br />type Random =<br />  new : unit -> Random + 1 overload<br />  member Next : unit -> int + 2 overloads<br />  member NextBytes : buffer:byte[] -> unit<br />  member NextDouble : unit -> float<br /><br />Full name: System.Random<br /><br />--------------------<br />System.Random() : unit<br />System.Random(Seed: int) : unit</div>
<div class="tip" id="fs5">val calculateChance : chance:int -> int * int<br /><br />Full name: Main.calculateChance</div>
<div class="tip" id="fs6">val chance : int</div>
<div class="tip" id="fs7">val mutable criticalHit : int</div>
<div class="tip" id="fs8">val mutable normalHit : int</div>
<div class="tip" id="fs9">val i : int32</div>
<div class="tip" id="fs10">val random : int</div>
<div class="tip" id="fs11">System.Random.Next() : int<br />System.Random.Next(maxValue: int) : int<br />System.Random.Next(minValue: int, maxValue: int) : int</div>
<div class="tip" id="fs12">val percentage : x:float -> y:float -> float<br /><br />Full name: Main.percentage</div>
<div class="tip" id="fs13">val x : float</div>
<div class="tip" id="fs14">val y : float</div>
<div class="tip" id="fs15">val crit : int</div>
<div class="tip" id="fs16">val normal : int</div>
<div class="tip" id="fs17">val printfn : format:Printf.TextWriterFormat<'T> -> 'T<br /><br />Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn</div>
<div class="tip" id="fs18">Multiple items<br />val float : value:'T -> float (requires member op_Explicit)<br /><br />Full name: Microsoft.FSharp.Core.Operators.float<br /><br />--------------------<br />type float = System.Double<br /><br />Full name: Microsoft.FSharp.Core.float<br /><br />--------------------<br />type float<'Measure> = float<br /><br />Full name: Microsoft.FSharp.Core.float<_></div>
<div class="tip" id="fs19">val loop : (int -> int -> int -> int * int)</div>
<div class="tip" id="fs20">val count : int</div>
<div class="tip" id="fs21">val criticalHit : int</div>
<div class="tip" id="fs22">val normalHit : int</div>
<div class="tip" id="fs23">val randomSeq : min:int -> max:int -> seq<int><br /><br />Full name: Main.randomSeq</div>
<div class="tip" id="fs24">val min : int</div>
<div class="tip" id="fs25">val max : int</div>
<div class="tip" id="fs26">module Seq<br /><br />from Microsoft.FSharp.Collections</div>
<div class="tip" id="fs27">val initInfinite : initializer:(int -> 'T) -> seq<'T><br /><br />Full name: Microsoft.FSharp.Collections.Seq.initInfinite</div>
<div class="tip" id="fs28">val take : count:int -> source:seq<'T> -> seq<'T><br /><br />Full name: Microsoft.FSharp.Collections.Seq.take</div>
<div class="tip" id="fs29">val fold : folder:('State -> 'T -> 'State) -> state:'State -> source:seq<'T> -> 'State<br /><br />Full name: Microsoft.FSharp.Collections.Seq.fold</div>
<div class="tip" id="fs30">val calculateChance : chance:int -> float<br /><br />Full name: Main.calculateChance</div>
<div class="tip" id="fs31">val map : mapping:('T -> 'U) -> source:seq<'T> -> seq<'U><br /><br />Full name: Microsoft.FSharp.Collections.Seq.map</div>
<div class="tip" id="fs32">val x : int</div>
<div class="tip" id="fs33">val average : source:seq<'T> -> 'T (requires member ( + ) and member DivideByInt and member get_Zero)<br /><br />Full name: Microsoft.FSharp.Collections.Seq.average</div>
<div class="tip" id="fs34">val averageBy : projection:('T -> 'U) -> source:seq<'T> -> 'U (requires member ( + ) and member DivideByInt and member get_Zero)<br /><br />Full name: Microsoft.FSharp.Collections.Seq.averageBy</div>
<div class="tip" id="fs35">val percentage : float</div>
Structured Programming2016-03-09T00:00:00+00:00https://sidburn.github.io/blog/2016/03/09/structured-programming<p>Back in 1968 Edsger W. Dijkstra wrote an open letter named "Go To Statement Considered Harmful". As already suggested from
the title, the very idea was to raise consciousness that the <code>goto</code> statement is more harmful then helpful. From
today view we would expect that this idea catches fire really fast, but it didn't. It took quite a long time. Even during
all the 1970s and 1980s that question was debated a lot.</p>
<p>Looking back at it there are some interesting questions that is worth to look at. The first one was, if <code>goto</code> was
harmful, what was the alternative to <code>goto</code>? And why exactly is <code>goto</code> harmful, and why exactly is the alternative better?</p>
<p>I think that looking at this questions and their answers is still a very important step forward in understanding programming and
raise the awareness on how we achieve a more clean way of coding.</p>
<h2>Why "goto" was considered harmful</h2>
<p>At first we have to understand the time in which these statement was published. It was a time in that nearly every programmer
actually used a language with such a control statement. Not only that, it usually often was the only way to provide any
kind of control structures. There were no "subroutines", no <code>if</code>, <code>while</code>, or <code>for</code> loops. No blocks of code ans so one. Sure
there existed languages that provides this kind of style of programming. The ALGOL 58 and ALGOL 60 (1958 and 1960) already
provided those kind of structures, but those languages were not used by the large.</p>
<p>Most of the programmers still used languages where a <code>goto</code> statement dominated. And where the flow of a program was dominated
by direct <code>goto</code> statements. Dijkstra that was a huge proponent of the ALGOL language coined the term <em>Structured Programming</em>
as an alternative to the <code>goto</code> keyword, the idea was that we should have explicit control flow. Mainly a language should be separated
into Control Structures, Subroutines and Blocks. Control Structures should be further divided into <strong>sequence</strong>, <strong>selection</strong>,
<strong>iteration</strong> and <strong>recursion</strong> statements.</p>
<p>But why should we do something like that? The reason was that we anyway had this concepts, but implicitly. All of these ideas
was <em>emulated</em> with the <code>goto</code> statement. You wanted a <code>for</code> loop? No problem just jump with <code>goto</code> to some earlier point.</p>
<p>You wanted a subroutine? You pushed some values onto the stack, jumped to a certain point (your subroutine entry) and that
subroutine poped the right amount of values from a stack. That is still how functions are implemented in today's language.
That is the very reason of why you can get a <code>StackOverflowException</code> if your language don't support tail-recursion.</p>
<p>But by giving all of them direct labels we give all of our programs more structure. And this structure helps us in understanding
our programs. Or in other words the idea was that we should eliminate powerful construct like <code>goto</code> and yet use a lot more
weaker but specific constructs.</p>
<h2>Structured Programming</h2>
<p>That overall leads to another important realization. Nearly all programming languages that we use today are basically some kind
of Structured Programming. Whether we are talking about object-oriented language, functional languages or other paradigms.</p>
<p>All of those languages usually provide some kind of control structures, in the form of looping <code>while</code>, <code>for</code> or <code>foreach</code>. Subroutines
in the form of procedures, functions, (static) methods or however your language names them. Selection in the form of
<code>if</code>, <code>switch</code> or pattern matching.</p>
<p>It is important to realize this, because you don't really need any of those if you have a goto statement. The goto statement
could implement all of those structures just through the use of goto. That is also the reason why i said at the beginning that
Structured Programming is still a very important idea up to the current days.</p>
<p>But looking more deeply into it, you will probably ask. Well is that really so? Especially if you use a functional language
you will encounter that looping constructs are discouraged. Even in object-oriented language it is more and more discouraged.
Instead of typical <code>while</code> or <code>foreach</code> loops in C# for example you will use LINQ, Java 8 introduced Stream as a more declarative
alternative.</p>
<p>And yet Structured Programming is even more an important topic. The thing is. All those functional interfaces itself or LINQ or Stream
are basically Structured Programming brought to an extreme. Because the important point of Structured programming was not
the introduction of <code>if</code>, <code>while</code>, <code>for</code>, functions or blocks. The important idea was the general concept of eliminating
something powerful and provide more declarative and specific control structures instead.</p>
<h2>Powerful vs. Specific</h2>
<p>So let's reconsider, why was <code>goto</code> harmful? <code>goto</code> was a very powerful concept. It was so powerful that we basically don't need
any concepts of looping constructs, functions and so on. The problem that it raised was that we ended up with programs that was
hard to maintain. Without <strong>words</strong> that describe specific problems we have problems to face growing programs and we as humans
have problems understanding what happens.</p>
<p>With the introduction of <code>if</code>, <code>while</code>, <code>for</code>, functions and so on we introduced specific concepts that are all possible to express
with goto. But giving them proper names we have it more easy to follow and understand the intention of our code. It is more
easier because every control structure was build for one specific task.</p>
<p>But when we look at the looping constructs we basically see the same things happen. Why do we consider <code>while</code>, <code>foreach</code> and so
on more and more harmful these days, and replace them with functional interfaces instead? Because those concepts are still to
powerful. For example what does a <code>foreach</code> really express? Actually not much. It just describes a <em>go through all data</em>. That is
a general purpose way. But what can you do with it? Well a lot of powerful things!</p>
<p>For example you can can loop with <code>foreach</code> through an array to find the smallest element or the biggest element. You can apply a function
to every element and change every element, or insert the applied element into a new array. You can filter an array by some condition.
You can loop through two arrays, combine them in various ways, do some calculations with every element and so on. Or in other words.
We can do a lot with such a simple constructs. <code>foreach</code> is actually the same kind of a powerful concept like <code>goto</code>.
And that is why we view them as <em>harmful</em>.</p>
<p>Looking at functional interface, they really brought the concept of Structured Programming even further. Instead of just <em>looping</em> we now
have even further separated the idea of looping. We have <code>List.min</code>, <code>List.max</code>, <code>List.map</code>, <code>List.filter</code>, <code>List.map2</code>, <code>List.zip</code>, ...
and so one just to name a view. All of those constructs are still basically just <em>looping</em> constructs. But they are specialized looping
constructs that just do one specific thing.</p>
<h2>So having powerful things is bad?</h2>
<p>If we follow this thinking then it can lead to the idea that a programming language itself should not have any powerful concepts at all.
The less powerful a language is, the better. But actually it cannot be further from the truth. In fact it is quite the opposite, a language
absolute must provide as much powerful things as possible.</p>
<p>The reason for that is that we need those powerful concepts to build our less powerful, more specific things. And in building more of those
constructs we achieve a better more clean code. A result of this is also that code will be shorter, easier to understand with less bugs.</p>
<p>So we should aim for powerful constructs, and a language should provide those powerful constructs. But we should use them to build all our
more specific less powerful constructs. Or in other words, in programming we always should prefer the least powerful concept to implement
something.</p>
<p>Sure you can implement filtering a <code>List</code> with a <code>foreach</code> loop. Go through every element, push it into a new <code>List</code> based on some condition.
But why not abstract such a common task? <code>List.filter</code> does exactly that. It is less powerful, because it just can filter, nothing more,<br />
but we only need to provide the logic for filtering. We have less code after we have a construct like <code>List.filter</code>. The intention is more clearer.
Reading a <code>List.filter</code> is easier as to basically try to understand filtering through a series of commands expressed within a <code>foreach</code>
loop.</p>
<h2>Using the least powerful thing</h2>
<p>When we follow these rule and thinking what Structured Programming is about, I think it leads to more readable code with all of
the benefit this usually have. Like higher maintainability, less bugs, in general less code because of reusable constructs. The
only thing we have todo is to identify our powerful constructs and try to come up with some alternative. In C# the usage of
<code>while</code>, <code>for</code> or <code>foreach</code> is such a thing. In F# besides using looping constructs itself also using direct recursion or using
<code>fold</code> counts as powerful. Recursion is basically just looping, and fold is the abstraction of tail-recursive looping with
an accumulator. Watch out for them and either try to replace them with more specific constructs. Or build your own control
structs!</p>
<h2>Further Reading</h2>
<ul>
<li><a href="https://blog.8thlight.com/uncle-bob/2015/09/23/a-little-structure.html">Uncle Bob - A Little Structure</a></li>
</ul>