<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> 
<head>
<title>Multi-line Function Definitions</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="pandoc" />
<link rel="shortcut icon" href="icon.ico" />
<script src="common_en.js" charset="utf-8" type="text/javascript"></script> 
<link rel="stylesheet" href="common.css" type="text/css" />
</head>
<body onload="javascript:resetForms(); javascript:slidy_init();">
<div><h1 class="cover">Multi-line Function Definitions</h1>
<div id="info"></div>
<ul>
<li><a href="#local-definitions">Local Definitions</a></li>
<li><a href="#example">Example</a></li>
<li><a href="#constant-patterns">Constant Patterns</a></li>
<li><a href="#application">Application</a></li>
<li><a href="#exercise-prelude.splitat">Exercise: <code>Prelude.splitAt</code> [*]</a></li>
<li><a href="#exercise-split-list">Exercise: Split List</a></li>
<li><a href="#exercise-merge-of-ordered-lists">Exercise: Merge of Ordered Lists</a></li>
<li><a href="#exercise-sort-merge">Exercise: Sort Merge [*]</a></li>
<li><a href="#exercise-draw-triangle">Exercise: Draw Triangle</a></li>
</ul>
</div>
<section id="local-definitions" class="level1">
<h1>Local Definitions</h1>
<p>For example:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb1-1" data-line-number="1">res <span class="fu">=</span> f <span class="fu">*</span> (f <span class="fu">-</span> y)  <span class="kw">where</span></a>
<a class="sourceLine" id="cb1-2" data-line-number="2"> </a>
<a class="sourceLine" id="cb1-3" data-line-number="3">    y <span class="fu">=</span> <span class="dv">1</span> <span class="fu">/</span> <span class="dv">4</span></a>
<a class="sourceLine" id="cb1-4" data-line-number="4"> </a>
<a class="sourceLine" id="cb1-5" data-line-number="5">    f <span class="fu">=</span> <span class="dv">6</span> <span class="fu">*</span> y</a></code></pre></div>
<p>Syntax:</p>
<ul>
<li>The <code>where</code> is a keyword.</li>
<li>Indentation.</li>
</ul>
<p>Semantics: Limited scope for the variables (<code>y</code>, <code>f</code>).</p>
<div class="handout">
<hr />
<p>Local definitions are definitions of constants or functions with limited scope.</p>
<p>Syntax of local definitions:</p>
<ul>
<li>Local definitions are introduced by the <code>where</code> keyword.</li>
<li>Indentation of local definitons are greater than global ones.</li>
<li>Local definitions in the same group must have the same level of indentation, and they cannot be interrupted by indentation of lower level.</li>
</ul>
<p>The <code>res</code> is a global definition, that is, it is visible through the entire module. <code>f</code> and <code>y</code> are local definitions, they can be only visible for each other and the definition before <code>where</code>.</p>
<p>It is recommended to place the <code>where</code> at end of the line. It may be also written to the following line, but it must be indented one level higher than the preceding definition in that case.</p>
<p>Local definitions are recommended to use when both of the following criteria are satisfied at the same time.</p>
<ul>
<li>The definition is used only in a single definition (but multiple times).</li>
<li>The definition is not worth to be published because it is too specialized, or it refers to other local definitions or parameters.</li>
</ul>
</div>
</section>
<section id="example" class="level1">
<h1>Example</h1>
<p>Definition of function composition by introducing local definitions.</p>
<pre><code>(.) :: (b -&gt; c) -&gt; (a -&gt; b) -&gt; (a -&gt; c)

f . g = h  where
  h x = f (g x)</code></pre>
