update material

This commit is contained in:
Joel Kaasinen
2020-05-06 09:02:53 +03:00
parent f33279b5d9
commit 64d89ced35
2 changed files with 490 additions and 362 deletions
+14 -1
View File
@@ -24,4 +24,17 @@ The material is available as [part1.html](part1.html) in this repository.
## Exercises
Exercises can be found under exercises/. See material for more info on working on them.
Exercises can be found under `exercises/`. Exercises are Haskell
source code files named `Set1.hs`, `Set2.hs` and so on. You complete
the exercises by editing the file according to the instructions in the
file. You can check your answers by running
```
stack runhaskell SetXTest.hs
```
in the `exercises/` directory. Remember to replace `X` with the number
of the set you are working on.
See [the material](part1.html#working-on-the-exercises) for more info.
+476 -361
View File
@@ -153,11 +153,12 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
</ul></li>
<li><a href="#lecture-6-working-class-hero"><span class="toc-section-number">6</span> Lecture 6: Working Class Hero</a><ul>
<li><a href="#the-syntax-of-classes-and-instances"><span class="toc-section-number">6.1</span> The syntax of classes and instances</a></li>
<li><a href="#default-implementations"><span class="toc-section-number">6.2</span> Default implementations</a></li>
<li><a href="#useful-stuff"><span class="toc-section-number">6.3</span> Useful stuff</a></li>
<li><a href="#hierarchies"><span class="toc-section-number">6.4</span> Hierarchies</a></li>
<li><a href="#todo-quiz"><span class="toc-section-number">6.5</span> TODO: Quiz</a></li>
<li><a href="#exercises-5"><span class="toc-section-number">6.6</span> Exercises</a></li>
<li><a href="#sidenote-restrictions-on-instances"><span class="toc-section-number">6.2</span> Sidenote: restrictions on instances</a></li>
<li><a href="#default-implementations"><span class="toc-section-number">6.3</span> Default implementations</a></li>
<li><a href="#useful-stuff"><span class="toc-section-number">6.4</span> Useful stuff</a></li>
<li><a href="#hierarchies"><span class="toc-section-number">6.5</span> Hierarchies</a></li>
<li><a href="#quiz-5"><span class="toc-section-number">6.6</span> Quiz</a></li>
<li><a href="#exercises-5"><span class="toc-section-number">6.7</span> Exercises</a></li>
</ul></li>
<li><a href="#lecture-7-new-constellations"><span class="toc-section-number">7</span> Lecture 7: New Constellations</a><ul>
<li><a href="#modeling-with-boxes"><span class="toc-section-number">7.1</span> Modeling with boxes</a></li>
@@ -165,8 +166,7 @@ code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warni
<li><a href="#monoids"><span class="toc-section-number">7.3</span> Monoids</a></li>
<li><a href="#open-and-closed-abstractions"><span class="toc-section-number">7.4</span> Open and closed abstractions</a></li>
<li><a href="#modeling-with-languages"><span class="toc-section-number">7.5</span> Modeling with languages</a></li>
<li><a href="#todo-quiz-1"><span class="toc-section-number">7.6</span> TODO: Quiz</a></li>
<li><a href="#exercises-6"><span class="toc-section-number">7.7</span> Exercises</a></li>
<li><a href="#exercises-6"><span class="toc-section-number">7.6</span> Exercises</a></li>
</ul></li>
<li><a href="#lecture-8-the-aftertaste"><span class="toc-section-number">8</span> Lecture 8: The Aftertaste</a><ul>
<li><a href="#a-taste-of-io"><span class="toc-section-number">8.1</span> A taste of IO</a></li>
@@ -1099,7 +1099,8 @@ GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
Ok, two modules loaded.
*Set1&gt; quadruple 1
2</code></pre>
<p>Once you’re done with an exercise set, you can return it to TODO</p>
<p>Once you’re done with an exercise set, you can turn it in on the <a href="https://haskell.mooc.fi/submit.php">Submit page</a> on the course pages. After that you can see the results of your submission on the <a href="https://haskell.mooc.fi/results.php">Results page</a> and your total score on the <a href="https://haskell.mooc.fi/status.php">My status page</a>.</p>
<p><strong>Note!</strong> you may turn in an exercise set as many times as you want.</p>
<h2 id="exercises"><span class="header-section-number">1.14</span> Exercises</h2>
<ul>
<li>Set1</li>
@@ -1972,7 +1973,7 @@ Returns the second element of a list
<div class="sourceCode" id="cb220"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb220-1" data-line-number="1">sumIf [(<span class="dt">True</span>,<span class="dv">1</span>),(<span class="dt">False</span>,<span class="dv">10</span>),(<span class="dt">True</span>,<span class="dv">100</span>)]</a>
<a class="sourceLine" id="cb220-2" data-line-number="2"> <span class="fu">==&gt;</span> <span class="dv">101</span></a></code></pre></div>
<h2 id="interlude-folding"><span class="header-section-number">4.2</span> Interlude: folding</h2>
<p>TODO: should this be in the same section as foldable?</p>
<!-- TODO: should this be in the same section as foldable? -->
<p>Consider the functions <code>sumNumbers :: [Int] -&gt; Int</code>, <code>myMaximum :: [Int] -&gt; Int</code>, and <code>countNothings :: [Maybe a] -&gt; Int</code> again.</p>
<p>```haskell sumNumbers :: [Int] -&gt; Int sumNumbers [] = 0 sumNumbers (x:xs) = x + sumNumbers xs</p>
<p>myMaximum :: [Int] -&gt; Int myMaximum [] = 0 myMaximum (x:xs) = go x xs where go biggest [] = biggest go biggest (x:xs) = go (max biggest x) xs</p>
@@ -2354,7 +2355,7 @@ It turns a list of pairs into a list of elements
<code>(Foldable t, Eq a, Num a) =&gt; Bool -&gt; [ a ] -&gt; Bool</code>
</li>
</ol>
<p>TODO more <!-- Maybe some Array and Map questions --></p>
<!-- TODO more, maybe some Array and Map questions -->
<h2 id="exercises-3"><span class="header-section-number">4.9</span> Exercises</h2>
<ul>
<li>Set4a: type classes</li>
@@ -2809,157 +2810,271 @@ Because <code>Nothing</code> is a constructor.
<a class="sourceLine" id="cb337-15" data-line-number="15"> empty <span class="fu">=</span> []</a>
<a class="sourceLine" id="cb337-16" data-line-number="16"> size xs <span class="fu">=</span> length xs</a>
<a class="sourceLine" id="cb337-17" data-line-number="17"> sameSize x y <span class="fu">=</span> size x <span class="fu">==</span> size y</a></code></pre></div>
<h2 id="default-implementations"><span class="header-section-number">6.2</span> Default implementations</h2>
<h2 id="sidenote-restrictions-on-instances"><span class="header-section-number">6.2</span> Sidenote: restrictions on instances</h2>
<p>The Haskell 2010 allows only a very specific type of class instance. Let’s look at some instances that aren’t allowed. The examples use the <code>Size</code> class:</p>
<div class="sourceCode" id="cb338"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb338-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Size</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb338-2" data-line-number="2"><span class="ot"> size ::</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span></a></code></pre></div>
<p>We saw a <code>Size [a]</code> instance above. Why not define an instance just for lists of booleans?</p>
<div class="sourceCode" id="cb339"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb339-1" data-line-number="1"><span class="kw">instance</span> <span class="dt">Size</span> [<span class="dt">Bool</span>] <span class="kw">where</span></a>
<a class="sourceLine" id="cb339-2" data-line-number="2"> size bs <span class="fu">=</span> length (filter id bs) <span class="co">-- count Trues</span></a></code></pre></div>
<pre class="haskel"><code>error:
• Illegal instance declaration for ‘Size [Bool]’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
• In the instance declaration for ‘Size [Bool]’</code></pre>
<p>Dang. As the error tries to tell us, we can only define instances where all type parameters are <em>different</em> type variables. That is, we can define <code>instance Size (Either a b)</code> but we can’t define:</p>
<ul>
<li><code>instance Size (Either String a)</code> – since <code>String</code> is not a type variable</li>
<li><code>instance Size (Either a a)</code> – since the type variables aren’t different</li>
<li><code>instance Size [[a]]</code> – since <code>[a]</code> is not a type variable</li>
</ul>
<p>Why is this? This rule guarantees that it’s simple for the compiler to look up the correct type class instance. It can just look at what the <em>top-level type constructor</em> is, and then pick an instance.</p>
<p>The GHC Haskell implementation has many extensions to the type class system – we’ll get back to some of them in part 2 of this course.</p>
<h2 id="default-implementations"><span class="header-section-number">6.3</span> Default implementations</h2>
<p>Did you notice how in the previous example we gave <code>sameSize</code> the same definition in both instances? This is a very common occurrence, and it’s why Haskell classes can have <em>default implementations</em>. As a first example, here’s an <code>Example</code> type class for giving example values of types.</p>
<div class="sourceCode" id="cb338"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb338-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Example</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb338-2" data-line-number="2"><span class="ot"> example ::</span> a <span class="co">-- the main example for the type `a`</span></a>
<a class="sourceLine" id="cb338-3" data-line-number="3"><span class="ot"> examples ::</span> [a] <span class="co">-- a short list of examples</span></a>
<a class="sourceLine" id="cb338-4" data-line-number="4"> examples <span class="fu">=</span> [example] <span class="co">-- ...defaulting to just the main example</span></a>
<a class="sourceLine" id="cb338-5" data-line-number="5"></a>
<a class="sourceLine" id="cb338-6" data-line-number="6"><span class="kw">instance</span> <span class="dt">Example</span> <span class="dt">Int</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb338-7" data-line-number="7"> example <span class="fu">=</span> <span class="dv">1</span></a>
<a class="sourceLine" id="cb338-8" data-line-number="8"> examples <span class="fu">=</span> [<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>]</a>
<a class="sourceLine" id="cb338-9" data-line-number="9"></a>
<a class="sourceLine" id="cb338-10" data-line-number="10"><span class="kw">instance</span> <span class="dt">Example</span> <span class="dt">Bool</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb338-11" data-line-number="11"> example <span class="fu">=</span> <span class="dt">True</span></a></code></pre></div>
<div class="sourceCode" id="cb341"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb341-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Example</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb341-2" data-line-number="2"><span class="ot"> example ::</span> a <span class="co">-- the main example for the type `a`</span></a>
<a class="sourceLine" id="cb341-3" data-line-number="3"><span class="ot"> examples ::</span> [a] <span class="co">-- a short list of examples</span></a>
<a class="sourceLine" id="cb341-4" data-line-number="4"> examples <span class="fu">=</span> [example] <span class="co">-- ...defaulting to just the main example</span></a>
<a class="sourceLine" id="cb341-5" data-line-number="5"></a>
<a class="sourceLine" id="cb341-6" data-line-number="6"><span class="kw">instance</span> <span class="dt">Example</span> <span class="dt">Int</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb341-7" data-line-number="7"> example <span class="fu">=</span> <span class="dv">1</span></a>
<a class="sourceLine" id="cb341-8" data-line-number="8"> examples <span class="fu">=</span> [<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>]</a>
<a class="sourceLine" id="cb341-9" data-line-number="9"></a>
<a class="sourceLine" id="cb341-10" data-line-number="10"><span class="kw">instance</span> <span class="dt">Example</span> <span class="dt">Bool</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb341-11" data-line-number="11"> example <span class="fu">=</span> <span class="dt">True</span></a></code></pre></div>
<p>Here’s how <code>Example</code> works. Note how the default implementation of <code>examples</code> got used in the <code>Bool</code> case but not in the <code>Int</code> case. Also note the need for explicit type signatures to tell GHCi which instance we’re interested in. Without them, we would get an “Ambiguous type variable” error.</p>
<div class="sourceCode" id="cb339"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb339-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> example ::</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb339-2" data-line-number="2"><span class="dt">True</span></a>
<a class="sourceLine" id="cb339-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> example ::</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb339-4" data-line-number="4"><span class="dv">1</span></a>
<a class="sourceLine" id="cb339-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> examples ::</span> [<span class="dt">Bool</span>]</a>
<a class="sourceLine" id="cb339-6" data-line-number="6">[<span class="dt">True</span>]</a>
<a class="sourceLine" id="cb339-7" data-line-number="7"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> examples ::</span> [<span class="dt">Int</span>]</a>
<a class="sourceLine" id="cb339-8" data-line-number="8">[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>]</a></code></pre></div>
<div class="sourceCode" id="cb342"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb342-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> example ::</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb342-2" data-line-number="2"><span class="dt">True</span></a>
<a class="sourceLine" id="cb342-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> example ::</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb342-4" data-line-number="4"><span class="dv">1</span></a>
<a class="sourceLine" id="cb342-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> examples ::</span> [<span class="dt">Bool</span>]</a>
<a class="sourceLine" id="cb342-6" data-line-number="6">[<span class="dt">True</span>]</a>
<a class="sourceLine" id="cb342-7" data-line-number="7"><span class="dt">Prelude</span><span class="fu">&gt;</span><span class="ot"> examples ::</span> [<span class="dt">Int</span>]</a>
<a class="sourceLine" id="cb342-8" data-line-number="8">[<span class="dv">0</span>,<span class="dv">1</span>,<span class="dv">2</span>]</a></code></pre></div>
<p>The standard type classes use lots of default implementations to make implementing the classes easy. Here is the standard definitions for <code>Eq</code> (formatted for readability).</p>
<div class="sourceCode" id="cb340"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb340-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Eq</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb340-2" data-line-number="2"><span class="ot"> (==) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb340-3" data-line-number="3"> x <span class="fu">==</span> y <span class="fu">=</span> not (x <span class="fu">/=</span> y)</a>
<a class="sourceLine" id="cb340-4" data-line-number="4"></a>
<a class="sourceLine" id="cb340-5" data-line-number="5"><span class="ot"> (/=) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb340-6" data-line-number="6"> x <span class="fu">/=</span> y <span class="fu">=</span> not (x <span class="fu">==</span> y)</a></code></pre></div>
<div class="sourceCode" id="cb343"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb343-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Eq</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb343-2" data-line-number="2"><span class="ot"> (==) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb343-3" data-line-number="3"> x <span class="fu">==</span> y <span class="fu">=</span> not (x <span class="fu">/=</span> y)</a>
<a class="sourceLine" id="cb343-4" data-line-number="4"></a>
<a class="sourceLine" id="cb343-5" data-line-number="5"><span class="ot"> (/=) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb343-6" data-line-number="6"> x <span class="fu">/=</span> y <span class="fu">=</span> not (x <span class="fu">==</span> y)</a></code></pre></div>
<p>Note how both operations have a default implementation in terms of the other. This means we could define an <code>Eq</code> instance with no content at all, but the resulting functions would just recurse forever. In practice, we want to define at least one of <code>==</code> and <code>/=</code>.</p>
<p>When there are lots of default implementations, it can be hard to know which functions you need to implement yourself. For this reason class documentation usually mentions the <em>minimal complete definition</em>. For <code>Eq</code>, <a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html#t:Eq">the docs say</a> “Minimal complete definition: either == or /=.”</p>
<p>Let’s look at <code>Ord</code> next. <code>Ord</code> has 7 operations, all with default implementations in terms of each other. By the way, note the quirky way of defining multiple type signatures at once. It’s okay, it’s a feature of Haskell, this is how <code>Ord</code> is defined in <a href="https://www.haskell.org/onlinereport/haskell2010/haskellch6.html#x13-1270006.3">the standard</a>. (We’ll get back to what the <code>(Eq a) =&gt;</code> part means soon.)</p>
<div class="sourceCode" id="cb341"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb341-1" data-line-number="1"><span class="kw">class</span> (<span class="dt">Eq</span> a) <span class="ot">=&gt;</span> <span class="dt">Ord</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb341-2" data-line-number="2"><span class="ot"> compare ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Ordering</span></a>
<a class="sourceLine" id="cb341-3" data-line-number="3"> (<span class="fu">&lt;</span>), (<span class="fu">&lt;=</span>), (<span class="fu">&gt;=</span>),<span class="ot"> (&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb341-4" data-line-number="4"> max,<span class="ot"> min ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb341-5" data-line-number="5"></a>
<a class="sourceLine" id="cb341-6" data-line-number="6"> compare x y <span class="fu">|</span> x <span class="fu">==</span> y <span class="fu">=</span> <span class="dt">EQ</span></a>
<a class="sourceLine" id="cb341-7" data-line-number="7"> <span class="fu">|</span> x <span class="fu">&lt;=</span> y <span class="fu">=</span> <span class="dt">LT</span></a>
<a class="sourceLine" id="cb341-8" data-line-number="8"> <span class="fu">|</span> otherwise <span class="fu">=</span> <span class="dt">GT</span></a>
<a class="sourceLine" id="cb341-9" data-line-number="9"></a>
<a class="sourceLine" id="cb341-10" data-line-number="10"> x <span class="fu">&lt;=</span> y <span class="fu">=</span> compare x y <span class="fu">/=</span> <span class="dt">GT</span></a>
<a class="sourceLine" id="cb341-11" data-line-number="11"> x <span class="fu">&lt;</span> y <span class="fu">=</span> compare x y <span class="fu">==</span> <span class="dt">LT</span></a>
<a class="sourceLine" id="cb341-12" data-line-number="12"> x <span class="fu">&gt;=</span> y <span class="fu">=</span> compare x y <span class="fu">/=</span> <span class="dt">LT</span></a>
<a class="sourceLine" id="cb341-13" data-line-number="13"> x <span class="fu">&gt;</span> y <span class="fu">=</span> compare x y <span class="fu">==</span> <span class="dt">GT</span></a>
<a class="sourceLine" id="cb341-14" data-line-number="14"></a>
<a class="sourceLine" id="cb341-15" data-line-number="15"> max x y <span class="fu">|</span> x <span class="fu">&lt;=</span> y <span class="fu">=</span> y</a>
<a class="sourceLine" id="cb341-16" data-line-number="16"> <span class="fu">|</span> otherwise <span class="fu">=</span> x</a>
<a class="sourceLine" id="cb341-17" data-line-number="17"> min x y <span class="fu">|</span> x <span class="fu">&lt;=</span> y <span class="fu">=</span> x</a>
<a class="sourceLine" id="cb341-18" data-line-number="18"> <span class="fu">|</span> otherwise <span class="fu">=</span> y</a></code></pre></div>
<div class="sourceCode" id="cb344"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb344-1" data-line-number="1"><span class="kw">class</span> (<span class="dt">Eq</span> a) <span class="ot">=&gt;</span> <span class="dt">Ord</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb344-2" data-line-number="2"><span class="ot"> compare ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Ordering</span></a>
<a class="sourceLine" id="cb344-3" data-line-number="3"> (<span class="fu">&lt;</span>), (<span class="fu">&lt;=</span>), (<span class="fu">&gt;=</span>),<span class="ot"> (&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb344-4" data-line-number="4"> max,<span class="ot"> min ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb344-5" data-line-number="5"></a>
<a class="sourceLine" id="cb344-6" data-line-number="6"> compare x y <span class="fu">|</span> x <span class="fu">==</span> y <span class="fu">=</span> <span class="dt">EQ</span></a>
<a class="sourceLine" id="cb344-7" data-line-number="7"> <span class="fu">|</span> x <span class="fu">&lt;=</span> y <span class="fu">=</span> <span class="dt">LT</span></a>
<a class="sourceLine" id="cb344-8" data-line-number="8"> <span class="fu">|</span> otherwise <span class="fu">=</span> <span class="dt">GT</span></a>
<a class="sourceLine" id="cb344-9" data-line-number="9"></a>
<a class="sourceLine" id="cb344-10" data-line-number="10"> x <span class="fu">&lt;=</span> y <span class="fu">=</span> compare x y <span class="fu">/=</span> <span class="dt">GT</span></a>
<a class="sourceLine" id="cb344-11" data-line-number="11"> x <span class="fu">&lt;</span> y <span class="fu">=</span> compare x y <span class="fu">==</span> <span class="dt">LT</span></a>
<a class="sourceLine" id="cb344-12" data-line-number="12"> x <span class="fu">&gt;=</span> y <span class="fu">=</span> compare x y <span class="fu">/=</span> <span class="dt">LT</span></a>
<a class="sourceLine" id="cb344-13" data-line-number="13"> x <span class="fu">&gt;</span> y <span class="fu">=</span> compare x y <span class="fu">==</span> <span class="dt">GT</span></a>
<a class="sourceLine" id="cb344-14" data-line-number="14"></a>
<a class="sourceLine" id="cb344-15" data-line-number="15"> max x y <span class="fu">|</span> x <span class="fu">&lt;=</span> y <span class="fu">=</span> y</a>
<a class="sourceLine" id="cb344-16" data-line-number="16"> <span class="fu">|</span> otherwise <span class="fu">=</span> x</a>
<a class="sourceLine" id="cb344-17" data-line-number="17"> min x y <span class="fu">|</span> x <span class="fu">&lt;=</span> y <span class="fu">=</span> x</a>
<a class="sourceLine" id="cb344-18" data-line-number="18"> <span class="fu">|</span> otherwise <span class="fu">=</span> y</a></code></pre></div>
<p>With this definition it’s really hard to know what the minimal complete definition is. Luckily the [docs tell us][ord-docs] “Minimal complete definition: either compare or &lt;=.”</p>
<p>As a final word on default implementations, if there is never a need to override the default definition, the function can be moved out of the class for simplicity. Consider a class like <code>Combine</code> below:</p>
<div class="sourceCode" id="cb342"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb342-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Combine</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb342-2" data-line-number="2"><span class="ot"> combine ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb342-3" data-line-number="3"><span class="ot"> combine3 ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb342-4" data-line-number="4"> combine3 x y z <span class="fu">=</span> combine x (combine y z)</a></code></pre></div>
<div class="sourceCode" id="cb345"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb345-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Combine</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb345-2" data-line-number="2"><span class="ot"> combine ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb345-3" data-line-number="3"><span class="ot"> combine3 ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb345-4" data-line-number="4"> combine3 x y z <span class="fu">=</span> combine x (combine y z)</a></code></pre></div>
<p>It’s hard to think of a case where <code>combine3</code> would be given any other definition, so why not move it out of the class:</p>
<div class="sourceCode" id="cb343"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb343-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Combine</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb343-2" data-line-number="2"><span class="ot"> combine ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb343-3" data-line-number="3"></a>
<a class="sourceLine" id="cb343-4" data-line-number="4"><span class="ot">combine3 ::</span> <span class="dt">Combine</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb343-5" data-line-number="5">combine3 x y z <span class="fu">=</span> combine x (combine y z)</a></code></pre></div>
<h3 id="example-the-pair-type"><span class="header-section-number">6.2.1</span> Example: the Pair type</h3>
<div class="sourceCode" id="cb346"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb346-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Combine</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb346-2" data-line-number="2"><span class="ot"> combine ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb346-3" data-line-number="3"></a>
<a class="sourceLine" id="cb346-4" data-line-number="4"><span class="ot">combine3 ::</span> <span class="dt">Combine</span> a <span class="ot">=&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb346-5" data-line-number="5">combine3 x y z <span class="fu">=</span> combine x (combine y z)</a></code></pre></div>
<h3 id="example-the-pair-type"><span class="header-section-number">6.3.1</span> Example: the Pair type</h3>
<p>Here are the <code>Eq</code> and <code>Ord</code> instances for a simple pair type. Note how the definition uses the minimal complete definition rules by only defining <code>==</code> and <code>&lt;=</code>.</p>
<div class="sourceCode" id="cb344"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb344-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Pair</span> a <span class="fu">=</span> <span class="dt">MakePair</span> a a</a>
<a class="sourceLine" id="cb344-2" data-line-number="2"> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb344-3" data-line-number="3"></a>
<a class="sourceLine" id="cb344-4" data-line-number="4"><span class="kw">instance</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Eq</span> (<span class="dt">Pair</span> a) <span class="kw">where</span></a>
<a class="sourceLine" id="cb344-5" data-line-number="5"> <span class="dt">MakePair</span> a b <span class="fu">==</span> <span class="dt">MakePair</span> c d <span class="fu">=</span> a<span class="fu">==</span>c <span class="fu">&amp;&amp;</span> b<span class="fu">==</span>d</a>
<a class="sourceLine" id="cb344-6" data-line-number="6"></a>
<a class="sourceLine" id="cb344-7" data-line-number="7"><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Ord</span> (<span class="dt">Pair</span> a) <span class="kw">where</span></a>
<a class="sourceLine" id="cb344-8" data-line-number="8"> <span class="dt">MakePair</span> a b <span class="fu">&lt;=</span> <span class="dt">MakePair</span> c d</a>
<a class="sourceLine" id="cb344-9" data-line-number="9"> <span class="fu">|</span> a<span class="fu">&lt;</span>c <span class="fu">=</span> <span class="dt">True</span></a>
<a class="sourceLine" id="cb344-10" data-line-number="10"> <span class="fu">|</span> a<span class="fu">&gt;</span>c <span class="fu">=</span> <span class="dt">False</span></a>
<a class="sourceLine" id="cb344-11" data-line-number="11"> <span class="fu">|</span> otherwise <span class="fu">=</span> b<span class="fu">&lt;=</span>d</a></code></pre></div>
<div class="sourceCode" id="cb345"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb345-1" data-line-number="1"><span class="fu">*</span><span class="dt">Main</span><span class="fu">&gt;</span> (<span class="dt">MakePair</span> <span class="dv">1</span> <span class="dv">2</span>) <span class="fu">&lt;</span> (<span class="dt">MakePair</span> <span class="dv">2</span> <span class="dv">3</span>)</a>
<a class="sourceLine" id="cb345-2" data-line-number="2"><span class="dt">True</span></a>
<a class="sourceLine" id="cb345-3" data-line-number="3"><span class="fu">*</span><span class="dt">Main</span><span class="fu">&gt;</span> (<span class="dt">MakePair</span> <span class="dv">1</span> <span class="dv">2</span>) <span class="fu">&gt;</span> (<span class="dt">MakePair</span> <span class="dv">2</span> <span class="dv">3</span>)</a>
<a class="sourceLine" id="cb345-4" data-line-number="4"><span class="dt">False</span></a>
<a class="sourceLine" id="cb345-5" data-line-number="5"><span class="fu">*</span><span class="dt">Main</span><span class="fu">&gt;</span> compare (<span class="dt">MakePair</span> <span class="dv">1</span> <span class="dv">2</span>) (<span class="dt">MakePair</span> <span class="dv">2</span> <span class="dv">3</span>)</a>
<a class="sourceLine" id="cb345-6" data-line-number="6"><span class="dt">LT</span></a></code></pre></div>
<h2 id="useful-stuff"><span class="header-section-number">6.3</span> Useful stuff</h2>
<h3 id="deriving"><span class="header-section-number">6.3.1</span> Deriving</h3>
<div class="sourceCode" id="cb347"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb347-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Pair</span> a <span class="fu">=</span> <span class="dt">MakePair</span> a a</a>
<a class="sourceLine" id="cb347-2" data-line-number="2"> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb347-3" data-line-number="3"></a>
<a class="sourceLine" id="cb347-4" data-line-number="4"><span class="kw">instance</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Eq</span> (<span class="dt">Pair</span> a) <span class="kw">where</span></a>
<a class="sourceLine" id="cb347-5" data-line-number="5"> <span class="dt">MakePair</span> a b <span class="fu">==</span> <span class="dt">MakePair</span> c d <span class="fu">=</span> a<span class="fu">==</span>c <span class="fu">&amp;&amp;</span> b<span class="fu">==</span>d</a>
<a class="sourceLine" id="cb347-6" data-line-number="6"></a>
<a class="sourceLine" id="cb347-7" data-line-number="7"><span class="kw">instance</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> <span class="dt">Ord</span> (<span class="dt">Pair</span> a) <span class="kw">where</span></a>
<a class="sourceLine" id="cb347-8" data-line-number="8"> <span class="dt">MakePair</span> a b <span class="fu">&lt;=</span> <span class="dt">MakePair</span> c d</a>
<a class="sourceLine" id="cb347-9" data-line-number="9"> <span class="fu">|</span> a<span class="fu">&lt;</span>c <span class="fu">=</span> <span class="dt">True</span></a>
<a class="sourceLine" id="cb347-10" data-line-number="10"> <span class="fu">|</span> a<span class="fu">&gt;</span>c <span class="fu">=</span> <span class="dt">False</span></a>
<a class="sourceLine" id="cb347-11" data-line-number="11"> <span class="fu">|</span> otherwise <span class="fu">=</span> b<span class="fu">&lt;=</span>d</a></code></pre></div>
<div class="sourceCode" id="cb348"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb348-1" data-line-number="1"><span class="fu">*</span><span class="dt">Main</span><span class="fu">&gt;</span> (<span class="dt">MakePair</span> <span class="dv">1</span> <span class="dv">2</span>) <span class="fu">&lt;</span> (<span class="dt">MakePair</span> <span class="dv">2</span> <span class="dv">3</span>)</a>
<a class="sourceLine" id="cb348-2" data-line-number="2"><span class="dt">True</span></a>
<a class="sourceLine" id="cb348-3" data-line-number="3"><span class="fu">*</span><span class="dt">Main</span><span class="fu">&gt;</span> (<span class="dt">MakePair</span> <span class="dv">1</span> <span class="dv">2</span>) <span class="fu">&gt;</span> (<span class="dt">MakePair</span> <span class="dv">2</span> <span class="dv">3</span>)</a>
<a class="sourceLine" id="cb348-4" data-line-number="4"><span class="dt">False</span></a>
<a class="sourceLine" id="cb348-5" data-line-number="5"><span class="fu">*</span><span class="dt">Main</span><span class="fu">&gt;</span> compare (<span class="dt">MakePair</span> <span class="dv">1</span> <span class="dv">2</span>) (<span class="dt">MakePair</span> <span class="dv">2</span> <span class="dv">3</span>)</a>
<a class="sourceLine" id="cb348-6" data-line-number="6"><span class="dt">LT</span></a></code></pre></div>
<h2 id="useful-stuff"><span class="header-section-number">6.4</span> Useful stuff</h2>
<h3 id="deriving"><span class="header-section-number">6.4.1</span> Deriving</h3>
<p>As we’ve seen many times already, <code>deriving</code> is a way to get automatically generated class instances. The <code>Read</code> and <code>Show</code> classes should pretty much always be derived to get the standard behaviour. The derived instance for <code>Eq</code> is typically what you want. It requires constructors and fields to match.</p>
<p>The derived <code>Ord</code> instance might not be what you want. It orders constructors left-to-right, and then compares fields inside constructors left-to-right. An example:</p>
<div class="sourceCode" id="cb346"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb346-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Person</span> <span class="fu">=</span> <span class="dt">Dead</span> <span class="fu">|</span> <span class="dt">Alive</span> <span class="dt">String</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb346-2" data-line-number="2"> <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>, <span class="dt">Ord</span>)</a></code></pre></div>
<div class="sourceCode" id="cb347"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb347-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="dt">Dead</span> <span class="fu">&lt;</span> <span class="dt">Alive</span> <span class="st">&quot;Bob&quot;</span> <span class="dv">35</span> <span class="co">-- constructors are ordered left-to-right</span></a>
<a class="sourceLine" id="cb347-2" data-line-number="2"><span class="dt">True</span></a>
<a class="sourceLine" id="cb347-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="dt">Alive</span> <span class="st">&quot;Barbara&quot;</span> <span class="dv">35</span> <span class="fu">&lt;</span> <span class="dt">Alive</span> <span class="st">&quot;Clive&quot;</span> <span class="dv">17</span> <span class="co">-- names are compared before ages</span></a>
<a class="sourceLine" id="cb347-4" data-line-number="4"><span class="dt">True</span></a>
<a class="sourceLine" id="cb347-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="dt">Alive</span> <span class="st">&quot;Clive&quot;</span> <span class="dv">17</span> <span class="fu">&lt;</span> <span class="dt">Alive</span> <span class="st">&quot;Clive&quot;</span> <span class="dv">30</span> <span class="co">-- finally, ages are compared if names match</span></a>
<a class="sourceLine" id="cb347-6" data-line-number="6"><span class="dt">True</span></a></code></pre></div>
<h3 id="asking-ghci-about-classes"><span class="header-section-number">6.3.2</span> Asking GHCi about classes</h3>
<div class="sourceCode" id="cb349"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb349-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Person</span> <span class="fu">=</span> <span class="dt">Dead</span> <span class="fu">|</span> <span class="dt">Alive</span> <span class="dt">String</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb349-2" data-line-number="2"> <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>, <span class="dt">Ord</span>)</a></code></pre></div>
<div class="sourceCode" id="cb350"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb350-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="dt">Dead</span> <span class="fu">&lt;</span> <span class="dt">Alive</span> <span class="st">&quot;Bob&quot;</span> <span class="dv">35</span> <span class="co">-- constructors are ordered left-to-right</span></a>
<a class="sourceLine" id="cb350-2" data-line-number="2"><span class="dt">True</span></a>
<a class="sourceLine" id="cb350-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="dt">Alive</span> <span class="st">&quot;Barbara&quot;</span> <span class="dv">35</span> <span class="fu">&lt;</span> <span class="dt">Alive</span> <span class="st">&quot;Clive&quot;</span> <span class="dv">17</span> <span class="co">-- names are compared before ages</span></a>
<a class="sourceLine" id="cb350-4" data-line-number="4"><span class="dt">True</span></a>
<a class="sourceLine" id="cb350-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="dt">Alive</span> <span class="st">&quot;Clive&quot;</span> <span class="dv">17</span> <span class="fu">&lt;</span> <span class="dt">Alive</span> <span class="st">&quot;Clive&quot;</span> <span class="dv">30</span> <span class="co">-- finally, ages are compared if names match</span></a>
<a class="sourceLine" id="cb350-6" data-line-number="6"><span class="dt">True</span></a></code></pre></div>
<h3 id="asking-ghci-about-classes"><span class="header-section-number">6.4.2</span> Asking GHCi about classes</h3>
<p>You can use the <code>:info</code> command in GHCi to get the contents and instances of a class. These days the info even includes the minimal complete definition (see the MINIMAL pragma). For example:</p>
<div class="sourceCode" id="cb348"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb348-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>info <span class="dt">Num</span></a>
<a class="sourceLine" id="cb348-2" data-line-number="2"><span class="kw">class</span> <span class="dt">Num</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb348-3" data-line-number="3"><span class="ot"> (+) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb348-4" data-line-number="4"><span class="ot"> (-) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb348-5" data-line-number="5"><span class="ot"> (*) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb348-6" data-line-number="6"><span class="ot"> negate ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb348-7" data-line-number="7"><span class="ot"> abs ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb348-8" data-line-number="8"><span class="ot"> signum ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb348-9" data-line-number="9"><span class="ot"> fromInteger ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb348-10" data-line-number="10"> <span class="ot">{-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}</span></a>
<a class="sourceLine" id="cb348-11" data-line-number="11"> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb348-12" data-line-number="12"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Word</span> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb348-13" data-line-number="13"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Integer</span> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb348-14" data-line-number="14"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Int</span> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb348-15" data-line-number="15"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Float</span> <span class="co">-- Defined in ‘GHC.Float’</span></a>
<a class="sourceLine" id="cb348-16" data-line-number="16"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Double</span> <span class="co">-- Defined in ‘GHC.Float’</span></a></code></pre></div>
<h2 id="hierarchies"><span class="header-section-number">6.4</span> Hierarchies</h2>
<div class="sourceCode" id="cb351"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb351-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>info <span class="dt">Num</span></a>
<a class="sourceLine" id="cb351-2" data-line-number="2"><span class="kw">class</span> <span class="dt">Num</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb351-3" data-line-number="3"><span class="ot"> (+) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb351-4" data-line-number="4"><span class="ot"> (-) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb351-5" data-line-number="5"><span class="ot"> (*) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb351-6" data-line-number="6"><span class="ot"> negate ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb351-7" data-line-number="7"><span class="ot"> abs ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb351-8" data-line-number="8"><span class="ot"> signum ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb351-9" data-line-number="9"><span class="ot"> fromInteger ::</span> <span class="dt">Integer</span> <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb351-10" data-line-number="10"> <span class="ot">{-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}</span></a>
<a class="sourceLine" id="cb351-11" data-line-number="11"> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb351-12" data-line-number="12"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Word</span> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb351-13" data-line-number="13"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Integer</span> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb351-14" data-line-number="14"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Int</span> <span class="co">-- Defined in ‘GHC.Num’</span></a>
<a class="sourceLine" id="cb351-15" data-line-number="15"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Float</span> <span class="co">-- Defined in ‘GHC.Float’</span></a>
<a class="sourceLine" id="cb351-16" data-line-number="16"><span class="kw">instance</span> <span class="dt">Num</span> <span class="dt">Double</span> <span class="co">-- Defined in ‘GHC.Float’</span></a></code></pre></div>
<h2 id="hierarchies"><span class="header-section-number">6.5</span> Hierarchies</h2>
<p>Both classes and instances can form <em>hierarchies</em>. This means that a class or instance depends on another class or instance.</p>
<p>Let’s start with a simple type class and instance</p>
<div class="sourceCode" id="cb349"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb349-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Check</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb349-2" data-line-number="2"><span class="ot"> check ::</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb349-3" data-line-number="3"></a>
<a class="sourceLine" id="cb349-4" data-line-number="4"><span class="kw">instance</span> <span class="dt">Check</span> <span class="dt">Int</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb349-5" data-line-number="5"> check x <span class="fu">=</span> x <span class="fu">&gt;</span> <span class="dv">0</span></a></code></pre></div>
<div class="sourceCode" id="cb352"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb352-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Check</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb352-2" data-line-number="2"><span class="ot"> check ::</span> a <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb352-3" data-line-number="3"></a>
<a class="sourceLine" id="cb352-4" data-line-number="4"><span class="kw">instance</span> <span class="dt">Check</span> <span class="dt">Int</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb352-5" data-line-number="5"> check x <span class="fu">=</span> x <span class="fu">&gt;</span> <span class="dv">0</span></a></code></pre></div>
<p>Now we can write a function that checks a list:</p>
<div class="sourceCode" id="cb350"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb350-1" data-line-number="1"><span class="ot">checkAll ::</span> <span class="dt">Check</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb350-2" data-line-number="2">checkAll <span class="fu">=</span> and (map check xs)</a></code></pre></div>
<div class="sourceCode" id="cb353"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb353-1" data-line-number="1"><span class="ot">checkAll ::</span> <span class="dt">Check</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb353-2" data-line-number="2">checkAll <span class="fu">=</span> and (map check xs)</a></code></pre></div>
<p>In order to turn this into a <code>Check [a]</code> instance, we need to add a constraint to the instance declaration. Our <code>Check [a]</code> is based on the <code>Check a</code> instance.</p>
<div class="sourceCode" id="cb351"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb351-1" data-line-number="1"><span class="kw">instance</span> <span class="dt">Check</span> a <span class="ot">=&gt;</span> <span class="dt">Check</span> [a] <span class="kw">where</span></a>
<a class="sourceLine" id="cb351-2" data-line-number="2"> check xs <span class="fu">=</span> and (map check xs)</a></code></pre></div>
<div class="sourceCode" id="cb354"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb354-1" data-line-number="1"><span class="kw">instance</span> <span class="dt">Check</span> a <span class="ot">=&gt;</span> <span class="dt">Check</span> [a] <span class="kw">where</span></a>
<a class="sourceLine" id="cb354-2" data-line-number="2"> check xs <span class="fu">=</span> and (map check xs)</a></code></pre></div>
<p>This means that our <code>Check [a]</code> instance is only valid when there is a corresponding <code>Check a</code> instance. For example, if we try to invoke a <code>Check [Bool]</code> instance, we get an error about the missing <code>Check Bool</code> instance:</p>
<div class="sourceCode" id="cb352"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb352-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> check [<span class="dt">True</span>,<span class="dt">False</span>]</a>
<a class="sourceLine" id="cb352-2" data-line-number="2"></a>
<a class="sourceLine" id="cb352-3" data-line-number="3"><span class="fu">&lt;</span>interactive<span class="fu">&gt;:</span><span class="dv">1</span><span class="fu">:</span><span class="dv">1</span><span class="fu">:</span> error<span class="fu">:</span></a>
<a class="sourceLine" id="cb352-4" data-line-number="4"> • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">Check</span> <span class="dt">Bool</span>) arising from a use <span class="kw">of</span> ‘check’</a>
<a class="sourceLine" id="cb352-5" data-line-number="5"> • <span class="dt">In</span> the expression<span class="fu">:</span> check [<span class="dt">True</span>, <span class="dt">False</span>]</a>
<a class="sourceLine" id="cb352-6" data-line-number="6"> <span class="dt">In</span> an equation for ‘it’<span class="fu">:</span> it <span class="fu">=</span> check [<span class="dt">True</span>, <span class="dt">False</span>]</a></code></pre></div>
<div class="sourceCode" id="cb355"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb355-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> check [<span class="dt">True</span>,<span class="dt">False</span>]</a>
<a class="sourceLine" id="cb355-2" data-line-number="2"></a>
<a class="sourceLine" id="cb355-3" data-line-number="3"><span class="fu">&lt;</span>interactive<span class="fu">&gt;:</span><span class="dv">1</span><span class="fu">:</span><span class="dv">1</span><span class="fu">:</span> error<span class="fu">:</span></a>
<a class="sourceLine" id="cb355-4" data-line-number="4"> • <span class="dt">No</span> <span class="kw">instance</span> for (<span class="dt">Check</span> <span class="dt">Bool</span>) arising from a use <span class="kw">of</span> ‘check’</a>
<a class="sourceLine" id="cb355-5" data-line-number="5"> • <span class="dt">In</span> the expression<span class="fu">:</span> check [<span class="dt">True</span>, <span class="dt">False</span>]</a>
<a class="sourceLine" id="cb355-6" data-line-number="6"> <span class="dt">In</span> an equation for ‘it’<span class="fu">:</span> it <span class="fu">=</span> check [<span class="dt">True</span>, <span class="dt">False</span>]</a></code></pre></div>
<p>Also, if we try to define <code>Check [a]</code> instance without the constraint, we get an error (with a pretty good suggestion!)</p>
<pre><code> • No instance for (Check a) arising from a use of ‘check’
Possible fix:
add (Check a) to the context of the instance declaration</code></pre>
<p>If you think about it, this instance hierarchy allows us to circumventing the limitation that we can’t make a <code>Check [Int]</code> instance.</p>
<p>Respectively, a class can depend on another class. This is useful for instance when you want to use functions from another class in your default implementations:</p>
<div class="sourceCode" id="cb354"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb354-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Size</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb354-2" data-line-number="2"><span class="ot"> size ::</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb354-3" data-line-number="3"></a>
<a class="sourceLine" id="cb354-4" data-line-number="4"><span class="kw">class</span> <span class="dt">Size</span> a <span class="ot">=&gt;</span> <span class="dt">SizeBoth</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb354-5" data-line-number="5"><span class="ot"> sizeBoth ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb354-6" data-line-number="6"> sizeBoth x y <span class="fu">=</span> size x <span class="fu">+</span> size y</a></code></pre></div>
<div class="sourceCode" id="cb357"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb357-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Size</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb357-2" data-line-number="2"><span class="ot"> size ::</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb357-3" data-line-number="3"></a>
<a class="sourceLine" id="cb357-4" data-line-number="4"><span class="kw">class</span> <span class="dt">Size</span> a <span class="ot">=&gt;</span> <span class="dt">SizeBoth</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb357-5" data-line-number="5"><span class="ot"> sizeBoth ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb357-6" data-line-number="6"> sizeBoth x y <span class="fu">=</span> size x <span class="fu">+</span> size y</a></code></pre></div>
<p>In cases like this we say <code>SizeBoth</code> is a <em>subclass</em> of <code>Size</code>. Note again the confusion with object oriented programming. Examples of subclasses in the standard library include:</p>
<div class="sourceCode" id="cb355"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb355-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Ord</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb355-2" data-line-number="2"> <span class="fu">...</span></a>
<a class="sourceLine" id="cb355-3" data-line-number="3"><span class="kw">class</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Fractional</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb355-4" data-line-number="4"> <span class="fu">...</span></a></code></pre></div>
<h2 id="todo-quiz"><span class="header-section-number">6.5</span> TODO: Quiz</h2>
<h2 id="exercises-5"><span class="header-section-number">6.6</span> Exercises</h2>
<div class="sourceCode" id="cb358"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb358-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Eq</span> a <span class="ot">=&gt;</span> <span class="dt">Ord</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb358-2" data-line-number="2"> <span class="fu">...</span></a>
<a class="sourceLine" id="cb358-3" data-line-number="3"><span class="kw">class</span> <span class="dt">Num</span> a <span class="ot">=&gt;</span> <span class="dt">Fractional</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb358-4" data-line-number="4"> <span class="fu">...</span></a></code></pre></div>
<p>Another way to look at subclasses is that if you have a <code>class Sub a =&gt; Main a</code>, you must provide an <code>instance Sub MyType</code> in order to be able to declare <code>instance Main MyType</code>.</p>
<h2 id="quiz-5"><span class="header-section-number">6.6</span> Quiz</h2>
<p>What are the functions in the <code>Eq</code> class?</p>
<ol class="quiz">
<li class="correct">
<code>(==), (/=)</code>
</li>
<li>
<code>(==)</code>
</li>
<li>
<code>(==)</code>, <code>(&lt;)</code>, <code>(&gt;)</code>
</li>
</ol>
<p>For which of the following classes can we get automatic instances with <code>deriving</code>?</p>
<ol class="quiz">
<li>
<code>Num</code>
</li>
<li class="correct">
<code>Ord</code>
</li>
<li>
<code>Size</code>
</li>
</ol>
<p>Which of the following instance declarations is legal?</p>
<ol class="quiz">
<li>
<code>instance Eq Maybe</code>
</li>
<li>
<code>instance Eq (a,a)</code>
</li>
<li>
<code>instance Eq (Maybe Int)</code>
</li>
<li class="correct">
<code>instance Eq (a,b)</code>
</li>
</ol>
<p>Given the following definition of the class <code>BitOperations</code></p>
<div class="sourceCode" id="cb359"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb359-1" data-line-number="1"><span class="kw">class</span> <span class="dt">BitOperations</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb359-2" data-line-number="2"><span class="ot"> bitNot ::</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb359-3" data-line-number="3"> bitNot x <span class="fu">=</span> bitXor x x</a>
<a class="sourceLine" id="cb359-4" data-line-number="4"><span class="ot"> bitAnd ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb359-5" data-line-number="5"> bitAnd x y <span class="fu">=</span> bitNot (bitOr (bitNot x) (bitNot y))</a>
<a class="sourceLine" id="cb359-6" data-line-number="6"><span class="ot"> bitOr ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb359-7" data-line-number="7"> bitOr x y <span class="fu">=</span> bitNot (bitAnd (bitNot x) (bitNot y))</a>
<a class="sourceLine" id="cb359-8" data-line-number="8"><span class="ot"> bitXor ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb359-9" data-line-number="9"> bitXor x y <span class="fu">=</span> bitAnd (bitOr x y) (bitOr (bitNot x) (botNot y))</a></code></pre></div>
<p>which set of operations is <em>not</em> a minimal complete definition of <code>BitOperations</code>?</p>
<ol class="quiz">
<li>
<code>bitXor, bitAnd</code>
</li>
<li class="correct">
<code>bitAnd, bitOr</code>
</li>
<li>
<code>bitAnd, bitNot</code>
</li>
<li>
<code>bitNot, bitAnd, bitOr</code>
</li>
</ol>
<p>The declaration <code>instance Num a =&gt; Eq (Pair a)</code> tells me that</p>
<ol class="quiz">
<li>
All instances of <code>Num</code> are instances of <code>Eq</code>
</li>
<li class="correct">
<code>Pair a</code> is an instance of <code>Eq</code> if <code>a</code> is an instance of <code>Num</code>
</li>
<li>
The instance <code>Eq (Pair a)</code> inherits the instance <code>Num a</code>
</li>
</ol>
<p>The declaration <code>class Num a =&gt; Fractional a</code> tells me that</p>
<ol class="quiz">
<li class="correct">
All instances of <code>Fractional</code> must be instances of <code>Num</code>
</li>
<li>
All instances of <code>Num</code> must be instances of <code>Fractional</code>
</li>
<li>
If I define an instance for <code>Fractional</code>, I also get an instance for <code>Num</code>
</li>
<li>
If I define an instance for <code>Num</code>, I also get an instance for <code>Fractional</code>
</li>
</ol>
<h2 id="exercises-5"><span class="header-section-number">6.7</span> Exercises</h2>
<ul>
<li>Defining classes and instances: Set6</li>
</ul>
@@ -2969,72 +3084,72 @@ Because <code>Nothing</code> is a constructor.
<h2 id="modeling-with-boxes"><span class="header-section-number">7.1</span> Modeling with boxes</h2>
<p>Sometimes you don’t need a new type, but instead can just reuse a standard type. For example, repesenting car register plate numbers with <code>String</code>. However, if your code is full of <code>String</code>s, it can be easy to accidentally mix up e.g. a car’s model and registration in a function like <code>registerCar :: String -&gt; String -&gt; CarRegistry -&gt; CarRegistry</code>.</p>
<p>For situations like this it’s common to create a new type that just contains a <code>String</code> (a “boxed” string):</p>
<div class="sourceCode" id="cb356"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb356-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Plate</span> <span class="fu">=</span> <span class="dt">Plate</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb356-2" data-line-number="2"> <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>)</a></code></pre></div>
<div class="sourceCode" id="cb360"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb360-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Plate</span> <span class="fu">=</span> <span class="dt">Plate</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb360-2" data-line-number="2"> <span class="kw">deriving</span> (<span class="dt">Show</span>, <span class="dt">Eq</span>)</a></code></pre></div>
<p>We can now give <code>registerCar</code> a slightly nicer type, <code>String -&gt; Plate -&gt; CarRegistry -&gt; CarRegistry</code>. Additionally, we can restrict the operations that are possible on <code>Plate</code>s to a subset of those that are possible on strings. For example, there is no need to combine the register plate numbers of two cars. Thus we don’t need to offer a function <code>concatPlates :: Plate -&gt; Plate -&gt; Plate</code>. We can also define a <em>smart constructor</em> for <code>Plate</code> that checks that the register number is in the correct format:</p>
<div class="sourceCode" id="cb357"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb357-1" data-line-number="1"><span class="ot">parsePlate ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Plate</span></a>
<a class="sourceLine" id="cb357-2" data-line-number="2">parsePlate string</a>
<a class="sourceLine" id="cb357-3" data-line-number="3"> <span class="fu">|</span> correctPlateNumber string <span class="fu">=</span> <span class="dt">Just</span> (<span class="dt">Plate</span> string)</a>
<a class="sourceLine" id="cb357-4" data-line-number="4"> <span class="fu">|</span> otherwise <span class="fu">=</span> <span class="dt">Nothing</span></a></code></pre></div>
<div class="sourceCode" id="cb361"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb361-1" data-line-number="1"><span class="ot">parsePlate ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Maybe</span> <span class="dt">Plate</span></a>
<a class="sourceLine" id="cb361-2" data-line-number="2">parsePlate string</a>
<a class="sourceLine" id="cb361-3" data-line-number="3"> <span class="fu">|</span> correctPlateNumber string <span class="fu">=</span> <span class="dt">Just</span> (<span class="dt">Plate</span> string)</a>
<a class="sourceLine" id="cb361-4" data-line-number="4"> <span class="fu">|</span> otherwise <span class="fu">=</span> <span class="dt">Nothing</span></a></code></pre></div>
<p>Here’s another example: representing money. If we just store money as <code>Int</code>s, the compiler won’t protect us from mistakes like multiplying money with money. If instead we implement our own <code>Money</code> type that wraps <code>Int</code>, we get type safety. Additionally, we can encapsulate the fact that money is represented as an integer amount of cents.</p>
<div class="sourceCode" id="cb358"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb358-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Money</span> <span class="fu">=</span> <span class="dt">Money</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb358-2" data-line-number="2"> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb358-3" data-line-number="3"></a>
<a class="sourceLine" id="cb358-4" data-line-number="4"><span class="ot">renderMoney ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb358-5" data-line-number="5">renderMoney (<span class="dt">Money</span> cents) <span class="fu">=</span> show (fromIntegral cents <span class="fu">/</span> <span class="dv">100</span>)</a>
<a class="sourceLine" id="cb358-6" data-line-number="6"></a>
<a class="sourceLine" id="cb358-7" data-line-number="7"><span class="ot">(+!) ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Money</span></a>
<a class="sourceLine" id="cb358-8" data-line-number="8">(<span class="dt">Money</span> a) <span class="fu">+!</span> (<span class="dt">Money</span> b) <span class="fu">=</span> <span class="dt">Money</span> (a<span class="fu">+</span>b)</a>
<a class="sourceLine" id="cb358-9" data-line-number="9"></a>
<a class="sourceLine" id="cb358-10" data-line-number="10"><span class="ot">scale ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Money</span></a>
<a class="sourceLine" id="cb358-11" data-line-number="11">scale (<span class="dt">Money</span> a) x <span class="fu">=</span> <span class="dt">Money</span> (round (fromIntegral a <span class="fu">*</span> x))</a>
<a class="sourceLine" id="cb358-12" data-line-number="12"></a>
<a class="sourceLine" id="cb358-13" data-line-number="13"><span class="ot">addVat ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Money</span></a>
<a class="sourceLine" id="cb358-14" data-line-number="14">addVat m <span class="fu">=</span> m <span class="fu">+!</span> scale m <span class="fl">0.24</span></a></code></pre></div>
<div class="sourceCode" id="cb359"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb359-1" data-line-number="1">renderMoney (<span class="dt">Money</span> <span class="dv">100</span> <span class="fu">+!</span> <span class="dt">Money</span> <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb359-2" data-line-number="2"> <span class="fu">==&gt;</span> <span class="st">&quot;2.5&quot;</span></a>
<a class="sourceLine" id="cb359-3" data-line-number="3"></a>
<a class="sourceLine" id="cb359-4" data-line-number="4">scale (<span class="dt">Money</span> <span class="dv">299</span>) <span class="fl">0.24</span></a>
<a class="sourceLine" id="cb359-5" data-line-number="5"> <span class="fu">==&gt;</span> <span class="dt">Money</span> <span class="dv">72</span></a>
<a class="sourceLine" id="cb359-6" data-line-number="6"></a>
<a class="sourceLine" id="cb359-7" data-line-number="7">addVat (<span class="dt">Money</span> <span class="dv">299</span>)</a>
<a class="sourceLine" id="cb359-8" data-line-number="8"> <span class="fu">==&gt;</span> <span class="dt">Money</span> <span class="dv">371</span></a></code></pre></div>
<div class="sourceCode" id="cb362"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb362-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Money</span> <span class="fu">=</span> <span class="dt">Money</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb362-2" data-line-number="2"> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb362-3" data-line-number="3"></a>
<a class="sourceLine" id="cb362-4" data-line-number="4"><span class="ot">renderMoney ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb362-5" data-line-number="5">renderMoney (<span class="dt">Money</span> cents) <span class="fu">=</span> show (fromIntegral cents <span class="fu">/</span> <span class="dv">100</span>)</a>
<a class="sourceLine" id="cb362-6" data-line-number="6"></a>
<a class="sourceLine" id="cb362-7" data-line-number="7"><span class="ot">(+!) ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Money</span></a>
<a class="sourceLine" id="cb362-8" data-line-number="8">(<span class="dt">Money</span> a) <span class="fu">+!</span> (<span class="dt">Money</span> b) <span class="fu">=</span> <span class="dt">Money</span> (a<span class="fu">+</span>b)</a>
<a class="sourceLine" id="cb362-9" data-line-number="9"></a>
<a class="sourceLine" id="cb362-10" data-line-number="10"><span class="ot">scale ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Money</span></a>
<a class="sourceLine" id="cb362-11" data-line-number="11">scale (<span class="dt">Money</span> a) x <span class="fu">=</span> <span class="dt">Money</span> (round (fromIntegral a <span class="fu">*</span> x))</a>
<a class="sourceLine" id="cb362-12" data-line-number="12"></a>
<a class="sourceLine" id="cb362-13" data-line-number="13"><span class="ot">addVat ::</span> <span class="dt">Money</span> <span class="ot">-&gt;</span> <span class="dt">Money</span></a>
<a class="sourceLine" id="cb362-14" data-line-number="14">addVat m <span class="fu">=</span> m <span class="fu">+!</span> scale m <span class="fl">0.24</span></a></code></pre></div>
<div class="sourceCode" id="cb363"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb363-1" data-line-number="1">renderMoney (<span class="dt">Money</span> <span class="dv">100</span> <span class="fu">+!</span> <span class="dt">Money</span> <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb363-2" data-line-number="2"> <span class="fu">==&gt;</span> <span class="st">&quot;2.5&quot;</span></a>
<a class="sourceLine" id="cb363-3" data-line-number="3"></a>
<a class="sourceLine" id="cb363-4" data-line-number="4">scale (<span class="dt">Money</span> <span class="dv">299</span>) <span class="fl">0.24</span></a>
<a class="sourceLine" id="cb363-5" data-line-number="5"> <span class="fu">==&gt;</span> <span class="dt">Money</span> <span class="dv">72</span></a>
<a class="sourceLine" id="cb363-6" data-line-number="6"></a>
<a class="sourceLine" id="cb363-7" data-line-number="7">addVat (<span class="dt">Money</span> <span class="dv">299</span>)</a>
<a class="sourceLine" id="cb363-8" data-line-number="8"> <span class="fu">==&gt;</span> <span class="dt">Money</span> <span class="dv">371</span></a></code></pre></div>
<h2 id="modeling-with-cases"><span class="header-section-number">7.2</span> Modeling with cases</h2>
<p>Haskell’s algebraic datatypes are really powerful at modeling things based on <em>cases</em>. It’s often useful to think of types as defining the set of possible cases, and functions <em>handling</em> those cases (often via pattern matching). Let’s look at two examples.</p>
<p>Since it’s so easy to define custom types in Haskell, it’s quite convenient to use more descriptive types instead of booleans or strings. Consider a list of persons. In some other language if you wanted to sort the persons into ascending order by name you might use a call like <code>sortPersons(persons, &quot;name&quot;, true)</code>. In Haskell you can do this instead:</p>
<div class="sourceCode" id="cb360"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb360-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Person</span> <span class="fu">=</span> <span class="dt">Person</span> {<span class="ot">name ::</span> <span class="dt">String</span>,<span class="ot"> age ::</span> <span class="dt">Int</span>}</a>
<a class="sourceLine" id="cb360-2" data-line-number="2"> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb360-3" data-line-number="3"></a>
<a class="sourceLine" id="cb360-4" data-line-number="4"><span class="kw">data</span> <span class="dt">SortOrder</span> <span class="fu">=</span> <span class="dt">Ascending</span> <span class="fu">|</span> <span class="dt">Descending</span></a>
<a class="sourceLine" id="cb360-5" data-line-number="5"><span class="kw">data</span> <span class="dt">SortField</span> <span class="fu">=</span> <span class="dt">Name</span> <span class="fu">|</span> <span class="dt">Age</span></a>
<a class="sourceLine" id="cb360-6" data-line-number="6"></a>
<a class="sourceLine" id="cb360-7" data-line-number="7"><span class="ot">sortByField ::</span> <span class="dt">SortField</span> <span class="ot">-&gt;</span> [<span class="dt">Person</span>] <span class="ot">-&gt;</span> [<span class="dt">Person</span>]</a>
<a class="sourceLine" id="cb360-8" data-line-number="8">sortByField <span class="dt">Name</span> ps <span class="fu">=</span> sortBy (comparing name) ps</a>
<a class="sourceLine" id="cb360-9" data-line-number="9">sortByField <span class="dt">Age</span> ps <span class="fu">=</span> sortBy (comparing age) ps</a>
<a class="sourceLine" id="cb360-10" data-line-number="10"></a>
<a class="sourceLine" id="cb360-11" data-line-number="11"><span class="ot">sortPersons ::</span> <span class="dt">SortField</span> <span class="ot">-&gt;</span> <span class="dt">SortOrder</span> <span class="ot">-&gt;</span> [<span class="dt">Person</span>] <span class="ot">-&gt;</span> [<span class="dt">Person</span>]</a>
<a class="sourceLine" id="cb360-12" data-line-number="12">sortPersons field <span class="dt">Ascending</span> ps <span class="fu">=</span> sortByField field ps</a>
<a class="sourceLine" id="cb360-13" data-line-number="13">sortPersons field <span class="dt">Descending</span> ps <span class="fu">=</span> reverse (sortByField field ps)</a>
<a class="sourceLine" id="cb360-14" data-line-number="14"></a>
<a class="sourceLine" id="cb360-15" data-line-number="15">persons <span class="fu">=</span> [<span class="dt">Person</span> <span class="st">&quot;Fridolf&quot;</span> <span class="dv">73</span>, <span class="dt">Person</span> <span class="st">&quot;Greta&quot;</span> <span class="dv">60</span>, <span class="dt">Person</span> <span class="st">&quot;Hans&quot;</span> <span class="dv">65</span>]</a></code></pre></div>
<div class="sourceCode" id="cb361"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb361-1" data-line-number="1">sortPersons <span class="dt">Name</span> <span class="dt">Ascending</span> persons</a>
<a class="sourceLine" id="cb361-2" data-line-number="2"> <span class="fu">==&gt;</span> [<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Fridolf&quot;</span>, age <span class="fu">=</span> <span class="dv">73</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Greta&quot;</span>, age <span class="fu">=</span> <span class="dv">60</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Hans&quot;</span>, age <span class="fu">=</span> <span class="dv">65</span>}]</a>
<a class="sourceLine" id="cb361-3" data-line-number="3">sortPersons <span class="dt">Age</span> <span class="dt">Descending</span> persons</a>
<a class="sourceLine" id="cb361-4" data-line-number="4"> <span class="fu">==&gt;</span> [<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Fridolf&quot;</span>, age <span class="fu">=</span> <span class="dv">73</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Hans&quot;</span>, age <span class="fu">=</span> <span class="dv">65</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Greta&quot;</span>, age <span class="fu">=</span> <span class="dv">60</span>}]</a></code></pre></div>
<div class="sourceCode" id="cb364"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb364-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Person</span> <span class="fu">=</span> <span class="dt">Person</span> {<span class="ot">name ::</span> <span class="dt">String</span>,<span class="ot"> age ::</span> <span class="dt">Int</span>}</a>
<a class="sourceLine" id="cb364-2" data-line-number="2"> <span class="kw">deriving</span> <span class="dt">Show</span></a>
<a class="sourceLine" id="cb364-3" data-line-number="3"></a>
<a class="sourceLine" id="cb364-4" data-line-number="4"><span class="kw">data</span> <span class="dt">SortOrder</span> <span class="fu">=</span> <span class="dt">Ascending</span> <span class="fu">|</span> <span class="dt">Descending</span></a>
<a class="sourceLine" id="cb364-5" data-line-number="5"><span class="kw">data</span> <span class="dt">SortField</span> <span class="fu">=</span> <span class="dt">Name</span> <span class="fu">|</span> <span class="dt">Age</span></a>
<a class="sourceLine" id="cb364-6" data-line-number="6"></a>
<a class="sourceLine" id="cb364-7" data-line-number="7"><span class="ot">sortByField ::</span> <span class="dt">SortField</span> <span class="ot">-&gt;</span> [<span class="dt">Person</span>] <span class="ot">-&gt;</span> [<span class="dt">Person</span>]</a>
<a class="sourceLine" id="cb364-8" data-line-number="8">sortByField <span class="dt">Name</span> ps <span class="fu">=</span> sortBy (comparing name) ps</a>
<a class="sourceLine" id="cb364-9" data-line-number="9">sortByField <span class="dt">Age</span> ps <span class="fu">=</span> sortBy (comparing age) ps</a>
<a class="sourceLine" id="cb364-10" data-line-number="10"></a>
<a class="sourceLine" id="cb364-11" data-line-number="11"><span class="ot">sortPersons ::</span> <span class="dt">SortField</span> <span class="ot">-&gt;</span> <span class="dt">SortOrder</span> <span class="ot">-&gt;</span> [<span class="dt">Person</span>] <span class="ot">-&gt;</span> [<span class="dt">Person</span>]</a>
<a class="sourceLine" id="cb364-12" data-line-number="12">sortPersons field <span class="dt">Ascending</span> ps <span class="fu">=</span> sortByField field ps</a>
<a class="sourceLine" id="cb364-13" data-line-number="13">sortPersons field <span class="dt">Descending</span> ps <span class="fu">=</span> reverse (sortByField field ps)</a>
<a class="sourceLine" id="cb364-14" data-line-number="14"></a>
<a class="sourceLine" id="cb364-15" data-line-number="15">persons <span class="fu">=</span> [<span class="dt">Person</span> <span class="st">&quot;Fridolf&quot;</span> <span class="dv">73</span>, <span class="dt">Person</span> <span class="st">&quot;Greta&quot;</span> <span class="dv">60</span>, <span class="dt">Person</span> <span class="st">&quot;Hans&quot;</span> <span class="dv">65</span>]</a></code></pre></div>
<div class="sourceCode" id="cb365"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb365-1" data-line-number="1">sortPersons <span class="dt">Name</span> <span class="dt">Ascending</span> persons</a>
<a class="sourceLine" id="cb365-2" data-line-number="2"> <span class="fu">==&gt;</span> [<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Fridolf&quot;</span>, age <span class="fu">=</span> <span class="dv">73</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Greta&quot;</span>, age <span class="fu">=</span> <span class="dv">60</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Hans&quot;</span>, age <span class="fu">=</span> <span class="dv">65</span>}]</a>
<a class="sourceLine" id="cb365-3" data-line-number="3">sortPersons <span class="dt">Age</span> <span class="dt">Descending</span> persons</a>
<a class="sourceLine" id="cb365-4" data-line-number="4"> <span class="fu">==&gt;</span> [<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Fridolf&quot;</span>, age <span class="fu">=</span> <span class="dv">73</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Hans&quot;</span>, age <span class="fu">=</span> <span class="dv">65</span>},<span class="dt">Person</span> {name <span class="fu">=</span> <span class="st">&quot;Greta&quot;</span>, age <span class="fu">=</span> <span class="dv">60</span>}]</a></code></pre></div>
<p>Note how you can’t accidentally typo the field name (unlike with strings), and how you don’t need to remember whether <code>true</code> refers to ascending or descending order.</p>
<p>Let’s move on to the next example. Many Haskell functions don’t work with empty lists (consider <code>head []</code>). If you’re writing code that needs to track whether lists are possibly empty or guaranteed to not be empty, you can use the <code>NonEmpty</code> type from the <a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/Data-List-NonEmpty.html">Data.List.NonEmpty</a> module.</p>
<p>Consider the definition of <code>NonEmpty</code>:</p>
<div class="sourceCode" id="cb362"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb362-1" data-line-number="1"><span class="kw">data</span> <span class="dt">NonEmpty</span> a <span class="fu">=</span> a <span class="fu">:|</span> [a]</a></code></pre></div>
<div class="sourceCode" id="cb366"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb366-1" data-line-number="1"><span class="kw">data</span> <span class="dt">NonEmpty</span> a <span class="fu">=</span> a <span class="fu">:|</span> [a]</a></code></pre></div>
<p>Here the type represents a <em>lack of</em> cases. The type <code>NonEmpty a</code> will always consist of a value of type <code>a</code>, and some further <code>a</code>s, collected in a list. Here are some example values of <code>NonEmpty Int</code>:</p>
<div class="sourceCode" id="cb363"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb363-1" data-line-number="1"><span class="dv">1</span> <span class="fu">:|</span> [<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>]</a>
<a class="sourceLine" id="cb363-2" data-line-number="2"><span class="dv">1</span> <span class="fu">:|</span> []</a></code></pre></div>
<div class="sourceCode" id="cb367"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb367-1" data-line-number="1"><span class="dv">1</span> <span class="fu">:|</span> [<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>]</a>
<a class="sourceLine" id="cb367-2" data-line-number="2"><span class="dv">1</span> <span class="fu">:|</span> []</a></code></pre></div>
<p>Here are the functions that convert between normal lists and nonempty lists. Note how we can’t have a function <code>[a] -&gt; NonEmpty a</code>, but must instead use <code>Maybe</code> to represent the possibility that the list was, indeed, empty. Note also how <code>toList</code> has only one equation, we can’t have a <code>toList []</code> situation due to the type <code>NonEmpty</code>.</p>
<div class="sourceCode" id="cb364"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb364-1" data-line-number="1"><span class="ot">nonEmpty ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">NonEmpty</span> a)</a>
<a class="sourceLine" id="cb364-2" data-line-number="2">nonEmpty [] <span class="fu">=</span> <span class="dt">Nothing</span></a>
<a class="sourceLine" id="cb364-3" data-line-number="3">nonEmpty (x<span class="fu">:</span>xs) <span class="fu">=</span> <span class="dt">Just</span> (x <span class="fu">:|</span> xs)</a>
<a class="sourceLine" id="cb364-4" data-line-number="4"></a>
<a class="sourceLine" id="cb364-5" data-line-number="5"><span class="ot">toList ::</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> [a]</a>
<a class="sourceLine" id="cb364-6" data-line-number="6">toList (x <span class="fu">:|</span> xs) <span class="fu">=</span> x <span class="fu">:</span> xs</a></code></pre></div>
<div class="sourceCode" id="cb368"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb368-1" data-line-number="1"><span class="ot">nonEmpty ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Maybe</span> (<span class="dt">NonEmpty</span> a)</a>
<a class="sourceLine" id="cb368-2" data-line-number="2">nonEmpty [] <span class="fu">=</span> <span class="dt">Nothing</span></a>
<a class="sourceLine" id="cb368-3" data-line-number="3">nonEmpty (x<span class="fu">:</span>xs) <span class="fu">=</span> <span class="dt">Just</span> (x <span class="fu">:|</span> xs)</a>
<a class="sourceLine" id="cb368-4" data-line-number="4"></a>
<a class="sourceLine" id="cb368-5" data-line-number="5"><span class="ot">toList ::</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> [a]</a>
<a class="sourceLine" id="cb368-6" data-line-number="6">toList (x <span class="fu">:|</span> xs) <span class="fu">=</span> x <span class="fu">:</span> xs</a></code></pre></div>
<p>In summary, if you write types that represent all possible cases for your values, and then write functions that handle those cases, your code will be simple and correct.</p>
<h2 id="monoids"><span class="header-section-number">7.3</span> Monoids</h2>
<h3 id="what"><span class="header-section-number">7.3.1</span> What?</h3>
@@ -3042,136 +3157,136 @@ Because <code>Nothing</code> is a constructor.
<p>The <code>&lt;&gt;</code> operation is meant to be <em>associative</em> that is, <code>x &lt;&gt; (y &lt;&gt; z) == (x &lt;&gt; y) &lt;&gt; z</code>. Familiar examples of associative operations include <code>+</code>, <code>*</code>, <code>++</code>, <code>max</code>, etc.</p>
<p>The <code>mempty</code> constant is meant to be a <em>neutral element</em> of the <code>&lt;&gt;</code> operation. This means that <code>mempty &lt;&gt; x == x</code> and <code>x &lt;&gt; mempty == x</code>. The neutral elements of <code>+</code>, <code>*</code> and <code>++</code> are 0, 1 and <code>[]</code>, respectively.</p>
<p>As we can guess at this point, there is a <code>Monoid [a]</code> instance that has <code>(&lt;&gt;) = (++)</code> and <code>mempty = []</code>:</p>
<div class="sourceCode" id="cb365"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb365-1" data-line-number="1">[<span class="dv">1</span>,<span class="dv">2</span>] <span class="fu">&lt;&gt;</span> [<span class="dv">3</span>] <span class="fu">&lt;&gt;</span> mempty <span class="fu">&lt;&gt;</span> [<span class="dv">4</span>] <span class="fu">==&gt;</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>]</a></code></pre></div>
<div class="sourceCode" id="cb369"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb369-1" data-line-number="1">[<span class="dv">1</span>,<span class="dv">2</span>] <span class="fu">&lt;&gt;</span> [<span class="dv">3</span>] <span class="fu">&lt;&gt;</span> mempty <span class="fu">&lt;&gt;</span> [<span class="dv">4</span>] <span class="fu">==&gt;</span> [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>]</a></code></pre></div>
<p>For a type like <code>Int</code>, it would be hard to pick a single instance <code>Monoid Int</code> since there are so many candidates for <code>&lt;&gt;</code>: at least <code>+</code>, <code>*</code>, <code>max</code> and <code>min</code>. That’s why the Haskell standard library defines the wrapper types <code>Sum</code>, <code>Product</code>, <code>Max</code> and <code>Min</code>. These types are from the <code>Data.Monoid</code> and <code>Data.Semigroup</code> modules.</p>
<div class="sourceCode" id="cb366"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb366-1" data-line-number="1"><span class="kw">import</span> <span class="dt">Data.Monoid</span></a>
<a class="sourceLine" id="cb366-2" data-line-number="2"><span class="kw">import</span> <span class="dt">Data.Semigroup</span></a></code></pre></div>
<div class="sourceCode" id="cb370"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb370-1" data-line-number="1"><span class="kw">import</span> <span class="dt">Data.Monoid</span></a>
<a class="sourceLine" id="cb370-2" data-line-number="2"><span class="kw">import</span> <span class="dt">Data.Semigroup</span></a></code></pre></div>
<p>They work like this:</p>
<div class="sourceCode" id="cb367"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb367-1" data-line-number="1"><span class="dt">Max</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Max</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Max</span> <span class="dv">4</span></a>
<a class="sourceLine" id="cb367-2" data-line-number="2"><span class="dt">Min</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Min</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Min</span> <span class="dv">3</span></a>
<a class="sourceLine" id="cb367-3" data-line-number="3"><span class="dt">Sum</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Sum</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Sum</span> <span class="dv">7</span></a>
<a class="sourceLine" id="cb367-4" data-line-number="4"><span class="dt">Product</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Product</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Product</span> <span class="dv">12</span></a></code></pre></div>
<div class="sourceCode" id="cb371"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb371-1" data-line-number="1"><span class="dt">Max</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Max</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Max</span> <span class="dv">4</span></a>
<a class="sourceLine" id="cb371-2" data-line-number="2"><span class="dt">Min</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Min</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Min</span> <span class="dv">3</span></a>
<a class="sourceLine" id="cb371-3" data-line-number="3"><span class="dt">Sum</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Sum</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Sum</span> <span class="dv">7</span></a>
<a class="sourceLine" id="cb371-4" data-line-number="4"><span class="dt">Product</span> <span class="dv">3</span> <span class="fu">&lt;&gt;</span> <span class="dt">Product</span> <span class="dv">4</span> <span class="fu">==&gt;</span> <span class="dt">Product</span> <span class="dv">12</span></a></code></pre></div>
<p>This is another benefit of boxing things: being able to declare different type class instances!</p>
<p>The reason we want both a neutral element and an associative binary operator is that those are the exact two things we need in order to <em>reduce</em> or <em>fold</em> multiple elements into one value. This is the job of:</p>
<div class="sourceCode" id="cb368"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb368-1" data-line-number="1">mconcat<span class="ot"> ::</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</a></code></pre></div>
<div class="sourceCode" id="cb372"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb372-1" data-line-number="1">mconcat<span class="ot"> ::</span> <span class="dt">Monoid</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> a</a></code></pre></div>
<p>Sidenote: one way to define <code>mconcat</code> is <code>foldr (&lt;&gt;) mempty</code>. Do you remember <code>foldr</code>?</p>
<p>Let’s look at why we need the properties of <code>Monoid</code> to implement <code>mconcat</code>. Firstly, we need <code>mempty</code> to handle empty lists:</p>
<div class="sourceCode" id="cb369"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb369-1" data-line-number="1">mconcat []<span class="ot"> ::</span> <span class="dt">Sum</span> <span class="dt">Int</span> <span class="fu">==&gt;</span> <span class="dt">Sum</span> <span class="dv">0</span></a></code></pre></div>
<div class="sourceCode" id="cb373"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb373-1" data-line-number="1">mconcat []<span class="ot"> ::</span> <span class="dt">Sum</span> <span class="dt">Int</span> <span class="fu">==&gt;</span> <span class="dt">Sum</span> <span class="dv">0</span></a></code></pre></div>
<p>Secondly, we need associativity to be able to reduce a list <code>[x,y,z]</code> to a unique value. If <code>&lt;&gt;</code> were not associative, we would have two possible values for <code>mconcat [x,y,z]</code>, namely <code>(x&lt;&gt;y)&lt;&gt;z</code> and <code>x&lt;&gt;(y&lt;&gt;z)</code>.</p>
<h3 id="why"><span class="header-section-number">7.3.2</span> Why?</h3>
<p>What use is this <code>Monoid</code> class? Can’t we just write <code>1 + 2</code> instead of <code>Sum 1 &lt;&gt; Sum 2</code>? We can, yes, but some library functions work on all <code>Monoid</code> types. The most useful one is <code>foldMap</code>:</p>
<div class="sourceCode" id="cb370"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb370-1" data-line-number="1">foldMap<span class="ot"> ::</span> (<span class="dt">Foldable</span> t, <span class="dt">Monoid</span> m) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> m</a></code></pre></div>
<div class="sourceCode" id="cb374"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb374-1" data-line-number="1">foldMap<span class="ot"> ::</span> (<span class="dt">Foldable</span> t, <span class="dt">Monoid</span> m) <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m) <span class="ot">-&gt;</span> t a <span class="ot">-&gt;</span> m</a></code></pre></div>
<p>That looks scary, but it’s very easy to use:</p>
<div class="sourceCode" id="cb371"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb371-1" data-line-number="1">foldMap <span class="dt">Max</span> [<span class="dv">1</span><span class="ot">::</span><span class="dt">Int</span>,<span class="dv">4</span>,<span class="dv">2</span>] <span class="fu">==&gt;</span> <span class="dt">Max</span> <span class="dv">4</span></a>
<a class="sourceLine" id="cb371-2" data-line-number="2">foldMap <span class="dt">Product</span> [<span class="dv">1</span><span class="ot">::</span><span class="dt">Int</span>,<span class="dv">4</span>,<span class="dv">2</span>] <span class="fu">==&gt;</span> <span class="dt">Product</span> <span class="dv">8</span></a>
<a class="sourceLine" id="cb371-3" data-line-number="3"><span class="co">-- We need the ::Int to avoid an &quot;Ambiguous type variable&quot; error when printing the result</span></a></code></pre></div>
<div class="sourceCode" id="cb375"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb375-1" data-line-number="1">foldMap <span class="dt">Max</span> [<span class="dv">1</span><span class="ot">::</span><span class="dt">Int</span>,<span class="dv">4</span>,<span class="dv">2</span>] <span class="fu">==&gt;</span> <span class="dt">Max</span> <span class="dv">4</span></a>
<a class="sourceLine" id="cb375-2" data-line-number="2">foldMap <span class="dt">Product</span> [<span class="dv">1</span><span class="ot">::</span><span class="dt">Int</span>,<span class="dv">4</span>,<span class="dv">2</span>] <span class="fu">==&gt;</span> <span class="dt">Product</span> <span class="dv">8</span></a>
<a class="sourceLine" id="cb375-3" data-line-number="3"><span class="co">-- We need the ::Int to avoid an &quot;Ambiguous type variable&quot; error when printing the result</span></a></code></pre></div>
<p>Let’s break down that type. We know that an example of a <code>Foldable t =&gt; t a</code> type is <code>[a]</code>, so we can rewrite the type as</p>
<div class="sourceCode" id="cb372"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb372-1" data-line-number="1"><span class="ot">foldMap&#39; ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m</a></code></pre></div>
<div class="sourceCode" id="cb376"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb376-1" data-line-number="1"><span class="ot">foldMap&#39; ::</span> <span class="dt">Monoid</span> m <span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> m) <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> m</a></code></pre></div>
<p>this function is easy to implement:</p>
<div class="sourceCode" id="cb373"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb373-1" data-line-number="1">foldMap&#39; f xs <span class="fu">=</span> mconcat (map f xs)</a></code></pre></div>
<div class="sourceCode" id="cb377"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb377-1" data-line-number="1">foldMap&#39; f xs <span class="fu">=</span> mconcat (map f xs)</a></code></pre></div>
<p>Oh, by the way, thanks to the <code>(Monoid a, Monoid b) =&gt; Monoid (a,b)</code> instance we can even compute the maximum and product in one pass:</p>
<div class="sourceCode" id="cb374"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb374-1" data-line-number="1">foldMap (\x <span class="ot">-&gt;</span> (<span class="dt">Max</span> x, <span class="dt">Product</span> x)) [<span class="dv">1</span><span class="ot">::</span><span class="dt">Int</span>,<span class="dv">4</span>,<span class="dv">2</span>] <span class="fu">==&gt;</span> (<span class="dt">Max</span> <span class="dv">4</span>, <span class="dt">Product</span> <span class="dv">8</span>)</a></code></pre></div>
<div class="sourceCode" id="cb378"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb378-1" data-line-number="1">foldMap (\x <span class="ot">-&gt;</span> (<span class="dt">Max</span> x, <span class="dt">Product</span> x)) [<span class="dv">1</span><span class="ot">::</span><span class="dt">Int</span>,<span class="dv">4</span>,<span class="dv">2</span>] <span class="fu">==&gt;</span> (<span class="dt">Max</span> <span class="dv">4</span>, <span class="dt">Product</span> <span class="dv">8</span>)</a></code></pre></div>
<p>Note, you don’t need to use monoids in your own code, but you’ll eventually bump into them when using Haskell libraries so it’s good to know what they are.</p>
<h3 id="how"><span class="header-section-number">7.3.3</span> How?</h3>
<p>Due to various historical and performance reasons, the definition of the <code>Monoid</code> class isn’t just</p>
<div class="sourceCode" id="cb375"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb375-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Monoid</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb375-2" data-line-number="2"><span class="ot"> (&lt;&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb375-3" data-line-number="3"><span class="ot"> mempty ::</span> a</a></code></pre></div>
<div class="sourceCode" id="cb379"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb379-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Monoid</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb379-2" data-line-number="2"><span class="ot"> (&lt;&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb379-3" data-line-number="3"><span class="ot"> mempty ::</span> a</a></code></pre></div>
<p>although you can mostly pretend it is. The actual definition consists of two classes with a number of methods:</p>
<div class="sourceCode" id="cb376"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb376-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Semigroup</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb376-2" data-line-number="2"> <span class="co">-- | An associative operation.</span></a>
<a class="sourceLine" id="cb376-3" data-line-number="3"><span class="ot"> (&lt;&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb376-4" data-line-number="4"></a>
<a class="sourceLine" id="cb376-5" data-line-number="5"> <span class="co">-- Combine elements of a nonempty list with &lt;&gt;</span></a>
<a class="sourceLine" id="cb376-6" data-line-number="6"><span class="ot"> sconcat ::</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb376-7" data-line-number="7"> sconcat as <span class="fu">=</span> <span class="fu">...</span> <span class="co">-- default implementation omitted</span></a>
<a class="sourceLine" id="cb376-8" data-line-number="8"></a>
<a class="sourceLine" id="cb376-9" data-line-number="9"> <span class="co">-- Combine a value with itself using &lt;&gt;, n times</span></a>
<a class="sourceLine" id="cb376-10" data-line-number="10"><span class="ot"> stimes ::</span> <span class="dt">Integral</span> b <span class="ot">=&gt;</span> b <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb376-11" data-line-number="11"> stimes n x <span class="fu">=</span> <span class="fu">...</span> <span class="co">-- default implementation omitted</span></a></code></pre></div>
<div class="sourceCode" id="cb377"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb377-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Semigroup</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb377-2" data-line-number="2"><span class="ot"> mempty ::</span> a</a>
<a class="sourceLine" id="cb377-3" data-line-number="3"></a>
<a class="sourceLine" id="cb377-4" data-line-number="4"><span class="ot"> mappend ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb377-5" data-line-number="5"> mappend <span class="fu">=</span> (<span class="fu">&lt;&gt;</span>)</a>
<a class="sourceLine" id="cb377-6" data-line-number="6"></a>
<a class="sourceLine" id="cb377-7" data-line-number="7"> <span class="co">-- Combine elements of a list with &lt;&gt;</span></a>
<a class="sourceLine" id="cb377-8" data-line-number="8"><span class="ot"> mconcat ::</span> [a] <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb377-9" data-line-number="9"> mconcat <span class="fu">=</span> <span class="fu">...</span> <span class="co">-- default implementation omitted</span></a></code></pre></div>
<div class="sourceCode" id="cb380"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb380-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Semigroup</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb380-2" data-line-number="2"> <span class="co">-- | An associative operation.</span></a>
<a class="sourceLine" id="cb380-3" data-line-number="3"><span class="ot"> (&lt;&gt;) ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb380-4" data-line-number="4"></a>
<a class="sourceLine" id="cb380-5" data-line-number="5"> <span class="co">-- Combine elements of a nonempty list with &lt;&gt;</span></a>
<a class="sourceLine" id="cb380-6" data-line-number="6"><span class="ot"> sconcat ::</span> <span class="dt">NonEmpty</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb380-7" data-line-number="7"> sconcat as <span class="fu">=</span> <span class="fu">...</span> <span class="co">-- default implementation omitted</span></a>
<a class="sourceLine" id="cb380-8" data-line-number="8"></a>
<a class="sourceLine" id="cb380-9" data-line-number="9"> <span class="co">-- Combine a value with itself using &lt;&gt;, n times</span></a>
<a class="sourceLine" id="cb380-10" data-line-number="10"><span class="ot"> stimes ::</span> <span class="dt">Integral</span> b <span class="ot">=&gt;</span> b <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb380-11" data-line-number="11"> stimes n x <span class="fu">=</span> <span class="fu">...</span> <span class="co">-- default implementation omitted</span></a></code></pre></div>
<div class="sourceCode" id="cb381"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb381-1" data-line-number="1"><span class="kw">class</span> <span class="dt">Semigroup</span> a <span class="ot">=&gt;</span> <span class="dt">Monoid</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb381-2" data-line-number="2"><span class="ot"> mempty ::</span> a</a>
<a class="sourceLine" id="cb381-3" data-line-number="3"></a>
<a class="sourceLine" id="cb381-4" data-line-number="4"><span class="ot"> mappend ::</span> a <span class="ot">-&gt;</span> a <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb381-5" data-line-number="5"> mappend <span class="fu">=</span> (<span class="fu">&lt;&gt;</span>)</a>
<a class="sourceLine" id="cb381-6" data-line-number="6"></a>
<a class="sourceLine" id="cb381-7" data-line-number="7"> <span class="co">-- Combine elements of a list with &lt;&gt;</span></a>
<a class="sourceLine" id="cb381-8" data-line-number="8"><span class="ot"> mconcat ::</span> [a] <span class="ot">-&gt;</span> a</a>
<a class="sourceLine" id="cb381-9" data-line-number="9"> mconcat <span class="fu">=</span> <span class="fu">...</span> <span class="co">-- default implementation omitted</span></a></code></pre></div>
<p>As you can see, all the operations except <code>&lt;&gt;</code> and <code>mempty</code> have default definitions, so a normal <code>Monoid</code> instance declaration looks just like this:</p>
<div class="sourceCode" id="cb378"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb378-1" data-line-number="1"><span class="kw">instance</span> <span class="dt">Semigroup</span> <span class="dt">MyType</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb378-2" data-line-number="2"> x <span class="fu">&lt;&gt;</span> y <span class="fu">=</span> <span class="fu">...</span></a>
<a class="sourceLine" id="cb378-3" data-line-number="3"></a>
<a class="sourceLine" id="cb378-4" data-line-number="4"><span class="kw">instance</span> <span class="dt">Monoid</span> <span class="dt">MyType</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb378-5" data-line-number="5"> mempty <span class="fu">=</span> <span class="fu">...</span></a></code></pre></div>
<div class="sourceCode" id="cb382"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb382-1" data-line-number="1"><span class="kw">instance</span> <span class="dt">Semigroup</span> <span class="dt">MyType</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb382-2" data-line-number="2"> x <span class="fu">&lt;&gt;</span> y <span class="fu">=</span> <span class="fu">...</span></a>
<a class="sourceLine" id="cb382-3" data-line-number="3"></a>
<a class="sourceLine" id="cb382-4" data-line-number="4"><span class="kw">instance</span> <span class="dt">Monoid</span> <span class="dt">MyType</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb382-5" data-line-number="5"> mempty <span class="fu">=</span> <span class="fu">...</span></a></code></pre></div>
<h2 id="open-and-closed-abstractions"><span class="header-section-number">7.4</span> Open and closed abstractions</h2>
<p>A question novice Haskell programmers often ask (or at least should ask!) is: when should I use type classes? This section offers one answer.</p>
<p>Let’s look at a concrete example. A vehicle can be either a car or an airplane. We can model this with algebraic datatypes (as we’ve seen earlier in this chapter), but also with type classes. Here’s the datatype version:</p>
<div class="sourceCode" id="cb379"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb379-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Vehicle</span> <span class="fu">=</span> <span class="dt">Car</span> <span class="dt">String</span> <span class="fu">|</span> <span class="dt">Airplane</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb379-2" data-line-number="2"></a>
<a class="sourceLine" id="cb379-3" data-line-number="3"><span class="ot">sound ::</span> <span class="dt">Vehicle</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb379-4" data-line-number="4">sound (<span class="dt">Car</span> _) <span class="fu">=</span> <span class="st">&quot;brum brum&quot;</span></a>
<a class="sourceLine" id="cb379-5" data-line-number="5">sound (<span class="dt">Airplane</span> _) <span class="fu">=</span> <span class="st">&quot;zooooom&quot;</span></a></code></pre></div>
<div class="sourceCode" id="cb383"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb383-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Vehicle</span> <span class="fu">=</span> <span class="dt">Car</span> <span class="dt">String</span> <span class="fu">|</span> <span class="dt">Airplane</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb383-2" data-line-number="2"></a>
<a class="sourceLine" id="cb383-3" data-line-number="3"><span class="ot">sound ::</span> <span class="dt">Vehicle</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb383-4" data-line-number="4">sound (<span class="dt">Car</span> _) <span class="fu">=</span> <span class="st">&quot;brum brum&quot;</span></a>
<a class="sourceLine" id="cb383-5" data-line-number="5">sound (<span class="dt">Airplane</span> _) <span class="fu">=</span> <span class="st">&quot;zooooom&quot;</span></a></code></pre></div>
<p>Here’s the class version. Note how each case gets its own datatype, which are collected together in a type class.</p>
<div class="sourceCode" id="cb380"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb380-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Car</span> <span class="fu">=</span> <span class="dt">Car</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb380-2" data-line-number="2"><span class="kw">data</span> <span class="dt">Airplane</span> <span class="fu">=</span> <span class="dt">Airplane</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb380-3" data-line-number="3"></a>
<a class="sourceLine" id="cb380-4" data-line-number="4"><span class="kw">class</span> <span class="dt">VehicleClass</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb380-5" data-line-number="5"><span class="ot"> sound ::</span> a <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb380-6" data-line-number="6"></a>
<a class="sourceLine" id="cb380-7" data-line-number="7"><span class="kw">instance</span> <span class="dt">VehicleClass</span> <span class="dt">Car</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb380-8" data-line-number="8"> sound (<span class="dt">Car</span> _) <span class="fu">=</span> <span class="st">&quot;brum brum&quot;</span></a>
<a class="sourceLine" id="cb380-9" data-line-number="9"></a>
<a class="sourceLine" id="cb380-10" data-line-number="10"><span class="kw">instance</span> <span class="dt">VehicleClass</span> <span class="dt">Airplane</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb380-11" data-line-number="11"> sound (<span class="dt">Airplane</span> _) <span class="fu">=</span> <span class="st">&quot;zooooom&quot;</span></a></code></pre></div>
<div class="sourceCode" id="cb384"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb384-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Car</span> <span class="fu">=</span> <span class="dt">Car</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb384-2" data-line-number="2"><span class="kw">data</span> <span class="dt">Airplane</span> <span class="fu">=</span> <span class="dt">Airplane</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb384-3" data-line-number="3"></a>
<a class="sourceLine" id="cb384-4" data-line-number="4"><span class="kw">class</span> <span class="dt">VehicleClass</span> a <span class="kw">where</span></a>
<a class="sourceLine" id="cb384-5" data-line-number="5"><span class="ot"> sound ::</span> a <span class="ot">-&gt;</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb384-6" data-line-number="6"></a>
<a class="sourceLine" id="cb384-7" data-line-number="7"><span class="kw">instance</span> <span class="dt">VehicleClass</span> <span class="dt">Car</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb384-8" data-line-number="8"> sound (<span class="dt">Car</span> _) <span class="fu">=</span> <span class="st">&quot;brum brum&quot;</span></a>
<a class="sourceLine" id="cb384-9" data-line-number="9"></a>
<a class="sourceLine" id="cb384-10" data-line-number="10"><span class="kw">instance</span> <span class="dt">VehicleClass</span> <span class="dt">Airplane</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb384-11" data-line-number="11"> sound (<span class="dt">Airplane</span> _) <span class="fu">=</span> <span class="st">&quot;zooooom&quot;</span></a></code></pre></div>
<p>What is the difference between these solutions? The data-based solution is <em>closed</em>, meaning the set of cases is fixed and we can handle all of them in one place. The class-based solution is <em>open</em>, meaning we can add new cases, even in other modules.</p>
<p>An open abstraction is nice when we want extensibility. In the class-based solution, another module could define a bike:</p>
<div class="sourceCode" id="cb381"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb381-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Bike</span> <span class="fu">=</span> <span class="dt">Bike</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb381-2" data-line-number="2"></a>
<a class="sourceLine" id="cb381-3" data-line-number="3"><span class="kw">instance</span> <span class="dt">VehicleClass</span> <span class="dt">Bike</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb381-4" data-line-number="4"> sound (<span class="dt">Bike</span> _) <span class="fu">=</span> <span class="st">&quot;whirrr&quot;</span></a></code></pre></div>
<div class="sourceCode" id="cb385"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb385-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Bike</span> <span class="fu">=</span> <span class="dt">Bike</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb385-2" data-line-number="2"></a>
<a class="sourceLine" id="cb385-3" data-line-number="3"><span class="kw">instance</span> <span class="dt">VehicleClass</span> <span class="dt">Bike</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb385-4" data-line-number="4"> sound (<span class="dt">Bike</span> _) <span class="fu">=</span> <span class="st">&quot;whirrr&quot;</span></a></code></pre></div>
<p>A closed abstraction is good when we want to know that we’ve handled all cases, consider for example the function <code>canCollide</code> which checks whether two vehicles can collide:</p>
<div class="sourceCode" id="cb382"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb382-1" data-line-number="1"><span class="ot">canCollide ::</span> <span class="dt">Vehicle</span> <span class="ot">-&gt;</span> <span class="dt">Vehicle</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb382-2" data-line-number="2">canCollide (<span class="dt">Car</span> _) (<span class="dt">Car</span> _) <span class="fu">=</span> <span class="dt">True</span></a>
<a class="sourceLine" id="cb382-3" data-line-number="3">canCollide (<span class="dt">Airplane</span> _) (<span class="dt">Airplane</span> _) <span class="fu">=</span> <span class="dt">True</span></a>
<a class="sourceLine" id="cb382-4" data-line-number="4">canCollide _ _ <span class="fu">=</span> <span class="dt">False</span></a></code></pre></div>
<div class="sourceCode" id="cb386"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb386-1" data-line-number="1"><span class="ot">canCollide ::</span> <span class="dt">Vehicle</span> <span class="ot">-&gt;</span> <span class="dt">Vehicle</span> <span class="ot">-&gt;</span> <span class="dt">Bool</span></a>
<a class="sourceLine" id="cb386-2" data-line-number="2">canCollide (<span class="dt">Car</span> _) (<span class="dt">Car</span> _) <span class="fu">=</span> <span class="dt">True</span></a>
<a class="sourceLine" id="cb386-3" data-line-number="3">canCollide (<span class="dt">Airplane</span> _) (<span class="dt">Airplane</span> _) <span class="fu">=</span> <span class="dt">True</span></a>
<a class="sourceLine" id="cb386-4" data-line-number="4">canCollide _ _ <span class="fu">=</span> <span class="dt">False</span></a></code></pre></div>
<p>This would be very hard to implement reliably in the class-based solution. Consider for example how collision checks between <code>Bike</code>s and <code>Car</code>s would get handled.</p>
<h2 id="modeling-with-languages"><span class="header-section-number">7.5</span> Modeling with languages</h2>
<p>Sometimes it’s useful to implement a mini programming language for describing parts of your software. The fancy term for these is an <em>Embedded Domain-Specific Language (EDSL)</em>. Haskell makes modeling and interpreting languages very easy. The expressions of the language are represented using (often recursive) algebraic data types. The language can be <em>interpreted</em> (that is, evaluated or run) by a recursive function.</p>
<p>Here’s an example of a language for describing price computations for products in a web shop.</p>
<div class="sourceCode" id="cb383"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb383-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Discount</span> <span class="fu">=</span> <span class="dt">DiscountPercent</span> <span class="dt">Int</span> <span class="co">-- A percentage discount</span></a>
<a class="sourceLine" id="cb383-2" data-line-number="2"> <span class="fu">|</span> <span class="dt">DiscountConstant</span> <span class="dt">Int</span> <span class="co">-- A constant discount</span></a>
<a class="sourceLine" id="cb383-3" data-line-number="3"> <span class="fu">|</span> <span class="dt">MinimumPrice</span> <span class="dt">Int</span> <span class="co">-- Set a minimum price</span></a>
<a class="sourceLine" id="cb383-4" data-line-number="4"> <span class="fu">|</span> <span class="dt">ForCustomer</span> <span class="dt">String</span> <span class="dt">Discount</span> <span class="co">-- Discounts can be conditional</span></a>
<a class="sourceLine" id="cb383-5" data-line-number="5"> <span class="fu">|</span> <span class="dt">Many</span> [<span class="dt">Discount</span>] <span class="co">-- Apply a number of discounts in row</span></a></code></pre></div>
<div class="sourceCode" id="cb387"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb387-1" data-line-number="1"><span class="kw">data</span> <span class="dt">Discount</span> <span class="fu">=</span> <span class="dt">DiscountPercent</span> <span class="dt">Int</span> <span class="co">-- A percentage discount</span></a>
<a class="sourceLine" id="cb387-2" data-line-number="2"> <span class="fu">|</span> <span class="dt">DiscountConstant</span> <span class="dt">Int</span> <span class="co">-- A constant discount</span></a>
<a class="sourceLine" id="cb387-3" data-line-number="3"> <span class="fu">|</span> <span class="dt">MinimumPrice</span> <span class="dt">Int</span> <span class="co">-- Set a minimum price</span></a>
<a class="sourceLine" id="cb387-4" data-line-number="4"> <span class="fu">|</span> <span class="dt">ForCustomer</span> <span class="dt">String</span> <span class="dt">Discount</span> <span class="co">-- Discounts can be conditional</span></a>
<a class="sourceLine" id="cb387-5" data-line-number="5"> <span class="fu">|</span> <span class="dt">Many</span> [<span class="dt">Discount</span>] <span class="co">-- Apply a number of discounts in row</span></a></code></pre></div>
<p>The language is interpreted by the function <code>applyDiscount</code> that takes a customer name, a price, a discount, and returns a price.</p>
<div class="sourceCode" id="cb384"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb384-1" data-line-number="1"><span class="ot">applyDiscount ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Discount</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb384-2" data-line-number="2">applyDiscount _ price (<span class="dt">DiscountPercent</span> percent) <span class="fu">=</span> price <span class="fu">-</span> (price <span class="fu">*</span> percent) <span class="ot">`div`</span> <span class="dv">100</span></a>
<a class="sourceLine" id="cb384-3" data-line-number="3">applyDiscount _ price (<span class="dt">DiscountConstant</span> discount) <span class="fu">=</span> price <span class="fu">-</span> discount</a>
<a class="sourceLine" id="cb384-4" data-line-number="4">applyDiscount _ price (<span class="dt">MinimumPrice</span> minPrice) <span class="fu">=</span> max price minPrice</a>
<a class="sourceLine" id="cb384-5" data-line-number="5">applyDiscount customer price (<span class="dt">ForCustomer</span> target discount)</a>
<a class="sourceLine" id="cb384-6" data-line-number="6"> <span class="fu">|</span> customer <span class="fu">==</span> target <span class="fu">=</span> applyDiscount customer price discount</a>
<a class="sourceLine" id="cb384-7" data-line-number="7"> <span class="fu">|</span> otherwise <span class="fu">=</span> price</a>
<a class="sourceLine" id="cb384-8" data-line-number="8">applyDiscount customer price (<span class="dt">Many</span> discounts) <span class="fu">=</span> go price discounts</a>
<a class="sourceLine" id="cb384-9" data-line-number="9"> <span class="kw">where</span> go p [] <span class="fu">=</span> p</a>
<a class="sourceLine" id="cb384-10" data-line-number="10"> go p (d<span class="fu">:</span>ds) <span class="fu">=</span> go (applyDiscount customer p d) ds</a></code></pre></div>
<div class="sourceCode" id="cb388"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb388-1" data-line-number="1"><span class="ot">applyDiscount ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Discount</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb388-2" data-line-number="2">applyDiscount _ price (<span class="dt">DiscountPercent</span> percent) <span class="fu">=</span> price <span class="fu">-</span> (price <span class="fu">*</span> percent) <span class="ot">`div`</span> <span class="dv">100</span></a>
<a class="sourceLine" id="cb388-3" data-line-number="3">applyDiscount _ price (<span class="dt">DiscountConstant</span> discount) <span class="fu">=</span> price <span class="fu">-</span> discount</a>
<a class="sourceLine" id="cb388-4" data-line-number="4">applyDiscount _ price (<span class="dt">MinimumPrice</span> minPrice) <span class="fu">=</span> max price minPrice</a>
<a class="sourceLine" id="cb388-5" data-line-number="5">applyDiscount customer price (<span class="dt">ForCustomer</span> target discount)</a>
<a class="sourceLine" id="cb388-6" data-line-number="6"> <span class="fu">|</span> customer <span class="fu">==</span> target <span class="fu">=</span> applyDiscount customer price discount</a>
<a class="sourceLine" id="cb388-7" data-line-number="7"> <span class="fu">|</span> otherwise <span class="fu">=</span> price</a>
<a class="sourceLine" id="cb388-8" data-line-number="8">applyDiscount customer price (<span class="dt">Many</span> discounts) <span class="fu">=</span> go price discounts</a>
<a class="sourceLine" id="cb388-9" data-line-number="9"> <span class="kw">where</span> go p [] <span class="fu">=</span> p</a>
<a class="sourceLine" id="cb388-10" data-line-number="10"> go p (d<span class="fu">:</span>ds) <span class="fu">=</span> go (applyDiscount customer p d) ds</a></code></pre></div>
<p>Here we apply a discount chain of -50%, -$30 with a minimum price of $35:</p>
<div class="sourceCode" id="cb385"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb385-1" data-line-number="1">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">120</span> (<span class="dt">DiscountPercent</span> <span class="dv">50</span>)</a>
<a class="sourceLine" id="cb385-2" data-line-number="2"> <span class="fu">==&gt;</span> <span class="dv">60</span></a>
<a class="sourceLine" id="cb385-3" data-line-number="3">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">60</span> (<span class="dt">DiscountConstant</span> <span class="dv">30</span>)</a>
<a class="sourceLine" id="cb385-4" data-line-number="4"> <span class="fu">==&gt;</span> <span class="dv">30</span></a>
<a class="sourceLine" id="cb385-5" data-line-number="5">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">30</span> (<span class="dt">MinimumPrice</span> <span class="dv">35</span>)</a>
<a class="sourceLine" id="cb385-6" data-line-number="6"> <span class="fu">==&gt;</span> <span class="dv">35</span></a>
<a class="sourceLine" id="cb385-7" data-line-number="7">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">120</span> (<span class="dt">Many</span> [<span class="dt">DiscountPercent</span> <span class="dv">50</span>, <span class="dt">DiscountConstant</span> <span class="dv">30</span>, <span class="dt">MinimumPrice</span> <span class="dv">35</span>])</a>
<a class="sourceLine" id="cb385-8" data-line-number="8"> <span class="fu">==&gt;</span> <span class="dv">35</span></a></code></pre></div>
<div class="sourceCode" id="cb389"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb389-1" data-line-number="1">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">120</span> (<span class="dt">DiscountPercent</span> <span class="dv">50</span>)</a>
<a class="sourceLine" id="cb389-2" data-line-number="2"> <span class="fu">==&gt;</span> <span class="dv">60</span></a>
<a class="sourceLine" id="cb389-3" data-line-number="3">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">60</span> (<span class="dt">DiscountConstant</span> <span class="dv">30</span>)</a>
<a class="sourceLine" id="cb389-4" data-line-number="4"> <span class="fu">==&gt;</span> <span class="dv">30</span></a>
<a class="sourceLine" id="cb389-5" data-line-number="5">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">30</span> (<span class="dt">MinimumPrice</span> <span class="dv">35</span>)</a>
<a class="sourceLine" id="cb389-6" data-line-number="6"> <span class="fu">==&gt;</span> <span class="dv">35</span></a>
<a class="sourceLine" id="cb389-7" data-line-number="7">applyDiscount <span class="st">&quot;Bob&quot;</span> <span class="dv">120</span> (<span class="dt">Many</span> [<span class="dt">DiscountPercent</span> <span class="dv">50</span>, <span class="dt">DiscountConstant</span> <span class="dv">30</span>, <span class="dt">MinimumPrice</span> <span class="dv">35</span>])</a>
<a class="sourceLine" id="cb389-8" data-line-number="8"> <span class="fu">==&gt;</span> <span class="dv">35</span></a></code></pre></div>
<p>Here we have different discounts for Ssarah and Yvonne:</p>
<div class="sourceCode" id="cb386"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb386-1" data-line-number="1">applyDiscount <span class="st">&quot;Yvonne&quot;</span> <span class="dv">100</span> (<span class="dt">Many</span> [<span class="dt">ForCustomer</span> <span class="st">&quot;Yvonne&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">10</span>), <span class="dt">ForCustomer</span> <span class="st">&quot;Ssarah&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">20</span>)])</a>
<a class="sourceLine" id="cb386-2" data-line-number="2"> <span class="fu">==&gt;</span> <span class="dv">90</span></a>
<a class="sourceLine" id="cb386-3" data-line-number="3">applyDiscount <span class="st">&quot;Ssarah&quot;</span> <span class="dv">100</span> (<span class="dt">Many</span> [<span class="dt">ForCustomer</span> <span class="st">&quot;Yvonne&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">10</span>), <span class="dt">ForCustomer</span> <span class="st">&quot;Ssarah&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">20</span>)])</a>
<a class="sourceLine" id="cb386-4" data-line-number="4"> <span class="fu">==&gt;</span> <span class="dv">80</span></a></code></pre></div>
<div class="sourceCode" id="cb390"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb390-1" data-line-number="1">applyDiscount <span class="st">&quot;Yvonne&quot;</span> <span class="dv">100</span> (<span class="dt">Many</span> [<span class="dt">ForCustomer</span> <span class="st">&quot;Yvonne&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">10</span>), <span class="dt">ForCustomer</span> <span class="st">&quot;Ssarah&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">20</span>)])</a>
<a class="sourceLine" id="cb390-2" data-line-number="2"> <span class="fu">==&gt;</span> <span class="dv">90</span></a>
<a class="sourceLine" id="cb390-3" data-line-number="3">applyDiscount <span class="st">&quot;Ssarah&quot;</span> <span class="dv">100</span> (<span class="dt">Many</span> [<span class="dt">ForCustomer</span> <span class="st">&quot;Yvonne&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">10</span>), <span class="dt">ForCustomer</span> <span class="st">&quot;Ssarah&quot;</span> (<span class="dt">DiscountConstant</span> <span class="dv">20</span>)])</a>
<a class="sourceLine" id="cb390-4" data-line-number="4"> <span class="fu">==&gt;</span> <span class="dv">80</span></a></code></pre></div>
<p>As you can see, even a simple <code>Discount</code> type can generate complex behaviours because it is self-referential (recursive). Using <code>Discount</code> we are able to represent the discount logic of our webshop as <em>data</em> instead of writing code. This data can be stored in a database, and we can even create multiple different interpreters for it. We could also visualize the discount chains in an administration user interface.</p>
<h2 id="todo-quiz-1"><span class="header-section-number">7.6</span> TODO: Quiz</h2>
<h2 id="exercises-6"><span class="header-section-number">7.7</span> Exercises</h2>
<!-- ## TODO: Quiz -->
<h2 id="exercises-6"><span class="header-section-number">7.6</span> Exercises</h2>
<ul>
<li>Set7</li>
</ul>
@@ -3180,103 +3295,103 @@ Because <code>Nothing</code> is a constructor.
<h2 id="a-taste-of-io"><span class="header-section-number">8.1</span> A taste of IO</h2>
<p>This course has been centered about pure functional programming. We’ve done lots of arithmetic, reversed lists, worked with binary trees, but so far we haven’t been able to affect the world outside our GHCi.</p>
<p>Things like reading input, writing to a file, or talking over the network are <em>side effects</em>. Side effects can’t be represented with pure functional code. A function like</p>
<div class="sourceCode" id="cb387"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb387-1" data-line-number="1"><span class="ot">readInputFromTheUser ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a></code></pre></div>
<div class="sourceCode" id="cb391"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb391-1" data-line-number="1"><span class="ot">readInputFromTheUser ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">String</span></a></code></pre></div>
<p>can’t be pure, because if it were, <code>readInputFromUser &quot;What is your name?&quot;</code> would always have to return the same result. However, representing side-effects and impurity in a pure language <em>is</em> possible. There are many ways of doing it, and the Haskell way is to use <em>Monads</em>.</p>
<p>Monads are reputedly difficult to understand, but I think they’re easy to use in practice. Here’s a taste of the <code>IO</code> Monad, which you can use for all sorts of side effects in Haskell.</p>
<p>Let’s start!</p>
<div class="sourceCode" id="cb388"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb388-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t getLine</a>
<a class="sourceLine" id="cb388-2" data-line-number="2">getLine<span class="ot"> ::</span> <span class="dt">IO</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb388-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> line <span class="ot">&lt;-</span> getLine</a></code></pre></div>
<div class="sourceCode" id="cb392"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb392-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t getLine</a>
<a class="sourceLine" id="cb392-2" data-line-number="2">getLine<span class="ot"> ::</span> <span class="dt">IO</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb392-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> line <span class="ot">&lt;-</span> getLine</a></code></pre></div>
<pre><code>another line</code></pre>
<div class="sourceCode" id="cb390"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb390-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t line</a>
<a class="sourceLine" id="cb390-2" data-line-number="2"><span class="ot">line ::</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb390-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> line</a>
<a class="sourceLine" id="cb390-4" data-line-number="4"><span class="st">&quot;another line&quot;</span></a>
<a class="sourceLine" id="cb390-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span> reverse line</a>
<a class="sourceLine" id="cb390-6" data-line-number="6"><span class="st">&quot;enil rehtona&quot;</span></a></code></pre></div>
<div class="sourceCode" id="cb394"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb394-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t line</a>
<a class="sourceLine" id="cb394-2" data-line-number="2"><span class="ot">line ::</span> <span class="dt">String</span></a>
<a class="sourceLine" id="cb394-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> line</a>
<a class="sourceLine" id="cb394-4" data-line-number="4"><span class="st">&quot;another line&quot;</span></a>
<a class="sourceLine" id="cb394-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span> reverse line</a>
<a class="sourceLine" id="cb394-6" data-line-number="6"><span class="st">&quot;enil rehtona&quot;</span></a></code></pre></div>
<p>What we’ve seen here is the <em>IO action</em> <code>getLine</code>. It has type <code>IO String</code>. This means that GHCi can <em>execute</em> the action to produce a value of type <code>String</code>. When we enter <code>line &lt;- getLine</code> into GHCi, we mean:</p>
<blockquote>
<p>Execute the IO action <code>getLine</code>, and give the result the name <code>line</code>.</p>
</blockquote>
<p>After we’ve received <code>line</code>, it’s a pure <code>String</code> value and we can work with it normally.</p>
<p>Some IO actions take parameters. For example <code>putStrLn :: String -&gt; IO ()</code> takes a <code>String</code> and returns an <code>IO</code> action that prints that string. The <code>()</code> type is a special type that only has one value, <code>()</code>. In this case <code>IO ()</code> means that this IO always produces the same empty value <code>()</code>. You can run IO actions by just</p>
<div class="sourceCode" id="cb391"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb391-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t putStrLn</a>
<a class="sourceLine" id="cb391-2" data-line-number="2">putStrLn<span class="ot"> ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb391-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t putStrLn <span class="st">&quot;hello&quot;</span></a>
<a class="sourceLine" id="cb391-4" data-line-number="4">putStrLn <span class="st">&quot;hello&quot;</span><span class="ot"> ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb391-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span> val <span class="ot">&lt;-</span> putStrLn <span class="st">&quot;hello&quot;</span></a>
<a class="sourceLine" id="cb391-6" data-line-number="6">hello</a>
<a class="sourceLine" id="cb391-7" data-line-number="7"><span class="dt">Prelude</span><span class="fu">&gt;</span> val</a>
<a class="sourceLine" id="cb391-8" data-line-number="8">()</a></code></pre></div>
<div class="sourceCode" id="cb395"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb395-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t putStrLn</a>
<a class="sourceLine" id="cb395-2" data-line-number="2">putStrLn<span class="ot"> ::</span> <span class="dt">String</span> <span class="ot">-&gt;</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb395-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t putStrLn <span class="st">&quot;hello&quot;</span></a>
<a class="sourceLine" id="cb395-4" data-line-number="4">putStrLn <span class="st">&quot;hello&quot;</span><span class="ot"> ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb395-5" data-line-number="5"><span class="dt">Prelude</span><span class="fu">&gt;</span> val <span class="ot">&lt;-</span> putStrLn <span class="st">&quot;hello&quot;</span></a>
<a class="sourceLine" id="cb395-6" data-line-number="6">hello</a>
<a class="sourceLine" id="cb395-7" data-line-number="7"><span class="dt">Prelude</span><span class="fu">&gt;</span> val</a>
<a class="sourceLine" id="cb395-8" data-line-number="8">()</a></code></pre></div>
<p>If you don’t need the return value of an IO action, you can run it <em>in GHCi</em> without the <code>&lt;-</code>:</p>
<div class="sourceCode" id="cb392"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb392-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> putStrLn <span class="st">&quot;hello&quot;</span></a>
<a class="sourceLine" id="cb392-2" data-line-number="2">hello</a></code></pre></div>
<div class="sourceCode" id="cb396"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb396-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> putStrLn <span class="st">&quot;hello&quot;</span></a>
<a class="sourceLine" id="cb396-2" data-line-number="2">hello</a></code></pre></div>
<p>You can build your own IO actions by combining other actions with <em>do-notation</em>. A <code>do</code> block lists IO actions that are executed in order.</p>
<div class="sourceCode" id="cb393"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb393-1" data-line-number="1"><span class="ot">printTwoThings ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb393-2" data-line-number="2">printTwoThings <span class="fu">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb393-3" data-line-number="3"> putStrLn <span class="st">&quot;Hello!&quot;</span></a>
<a class="sourceLine" id="cb393-4" data-line-number="4"> putStrLn <span class="st">&quot;How are you?&quot;</span></a>
<a class="sourceLine" id="cb393-5" data-line-number="5"></a>
<a class="sourceLine" id="cb393-6" data-line-number="6"><span class="ot">greet ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb393-7" data-line-number="7">greet <span class="fu">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb393-8" data-line-number="8"> putStrLn <span class="st">&quot;What&#39;s your name?&quot;</span></a>
<a class="sourceLine" id="cb393-9" data-line-number="9"> name <span class="ot">&lt;-</span> getLine</a>
<a class="sourceLine" id="cb393-10" data-line-number="10"> putStrLn (<span class="st">&quot;Hello, &quot;</span> <span class="fu">++</span> name)</a></code></pre></div>
<div class="sourceCode" id="cb394"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb394-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> printTwoThings</a>
<a class="sourceLine" id="cb394-2" data-line-number="2"><span class="dt">Hello</span><span class="fu">!</span></a>
<a class="sourceLine" id="cb394-3" data-line-number="3"><span class="dt">How</span> are you<span class="fu">?</span></a>
<a class="sourceLine" id="cb394-4" data-line-number="4"><span class="dt">Prelude</span><span class="fu">&gt;</span> greet</a>
<a class="sourceLine" id="cb394-5" data-line-number="5"><span class="dt">What&#39;s</span> your name<span class="fu">?</span></a>
<a class="sourceLine" id="cb394-6" data-line-number="6"><span class="dt">Seraphim</span></a>
<a class="sourceLine" id="cb394-7" data-line-number="7"><span class="dt">Hello</span>, <span class="dt">Seraphim</span></a></code></pre></div>
<div class="sourceCode" id="cb397"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb397-1" data-line-number="1"><span class="ot">printTwoThings ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb397-2" data-line-number="2">printTwoThings <span class="fu">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb397-3" data-line-number="3"> putStrLn <span class="st">&quot;Hello!&quot;</span></a>
<a class="sourceLine" id="cb397-4" data-line-number="4"> putStrLn <span class="st">&quot;How are you?&quot;</span></a>
<a class="sourceLine" id="cb397-5" data-line-number="5"></a>
<a class="sourceLine" id="cb397-6" data-line-number="6"><span class="ot">greet ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb397-7" data-line-number="7">greet <span class="fu">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb397-8" data-line-number="8"> putStrLn <span class="st">&quot;What&#39;s your name?&quot;</span></a>
<a class="sourceLine" id="cb397-9" data-line-number="9"> name <span class="ot">&lt;-</span> getLine</a>
<a class="sourceLine" id="cb397-10" data-line-number="10"> putStrLn (<span class="st">&quot;Hello, &quot;</span> <span class="fu">++</span> name)</a></code></pre></div>
<div class="sourceCode" id="cb398"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb398-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> printTwoThings</a>
<a class="sourceLine" id="cb398-2" data-line-number="2"><span class="dt">Hello</span><span class="fu">!</span></a>
<a class="sourceLine" id="cb398-3" data-line-number="3"><span class="dt">How</span> are you<span class="fu">?</span></a>
<a class="sourceLine" id="cb398-4" data-line-number="4"><span class="dt">Prelude</span><span class="fu">&gt;</span> greet</a>
<a class="sourceLine" id="cb398-5" data-line-number="5"><span class="dt">What&#39;s</span> your name<span class="fu">?</span></a>
<a class="sourceLine" id="cb398-6" data-line-number="6"><span class="dt">Seraphim</span></a>
<a class="sourceLine" id="cb398-7" data-line-number="7"><span class="dt">Hello</span>, <span class="dt">Seraphim</span></a></code></pre></div>
<h3 id="what-about-purity"><span class="header-section-number">8.1.1</span> What about purity?</h3>
<p>It feels as if we can just do side effects where ever we want with these IO actions. However, it’s important to remember the distinction between <em>defining</em> an IO action and <em>executing</em> it.</p>
<p>Let’s try to print while mapping over a list</p>
<div class="sourceCode" id="cb395"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb395-1" data-line-number="1"><span class="ot">printAndIncrement ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb395-2" data-line-number="2">printAndIncrement x <span class="fu">=</span> x<span class="fu">+</span><span class="dv">1</span></a>
<a class="sourceLine" id="cb395-3" data-line-number="3"> <span class="kw">where</span> action <span class="fu">=</span> putStrLn <span class="st">&quot;got a number!&quot;</span></a></code></pre></div>
<div class="sourceCode" id="cb396"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb396-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> map printAndIncrement [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</a>
<a class="sourceLine" id="cb396-2" data-line-number="2">[<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>]</a></code></pre></div>
<div class="sourceCode" id="cb399"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb399-1" data-line-number="1"><span class="ot">printAndIncrement ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> <span class="dt">Int</span></a>
<a class="sourceLine" id="cb399-2" data-line-number="2">printAndIncrement x <span class="fu">=</span> x<span class="fu">+</span><span class="dv">1</span></a>
<a class="sourceLine" id="cb399-3" data-line-number="3"> <span class="kw">where</span> action <span class="fu">=</span> putStrLn <span class="st">&quot;got a number!&quot;</span></a></code></pre></div>
<div class="sourceCode" id="cb400"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb400-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> map printAndIncrement [<span class="dv">1</span>,<span class="dv">2</span>,<span class="dv">3</span>]</a>
<a class="sourceLine" id="cb400-2" data-line-number="2">[<span class="dv">2</span>,<span class="dv">3</span>,<span class="dv">4</span>]</a></code></pre></div>
<p>This didn’t print anything, because even though we defined our <code>action</code>, it wasn’t given to GHCi for execution. Because <code>printAndIncrement</code> returns an <code>Int</code>, it can’t return an action. Ok, let’s try another approach:</p>
<div class="sourceCode" id="cb397"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb397-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> length (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb397-2" data-line-number="2"><span class="dv">2</span></a></code></pre></div>
<div class="sourceCode" id="cb401"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb401-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> length (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb401-2" data-line-number="2"><span class="dv">2</span></a></code></pre></div>
<p>That didn’t print anything either! Let’s see why:</p>
<div class="sourceCode" id="cb398"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb398-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>]</a>
<a class="sourceLine" id="cb398-2" data-line-number="2">map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>]<span class="ot"> ::</span> [<span class="dt">IO</span> ()]</a>
<a class="sourceLine" id="cb398-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t length (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb398-4" data-line-number="4">length (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])<span class="ot"> ::</span> <span class="dt">Int</span></a></code></pre></div>
<div class="sourceCode" id="cb402"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb402-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>]</a>
<a class="sourceLine" id="cb402-2" data-line-number="2">map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>]<span class="ot"> ::</span> [<span class="dt">IO</span> ()]</a>
<a class="sourceLine" id="cb402-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t length (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb402-4" data-line-number="4">length (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])<span class="ot"> ::</span> <span class="dt">Int</span></a></code></pre></div>
<p>We generated a list of IO actions and computed the value of the list. Defining IO actions is pure, it’s <em>running</em> them that causes side effects. Since the type of our expression was <code>Int</code>, no <code>IO</code> actions could land in GHCi and be executed.</p>
<p>If we instead return an IO action, it does get run:</p>
<div class="sourceCode" id="cb399"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb399-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t head (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb399-2" data-line-number="2">head (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])<span class="ot"> ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb399-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> head (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb399-4" data-line-number="4">string1</a></code></pre></div>
<div class="sourceCode" id="cb403"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb403-1" data-line-number="1"><span class="dt">Prelude</span><span class="fu">&gt;</span> <span class="fu">:</span>t head (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb403-2" data-line-number="2">head (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])<span class="ot"> ::</span> <span class="dt">IO</span> ()</a>
<a class="sourceLine" id="cb403-3" data-line-number="3"><span class="dt">Prelude</span><span class="fu">&gt;</span> head (map putStrLn [<span class="st">&quot;string1&quot;</span>,<span class="st">&quot;string2&quot;</span>])</a>
<a class="sourceLine" id="cb403-4" data-line-number="4">string1</a></code></pre></div>
<p>Here too, the code that produces the action <code>putStrLn &quot;string1&quot;</code> is pure, it’s only after the IO action is executed by GHCi that we see the printed string. And as you can see, the other IO action, <code>putStrLn &quot;string2&quot;</code>, never got run.</p>
<p>If this feels complicated, don’t worry. We’ll get back to this on part 2 of the course.</p>
<h3 id="what-about-haskell-programs"><span class="header-section-number">8.1.2</span> What about Haskell programs?</h3>
<p>We know that GHCi can run IO actions. What about actual Haskell programs? The way Haskell programs work is that the IO action called <code>main</code> gets executed when the program is run. Recall our example program from Lecture 1.</p>
<div class="sourceCode" id="cb400"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb400-1" data-line-number="1"><span class="kw">module</span> <span class="dt">Gold</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb400-2" data-line-number="2"></a>
<a class="sourceLine" id="cb400-3" data-line-number="3"><span class="co">-- The golden ratio</span></a>
<a class="sourceLine" id="cb400-4" data-line-number="4"><span class="ot">phi ::</span> <span class="dt">Double</span></a>
<a class="sourceLine" id="cb400-5" data-line-number="5">phi <span class="fu">=</span> (sqrt <span class="dv">5</span> <span class="fu">+</span> <span class="dv">1</span>) <span class="fu">/</span> <span class="dv">2</span></a>
<a class="sourceLine" id="cb400-6" data-line-number="6"></a>
<a class="sourceLine" id="cb400-7" data-line-number="7"><span class="ot">polynomial ::</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Double</span></a>
<a class="sourceLine" id="cb400-8" data-line-number="8">polynomial x <span class="fu">=</span> x<span class="fu">^</span><span class="dv">2</span> <span class="fu">-</span> x <span class="fu">-</span> <span class="dv">1</span></a>
<a class="sourceLine" id="cb400-9" data-line-number="9"></a>
<a class="sourceLine" id="cb400-10" data-line-number="10">f x <span class="fu">=</span> polynomial (polynomial x)</a>
<a class="sourceLine" id="cb400-11" data-line-number="11"></a>
<a class="sourceLine" id="cb400-12" data-line-number="12">main <span class="fu">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb400-13" data-line-number="13"> print (polynomial phi)</a>
<a class="sourceLine" id="cb400-14" data-line-number="14"> print (f phi)</a></code></pre></div>
<div class="sourceCode" id="cb404"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb404-1" data-line-number="1"><span class="kw">module</span> <span class="dt">Gold</span> <span class="kw">where</span></a>
<a class="sourceLine" id="cb404-2" data-line-number="2"></a>
<a class="sourceLine" id="cb404-3" data-line-number="3"><span class="co">-- The golden ratio</span></a>
<a class="sourceLine" id="cb404-4" data-line-number="4"><span class="ot">phi ::</span> <span class="dt">Double</span></a>
<a class="sourceLine" id="cb404-5" data-line-number="5">phi <span class="fu">=</span> (sqrt <span class="dv">5</span> <span class="fu">+</span> <span class="dv">1</span>) <span class="fu">/</span> <span class="dv">2</span></a>
<a class="sourceLine" id="cb404-6" data-line-number="6"></a>
<a class="sourceLine" id="cb404-7" data-line-number="7"><span class="ot">polynomial ::</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Double</span></a>
<a class="sourceLine" id="cb404-8" data-line-number="8">polynomial x <span class="fu">=</span> x<span class="fu">^</span><span class="dv">2</span> <span class="fu">-</span> x <span class="fu">-</span> <span class="dv">1</span></a>
<a class="sourceLine" id="cb404-9" data-line-number="9"></a>
<a class="sourceLine" id="cb404-10" data-line-number="10">f x <span class="fu">=</span> polynomial (polynomial x)</a>
<a class="sourceLine" id="cb404-11" data-line-number="11"></a>
<a class="sourceLine" id="cb404-12" data-line-number="12">main <span class="fu">=</span> <span class="kw">do</span></a>
<a class="sourceLine" id="cb404-13" data-line-number="13"> print (polynomial phi)</a>
<a class="sourceLine" id="cb404-14" data-line-number="14"> print (f phi)</a></code></pre></div>
<p>Here we see some pure code and a <code>main</code> IO action that prints two things (<code>print</code> is just <code>putStrLn</code> combined with <code>show</code>).</p>
<p>We can place this code in a file called <code>Gold.hs</code>, compile it into an executable, and run it:</p>
<div class="sourceCode" id="cb401"><pre class="sourceCode sh"><code class="sourceCode bash"><a class="sourceLine" id="cb401-1" data-line-number="1">$ <span class="ex">ghc</span> -main-is Gold Gold.hs</a>
<a class="sourceLine" id="cb401-2" data-line-number="2">[<span class="ex">1</span> of 1] Compiling Gold ( Gold.hs, Gold.o )</a>
<a class="sourceLine" id="cb401-3" data-line-number="3"><span class="ex">Linking</span> Gold ...</a>
<a class="sourceLine" id="cb401-4" data-line-number="4">$ <span class="ex">./Gold</span></a>
<a class="sourceLine" id="cb401-5" data-line-number="5"><span class="ex">0.0</span></a>
<a class="sourceLine" id="cb401-6" data-line-number="6"><span class="ex">-1.0</span></a></code></pre></div>
<div class="sourceCode" id="cb405"><pre class="sourceCode sh"><code class="sourceCode bash"><a class="sourceLine" id="cb405-1" data-line-number="1">$ <span class="ex">ghc</span> -main-is Gold Gold.hs</a>
<a class="sourceLine" id="cb405-2" data-line-number="2">[<span class="ex">1</span> of 1] Compiling Gold ( Gold.hs, Gold.o )</a>
<a class="sourceLine" id="cb405-3" data-line-number="3"><span class="ex">Linking</span> Gold ...</a>
<a class="sourceLine" id="cb405-4" data-line-number="4">$ <span class="ex">./Gold</span></a>
<a class="sourceLine" id="cb405-5" data-line-number="5"><span class="ex">0.0</span></a>
<a class="sourceLine" id="cb405-6" data-line-number="6"><span class="ex">-1.0</span></a></code></pre></div>
<h2 id="summary"><span class="header-section-number">8.2</span> Summary</h2>
<p>So far, we’ve learned about Haskell’s syntax and types, quite a bit of functional programming and about some language features like type classes.</p>
<p>We’ve also seen some type-oriented programming, and even gotten a taste of I/O in Haskell.</p>