Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion exercises/Set1.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ checkPassword password = if password == "swordfish"
------------------------------------------------------------------------------
-- Ex 7: A postal service prices packages the following way.
-- Packages that weigh up to 500 grams cost 250 credits.
-- Packages over 500 grams cost 300 credit + 1 credit per gram.
-- Packages over 500 grams and up to 5000 grams cost 300 credit + 1 credit per gram.
-- Packages over 5000 grams cost a constant 6000 credits.
--
-- Write a function postagePrice that takes the weight of a package
Expand Down
48 changes: 24 additions & 24 deletions part1.html
Original file line number Diff line number Diff line change
Expand Up @@ -1398,7 +1398,7 @@ <h3 data-number="1.9.5" id="recursion"><span
1 1
```
-->
<p>This tree then exaclty corresponds with the expression
<p>This tree then exactly corresponds with the expression
<code>(1 + 1) + (1 + (1 + 1))</code>. Recursion can often produce
chain-like, tree-like, nested, or loopy structures and computations.
Recursion is one of the main techniques in functional programming, so
Expand All @@ -1407,7 +1407,7 @@ <h3 data-number="1.9.5" id="recursion"><span
<h2 data-number="1.10" id="all-together-now"><span
class="header-section-number">1.10</span> All Together Now!</h2>
<p>Finally, here’s a complete Haskell module that uses ifs, pattern
matching, local defintions and recursion. The module is interested in
matching, local definitions and recursion. The module is interested in
the <a
href="https://en.wikipedia.org/wiki/Collatz_conjecture"><em>Collatz
conjecture</em></a>, a famous open problem in mathematics. It asks:</p>
Expand Down Expand Up @@ -1550,7 +1550,7 @@ <h2 data-number="1.11" id="a-word-about-indentation"><span
just one long line at first.</p>
<h2 data-number="1.12" id="quiz"><span
class="header-section-number">1.12</span> Quiz</h2>
<p>At the end of each lecture you’ll find a quiz like this. The quizes
<p>At the end of each lecture you’ll find a quiz like this. The quizzes
aren’t graded, they’re just here to help you check you’ve understood the
chapter. You can check your answer by clicking on an option. You’ll see
a green background if you were right, a red one if you were wrong. Feel
Expand All @@ -1560,10 +1560,10 @@ <h2 data-number="1.12" id="quiz"><span
<code>combine(prettify(lawn),construct(house,concrete))</code>?</p>
<ol class="quiz">
<li>
<code>combine prettify (lawn) construct (house concerete)</code>
<code>combine prettify (lawn) construct (house concrete)</code>
</li>
<li>
<code>combine (prettify lawn (counstruct house concrete))</code>
<code>combine (prettify lawn (construct house concrete))</code>
</li>
<li class="correct">
<code>combine (prettify lawn) (construct house concrete)</code>
Expand Down Expand Up @@ -1684,7 +1684,7 @@ <h2 data-number="1.13" id="working-on-the-exercises"><span
<p>There are primarily two types of files in the <code>exercises</code>
directory: exercise sets named <code>SetNX.hs</code> and accompanying
test program for the exercises named <code>SetNXTest.hs</code>. Both are
Haskell source files, but only the exercise file should to be edited
Haskell source files, but only the exercise file should be edited
when solving the exercises. Instructions to all individual exercises are
embedded in the exercise file as comments.</p>
<p>Use the tests file to check your answers. For example when you have
Expand Down Expand Up @@ -1881,11 +1881,11 @@ <h2 data-number="2.1" id="recursion-and-helper-functions"><span
expression <code>fibonacci' _ _ n</code> calls
<code>fibonacci' _ _ (n-1)</code> once, and this means that we can
compute <code>fibonacci' _ _ n</code> in <code>n</code> steps.</p>
<p>This type of recursion where a function just directly calls itself
with different arguments is called <em>tail recursion</em>. As you’ve
seen above, tail recursion corresponds to loops. This is why tail
recursion is often fast: the compiler can generate a loop in machine
code when it sees tail recursion.</p>
<p>This type of recursion is called <em>tail recursion</em>, meaning
its recursive call occurs in tail position — that is, there is no
remaining work to perform after the recursive call. Because nothing
must be done afterward, a tail-recursive function can be optimized
into an efficient loop by the compiler in machine code.</p>
<h2 data-number="2.2" id="guards"><span
class="header-section-number">2.2</span> Guards</h2>
<p>Before we move on to new types, let’s go over one more piece of
Expand Down Expand Up @@ -1986,7 +1986,7 @@ <h3 data-number="2.3.1" id="list-operations"><span
<span id="cb99-4"><a href="#cb99-4" aria-hidden="true" tabindex="-1"></a><span class="fu">init</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [a] <span class="co">-- returns everything except the last element</span></span>
<span id="cb99-5"><a href="#cb99-5" aria-hidden="true" tabindex="-1"></a><span class="fu">take</span><span class="ot"> ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a] <span class="co">-- returns the n first elements</span></span>
<span id="cb99-6"><a href="#cb99-6" aria-hidden="true" tabindex="-1"></a><span class="fu">drop</span><span class="ot"> ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a] <span class="co">-- returns everything except the n first elements</span></span>
<span id="cb99-7"><a href="#cb99-7" aria-hidden="true" tabindex="-1"></a><span class="ot">(++) ::</span> [a] <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a] <span class="co">-- lists are catenated with the ++ operator</span></span>
<span id="cb99-7"><a href="#cb99-7" aria-hidden="true" tabindex="-1"></a><span class="ot">(++) ::</span> [a] <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a] <span class="co">-- lists are concatenated with the ++ operator</span></span>
<span id="cb99-8"><a href="#cb99-8" aria-hidden="true" tabindex="-1"></a><span class="ot">(!!) ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> a <span class="co">-- lists are indexed with the !! operator</span></span>
<span id="cb99-9"><a href="#cb99-9" aria-hidden="true" tabindex="-1"></a><span class="fu">reverse</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> [a] <span class="co">-- reverse a list</span></span>
<span id="cb99-10"><a href="#cb99-10" aria-hidden="true" tabindex="-1"></a><span class="fu">null</span><span class="ot"> ::</span> [a] <span class="ot">-&gt;</span> <span class="dt">Bool</span> <span class="co">-- is this list empty?</span></span>
Expand Down Expand Up @@ -2290,6 +2290,15 @@ <h2 data-number="2.8" id="the-either-type"><span
</tr>
</tbody>
</table>
<p>Sidenote: the constructors of <code>Either</code> are called
<code>Left</code> and <code>Right</code> because they refer to the left
and right type arguments of <code>Either</code>. Note how in
<code>Either a b</code>, <code>a</code> is the left argument and
<code>b</code> is the right argument. Thus <code>Left</code> contains a
value of type <code>a</code> and likewise <code>Right</code> of type
<code>b</code>. The convention of using <code>Right</code> for success
is probably simply because right also means correct. No offense is
intended to left-handed people.</p>
<p>Here’s a simple example: a <code>readInt</code> function that only
knows a couple of numbers and returns a descriptive error for the rest.
Note the Haskell convention of using <code>Left</code> for errors and
Expand All @@ -2299,15 +2308,6 @@ <h2 data-number="2.8" id="the-either-type"><span
<span id="cb122-2"><a href="#cb122-2" aria-hidden="true" tabindex="-1"></a><span class="fu">readInt</span> <span class="st">&quot;0&quot;</span> <span class="ot">=</span> <span class="dt">Right</span> <span class="dv">0</span></span>
<span id="cb122-3"><a href="#cb122-3" aria-hidden="true" tabindex="-1"></a><span class="fu">readInt</span> <span class="st">&quot;1&quot;</span> <span class="ot">=</span> <span class="dt">Right</span> <span class="dv">1</span></span>
<span id="cb122-4"><a href="#cb122-4" aria-hidden="true" tabindex="-1"></a><span class="fu">readInt</span> s <span class="ot">=</span> <span class="dt">Left</span> (<span class="st">&quot;Unsupported string: &quot;</span> <span class="op">++</span> s)</span></code></pre></div>
<p>Sidenote: the constructors of <code>Either</code> are called
<code>Left</code> and <code>Right</code> because they refer to the left
and right type arguments of <code>Either</code>. Note how in
<code>Either a b</code>, <code>a</code> is the left argument and
<code>b</code> is the right argument. Thus <code>Left</code> contains a
value of type <code>a</code> and likewise <code>Right</code> of type
<code>b</code>. The convention of using <code>Right</code> for success
is probably simply because right also means correct. No offense is
intended to left-handed people.</p>
<p>Here’s another example: pattern matching an <code>Either</code>. Just
like with <code>Maybe</code>, there are two patterns for an
<code>Either</code>, one for each constructor.</p>
Expand Down Expand Up @@ -2903,7 +2903,7 @@ <h2 data-number="3.3" id="prefix-and-infix-notations"><span
use a helper function – such as <code>add</code> above.</p>
<p>Note that omitting the parentheses leads into a type error:</p>
<div class="sourceCode" id="cb183"><pre
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb183-1"><a href="#cb183-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Prelude</span><span class="op">&gt;</span> <span class="fu">zipWith</span> <span class="op">+</span> [<span class="dv">0</span>,<span class="dv">2</span>,<span class="dv">5</span>,<span class="dv">3</span>] [<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">3</span>]</span>
class="sourceCode haskell"><code class="sourceCode haskell"><span id="cb183-1"><a href="#cb183-1" aria-hidden="true" tabindex="-1"></a><span class="dt">Prelude</span><span class="op">&gt;</span> <span class="fu">zipWith</span> <span class="op">+</span> [<span class="dv">0</span>,<span class="dv">2</span>,<span class="dv">5</span>] [<span class="dv">1</span>,<span class="dv">3</span>,<span class="dv">3</span>]</span>
<span id="cb183-2"><a href="#cb183-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb183-3"><a href="#cb183-3" aria-hidden="true" tabindex="-1"></a><span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">1</span><span class="op">:</span><span class="dv">11</span><span class="op">:</span> <span class="fu">error</span><span class="op">:</span></span>
<span id="cb183-4"><a href="#cb183-4" aria-hidden="true" tabindex="-1"></a> • <span class="dt">Couldn&#39;t</span> match expected <span class="kw">type</span> ‘[<span class="dt">Integer</span>]</span>
Expand All @@ -2918,8 +2918,8 @@ <h2 data-number="3.3" id="prefix-and-infix-notations"><span
<span id="cb183-13"><a href="#cb183-13" aria-hidden="true" tabindex="-1"></a> (bound at <span class="op">&lt;</span>interactive<span class="op">&gt;:</span><span class="dv">1</span><span class="op">:</span><span class="dv">1</span>)</span></code></pre></div>
<p>The reason for this weird-looking error is that GHCi got confused and
thought that we were somehow trying to add <code>zipWith</code> and
<code>[0,2,5,3] [1,3,3]</code> together. Logically, it deduced that
<code>[0,2,5,3]</code> must be a function since it’s being applied to
<code>[0,2,5] [1,3,3]</code> together. Logically, it deduced that
<code>[0,2,5]</code> must be a function since it’s being applied to
<code>[1,3,3]</code> (remember that functions bind tighter than
operators).</p>
<p>Unfortunately, error messages can sometimes be obscure, since the
Expand Down