<div class="handout">
<hr />
<p>Definition of function composition without local definitions.</p>
<pre><code>(.) :: (b -&gt; c) -&gt; (a -&gt; b) -&gt; (a -&gt; c)
(f . g) x = f (g x)</code></pre>
</div>
</section>
<section id="constant-patterns" class="level1">
<h1>Constant Patterns</h1>
<p>When defining constans, arbitrary patterns may be written in place of the name.</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb4-1" data-line-number="1">[one,two,three,four,five] <span class="fu">=</span> [<span class="dv">1</span><span class="fu">..</span><span class="dv">5</span>]</a></code></pre></div>
<p>There is now five constants are defined this way.</p>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','590f37f7328fe661cbad0a1b81289eef','590f37f7328fe661cbad0a1b81289eef');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea590f37f7328fe661cbad0a1b81289eef" value="one  " /><br /><div class="answer" id="res590f37f7328fe661cbad0a1b81289eef"><code class="result">1</code><code> :: </code><code class="type">Integer</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','1be0d4751a68ab736fa91b90463915c8','1be0d4751a68ab736fa91b90463915c8');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea1be0d4751a68ab736fa91b90463915c8" value="two  " /><br /><div class="answer" id="res1be0d4751a68ab736fa91b90463915c8"><code class="result">2</code><code> :: </code><code class="type">Integer</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','736cb365f45803c242cdb94bf4d4656c','736cb365f45803c242cdb94bf4d4656c');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea736cb365f45803c242cdb94bf4d4656c" value="three" /><br /><div class="answer" id="res736cb365f45803c242cdb94bf4d4656c"><code class="result">3</code><code> :: </code><code class="type">Integer</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','12ecde58f2613dff56456a7d8e7431da','12ecde58f2613dff56456a7d8e7431da');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea12ecde58f2613dff56456a7d8e7431da" value="four " /><br /><div class="answer" id="res12ecde58f2613dff56456a7d8e7431da"><code class="result">4</code><code> :: </code><code class="type">Integer</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','99fb909232f52148386f8b03826909f8','99fb909232f52148386f8b03826909f8');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea99fb909232f52148386f8b03826909f8" value="five " /><br /><div class="answer" id="res99fb909232f52148386f8b03826909f8"><code class="result">5</code><code> :: </code><code class="type">Integer</code></div></form>
</section>
<section id="application" class="level1">
<h1>Application</h1>
<p>Constants patterns can be very beneficial, especially when pattern matching on results of functions returning n-tuples is required.</p>
<p>For example:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb5-1" data-line-number="1">unzip<span class="ot"> ::</span> [(a, b)] <span class="ot">-&gt;</span> ([a], [b])</a></code></pre></div>
<div class="indent"><form class="interpreter" action="javascript:getOne('c=check&amp;f=Where_en_0487ed1552e286d74a6c844f860b39ee.hs','0487ed1552e286d74a6c844f860b39ee','0487ed1552e286d74a6c844f860b39ee');"><textarea cols="80" rows="6" id="tarea0487ed1552e286d74a6c844f860b39ee"></textarea><br /><input type="submit" value="Check" /></form><div class="answer" id="res0487ed1552e286d74a6c844f860b39ee"></div></div>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','4a5e4645e2343d8dee268e2c3f6d6c76','4a5e4645e2343d8dee268e2c3f6d6c76');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea4a5e4645e2343d8dee268e2c3f6d6c76" value="unzip [(1,'x'),(3,'z'),(4,'v')] " /><br /><div class="answer" id="res4a5e4645e2343d8dee268e2c3f6d6c76"><code class="result">([1, 3, 4], &quot;xzv&quot;)</code><code> :: </code><code class="type">([Integer], [Char])</code></div></form>
</section>
<section id="exercise-prelude.splitat" class="level1">
<h1>Exercise: <code>Prelude.splitAt</code> [*]</h1>
<p>Redefine the <code>splitAt</code> function. Give a more efficient version of the definition below.</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb6-1" data-line-number="1"><span class="co">-- splitAt n l = (take n l, drop n l)</span></a></code></pre></div>
<div class="sourceCode" id="cb7"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb7-1" data-line-number="1">splitAt<span class="ot"> ::</span> <span class="dt">Int</span> <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> ([a], [a])</a></code></pre></div>
<div class="indent"><form class="interpreter" action="javascript:getOne('c=check&amp;f=Where_en_fa9cb5ab7bedd852172da53926afe164.hs','fa9cb5ab7bedd852172da53926afe164','fa9cb5ab7bedd852172da53926afe164');"><textarea cols="80" rows="7" id="tareafa9cb5ab7bedd852172da53926afe164"></textarea><br /><input type="submit" value="Check" /></form><div class="answer" id="resfa9cb5ab7bedd852172da53926afe164"></div></div>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','db882c3c14284015db7de6600dc25404','db882c3c14284015db7de6600dc25404');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tareadb882c3c14284015db7de6600dc25404" value="splitAt   3  [1..9] " /><br /><div class="answer" id="resdb882c3c14284015db7de6600dc25404"><code class="result">([1, 2, 3], [4, 5, 6, 7, 8, 9])</code><code> :: </code><code class="type">([Integer], [Integer])</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','f90c025c3452422c419256173a8d163b','f90c025c3452422c419256173a8d163b');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tareaf90c025c3452422c419256173a8d163b" value="splitAt (-1) [1..9] " /><br /><div class="answer" id="resf90c025c3452422c419256173a8d163b"><code class="result">([], [1, 2, 3, 4, 5, 6, 7, 8, 9])</code><code> :: </code><code class="type">([Integer], [Integer])</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','2453c12a6d35e3c38a818f89255ffda1','2453c12a6d35e3c38a818f89255ffda1');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea2453c12a6d35e3c38a818f89255ffda1" value="splitAt  11  [1..9] " /><br /><div class="answer" id="res2453c12a6d35e3c38a818f89255ffda1"><code class="result">([1, 2, 3, 4, 5, 6, 7, 8, 9], [])</code><code> :: </code><code class="type">([Integer], [Integer])</code></div></form>
</section>
<section id="exercise-split-list" class="level1">
<h1>Exercise: Split List</h1>
<div class="sourceCode" id="cb8"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb8-1" data-line-number="1"><span class="ot">split ::</span> [a] <span class="ot">-&gt;</span> ([a], [a])</a></code></pre></div>
<div class="indent"><form class="interpreter" action="javascript:getOne('c=check&amp;f=Where_en_5c321dc445e5fb3e0748d6432e91c56e.hs','5c321dc445e5fb3e0748d6432e91c56e','5c321dc445e5fb3e0748d6432e91c56e');"><textarea cols="80" rows="6" id="tarea5c321dc445e5fb3e0748d6432e91c56e"></textarea><br /><input type="submit" value="Check" /></form><div class="answer" id="res5c321dc445e5fb3e0748d6432e91c56e"></div></div>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','be1efd305a993da35f87fbe11646c4de','be1efd305a993da35f87fbe11646c4de');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tareabe1efd305a993da35f87fbe11646c4de" value="split  [1..8] " /><br /><div class="answer" id="resbe1efd305a993da35f87fbe11646c4de"><code class="result">([1, 3, 5, 7], [2, 4, 6, 8])</code><code> :: </code><code class="type">([Integer], [Integer])</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','d1db36dc9cb5219a8693f2c4fbf6067a','d1db36dc9cb5219a8693f2c4fbf6067a');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="taread1db36dc9cb5219a8693f2c4fbf6067a" value="split  [1..9] " /><br /><div class="answer" id="resd1db36dc9cb5219a8693f2c4fbf6067a"><code class="result">([1, 3, 5, 7, 9], [2, 4, 6, 8])</code><code> :: </code><code class="type">([Integer], [Integer])</code></div></form>
</section>
<section id="exercise-merge-of-ordered-lists" class="level1">
<h1>Exercise: Merge of Ordered Lists</h1>
<div class="sourceCode" id="cb9"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb9-1" data-line-number="1"><span class="ot">ordMerge ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a] <span class="ot">-&gt;</span> [a]</a></code></pre></div>
<div class="indent"><form class="interpreter" action="javascript:getOne('c=check&amp;f=Where_en_4cc4a454642021f7f71a6c9c1f840e2f.hs','4cc4a454642021f7f71a6c9c1f840e2f','4cc4a454642021f7f71a6c9c1f840e2f');"><textarea cols="80" rows="7" id="tarea4cc4a454642021f7f71a6c9c1f840e2f"></textarea><br /><input type="submit" value="Check" /></form><div class="answer" id="res4cc4a454642021f7f71a6c9c1f840e2f"></div></div>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','22f0891bae1a702bb7d49947def8bf72','22f0891bae1a702bb7d49947def8bf72');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea22f0891bae1a702bb7d49947def8bf72" value="ordMerge [1,4,5,8] [2,4,6,7]" /><br /><div class="answer" id="res22f0891bae1a702bb7d49947def8bf72"><code class="result">[1, 2, 4, 4, 5, 6, 7, 8]</code><code> :: </code><code class="type">[Integer]</code></div></form>
</section>
<section id="exercise-sort-merge" class="level1">
<h1>Exercise: Sort Merge [*]</h1>
<p>Define a sort merge. The algorithm is as follows. Split list with more than one element, then merge the two partitions after they have been sorted.</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb10-1" data-line-number="1"><span class="ot">msort ::</span> <span class="dt">Ord</span> a <span class="ot">=&gt;</span> [a] <span class="ot">-&gt;</span> [a]</a>
<a class="sourceLine" id="cb10-2" data-line-number="2"> <span class="co">-- split, ordMerge</span></a></code></pre></div>
<div class="indent"><form class="interpreter" action="javascript:getOne('c=check&amp;f=Where_en_7a7bd40afc48157634815c9d5ea78c04.hs','7a7bd40afc48157634815c9d5ea78c04','7a7bd40afc48157634815c9d5ea78c04');"><textarea cols="80" rows="7" id="tarea7a7bd40afc48157634815c9d5ea78c04"></textarea><br /><input type="submit" value="Check" /></form><div class="answer" id="res7a7bd40afc48157634815c9d5ea78c04"></div></div>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','d1151ce77b904c022e60710753d7629d','d1151ce77b904c022e60710753d7629d');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="taread1151ce77b904c022e60710753d7629d" value="msort [1,4,6,3,2,11,0] " /><br /><div class="answer" id="resd1151ce77b904c022e60710753d7629d"><code class="result">[0, 1, 2, 3, 4, 6, 11]</code><code> :: </code><code class="type">[Integer]</code></div></form>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','021aca77e69943e3b2de057d16fbdedb','021aca77e69943e3b2de057d16fbdedb');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tarea021aca77e69943e3b2de057d16fbdedb" value="msort [1,2,1,2] " /><br /><div class="answer" id="res021aca77e69943e3b2de057d16fbdedb"><code class="result">[1, 1, 2, 2]</code><code> :: </code><code class="type">[Integer]</code></div></form>
</section>
<section id="exercise-draw-triangle" class="level1">
<h1>Exercise: Draw Triangle</h1>
<p>Draw a triangle with sides of <code>a</code>, <code>b</code>, and <code>c</code> in the way given by the figure below.</p>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','0799d40d926be9f21c10ee23896fa8e3','0799d40d926be9f21c10ee23896fa8e3');"><div class="answer" id="res0799d40d926be9f21c10ee23896fa8e3"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="230" height="130"><g style="stroke-width: 0.100; stroke: black; fill: white" transform="matrix(10.000 0.000 0.000 -10.000 30.000 100.000)"><polygon points="0.000,0.000 10.000,0.000 4.150,6.839"></polygon><g style="fill: gray"><text style="text-anchor: middle" transform="translate(0.000,-2.000) matrix(0.100 0.000 0.000 -0.100 0.000 0.000)">(0,0)</text><text style="text-anchor: middle" transform="translate(10.000,-2.000) matrix(0.100 0.000 0.000 -0.100 0.000 0.000)">(b,0)</text><text style="text-anchor: middle" transform="translate(6.000,8.000) matrix(0.100 0.000 0.000 -0.100 0.000 0.000)">(a*cos(&#947;),a*sin(&#947;))</text><text style="text-anchor: middle" transform="translate(5.000,-1.500) matrix(0.100 0.000 0.000 -0.100 0.000 0.000)">b</text><text style="text-anchor: middle" transform="translate(1.000,3.500) matrix(0.100 0.000 0.000 -0.100 0.000 0.000)">a</text><text style="text-anchor: middle" transform="translate(8.000,3.500) matrix(0.100 0.000 0.000 -0.100 0.000 0.000)">c</text></g></g></svg></div></form>
<p>Hint: cos(γ) = (a<sup>2</sup> + b<sup>2</sup> - c<sup>2</sup>) / (2ab).</p>
<p>It is recommended to calculate the value of <code>cos(y)</code> locally then derive the value of <code>sin(y)</code> from that.</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode haskell"><code class="sourceCode haskell"><a class="sourceLine" id="cb11-1" data-line-number="1"><span class="ot">triangleFromSides ::</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Double</span> <span class="ot">-&gt;</span> <span class="dt">Diagram</span></a></code></pre></div>
<div class="indent"><form class="interpreter" action="javascript:getOne('c=check&amp;f=Where_en_6b878509b3417de37fbb1183f8b90027.hs','6b878509b3417de37fbb1183f8b90027','6b878509b3417de37fbb1183f8b90027');"><textarea cols="80" rows="5" id="tarea6b878509b3417de37fbb1183f8b90027"></textarea><br /><input type="submit" value="Check" /></form><div class="answer" id="res6b878509b3417de37fbb1183f8b90027"></div></div>
<form class="resetinterpreter" action="javascript:getOne('c=eval&amp;f=Where_en.hs','f873c9f6c90317fc11a36810fc2ba4bc','f873c9f6c90317fc11a36810fc2ba4bc');"><code class="prompt">Test&gt; </code><input class="interpreter" type="text" size="80" id="tareaf873c9f6c90317fc11a36810fc2ba4bc" value="triangleFromSides 8 8 8 `fill` gray" /><br /><div class="answer" id="resf873c9f6c90317fc11a36810fc2ba4bc"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="320" height="200"><polygon points="0.000,0.000 8.000,0.000 4.000,6.928" style="stroke-width: 0.100; stroke: black; fill: white; fill: gray" transform="matrix(10.000 0.000 0.000 -10.000 160.000 100.000)"></polygon></svg></div></form>
</section>
</body>
</html>

