3755 lines
No EOL
173 KiB
HTML
3755 lines
No EOL
173 KiB
HTML
<?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="fr" xml:lang="fr">
|
||
<head>
|
||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||
|
||
|
||
<meta name="keywords" content="Haskell, programming, functional, tutorial">
|
||
|
||
<link rel="shortcut icon" type="image/x-icon" href="/Scratch/img/favicon.ico" />
|
||
<link rel="stylesheet" type="text/css" href="/Scratch/assets/css/main.css" />
|
||
<link rel="stylesheet" type="text/css" href="/Scratch/css/solarized.css" />
|
||
<link rel="stylesheet" type="text/css" href="/Scratch/css/idc.css" />
|
||
<link rel="alternate" type="application/rss+xml" title="RSS" href="http://feeds.feedburner.com/yannespositocomfr"/>
|
||
|
||
<link rel="alternate" lang="fr" xml:lang="fr" title="Haskell comme un vrai!" type="text/html" hreflang="fr" href="/Scratch/fr/blog/Haskell-the-Hard-Way/" />
|
||
<link rel="alternate" lang="en" xml:lang="en" title="Learn Haskell Fast and Hard" type="text/html" hreflang="en" href="/Scratch/en/blog/Haskell-the-Hard-Way/" />
|
||
<script type="text/javascript" src="/Scratch/js/jquery-1.3.1.min.js"></script>
|
||
<script type="text/javascript" src="/Scratch/js/jquery.cookie.js"></script>
|
||
<script type="text/javascript" src="/Scratch/js/index.js"></script>
|
||
<!--[if lt IE 9]>
|
||
<script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
|
||
<![endif]-->
|
||
<title>Haskell comme un vrai!</title>
|
||
</head>
|
||
<body lang="fr" class="article">
|
||
<script type="text/javascript">// <![CDATA[
|
||
document.write('<div id="blackpage"><img src="/Scratch/img/loading.gif" alt="Chargement en cours..."/></div>');
|
||
// ]]>
|
||
</script>
|
||
|
||
<div id="content">
|
||
|
||
<div id="choix">
|
||
<div class="return"><a href="#entete">↓ Menu ↓</a></div>
|
||
<div id="choixlang">
|
||
<a href="/Scratch/en/blog/Haskell-the-Hard-Way/" onclick="setLanguage('en')">in English</a>
|
||
</div>
|
||
<div class="flush"></div>
|
||
</div>
|
||
<div id="titre">
|
||
<h1>
|
||
Haskell comme un vrai!
|
||
</h1>
|
||
|
||
<h2>
|
||
Haskell à s'en faire griller les neurones
|
||
</h2>
|
||
|
||
</div>
|
||
<div class="flush"></div>
|
||
|
||
|
||
|
||
|
||
|
||
<div class="flush"></div>
|
||
<div id="afterheader">
|
||
<div class="corps">
|
||
<p><img alt="Magritte pleasure principle" src="/Scratch/img/blog/Haskell-the-Hard-Way/magritte_pleasure_principle.jpg" /></p>
|
||
|
||
|
||
<div class="intro">
|
||
|
||
|
||
<p><span class="sc"><abbr title="Trop long à lire">tlàl</abbr> : </span> Un tutoriel très court mais très dense pour apprendre Haskell.</p>
|
||
|
||
<blockquote>
|
||
<center><hr style="width:30%;float:left;border-color:#CCCCD0;margin-top:1em" /><span class="sc"><b>Table of Content</b></span><hr style="width:30%;float:right;border-color:#CCCCD0;margin-top:1em" /></center>
|
||
|
||
|
||
<div class="toc">
|
||
|
||
|
||
<ul>
|
||
<li><a href="#introduction">Introduction</a>
|
||
<ul>
|
||
<li><a href="#install">Install</a></li>
|
||
<li><a href="#don-t-be-afraid">Don’t be afraid</a></li>
|
||
<li><a href="#very-basic-haskell">Very basic Haskell</a>
|
||
<ul>
|
||
<li><a href="#function-declaration">Function declaration</a></li>
|
||
<li><a href="#a-type-example">A Type Example</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#essential-haskell">Essential Haskell</a>
|
||
<ul>
|
||
<li><a href="#notations">Notations</a>
|
||
<ul>
|
||
<li><a href="#arithmetic">Arithmetic</a></li>
|
||
<li><a href="#logic">Logic</a></li>
|
||
<li><a href="#powers">Powers</a></li>
|
||
<li><a href="#lists">Lists</a></li>
|
||
<li><a href="#strings">Strings</a></li>
|
||
<li><a href="#tuples">Tuples</a></li>
|
||
<li><a href="#deal-with-parenthesis">Deal with parenthesis</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#useful-notations-for-functions">Useful notations for functions</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#hard-part">Hard Part</a>
|
||
<ul>
|
||
<li><a href="#functional-style">Functional style</a>
|
||
<ul>
|
||
<li><a href="#higher-order-functions">Higher Order Functions</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#types">Types</a>
|
||
<ul>
|
||
<li><a href="#type-inference">Type inference</a></li>
|
||
<li><a href="#type-construction">Type construction</a></li>
|
||
<li><a href="#recursive-type">Recursive type</a></li>
|
||
<li><a href="#trees">Trees</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#infinite-structures">Infinite Structures</a></li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#hell-difficulty-part">Hell Difficulty Part</a>
|
||
<ul>
|
||
<li><a href="#deal-with-io">Deal With IO</a></li>
|
||
<li><a href="#io-trick-explained">IO trick explained</a></li>
|
||
<li><a href="#monads">Monads</a>
|
||
<ul>
|
||
<li><a href="#maybe-monad">Maybe is a monad</a></li>
|
||
<li><a href="#the-list-monad">The list monad</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
</li>
|
||
<li><a href="#appendix">Appendix</a>
|
||
<ul>
|
||
<li><a href="#more-on-infinite-tree">More on Infinite Tree</a></li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
</div>
|
||
|
||
</blockquote>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
<div class="intro">
|
||
|
||
|
||
<p>Je pense vraiment que
|
||
tous les développeurs devraient apprendre Haskell.
|
||
Peut-être pas devenir des ninjas d’Haskell,
|
||
mais au moins savoir ce que ce langage a de particulier.
|
||
Son apprentissage ouvre énormément l’esprit.</p>
|
||
|
||
<p>La plupart des langages partagent les mêmes fondamentaux :</p>
|
||
|
||
<ul>
|
||
<li>les variables</li>
|
||
<li>les boucles</li>
|
||
<li>les pointeurs<sup id="fnref:0001"><a href="#fn:0001" rel="footnote">1</a></sup></li>
|
||
<li>les structures de données, les objets et les classes</li>
|
||
</ul>
|
||
|
||
<p>Haskell est très différent.
|
||
Ce langage utilise des concepts dont je n’avais jamais entendu parlé avant.
|
||
Beaucoup de ces concepts pourront vous aider à devenir un meilleur développeur.</p>
|
||
|
||
<p>Plier son esprit à Haskell peut être difficile.
|
||
Ce le fût pour moi.
|
||
Dans cet article, j’essaye de fournir les informations qui m’ont manquées lors de mon apprentissage.</p>
|
||
|
||
<p>Cet article sera certainement difficile à suivre.
|
||
Mais c’est voulu.
|
||
Il n’y a pas de raccourci pour apprendre Haskell.
|
||
C’est difficile.
|
||
Mais je pense que c’est une bonne chose.
|
||
C’est parce qu’Haskell est difficile qu’il est intéressant.</p>
|
||
|
||
<p>La manière conventionnelle d’apprendre Haskell est de lire deux livres.
|
||
En premier <a href="http://learnyouahaskell.com">“Learn You a Haskell”</a>
|
||
et ensuite <a href="http://www.realworldhaskell.org">“Real World Haskell”</a>.
|
||
Je pense aussi que c’est la bonne manière de s’y prendre.
|
||
Mais apprendre même un tout petit peu d’Haskell est presque impossible sans se plonger réellement dans ces livres.</p>
|
||
|
||
<p>Cet article fait un résumé très dense et rapide des aspect majeurs d’Haskell.
|
||
J’y ai aussi rajouté des informations qui m’ont manqué pendant l’apprentissage de ce langage.</p>
|
||
|
||
<p>Pour les francophones ; je suis désolé.
|
||
Je n’ai pas eu le courage de tout retraduire en français.
|
||
Sachez cependant que si vous êtes plusieurs à insister, je ferai certainement l’effort de traduire l’article en entier.
|
||
Et si vous vous sentez d’avoir une bonne âme je ne suis pas contre un peu d’aide.
|
||
Les sources de cet article sont sur <a href="http://github.com/yogsototh/learn_haskell.git">gihub</a>.</p>
|
||
|
||
<p>Cet article contient cinq parties :</p>
|
||
|
||
<ul>
|
||
<li>Introduction : un exemple rapide pour montrer qu’Haskell peut être facile.</li>
|
||
<li>Les bases d’Haskell : La syntaxe et des notions essentielles</li>
|
||
<li>Partie difficile :
|
||
<ul>
|
||
<li>Style fonctionnel : un exemple progressif, du style impératif au style fonctionnel ;</li>
|
||
<li>Types : la syntaxe et un exemple d’arbre binaire ;</li>
|
||
<li>Structure infinie : manipulons un arbre infini !</li>
|
||
</ul>
|
||
</li>
|
||
<li>Partie de difficulté infernale :
|
||
<ul>
|
||
<li>Utiliser les IO : un exemple très minimal ;</li>
|
||
<li>Le truc des IO révélé : les détails cachés d’IO qui m’ont manqués</li>
|
||
<li>Les monades : incroyable à quel point on peut généraliser</li>
|
||
</ul>
|
||
</li>
|
||
<li>Appendice :
|
||
<ul>
|
||
<li>Revenons sur les arbres infinis : une discussion plus mathématique sur la manipulation d’arbres infinis.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<blockquote>
|
||
<p>Note: Chaque fois que vous voyez un séparateur avec un nom de fichier se terminant par <code>lhs</code>, vous pouvez cliquer sur le nom de fichier et télécharger le fichier.
|
||
Si vous sauvegarez le fichier sour le nom <code>filename.lhs</code>, vous pouvez l’exécuter avec :</p>
|
||
<pre>
|
||
runhaskell filename.lhs
|
||
</pre>
|
||
|
||
<p>Certain ne marcheront pas, mais la majorité vous donneront un résultat.
|
||
Vous devriez voir un lien juste en dessous.</p>
|
||
</blockquote>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/10_Introduction/00_hello_world.lhs" class="cut">01_basic/10_Introduction/<strong>00_hello_world.lhs</strong></a></p>
|
||
|
||
<h2 id="introduction">Introduction</h2>
|
||
|
||
<h3 id="install">Install</h3>
|
||
|
||
<p><img alt="Haskell logo" src="/Scratch/img/blog/Haskell-the-Hard-Way/Haskell-logo.png" /></p>
|
||
|
||
<ul>
|
||
<li><a href="http://www.haskell.org/platform">Haskell Platform</a> is the standard way to install Haskell.</li>
|
||
</ul>
|
||
|
||
<p>Tools:</p>
|
||
|
||
<ul>
|
||
<li><code>ghc</code>: Compiler similar to gcc for <code>C</code>.</li>
|
||
<li><code>ghci</code>: Interactive Haskell (REPL)</li>
|
||
<li><code>runhaskell</code>: Execute a program without compiling it. Convenient but very slow compared to compiled program.</li>
|
||
</ul>
|
||
|
||
<h3 id="don-t-be-afraid">Don't be afraid</h3>
|
||
|
||
<p><img alt="The Scream" src="/Scratch/img/blog/Haskell-the-Hard-Way/munch_TheScream.jpg" /></p>
|
||
|
||
<p>Many book/articles about Haskell start by introducing some esoteric formula (quick sort, Fibonacci, etc…).
|
||
I will make the exact opposite.
|
||
At first I won’t show you any Haskell super power.
|
||
I will start with similarities between Haskell and other programming languages.
|
||
Let’s jump in the obligatory “Hello World”.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Hello World!<span class="String">"</span></span>
|
||
</pre>
|
||
</div>
|
||
<p>To run it, you can save this code in a <code>hello.hs</code> and:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">~</span> runhaskell ./hello.hs
|
||
Hello World<span class="Keyword">!</span>
|
||
</pre>
|
||
|
||
<p>You could also download the literate Haskell source.
|
||
You should see a link just above the introduction title.
|
||
Download this file as <code>00_hello_world.lhs</code> and:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">~</span> runhaskell 00_hello_world.lhs
|
||
Hello World<span class="Keyword">!</span>
|
||
</pre>
|
||
|
||
<p><a href="code/01_basic/10_Introduction/00_hello_world.lhs" class="cut">01_basic/10_Introduction/<strong>00_hello_world.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/10_Introduction/10_hello_you.lhs" class="cut">01_basic/10_Introduction/<strong>10_hello_you.lhs</strong></a></p>
|
||
|
||
<p>Now, a program asking your name and reply “Hello” using the name you entered:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> <span class="String"><span class="String">"</span>What is your name?<span class="String">"</span></span>
|
||
name <- <span class="Entity">getLine</span>
|
||
<span class="Entity">print</span> (<span class="String"><span class="String">"</span>Hello <span class="String">"</span></span> ++ name ++ <span class="String"><span class="String">"</span>!<span class="String">"</span></span>)
|
||
</pre>
|
||
</div>
|
||
<p>First, let us compare with a similar program in other imperative languages:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">#</span> Python</span>
|
||
<span class="Keyword">print</span> <span class="String"><span class="String">"</span>What is your name?<span class="String">"</span></span>
|
||
name <span class="Keyword">=</span> <span class="SupportFunction">raw_input</span>()
|
||
<span class="Keyword">print</span> <span class="String"><span class="String">"</span>Hello <span class="StringConstant">%s</span>!<span class="String">"</span></span> <span class="Keyword">%</span> name
|
||
</pre>
|
||
|
||
<pre class="twilight">
|
||
<span class="Comment"> <span class="Comment">#</span> Ruby</span>
|
||
puts <span class="String"><span class="String">"</span>What is your name?<span class="String">"</span></span>
|
||
name <span class="Keyword">=</span> gets.<span class="Entity">chomp</span>
|
||
puts <span class="String"><span class="String">"</span>Hello <span class="StringEmbeddedSource"><span class="StringEmbeddedSource">#{</span>name<span class="StringEmbeddedSource">}</span></span>!<span class="String">"</span></span>
|
||
</pre>
|
||
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">//</span> In C</span>
|
||
<span class="CCCPreprocessorLine"> #<span class="CCCPreprocessorDirective">include</span> <span class="String"><span class="String"><</span>stdio.h<span class="String">></span></span></span>
|
||
<span class="Storage">int</span> <span class="Entity">ma<span class="Entity">in</span></span> (<span class="Storage">int</span> argc, <span class="Storage">char</span> **argv) {
|
||
<span class="Storage">char</span> name[<span class="Constant">666</span>]; <span class="Comment"><span class="Comment">//</span> <- An Evil Number!</span>
|
||
<span class="Comment"><span class="Comment">//</span> What if my name is more than 665 character long?</span>
|
||
<span class="SupportFunction">printf</span>(<span class="String"><span class="String">"</span>What is your name?<span class="StringConstant">\n</span><span class="String">"</span></span>);
|
||
<span class="SupportFunction">scanf</span>(<span class="String"><span class="String">"</span><span class="StringConstant">%s</span><span class="String">"</span></span>, name);
|
||
<span class="SupportFunction">printf</span>(<span class="String"><span class="String">"</span>Hello <span class="StringConstant">%s</span>!<span class="StringConstant">\n</span><span class="String">"</span></span>, name);
|
||
<span class="Keyword">return</span> <span class="Constant">0</span>;
|
||
}
|
||
</pre>
|
||
|
||
<p>The structure is the same, but there are some syntax differences.
|
||
A major part of this tutorial will explain why.</p>
|
||
|
||
<p>In Haskell, there is a <code>main</code> function and every object has a type.
|
||
The type of <code>main</code> is <code>IO ()</code>.
|
||
This means, <code>main</code> will cause side effects.
|
||
<code>IO</code> is a … .
|
||
Wait! No! I won’t say it now!
|
||
I am afraid to terrify you.
|
||
You might run away crying.
|
||
For now, I won’t talk about what <code>IO</code> really is.</p>
|
||
|
||
<p>Just remember that Haskell can look a lot like other imperative languages.</p>
|
||
|
||
<p><a href="code/01_basic/10_Introduction/10_hello_you.lhs" class="cut">01_basic/10_Introduction/<strong>10_hello_you.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/10_Introduction/20_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>20_very_basic.lhs</strong></a></p>
|
||
|
||
<h3 id="very-basic-haskell">Very basic Haskell</h3>
|
||
|
||
<p><img alt="Picasso minimal owl" src="/Scratch/img/blog/Haskell-the-Hard-Way/picasso_owl.jpg" /></p>
|
||
|
||
<p>Before continuing you need to be warned about some essential properties of Haskell. </p>
|
||
|
||
<p><em>Functional</em></p>
|
||
|
||
<p>Haskell is a functional language.
|
||
If you come from imperative language, you’ll have to learn a lot of new things.
|
||
Hopefully many of these new concepts will help you to program even in imperative languages.</p>
|
||
|
||
<p><em>Smart Static Typing</em></p>
|
||
|
||
<p>Instead of being in your way like in <code>C</code>, <code>C++</code> or <code>Java</code>, the type system is here to help you.</p>
|
||
|
||
<p><em>Purity</em></p>
|
||
|
||
<p>Generally your function won’t modify anything of the outside world.
|
||
This means, it can’t modify the value of a variable, can’t get user input, can’t write on the screen, can’t launch a missile.
|
||
On the other hand, parallelism will be very easy to achieve.
|
||
Haskell makes it clear where effects occurs and where you are pure.
|
||
Also, it will be far easier to reason about your program.
|
||
Most bug will be prevented in pure part of your program.</p>
|
||
|
||
<p>Furthermore there is an essential respected law in Haskell:</p>
|
||
|
||
<blockquote>
|
||
<p>Applying a function with the same parameter always return the same value.</p>
|
||
</blockquote>
|
||
|
||
<p><em>Lazyness</em></p>
|
||
|
||
<p>This is a very uncommon feature.
|
||
By default, Haskell evaluate something only when it is needed.
|
||
As consequence, it provides a very elegant way to manipulate infinite structures for example. </p>
|
||
|
||
<p>A last warning on how you should read Haskell code.
|
||
For me, it is like reading scientific papers.
|
||
Some part are very clear, but when you see a formula, just focus and read slower.
|
||
Also, while learning Haskell, it <em>really</em> doesn’t matter much if you don’t understand syntax details.
|
||
If you cross a <code>>>=</code>, <code><$></code>, <code><-</code> or any other weird symbol, just ignore them and follows the flow of the code.</p>
|
||
|
||
<h4 id="function-declaration">Function declaration</h4>
|
||
|
||
<p>You might be used to declare functions like this:</p>
|
||
|
||
<p>In <code>C</code>:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Storage">int</span> f(<span class="Storage">int</span> x, <span class="Storage">int</span> y) {
|
||
<span class="Keyword">return</span> x*x + y*y;
|
||
}
|
||
</pre>
|
||
|
||
<p>In javascript:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Storage">function</span> <span class="Entity">f</span>(<span class="Variable">x,y</span>) {
|
||
<span class="Keyword">return</span> x<span class="Keyword">*</span>x <span class="Keyword">+</span> y<span class="Keyword">*</span>y;
|
||
}
|
||
</pre>
|
||
|
||
<p>in Python:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Storage">def</span> <span class="Entity">f</span>(<span class="Variable">x</span>,<span class="Variable">y</span>):
|
||
<span class="Keyword">return</span> x<span class="Keyword">*</span>x <span class="Keyword">+</span> y<span class="Keyword">*</span>y;
|
||
</pre>
|
||
|
||
<p>in Ruby:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">def</span> <span class="Entity">f</span>(<span class="Variable">x<span class="Variable">,</span>y</span>)
|
||
x<span class="Keyword">*</span>x <span class="Keyword">+</span> y<span class="Keyword">*</span>y
|
||
<span class="Keyword">end</span>
|
||
</pre>
|
||
|
||
<p>In Scheme:</p>
|
||
|
||
<pre class="twilight">
|
||
(<span class="Keyword">define</span> (<span class="Entity">f</span><span class="Variable"> x y</span>)
|
||
(<span class="SupportFunction">+</span> (<span class="SupportFunction">*</span> x x) (<span class="SupportFunction">*</span> y y)))
|
||
</pre>
|
||
|
||
<p>Finaly, the Haskell way is:</p>
|
||
|
||
<pre class="twilight">
|
||
f x y = x*x + y*y
|
||
</pre>
|
||
|
||
<p>Very clean. No parenthesis, no <code>def</code>.</p>
|
||
|
||
<p>Don’t forget, Haskell use functions and types a lot.
|
||
It is thus very easy to define them.
|
||
The syntax was particularly well thought for these objects.</p>
|
||
|
||
<h4 id="a-type-example">A Type Example</h4>
|
||
|
||
<p>The common usage is to declare the type of your function.
|
||
This is not mandatory.
|
||
The compiler is smart enough to discover it for you.</p>
|
||
|
||
<p>Let’s play a little.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> We declare the type using ::</span>
|
||
<span class="Entity">f</span> :: <span class="Constant">Int</span> -> <span class="Constant">Int</span> -> <span class="Constant">Int</span>
|
||
f x y = x*x + y*y
|
||
|
||
main = <span class="Entity">print</span> (f 2 3)
|
||
</pre>
|
||
</div>
|
||
<pre><code>~ runhaskell 20_very_basic.lhs
|
||
13
|
||
</code></pre>
|
||
|
||
<p><a href="code/01_basic/10_Introduction/20_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>20_very_basic.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/10_Introduction/21_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>21_very_basic.lhs</strong></a></p>
|
||
|
||
<p>Now try</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">f</span> :: <span class="Constant">Int</span> -> <span class="Constant">Int</span> -> <span class="Constant">Int</span>
|
||
f x y = x*x + y*y
|
||
|
||
main = <span class="Entity">print</span> (f 2.3 4.2)
|
||
</pre>
|
||
</div>
|
||
<p>You get this error:</p>
|
||
|
||
<pre><code>21_very_basic.lhs:6:23:
|
||
No instance for (Fractional Int)
|
||
arising from the literal `4.2'
|
||
Possible fix: add an instance declaration for (Fractional Int)
|
||
In the second argument of `f', namely `4.2'
|
||
In the first argument of `print', namely `(f 2.3 4.2)'
|
||
In the expression: print (f 2.3 4.2)
|
||
</code></pre>
|
||
|
||
<p>The problem: <code>4.2</code> isn’t an Int.</p>
|
||
|
||
<p><a href="code/01_basic/10_Introduction/21_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>21_very_basic.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/10_Introduction/22_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>22_very_basic.lhs</strong></a></p>
|
||
|
||
<p>The solution,
|
||
don’t declare the type for <code>f</code>.
|
||
Haskell will infer the most general type for us:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
f x y = x*x + y*y
|
||
|
||
main = <span class="Entity">print</span> (f 2.3 4.2)
|
||
</pre>
|
||
</div>
|
||
<p>It works!
|
||
Great, we don’t have to declare a new function for each different type.
|
||
For example, in <code>C</code>, you’ll have to declare a function for <code>int</code>, for <code>float</code>, for <code>long</code>, for <code>double</code>, etc…</p>
|
||
|
||
<p>But, what type should we declare?
|
||
To discover the type Haskell as found for us, just launch ghci:</p>
|
||
|
||
<pre><span class="low">
|
||
%</span> ghci<span class="low"><code>
|
||
GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help
|
||
Loading package ghc-prim ... linking ... done.
|
||
Loading package integer-gmp ... linking ... done.
|
||
Loading package base ... linking ... done.
|
||
Loading package ffi-1.0 ... linking ... done.
|
||
Prelude></code></span> let f x y = x*x + y*y
|
||
<span class="low"><code>Prelude></code></span> :type f
|
||
<code>f :: Num a => a -> a -> a</code>
|
||
</pre>
|
||
|
||
<p>Hey? What is this strange type?</p>
|
||
|
||
<pre><code>Num a => a -> a -> a
|
||
</code></pre>
|
||
|
||
<p>First, let’s focus on the right part <code>a -> a -> a</code>.
|
||
To understand it, just look at a list of progressive examples: </p>
|
||
|
||
<table>
|
||
<tbody>
|
||
<tr>
|
||
<td>The written type</td>
|
||
<td>It’s meaning</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>Int</code></td>
|
||
<td>the type <code>Int</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>Int -> Int</code></td>
|
||
<td>the type function from <code>Int</code> to <code>Int</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>Float -> Int</code></td>
|
||
<td>the type function from <code>Float</code> to <code>Int</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>a -> Int</code></td>
|
||
<td>the type function from any type to <code>Int</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>a -> a</code></td>
|
||
<td>the type function from any type <code>a</code> to the same type <code>a</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>a -> a -> a</code></td>
|
||
<td>the type function of two arguments of any type <code>a</code> to the same type <code>a</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
|
||
<p>In the type <code>a -> a -> a</code>, the letter <code>a</code> is a <em>type variable</em>.
|
||
It means <code>f</code> is a function with two argument and both argument and the result have the same type.
|
||
The type variable <code>a</code> could take many different type value.
|
||
For example <code>Int</code>, <code>Integer</code>, <code>Float</code>…</p>
|
||
|
||
<p>So instead of having a forced type like in <code>C</code> with declaring the function for <code>int</code>, <code>long</code>, <code>float</code>, <code>double</code>, etc…
|
||
We declare only one function like in a dynamic typed language.</p>
|
||
|
||
<p>Generally <code>a</code> can be any type.
|
||
For example a <code>String</code>, an <code>Int</code>, but also more complex types, like <code>Trees</code>, other functions, etc…
|
||
But here our type is prefixed with <code>Num a => </code>. </p>
|
||
|
||
<p><code>Num</code> is a <em>type class</em>.
|
||
A type class can be understood as a set of types.
|
||
<code>Num</code> contains only types which behave like numbers.
|
||
More precisely, <code>Num</code> is class containing types who implement a specific list of functions, and in particular <code>(+)</code> and <code>(*)</code>.</p>
|
||
|
||
<p>Type class is a very powerful language construction.
|
||
We can do some incredibly powerful stuff with this.
|
||
More on this later.</p>
|
||
|
||
<p>Finally, <code>Num a => a -> a -> a</code> means:</p>
|
||
|
||
<p>Let <code>a</code> be a type belonging to the <code>Num</code> type class.
|
||
This is a function from type <code>a</code> to (<code>a -> a</code>).</p>
|
||
|
||
<p>Yes, strange.
|
||
In fact, in Haskell no function really have two arguments.
|
||
Instead all functions have only one argument.
|
||
But we remark that taking two argument is equivalent to taking one argument and returning a function taking the second argument as parameter.</p>
|
||
|
||
<p>More precisely <code>f 3 4</code> is equivalent to <code>(f 3) 4</code>.
|
||
Note <code>f 3</code> is a function:</p>
|
||
|
||
<pre><code>f :: Num a :: a -> a -> a
|
||
|
||
g :: Num a :: a -> a
|
||
g = f 3
|
||
|
||
g y ⇔ 3*3 + y*y
|
||
</code></pre>
|
||
|
||
<p>Another notation exists for function.
|
||
The lambda notation permit us to create function without assigning them a name.
|
||
We call them anonymous function.
|
||
We could have written:</p>
|
||
|
||
<pre><code>g = \y -> 3*3 + y*y
|
||
</code></pre>
|
||
|
||
<p>The <code>\</code> is used because it looks like <code>λ</code> and is ASCII.</p>
|
||
|
||
<p>If you are not used to functional programming your brain should start to heat up.
|
||
It is time to make some real application.</p>
|
||
|
||
<p><a href="code/01_basic/10_Introduction/22_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>22_very_basic.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/10_Introduction/23_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>23_very_basic.lhs</strong></a></p>
|
||
|
||
<p>But just before that, we should verify the type system works as expected:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">f</span> :: <span class="Constant">Num</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Variable">a</span> -> <span class="Variable">a</span>
|
||
f x y = x*x + y*y
|
||
|
||
main = <span class="Entity">print</span> (f 3 2.4)
|
||
</pre>
|
||
</div>
|
||
<p>It works, because, <code>3</code> is a valid representation for both Fractional numbers like Float and for Integer.
|
||
As <code>2.4</code> is a Fractional number, <code>3</code> is then interpreted as being also a Fractional number.</p>
|
||
|
||
<p><a href="code/01_basic/10_Introduction/23_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>23_very_basic.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/10_Introduction/24_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>24_very_basic.lhs</strong></a></p>
|
||
|
||
<p>If we force our function to work with different type, it will fail:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">f</span> :: <span class="Constant">Num</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Variable">a</span> -> <span class="Variable">a</span>
|
||
f x y = x*x + y*y
|
||
|
||
<span class="Entity">x</span> :: <span class="Constant">Int</span>
|
||
x = 3
|
||
<span class="Entity">y</span> :: <span class="Constant">Float</span>
|
||
y = 2.4
|
||
main = <span class="Entity">print</span> (f x y) <span class="Comment"><span class="Comment">--</span> won't work because type x ‡ type y</span>
|
||
</pre>
|
||
</div>
|
||
<p>The compiler complains.
|
||
The two parameter must have the same type.</p>
|
||
|
||
<p>If you believe it is a bad idea, and the compiler should make the transformation
|
||
from a type to another for you, you should really watch this great (and funny) video:
|
||
<a href="https://www.destroyallsoftware.com/talks/wat">WAT</a></p>
|
||
|
||
<p><a href="code/01_basic/10_Introduction/24_very_basic.lhs" class="cut">01_basic/10_Introduction/<strong>24_very_basic.lhs</strong> </a></p>
|
||
|
||
<h2 id="essential-haskell">Essential Haskell</h2>
|
||
|
||
<p><img alt="Kandinsky Gugg" src="/Scratch/img/blog/Haskell-the-Hard-Way/kandinsky_gugg.jpg" /></p>
|
||
|
||
<p>I suggest you to skim this part.
|
||
Think of it like a reference.
|
||
Haskell has a lot of features.
|
||
Many informations are missing here.
|
||
Get back here if notation feels strange.</p>
|
||
|
||
<p>I use the <code>⇔</code> symbol to state that two expression are equivalent.
|
||
It is a meta notation, <code>⇔</code> does not exists in Haskell.
|
||
I will also use <code>⇒</code> to show what is the return of an expression.</p>
|
||
|
||
<h3 id="notations">Notations</h3>
|
||
|
||
<h5 id="arithmetic">Arithmetic</h5>
|
||
|
||
<pre><code>3 + 2 * 6 / 3 ⇔ 3 + ((2*6)/3)
|
||
</code></pre>
|
||
|
||
<h5 id="logic">Logic</h5>
|
||
|
||
<pre><code>True || False ⇒ True
|
||
True && False ⇒ False
|
||
True == False ⇒ False
|
||
True /= False ⇒ True (/=) is the operator for different
|
||
</code></pre>
|
||
|
||
<h5 id="powers">Powers</h5>
|
||
|
||
<pre><code>x^n for n an integral (understand Int or Integer)
|
||
x**y for y any kind of number (Float for example)
|
||
</code></pre>
|
||
|
||
<p><code>Integer</code> have no limit except the capacity of your machine:</p>
|
||
|
||
<pre><code>4^103
|
||
102844034832575377634685573909834406561420991602098741459288064
|
||
</code></pre>
|
||
|
||
<p>Yeah!
|
||
And also rational numbers FTW!
|
||
But you need to import the module <code>Data.Ratio</code>:</p>
|
||
|
||
<pre><code>$ ghci
|
||
....
|
||
Prelude> :m Data.Ratio
|
||
Data.Ratio> (11 % 15) * (5 % 3)
|
||
11 % 9
|
||
</code></pre>
|
||
|
||
<h5 id="lists">Lists</h5>
|
||
|
||
<pre><code>[] ⇔ empty list
|
||
[1,2,3] ⇔ List of integral
|
||
["foo","bar","baz"] ⇔ List of String
|
||
1:[2,3] ⇔ [1,2,3], (:) prepend one element
|
||
1:2:[] ⇔ [1,2]
|
||
[1,2] ++ [3,4] ⇔ [1,2,3,4], (++) concatenate
|
||
[1,2,3] ++ ["foo"] ⇔ ERROR String ≠ Integral
|
||
[1..4] ⇔ [1,2,3,4]
|
||
[1,3..10] ⇔ [1,3,5,7,9]
|
||
[2,3,5,7,11..100] ⇔ ERROR! I am not so smart!
|
||
[10,9..1] ⇔ [10,9,8,7,6,5,4,3,2,1]
|
||
</code></pre>
|
||
|
||
<h5 id="strings">Strings</h5>
|
||
|
||
<p>In Haskell strings are list of <code>Char</code>.</p>
|
||
|
||
<pre><code>'a' :: Char
|
||
"a" :: [Char]
|
||
"" ⇔ []
|
||
"ab" ⇔ ['a','b'] ⇔ 'a':"b" ⇔ 'a':['b'] ⇔ 'a':'b':[]
|
||
"abc" ⇔ "ab"++"c"
|
||
</code></pre>
|
||
|
||
<blockquote>
|
||
<p><em>Remark</em>:
|
||
In real code you shouldn’t use list of char to represent text.
|
||
You should mostly use <code>Data.Text</code> instead.
|
||
If you want to represent stream of ASCII char, you should use <code>Data.ByteString</code>.</p>
|
||
</blockquote>
|
||
|
||
<h5 id="tuples">Tuples</h5>
|
||
|
||
<p>The type of couple is <code>(a,b)</code>.
|
||
Elements in a tuple can have different type.</p>
|
||
|
||
<pre><code>-- All these tuple are valid
|
||
(2,"foo")
|
||
(3,'a',[2,3])
|
||
((2,"a"),"c",3)
|
||
|
||
fst (x,y) ⇒ x
|
||
snd (x,y) ⇒ y
|
||
|
||
fst (x,y,z) ⇒ ERROR: fst :: (a,b) -> a
|
||
snd (x,y,z) ⇒ ERROR: snd :: (a,b) -> b
|
||
</code></pre>
|
||
|
||
<h5 id="deal-with-parenthesis">Deal with parenthesis</h5>
|
||
|
||
<p>To remove some parenthesis you can use two functions: <code>($)</code> and <code>(.)</code>.</p>
|
||
|
||
<pre><code>-- By default:
|
||
f g h x ⇔ (((f g) h) x)
|
||
|
||
-- the $ replace parenthesis from the $
|
||
-- to the end of the expression
|
||
f g $ h x ⇔ f g (h x) ⇔ (f g) (h x)
|
||
f $ g h x ⇔ f (g h x) ⇔ f ((g h) x)
|
||
f $ g $ h x ⇔ f (g (h x))
|
||
|
||
-- (.) the composition function
|
||
(f . g) x ⇔ f (g x)
|
||
(f . g . h) x ⇔ f (g (h x))
|
||
</code></pre>
|
||
|
||
<hr />
|
||
<p><a href="code/01_basic/20_Essential_Haskell/10a_Functions.lhs" class="cut">01_basic/20_Essential_Haskell/<strong>10a_Functions.lhs</strong></a></p>
|
||
|
||
<h3 id="useful-notations-for-functions">Useful notations for functions</h3>
|
||
|
||
<p>Just a reminder:</p>
|
||
|
||
<pre><code>x :: Int ⇔ x is of type Int
|
||
x :: a ⇔ x can be of any type
|
||
x :: Num a => a ⇔ x can be any type a
|
||
such that a belongs to Num type class
|
||
f :: a -> b ⇔ f is a function from a to b
|
||
f :: a -> b -> c ⇔ f is a function from a to (b→c)
|
||
f :: (a -> b) -> c ⇔ f is a function from (a→b) to c
|
||
</code></pre>
|
||
|
||
<p>Defining the type of a function before its declaration isn’t mandatory.
|
||
Haskell infers the most general type for you.
|
||
But it is considered a good practice to do so.</p>
|
||
|
||
<p><em>Infix notation</em></p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">square</span> :: <span class="Constant">Num</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Variable">a</span>
|
||
square x = x^2
|
||
</pre>
|
||
</div>
|
||
<p>Note <code>^</code> use infix notation.
|
||
For each infix operator there its associated prefix notation.
|
||
You just have to put it inside parenthesis.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
square' x = (^) x 2
|
||
|
||
square'' x = (^2) x
|
||
</pre>
|
||
</div>
|
||
<p>We can remove <code>x</code> in the left and right side!
|
||
It’s called currying.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
square''' = (^2)
|
||
</pre>
|
||
</div>
|
||
<p>Note we can declare function with <code>'</code> in their name.
|
||
Here:</p>
|
||
|
||
<blockquote>
|
||
<p><code>square</code> ⇔ <code>square'</code> ⇔ <code>square''</code> ⇔ <code>square '''</code></p>
|
||
</blockquote>
|
||
|
||
<p><em>Tests</em></p>
|
||
|
||
<p>An implementation of the absolute function.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">absolute</span> :: (<span class="Constant">Ord</span> <span class="Variable">a</span>, <span class="Constant">Num</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Variable">a</span>
|
||
absolute x = <span class="Keyword">if</span> x >= 0 <span class="Keyword">then</span> x <span class="Keyword">else</span> -x
|
||
</pre>
|
||
</div>
|
||
<p>Note: the <code>if .. then .. else</code> Haskell notation is more like the
|
||
<code>¤?¤:¤</code> C operator. You cannot forget the <code>else</code>.</p>
|
||
|
||
<p>Another equivalent version:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
absolute' x
|
||
| x >= 0 = x
|
||
| <span class="Keyword">otherwise</span> = -x
|
||
</pre>
|
||
</div>
|
||
<blockquote>
|
||
<p>Notation warning: indentation is <em>important</em> in Haskell.
|
||
Like in Python, a bad indentation could break your code!</p>
|
||
</blockquote>
|
||
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> $ square 10
|
||
<span class="Entity">print</span> $ square' 10
|
||
<span class="Entity">print</span> $ square'' 10
|
||
<span class="Entity">print</span> $ square''' 10
|
||
<span class="Entity">print</span> $ absolute 10
|
||
<span class="Entity">print</span> $ absolute (-10)
|
||
<span class="Entity">print</span> $ absolute' 10
|
||
<span class="Entity">print</span> $ absolute' (-10)
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/01_basic/20_Essential_Haskell/10a_Functions.lhs" class="cut">01_basic/20_Essential_Haskell/<strong>10a_Functions.lhs</strong> </a></p>
|
||
|
||
<h2 id="hard-part">Hard Part</h2>
|
||
|
||
<p>The hard part could now begins.</p>
|
||
|
||
<h3 id="functional-style">Functional style</h3>
|
||
|
||
<p><img alt="Biomechanical Landscape by H.R. Giger" src="/Scratch/img/blog/Haskell-the-Hard-Way/hr_giger_biomechanicallandscape_500.jpg" /></p>
|
||
|
||
<p>In this section, I give a short example of the impressive refactoring ability provided by Haskell.
|
||
We will choose a problem and resolve it using a standard imperative way.
|
||
Then I will make the code evolve.
|
||
The end result will be both more elegant and easier to adapt. </p>
|
||
|
||
<p>Let’s resolve the following problem:</p>
|
||
|
||
<blockquote>
|
||
<p>Given a list of integer, return the sum of its even numbers.</p>
|
||
|
||
<p>example:
|
||
<code>[1,2,3,4,5] ⇒ 2 + 4 ⇒ 6</code></p>
|
||
</blockquote>
|
||
|
||
<p>To show differences between functional and imperative approach,
|
||
I’ll start by providing an imperative solution (in javascript):</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Storage">function</span> <span class="Entity">evenSum</span>(<span class="Variable">list</span>) {
|
||
<span class="Storage">var</span> result <span class="Keyword">=</span> <span class="Constant">0</span>;
|
||
<span class="Keyword">for</span> (<span class="Storage">var</span> i<span class="Keyword">=</span><span class="Constant">0</span>; i<span class="Keyword"><</span> list.<span class="SupportConstant">length</span> ; i<span class="Keyword">++</span>) {
|
||
<span class="Keyword">if</span> (list[i] <span class="Keyword">%</span> <span class="Constant">2</span> <span class="Keyword">==</span><span class="Constant">0</span>) {
|
||
result <span class="Keyword">+</span><span class="Keyword">=</span> list[i];
|
||
}
|
||
}
|
||
<span class="Keyword">return</span> result;
|
||
}
|
||
</pre>
|
||
|
||
<p>But, in Haskell we don’t have variable, nor for loop.
|
||
One solution to achieve the same result without loop is to use recursion.</p>
|
||
|
||
<blockquote>
|
||
<p><em>Remark</em>:<br />
|
||
Recursion is generally perceived as slow in imperative language.
|
||
But it is generally not the case in functional programming.
|
||
Most of the time Haskell will handle recursive function efficiently.</p>
|
||
</blockquote>
|
||
|
||
<p>Here is a <code>C</code> version of the recursive function.
|
||
Note, for simplicity, I assume the int list should end with the first <code>0</code> value.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Storage">int</span> evenSum(<span class="Storage">int</span> *list) {
|
||
<span class="Keyword">return</span> accumSum(<span class="Constant">0</span>,list);
|
||
}
|
||
|
||
<span class="Storage">int</span> <span class="Entity">accumS<span class="Entity">um</span></span>(<span class="Storage">int</span> n, <span class="Storage">int</span> *list) {
|
||
<span class="Storage">int</span> x;
|
||
<span class="Storage">int</span> *xs;
|
||
<span class="Keyword">if</span> (*list == <span class="Constant">NULL</span>) { <span class="Comment"><span class="Comment">//</span> if the list is empty</span>
|
||
<span class="Keyword">return</span> n;
|
||
} <span class="Keyword">else</span> {
|
||
x = list[<span class="Constant">0</span>]; <span class="Comment"><span class="Comment">//</span> let x be the first element of the list</span>
|
||
xs = list+<span class="Constant">1</span>; <span class="Comment"><span class="Comment">//</span> let xs be the list without x</span>
|
||
<span class="Keyword">if</span> ( <span class="Constant">0</span> == (x%<span class="Constant">2</span>) ) { <span class="Comment"><span class="Comment">//</span> if x is even</span>
|
||
<span class="Keyword">return</span> accumSum(n+x, xs);
|
||
} <span class="Keyword">else</span> {
|
||
<span class="Keyword">return</span> accumSum(n, xs);
|
||
}
|
||
}
|
||
}
|
||
</pre>
|
||
|
||
<p>Keep this code in mind. We will translate it in Haskell.
|
||
But before, I need to introduce three simple but useful function we will use:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">even</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Constant">Bool</span>
|
||
<span class="Entity">head</span> :: [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
<span class="Entity">tail</span> :: [<span class="Variable">a</span>] -> [<span class="Variable">a</span>]
|
||
</pre>
|
||
|
||
<p><code>even</code> verify if a number is even.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">even</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Constant">Bool</span>
|
||
<span class="Entity">even</span> 3 ⇒ <span class="Constant">False</span>
|
||
<span class="Entity">even</span> 2 ⇒ <span class="Constant">True</span>
|
||
</pre>
|
||
|
||
<p><code>head</code> returns the first element of a list:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">head</span> :: [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
<span class="Entity">head</span> [1,2,3] ⇒ 1
|
||
<span class="Entity">head</span> [] ⇒ <span class="Constant">ERROR</span>
|
||
</pre>
|
||
|
||
<p><code>tail</code>, returns all element except the first of a list:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">tail</span> :: [<span class="Variable">a</span>] -> [<span class="Variable">a</span>]
|
||
<span class="Entity">tail</span> [1,2,3] ⇒ [2,3]
|
||
<span class="Entity">tail</span> [3] ⇒ []
|
||
<span class="Entity">tail</span> [] ⇒ <span class="Constant">ERROR</span>
|
||
</pre>
|
||
|
||
<p>Remark that for any non empty list <code>l</code>,
|
||
<code>l ⇔ (head l):(tail l)</code></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/11_Functions.lhs" class="cut">02_Hard_Part/<strong>11_Functions.lhs</strong></a></p>
|
||
|
||
<p>The first Haskell solution.
|
||
The function <code>evenSum</code> returns the sum of all even numbers in a list:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 1</span>
|
||
<span class="Entity">evenSum</span> :: [<span class="Constant">Integer</span>] -> <span class="Constant">Integer</span>
|
||
|
||
evenSum l = accumSum 0 l
|
||
|
||
accumSum n l = <span class="Keyword">if</span> l == []
|
||
<span class="Keyword">then</span> n
|
||
<span class="Keyword">else</span> <span class="Keyword">let</span> x = <span class="Entity">head</span> l
|
||
xs = <span class="Entity">tail</span> l
|
||
<span class="Keyword">in</span> <span class="Keyword">if</span> <span class="Entity">even</span> x
|
||
<span class="Keyword">then</span> accumSum (n+x) xs
|
||
<span class="Keyword">else</span> accumSum n xs
|
||
</pre>
|
||
</div>
|
||
<p>To test a function you can use <code>ghci</code>:</p>
|
||
|
||
<pre>
|
||
% ghci
|
||
<span class="low">GHCi, version 7.0.3: http://www.haskell.org/ghc/ :? for help
|
||
Loading package ghc-prim ... linking ... done.
|
||
Loading package integer-gmp ... linking ... done.
|
||
Loading package base ... linking ... done.
|
||
Prelude></span> :load 11_Functions.lhs
|
||
<span class="low">[1 of 1] Compiling Main ( 11_Functions.lhs, interpreted )
|
||
Ok, modules loaded: Main.
|
||
*Main></span> evenSum [1..5]
|
||
6
|
||
</pre>
|
||
|
||
<p>Here is an example of execution<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup>: </p>
|
||
|
||
<pre>
|
||
*Main> evenSum [1..5]
|
||
accumSum 0 [1,2,3,4,5]
|
||
<span class="yellow">1 is odd</span>
|
||
accumSum 0 [2,3,4,5]
|
||
<span class="yellow">2 is even</span>
|
||
accumSum (0+2) [3,4,5]
|
||
<span class="yellow">3 is odd</span>
|
||
accumSum (0+2) [4,5]
|
||
<span class="yellow">4 is even</span>
|
||
accumSum (0+2+4) [5]
|
||
<span class="yellow">5 is odd</span>
|
||
accumSum (0+2+4) []
|
||
<span class="yellow">l == []</span>
|
||
0+2+4
|
||
0+6
|
||
6
|
||
</pre>
|
||
|
||
<p>Coming from an imperative language all should seems right.
|
||
In reality many things can be improved.
|
||
First, we can generalize the type.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">evenSum</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
</pre>
|
||
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span> <span class="Entity">print</span> $ evenSum [1..10]
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/02_Hard_Part/11_Functions.lhs" class="cut">02_Hard_Part/<strong>11_Functions.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/12_Functions.lhs" class="cut">02_Hard_Part/<strong>12_Functions.lhs</strong></a></p>
|
||
|
||
<p>Next, we can use sub functions using <code>where</code> or <code>let</code>.
|
||
This way our <code>accumSum</code> function won’t pollute the global name space.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 2</span>
|
||
<span class="Entity">evenSum</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
|
||
evenSum l = accumSum 0 l
|
||
<span class="Keyword">where</span> accumSum n l =
|
||
<span class="Keyword">if</span> l == []
|
||
<span class="Keyword">then</span> n
|
||
<span class="Keyword">else</span> <span class="Keyword">let</span> x = <span class="Entity">head</span> l
|
||
xs = <span class="Entity">tail</span> l
|
||
<span class="Keyword">in</span> <span class="Keyword">if</span> <span class="Entity">even</span> x
|
||
<span class="Keyword">then</span> accumSum (n+x) xs
|
||
<span class="Keyword">else</span> accumSum n xs
|
||
</pre>
|
||
</div>
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ evenSum [1..10]
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/02_Hard_Part/12_Functions.lhs" class="cut">02_Hard_Part/<strong>12_Functions.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/13_Functions.lhs" class="cut">02_Hard_Part/<strong>13_Functions.lhs</strong></a></p>
|
||
|
||
<p>Next, we can use pattern matching.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 3</span>
|
||
evenSum l = accumSum 0 l
|
||
<span class="Keyword">where</span>
|
||
accumSum n [] = n
|
||
accumSum n (x:xs) =
|
||
<span class="Keyword">if</span> <span class="Entity">even</span> x
|
||
<span class="Keyword">then</span> accumSum (n+x) xs
|
||
<span class="Keyword">else</span> accumSum n xs
|
||
</pre>
|
||
</div>
|
||
<p>What is pattern matching?
|
||
Use value instead of general parameter name.</p>
|
||
|
||
<p>Instead of saying: <code>foo l = if l == [] then <x> else <y></code>
|
||
You simply state: </p>
|
||
|
||
<pre class="twilight">
|
||
foo [] = <x>
|
||
foo l = <y>
|
||
</pre>
|
||
|
||
<p>But pattern matching go even further.
|
||
It is also able to inspect inside data.
|
||
We can replace</p>
|
||
|
||
<pre class="twilight">
|
||
foo l = <span class="Keyword">let</span> x = <span class="Entity">head</span> l
|
||
xs = <span class="Entity">tail</span> l
|
||
<span class="Keyword">in</span> <span class="Keyword">if</span> <span class="Entity">even</span> x
|
||
<span class="Keyword">then</span> foo (n+x) xs
|
||
<span class="Keyword">else</span> foo n xs
|
||
</pre>
|
||
|
||
<p>by</p>
|
||
|
||
<pre class="twilight">
|
||
foo (x:xs) = <span class="Keyword">if</span> <span class="Entity">even</span> x
|
||
<span class="Keyword">then</span> foo (n+x) xs
|
||
<span class="Keyword">else</span> foo n xs
|
||
</pre>
|
||
|
||
<p>This is a very useful feature.
|
||
It makes our code both terser and easier to read.</p>
|
||
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ evenSum [1..10]
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/02_Hard_Part/13_Functions.lhs" class="cut">02_Hard_Part/<strong>13_Functions.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/14_Functions.lhs" class="cut">02_Hard_Part/<strong>14_Functions.lhs</strong></a></p>
|
||
|
||
<p>In Haskell you can simplify function definition by curry them.
|
||
For example, instead of writing:</p>
|
||
|
||
<pre class="twilight">
|
||
f x = (some expresion) x
|
||
</pre>
|
||
|
||
<p>you can simply write</p>
|
||
|
||
<pre class="twilight">
|
||
f = some expression
|
||
</pre>
|
||
|
||
<p>We use this method to remove the <code>l</code>:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 4</span>
|
||
<span class="Entity">evenSum</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
|
||
evenSum = accumSum 0
|
||
<span class="Keyword">where</span>
|
||
accumSum n [] = n
|
||
accumSum n (x:xs) =
|
||
<span class="Keyword">if</span> <span class="Entity">even</span> x
|
||
<span class="Keyword">then</span> accumSum (n+x) xs
|
||
<span class="Keyword">else</span> accumSum n xs
|
||
</pre>
|
||
</div>
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ evenSum [1..10]
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/02_Hard_Part/14_Functions.lhs" class="cut">02_Hard_Part/<strong>14_Functions.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/15_Functions.lhs" class="cut">02_Hard_Part/<strong>15_Functions.lhs</strong></a></p>
|
||
|
||
<h4 id="higher-order-functions">Higher Order Functions</h4>
|
||
|
||
<p><img alt="Escher" src="/Scratch/img/blog/Haskell-the-Hard-Way/escher_polygon.png" /></p>
|
||
|
||
<p>To make things even better we should use higher order functions.
|
||
What are these beast?
|
||
Higher order functions are functions taking function as parameter.</p>
|
||
|
||
<p>Here are some examples:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">filter</span> :: (<span class="Variable">a</span> -> <span class="Constant">Bool</span>) -> [<span class="Variable">a</span>] -> [<span class="Variable">a</span>]
|
||
<span class="Entity">map</span> :: (<span class="Variable">a</span> -> <span class="Variable">b</span>) -> [<span class="Variable">a</span>] -> [<span class="Variable">b</span>]
|
||
<span class="Entity">foldl</span> :: (<span class="Variable">a</span> -> <span class="Variable">b</span> -> <span class="Variable">a</span>) -> <span class="Variable">a</span> -> [<span class="Variable">b</span>] -> <span class="Variable">a</span>
|
||
</pre>
|
||
|
||
<p>Let’s proceed by small steps.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 5</span>
|
||
evenSum l = mysum 0 (<span class="Entity">filter</span> <span class="Entity">even</span> l)
|
||
<span class="Keyword">where</span>
|
||
mysum n [] = n
|
||
mysum n (x:xs) = mysum xs (n+x)
|
||
</pre>
|
||
|
||
<p>where</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">filter</span> <span class="Entity">even</span> [1..10] ⇔ [2,4,6,8,10]
|
||
</pre>
|
||
|
||
<p>The function <code>filter</code> takes a function of type (<code>a -> Bool</code>) and a list of type <code>[a]</code>. It returns a list containing only elements for which the function returned <code>true</code>.</p>
|
||
|
||
<p>Our next step is to use another way to simulate loop.
|
||
We will use the <code>foldl</code> to accumulate a value.
|
||
The function <code>foldl</code> capture a general coding pattern:</p>
|
||
|
||
<pre>
|
||
myfunc list = foo <span class="blue">initialValue</span> <span class="green">list</span>
|
||
foo accumulated [] = accumulated
|
||
foo tmpValue (x:xs) = foo (<span class="yellow">bar</span> tmpValue x) xs
|
||
</pre>
|
||
|
||
<p>Which can be replaced by:</p>
|
||
|
||
<pre>
|
||
myfunc list = foldl <span class="yellow">bar</span> <span class="blue">initialValue</span> <span class="green">list</span>
|
||
</pre>
|
||
|
||
<p>If you really want to know how the magic works.
|
||
Here is the definition of <code>foldl</code>.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">foldl</span> f z [] = z
|
||
<span class="Entity">foldl</span> f z (x:xs) = <span class="Entity">foldl</span> f (f z x) xs
|
||
</pre>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">foldl</span> f z [x1,...xn]
|
||
⇔ f (... (f (f z x1) x2) ...) xn
|
||
</pre>
|
||
|
||
<p>But as Haskell is lazy, it doesn’t evaluate <code>(f z x)</code> and push this to the stack.
|
||
This is why we generally use <code>foldl'</code> instead of <code>foldl</code>;
|
||
<code>foldl'</code> is a <em>strict</em> version of <code>foldl</code>.
|
||
If you don’t understand what lazy and strict means,
|
||
don’t worry, just follow the code as if <code>foldl</code> and <code>foldl'</code> where identical.</p>
|
||
|
||
<p>Now our new version of <code>evenSum</code> become:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 6</span>
|
||
<span class="Comment"><span class="Comment">--</span> foldl' isn't accessible by default</span>
|
||
<span class="Comment"><span class="Comment">--</span> we need to import it from the module Data.List</span>
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span>
|
||
evenSum l = <span class="Entity">foldl</span>' mysum 0 (<span class="Entity">filter</span> <span class="Entity">even</span> l)
|
||
<span class="Keyword">where</span> mysum acc value = acc + value
|
||
</pre>
|
||
|
||
<p>Version we can simplify by using directly a lambda notation.
|
||
This way we don’t have to create the temporary name <code>mysum</code>.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 7</span>
|
||
<span class="Comment"><span class="Comment">--</span> Generally it is considered a good practice</span>
|
||
<span class="Comment"><span class="Comment">--</span> to import only the necessary function(s)</span>
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span> (<span class="Entity">foldl</span>')
|
||
evenSum l = <span class="Entity">foldl</span>' (\x y -> x+y) 0 (<span class="Entity">filter</span> <span class="Entity">even</span> l)
|
||
</pre>
|
||
</div>
|
||
<p>And of course, we remark </p>
|
||
|
||
<pre class="twilight">
|
||
(\x y -> x+y) ⇔ <span class="Entity">(+)</span>
|
||
</pre>
|
||
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ evenSum [1..10]
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/02_Hard_Part/15_Functions.lhs" class="cut">02_Hard_Part/<strong>15_Functions.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/16_Functions.lhs" class="cut">02_Hard_Part/<strong>16_Functions.lhs</strong></a></p>
|
||
|
||
<p>Finally</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 8</span>
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span> (<span class="Entity">foldl</span>')
|
||
<span class="Entity">evenSum</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
evenSum l = <span class="Entity">foldl</span>' <span class="Entity">(+)</span> 0 (<span class="Entity">filter</span> <span class="Entity">even</span> l)
|
||
</pre>
|
||
|
||
<p><code>foldl'</code> isn’t the easiest function to intuit.
|
||
If you are not used to it, you should exercise a bit.</p>
|
||
|
||
<p>To help you understand what’s going on here, a step by step evaluation:</p>
|
||
|
||
<pre>
|
||
<span class="yellow">evenSum [1,2,3,4]</span>
|
||
⇒ foldl' (+) 0 (<span class="yellow">filter even [1,2,3,4]</span>)
|
||
⇒ <span class="yellow">foldl' (+) 0 <span class="blue">[2,4]</span></span>
|
||
⇒ <span class="blue">foldl' (+) (<span class="yellow">0+2</span>) [4]</span>
|
||
⇒ <span class="yellow">foldl' (+) <span class="blue">2</span> [4]</span>
|
||
⇒ <span class="blue">foldl' (+) (<span class="yellow">2+4</span>) []</span>
|
||
⇒ <span class="yellow">foldl' (+) <span class="blue">6</span> []</span>
|
||
⇒ <span class="blue">6</span>
|
||
</pre>
|
||
|
||
<p>Another useful higher order function is <code>(.)</code>.
|
||
The <code>(.)</code> function correspond to the mathematical composition.</p>
|
||
|
||
<pre class="twilight">
|
||
(f . g . h) x ⇔ f ( g (h x))
|
||
</pre>
|
||
|
||
<p>We can take advantage of this operator to curry a bit more our function:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 9</span>
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span> (<span class="Entity">foldl</span>')
|
||
<span class="Entity">evenSum</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
evenSum = (<span class="Entity">foldl</span>' <span class="Entity">(+)</span> 0) . (<span class="Entity">filter</span> <span class="Entity">even</span>)
|
||
</pre>
|
||
|
||
<p>Also, we could rename a bit some part to make it clearer:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> Version 10 </span>
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span> (<span class="Entity">foldl</span>')
|
||
<span class="Entity">sum</span>' :: (<span class="Constant">Num</span> a) => [a] -> a
|
||
<span class="Entity">sum</span>' = <span class="Entity">foldl</span>' <span class="Entity">(+)</span> 0
|
||
<span class="Entity">evenSum</span> :: <span class="Constant">Integral</span> <span class="Variable">a</span> => [<span class="Variable">a</span>] -> <span class="Variable">a</span>
|
||
evenSum = <span class="Entity">sum</span>' . (<span class="Entity">filter</span> <span class="Entity">even</span>)
|
||
|
||
</pre>
|
||
</div>
|
||
<p>It is time to discuss a bit.
|
||
What did we gain by using higher order functions?</p>
|
||
|
||
<p>At first, you can say it is terseness.
|
||
But in fact, it has more to do with better thinking.
|
||
Suppose we want to modify slightly our function.
|
||
We want to get the sum of all even square of element of the list.</p>
|
||
|
||
<pre><code>[1,2,3,4] ▷ [1,4,9,16] ▷ [4,16] ▷ 20
|
||
</code></pre>
|
||
|
||
<p>Update the version 10 is extremely easy:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
squareEvenSum = <span class="Entity">sum</span>' . (<span class="Entity">filter</span> <span class="Entity">even</span>) . (<span class="Entity">map</span> (^2))
|
||
squareEvenSum' = evenSum . (<span class="Entity">map</span> (^2))
|
||
squareEvenSum'' = <span class="Entity">sum</span>' . (<span class="Entity">map</span> (^2)) . (<span class="Entity">filter</span> <span class="Entity">even</span>)
|
||
</pre>
|
||
</div>
|
||
<p>We just had to add another “transformation function”<sup id="fnref:0216"><a href="#fn:0216" rel="footnote">3</a></sup>.</p>
|
||
|
||
<pre><code>map (^2) [1,2,3,4] ⇔ [1,4,9,16]
|
||
</code></pre>
|
||
|
||
<p>The <code>map</code> function simply apply a function to all element of a list.</p>
|
||
|
||
<p>We didn’t had to modify <em>inside</em> the function definition.
|
||
It feels more modular.
|
||
But there is also you can think more mathematically about your function.
|
||
You could then use your function as any other one.
|
||
You could compose, map, fold, filter using your new function.</p>
|
||
|
||
<p>To modify version 1 is left as an exercise to the reader ☺.</p>
|
||
|
||
<p>If you believe we reached the end of generalization, then know you are very wrong.
|
||
For example, there is a way to not only use this function on list but on any recursive type.
|
||
If you want to know how, I suggest you to read this quite fun article: <a href="http://eprints.eemcs.utwente.nl/7281/0
|
||
1/db-utwente-40501F46.pdf">Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire by Meijer, Fokkinga and Paterson</a>.</p>
|
||
|
||
<p>This example should show you how pure functional programming is great.
|
||
Unfortunately, using pure functional programming isn’t well suited for all usages.
|
||
Or at least it isn’t found yet.</p>
|
||
|
||
<p>One of the great power of Haskell, is the ability to create DSL
|
||
(Domain Specific Language)
|
||
making it easy to change the programming paradigm.</p>
|
||
|
||
<p>In fact, Haskell is also great when you want to write imperative style programming.
|
||
Understanding this was really hard for me when learning Haskell.
|
||
A lot of effort is provided to explain you how much functional approach is superior.
|
||
Then when you attack the imperative style of Haskell, it is hard to understand why and how.</p>
|
||
|
||
<p>But before talking about this Haskell super-power, we must talk about another
|
||
essential aspect of Haskell: <em>Types</em>.</p>
|
||
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ evenSum [1..10]
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/02_Hard_Part/16_Functions.lhs" class="cut">02_Hard_Part/<strong>16_Functions.lhs</strong> </a></p>
|
||
|
||
<h3 id="types">Types</h3>
|
||
|
||
<p><img alt="Dali, the madonna of port Lligat" src="/Scratch/img/blog/Haskell-the-Hard-Way/salvador-dali-the-madonna-of-port-lligat.jpg" /></p>
|
||
|
||
<blockquote>
|
||
<p><span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span></p>
|
||
|
||
<ul>
|
||
<li><code>type Name = AnotherType</code> is just an alias and the compiler doesn’t do any difference between <code>Name</code> and <code>AnotherType</code>.</li>
|
||
<li><code>data Name = NameConstructor AnotherType</code> make a difference.</li>
|
||
<li><code>data</code> can construct structures which can be recursives.</li>
|
||
<li><code>deriving</code> is magic and create functions for you.</li>
|
||
</ul>
|
||
</blockquote>
|
||
|
||
<p>In Haskell, types are strong and static.</p>
|
||
|
||
<p>Why is this important? It will help you <em>a lot</em> not to make some mistake.
|
||
In Haskell, most bugs are caught during the compilation of your program.
|
||
And the main reason is because of the type inference during compilation.
|
||
It will be easy to detect where you used the bad parameter at the wrong place for example.</p>
|
||
|
||
<h4 id="type-inference">Type inference</h4>
|
||
|
||
<p>Static typing is generally essential to reach fast execution time.
|
||
But most static typed language are bad to generalize concepts.
|
||
What saves Haskell is that it can <em>infere</em> types.</p>
|
||
|
||
<p>Here is a simple example.
|
||
The <code>square</code> function in Haskell:</p>
|
||
|
||
<pre class="twilight">
|
||
square x = x * x
|
||
</pre>
|
||
|
||
<p>This function can <code>square</code> any Numeral type.
|
||
You can provide <code>square</code> an <code>Int</code>, an <code>Integer</code>, a <code>Float</code> a <code>Fractional</code> and even <code>Complex</code>. Proof by example:</p>
|
||
|
||
<pre><code>% ghci
|
||
GHCi, version 7.0.4:
|
||
...
|
||
Prelude> let square x = x*x
|
||
Prelude> square 2
|
||
4
|
||
Prelude> square 2.1
|
||
4.41
|
||
Prelude> -- load the Data.Complex module
|
||
Prelude> :m Data.Complex
|
||
Prelude Data.Complex> square (2 :+ 1)
|
||
3.0 :+ 4.0
|
||
</code></pre>
|
||
|
||
<p><code>x :+ y</code> is the notation for the complex (<i>x + ib</i>).</p>
|
||
|
||
<p>Now compare with the necessary C code:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Storage">int</span> <span class="Entity">int_squa<span class="Entity">re</span></span>(<span class="Storage">int</span> x) { <span class="Keyword">return</span> x*x; }
|
||
|
||
<span class="Storage">float</span> <span class="Entity">float_squa<span class="Entity">re</span></span>(<span class="Storage">float</span> x) {<span class="Keyword">return</span> x*x; }
|
||
|
||
complex <span class="Entity">complex_squa<span class="Entity">re</span></span> (complex z) {
|
||
complex tmp;
|
||
tmp.real = z.real * z.real - z.img * z.img;
|
||
tmp.img = <span class="Constant">2</span> * z.img * z.real;
|
||
}
|
||
|
||
complex x,y;
|
||
y = complex_square(x);
|
||
</pre>
|
||
|
||
<p>For each type, you need to write a new function.
|
||
The only way to work around this problem is to use some meta-programming trick.
|
||
For example using the pre-processor.
|
||
In C++ there is a better way, the C++ templates:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Storage">class</span> Number<T> {
|
||
T value;
|
||
<span class="Entity">square</span>() {
|
||
value = value*value;
|
||
}
|
||
}
|
||
|
||
Number<<span class="Storage">int</span>> i;
|
||
i.square;
|
||
|
||
Number<<span class="Storage">float</span>> f;
|
||
f.square;
|
||
|
||
<span class="Storage">class</span> Complex {
|
||
<span class="Storage">int</span> real;
|
||
<span class="Storage">int</span> img;
|
||
Complex <span class="Entity">operat<span class="Entity">or</span><*></span>(Complex z) {
|
||
Complex result;
|
||
result.real = real*z.real - img*z.img;
|
||
result.img = img*z.real + real*z.img;
|
||
<span class="Keyword">return</span> res;
|
||
}
|
||
}
|
||
|
||
Number<Complex> z;
|
||
z.square
|
||
</pre>
|
||
|
||
<p>Even with C++ templates you are forced to write a line for each type.</p>
|
||
|
||
<p>To be fair, there is also a definition of the multiplication of <code>Complex</code> in Haskell.
|
||
But it takes only one line.
|
||
Somewhere in the source of the module <code>Data.Complex</code>:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">instance</span> <span class="Constant">Num</span> (<span class="Constant">Complex</span> a) <span class="Keyword">where</span>
|
||
...
|
||
(x:+y) * (x':+y') = (x*x'-y*y') :+ (x*y'+y*x')
|
||
...
|
||
</pre>
|
||
|
||
<p>The inference of type gives Haskell a feeling of the freedom that dynamic
|
||
typed languages provide.
|
||
But unlike dynamic typed languages, most error are caught before the execution.
|
||
Generally, in Haskell:</p>
|
||
|
||
<blockquote>
|
||
<p>“if it compiles it certainly does what you intended” </p>
|
||
</blockquote>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/21_Types.lhs" class="cut">02_Hard_Part/<strong>21_Types.lhs</strong></a></p>
|
||
|
||
<h4 id="type-construction">Type construction</h4>
|
||
|
||
<p>You can construct your own types.
|
||
First you can use aliases or type synonyms.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">type</span> <span class="Constant">Name</span> = <span class="Constant">String</span>
|
||
<span class="Keyword">type</span> <span class="Constant">Color</span> = <span class="Constant">String</span>
|
||
|
||
<span class="Entity">showInfos</span> :: <span class="Constant">Name</span> -> <span class="Constant">Color</span> -> <span class="Constant">String</span>
|
||
showInfos name color = <span class="String"><span class="String">"</span>Name: <span class="String">"</span></span> ++ name
|
||
++ <span class="String"><span class="String">"</span>, Color: <span class="String">"</span></span> ++ color
|
||
<span class="Entity">name</span> :: <span class="Constant">Name</span>
|
||
name = <span class="String"><span class="String">"</span>Robin<span class="String">"</span></span>
|
||
<span class="Entity">color</span> :: <span class="Constant">Color</span>
|
||
color = <span class="String"><span class="String">"</span>Blue<span class="String">"</span></span>
|
||
main = <span class="Entity">putStrLn</span> $ showInfos name color
|
||
</pre>
|
||
</div>
|
||
<p><a href="code/02_Hard_Part/21_Types.lhs" class="cut">02_Hard_Part/<strong>21_Types.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/22_Types.lhs" class="cut">02_Hard_Part/<strong>22_Types.lhs</strong></a></p>
|
||
|
||
<p>But it doesn’t protect you much.
|
||
Try to swap the two parameter of <code>showInfos</code> and run the program:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">putStrLn</span> $ showInfos color name
|
||
</pre>
|
||
|
||
<p>It will compile and execute.
|
||
In fact you can replace Name, Color and String everywhere.
|
||
The compiler will treat them as completely identical.</p>
|
||
|
||
<p>Another method is to create your own types using the keyword <code>data</code>.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">Name</span> = <span class="Constant">NameConstr</span> <span class="Constant">String</span>
|
||
<span class="Keyword">data</span> <span class="Constant">Color</span> = <span class="Constant">ColorConstr</span> <span class="Constant">String</span>
|
||
|
||
<span class="Entity">showInfos</span> :: <span class="Constant">Name</span> -> <span class="Constant">Color</span> -> <span class="Constant">String</span>
|
||
showInfos (<span class="Constant">NameConstr</span> name) (<span class="Constant">ColorConstr</span> color) =
|
||
<span class="String"><span class="String">"</span>Name: <span class="String">"</span></span> ++ name ++ <span class="String"><span class="String">"</span>, Color: <span class="String">"</span></span> ++ color
|
||
|
||
name = <span class="Constant">NameConstr</span> <span class="String"><span class="String">"</span>Robin<span class="String">"</span></span>
|
||
color = <span class="Constant">ColorConstr</span> <span class="String"><span class="String">"</span>Blue<span class="String">"</span></span>
|
||
main = <span class="Entity">putStrLn</span> $ showInfos name color
|
||
</pre>
|
||
</div>
|
||
<p>Now if you switch parameters of <code>showInfos</code>, the compiler complains!
|
||
A possible mistake you could never do again.
|
||
The only price is to be more verbose. </p>
|
||
|
||
<p>Also remark constructor are functions:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Constant">NameConstr</span> :: <span class="Constant">String</span> -> <span class="Constant">Name</span>
|
||
<span class="Constant">ColorConstr</span> :: <span class="Constant">String</span> -> <span class="Constant">Color</span>
|
||
</pre>
|
||
|
||
<p>The syntax of <code>data</code> is mainly:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">TypeName</span> = <span class="Constant">ConstructorName</span> [types]
|
||
| <span class="Constant">ConstructorName2</span> [types]
|
||
| ...
|
||
</pre>
|
||
|
||
<p>Generally the usage is to use the same name for the
|
||
DataTypeName and DataTypeConstructor.</p>
|
||
|
||
<p>Example:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">Complex</span> = <span class="Constant">Num</span> a => <span class="Constant">Complex</span> a a
|
||
</pre>
|
||
|
||
<p>Also you can use the record syntax:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">DataTypeName</span> = <span class="Constant">DataConstructor</span> {
|
||
<span class="Entity">field1</span> :: [<span class="Variable">type</span> <span class="Variable">of</span> <span class="Variable">field1</span>]
|
||
, field2 :: [<span class="Keyword">type</span> <span class="Keyword">of</span> field2]
|
||
...
|
||
, fieldn :: [<span class="Keyword">type</span> <span class="Keyword">of</span> fieldn] }
|
||
</pre>
|
||
|
||
<p>And many accessors are made for you.
|
||
Furthermore you can use another order when setting values.</p>
|
||
|
||
<p>Example:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">Complex</span> = <span class="Constant">Num</span> a => <span class="Constant">Complex</span> { real :: a, img :: a}
|
||
c = <span class="Constant">Complex</span> 1.0 2.0
|
||
z = <span class="Constant">Complex</span> { real = 3, img = 4 }
|
||
real c ⇒ 1.0
|
||
img z ⇒ 4
|
||
</pre>
|
||
|
||
<p><a href="code/02_Hard_Part/22_Types.lhs" class="cut">02_Hard_Part/<strong>22_Types.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/23_Types.lhs" class="cut">02_Hard_Part/<strong>23_Types.lhs</strong></a></p>
|
||
|
||
<h4 id="recursive-type">Recursive type</h4>
|
||
|
||
<p>You already encountered recursive types: lists.
|
||
You can re-create lists, but with a more verbose syntax:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">List</span> a = <span class="Constant">Empty</span> | <span class="Constant">Cons</span> a (<span class="Constant">List</span> a)
|
||
</pre>
|
||
|
||
<p>If you really want to use an easier syntax you can use infix name for constructors.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">infixr</span> 5 :::
|
||
<span class="Keyword">data</span> <span class="Constant">List</span> a = <span class="Constant">Nil</span> | a ::: (<span class="Constant">List</span> a)
|
||
</pre>
|
||
|
||
<p>The number after <code>infixr</code> is the priority.</p>
|
||
|
||
<p>If you want to be able to print (<code>Show</code>), read (<code>Read</code>), test equality (<code>Eq</code>) and compare (<code>Ord</code>) your new data structure you can tell Haskell to derive the appropriate function for you.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">infixr</span> 5 :::
|
||
<span class="Keyword">data</span> <span class="Constant">List</span> a = <span class="Constant">Nil</span> | a ::: (<span class="Constant">List</span> a)
|
||
<span class="Keyword">deriving</span> (<span class="Constant">Show</span>,<span class="Constant">Read</span>,<span class="Constant">Eq</span>,<span class="Constant">Ord</span>)
|
||
</pre>
|
||
</div>
|
||
<p>When you add <code>deriving (Show)</code> to your data declaration, Haskell create a <code>show</code> function for you.
|
||
We’ll see soon how you could use your own <code>show</code> function.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
convertList [] = <span class="Constant">Nil</span>
|
||
convertList (x:xs) = x ::: convertList xs
|
||
</pre>
|
||
</div>
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> (0 ::: 1 ::: <span class="Constant">Nil</span>)
|
||
<span class="Entity">print</span> (convertList [0,1])
|
||
</pre>
|
||
</div>
|
||
<p>This print:</p>
|
||
|
||
<pre><code>0 ::: (1 ::: Nil)
|
||
0 ::: (1 ::: Nil)
|
||
</code></pre>
|
||
|
||
<p><a href="code/02_Hard_Part/23_Types.lhs" class="cut">02_Hard_Part/<strong>23_Types.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/30_Trees.lhs" class="cut">02_Hard_Part/<strong>30_Trees.lhs</strong></a></p>
|
||
|
||
<h4 id="trees">Trees</h4>
|
||
|
||
<p><img alt="Magritte, l'Arbre" src="/Scratch/img/blog/Haskell-the-Hard-Way/magritte-l-arbre.jpg" /></p>
|
||
|
||
<p>We’ll just give another standard example: binary trees.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span>
|
||
|
||
<span class="Keyword">data</span> <span class="Constant">BinTree</span> a = <span class="Constant">Empty</span>
|
||
| <span class="Constant">Node</span> a (<span class="Constant">BinTree</span> a) (<span class="Constant">BinTree</span> a)
|
||
<span class="Keyword">deriving</span> (<span class="Constant">Show</span>)
|
||
</pre>
|
||
</div>
|
||
<p>Also we create a function which transform a list into an ordered binary tree.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">treeFromList</span> :: (<span class="Constant">Ord</span> <span class="Variable">a</span>) => [<span class="Variable">a</span>] -> <span class="Constant">BinTree</span> <span class="Variable">a</span>
|
||
treeFromList [] = <span class="Constant">Empty</span>
|
||
treeFromList (x:xs) = <span class="Constant">Node</span> x (treeFromList (<span class="Entity">filter</span> (<x) xs))
|
||
(treeFromList (<span class="Entity">filter</span> (>x) xs))
|
||
</pre>
|
||
</div>
|
||
<p>Look at how elegant this function is.
|
||
In plain English: </p>
|
||
|
||
<ul>
|
||
<li>an empty list will be converted to an empty tree.</li>
|
||
<li>a list <code>(x:xs)</code> will be converted to the tree where:
|
||
<ul>
|
||
<li>The root is <code>x</code></li>
|
||
<li>Its left subtree is the tree created from the list of the remaining element of <code>xs</code> which are strictly inferior to <code>x</code> and </li>
|
||
<li>the right subtree is the tree created from the elements strictly superior to <code>x</code> of the list <code>xs</code>.</li>
|
||
</ul>
|
||
</li>
|
||
</ul>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ treeFromList [7,2,4,8]
|
||
</pre>
|
||
</div>
|
||
<p>You should obtain the following:</p>
|
||
|
||
<pre><code>Node 7 (Node 2 Empty (Node 4 Empty Empty)) (Node 8 Empty Empty)
|
||
</code></pre>
|
||
|
||
<p>This is an informative but quite unpleasant representation of our tree.</p>
|
||
|
||
<p><a href="code/02_Hard_Part/30_Trees.lhs" class="cut">02_Hard_Part/<strong>30_Trees.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/31_Trees.lhs" class="cut">02_Hard_Part/<strong>31_Trees.lhs</strong></a></p>
|
||
|
||
<p>Just for fun, let’s code a better display for our trees.
|
||
I simply had fun into making a nice function to display tree in a general way.
|
||
You can safely pass this part if you find it too difficult to follow.</p>
|
||
|
||
<p>We have few changes to make.
|
||
We remove the <code>deriving (Show)</code> in the declaration of our <code>BinTree</code> type.
|
||
And it also might be useful to make our BinTree an instance of (<code>Eq</code> and <code>Ord</code>).
|
||
We will be able to test equality and compare trees.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">BinTree</span> a = <span class="Constant">Empty</span>
|
||
| <span class="Constant">Node</span> a (<span class="Constant">BinTree</span> a) (<span class="Constant">BinTree</span> a)
|
||
<span class="Keyword">deriving</span> (<span class="Constant">Eq</span>,<span class="Constant">Ord</span>)
|
||
</pre>
|
||
</div>
|
||
<p>Without the <code>deriving (Show)</code>, Haskell doesn’t create a <code>show</code> method for us.
|
||
We will create our own version of show.
|
||
To achieve this, we must declare that our newly created type <code>BinTree a</code>
|
||
is an instance of the type class <code>Show</code>.
|
||
The general syntax is:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">instance</span> <span class="Constant">Show</span> (<span class="Constant">BinTree</span> a) <span class="Keyword">where</span>
|
||
<span class="Entity">show</span> t = ... <span class="Comment"><span class="Comment">--</span> You declare your function here</span>
|
||
</pre>
|
||
|
||
<p>Here is my version on how to show a binary tree.
|
||
Don’t worry about the apparent complexity.
|
||
I made a lot of improvement in order to display even strange objects.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> declare BinTree a to be an instance of Show</span>
|
||
<span class="Keyword">instance</span> (<span class="Constant">Show</span> a) => <span class="Constant">Show</span> (<span class="Constant">BinTree</span> a) <span class="Keyword">where</span>
|
||
<span class="Comment"><span class="Comment">--</span> will start by a '<' before the root</span>
|
||
<span class="Comment"><span class="Comment">--</span> and put a : a begining of line</span>
|
||
<span class="Entity">show</span> t = <span class="String"><span class="String">"</span>< <span class="String">"</span></span> ++ replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>: <span class="String">"</span></span> (treeshow <span class="String"><span class="String">"</span><span class="String">"</span></span> t)
|
||
<span class="Keyword">where</span>
|
||
<span class="Comment"><span class="Comment">--</span> treeshow pref Tree </span>
|
||
<span class="Comment"><span class="Comment">--</span> show a tree and start each line with pref</span>
|
||
<span class="Comment"><span class="Comment">--</span> We don't display Empty tree</span>
|
||
treeshow pref <span class="Constant">Empty</span> = <span class="String"><span class="String">"</span><span class="String">"</span></span>
|
||
<span class="Comment"><span class="Comment">--</span> Leaf</span>
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> <span class="Constant">Empty</span>) =
|
||
(pshow pref x)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> Right branch is empty</span>
|
||
treeshow pref (<span class="Constant">Node</span> x left <span class="Constant">Empty</span>) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> left)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> Left branch is empty</span>
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> Tree with left and right sons non empty</span>
|
||
treeshow pref (<span class="Constant">Node</span> x left right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>|--<span class="String">"</span></span> <span class="String"><span class="String">"</span>| <span class="String">"</span></span> left) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> show a tree using some prefixes to make it nice</span>
|
||
showSon pref before next t =
|
||
pref ++ before ++ treeshow (pref ++ next) t
|
||
|
||
<span class="Comment"><span class="Comment">--</span> pshow replace "\n" by "\n"++pref</span>
|
||
pshow pref x = replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> (<span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span>++pref) (<span class="Entity">show</span> x)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> replace on char by another string</span>
|
||
replace c new string =
|
||
<span class="Entity">concatMap</span> (change c new) string
|
||
<span class="Keyword">where</span>
|
||
change c new x
|
||
| x == c = new
|
||
| <span class="Keyword">otherwise</span> = x:[] <span class="Comment"><span class="Comment">--</span> "x"</span>
|
||
</pre>
|
||
</div>
|
||
<p>The <code>treeFromList</code> method remain identical.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">treeFromList</span> :: (<span class="Constant">Ord</span> <span class="Variable">a</span>) => [<span class="Variable">a</span>] -> <span class="Constant">BinTree</span> <span class="Variable">a</span>
|
||
treeFromList [] = <span class="Constant">Empty</span>
|
||
treeFromList (x:xs) = <span class="Constant">Node</span> x (treeFromList (<span class="Entity">filter</span> (<x) xs))
|
||
(treeFromList (<span class="Entity">filter</span> (>x) xs))
|
||
</pre>
|
||
</div>
|
||
<p>And now, we can play:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Int binary tree:<span class="String">"</span></span>
|
||
<span class="Entity">print</span> $ treeFromList [7,2,4,8,1,3,6,21,12,23]
|
||
</pre>
|
||
</div>
|
||
<pre><code>Int binary tree:
|
||
< 7
|
||
: |--2
|
||
: | |--1
|
||
: | `--4
|
||
: | |--3
|
||
: | `--6
|
||
: `--8
|
||
: `--21
|
||
: |--12
|
||
: `--23
|
||
</code></pre>
|
||
|
||
<p>Now it is far better!
|
||
The root is shown by starting by the <code><</code> character.
|
||
And each other line start by a <code>:</code>.
|
||
But we could also use another type.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>String binary tree:<span class="String">"</span></span>
|
||
<span class="Entity">print</span> $ treeFromList [<span class="String"><span class="String">"</span>foo<span class="String">"</span></span>,<span class="String"><span class="String">"</span>bar<span class="String">"</span></span>,<span class="String"><span class="String">"</span>baz<span class="String">"</span></span>,<span class="String"><span class="String">"</span>gor<span class="String">"</span></span>,<span class="String"><span class="String">"</span>yog<span class="String">"</span></span>]
|
||
</pre>
|
||
</div>
|
||
<pre><code>String binary tree:
|
||
< "foo"
|
||
: |--"bar"
|
||
: | `--"baz"
|
||
: `--"gor"
|
||
: `--"yog"
|
||
</code></pre>
|
||
|
||
<p>As we can test equality and order trees, we can
|
||
make tree of trees!</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>Binary tree of Char binary trees:<span class="String">"</span></span>
|
||
<span class="Entity">print</span> ( treeFromList
|
||
(<span class="Entity">map</span> treeFromList [<span class="String"><span class="String">"</span>baz<span class="String">"</span></span>,<span class="String"><span class="String">"</span>zara<span class="String">"</span></span>,<span class="String"><span class="String">"</span>bar<span class="String">"</span></span>]))
|
||
</pre>
|
||
</div>
|
||
<pre><code>Binary tree of Char binary trees:
|
||
< < 'b'
|
||
: : |--'a'
|
||
: : `--'z'
|
||
: |--< 'b'
|
||
: | : |--'a'
|
||
: | : `--'r'
|
||
: `--< 'z'
|
||
: : `--'a'
|
||
: : `--'r'
|
||
</code></pre>
|
||
|
||
<p>This is why I chosen to prefix each line of tree display by <code>:</code> (except for the root).</p>
|
||
|
||
<p><img alt="Yo Dawg Tree" src="/Scratch/img/blog/Haskell-the-Hard-Way/yo_dawg_tree.jpg" /></p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>Tree of Binary trees of Char binary trees:<span class="String">"</span></span>
|
||
<span class="Entity">print</span> $ (treeFromList . <span class="Entity">map</span> (treeFromList . <span class="Entity">map</span> treeFromList))
|
||
[ [<span class="String"><span class="String">"</span>YO<span class="String">"</span></span>,<span class="String"><span class="String">"</span>DAWG<span class="String">"</span></span>]
|
||
, [<span class="String"><span class="String">"</span>I<span class="String">"</span></span>,<span class="String"><span class="String">"</span>HEARD<span class="String">"</span></span>]
|
||
, [<span class="String"><span class="String">"</span>I<span class="String">"</span></span>,<span class="String"><span class="String">"</span>HEARD<span class="String">"</span></span>]
|
||
, [<span class="String"><span class="String">"</span>YOU<span class="String">"</span></span>,<span class="String"><span class="String">"</span>LIKE<span class="String">"</span></span>,<span class="String"><span class="String">"</span>TREES<span class="String">"</span></span>] ]
|
||
</pre>
|
||
</div>
|
||
<p>Which is equivalent to</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">print</span> ( treeFromList (
|
||
<span class="Entity">map</span> treeFromList
|
||
[ <span class="Entity">map</span> treeFromList [<span class="String"><span class="String">"</span>YO<span class="String">"</span></span>,<span class="String"><span class="String">"</span>DAWG<span class="String">"</span></span>]
|
||
, <span class="Entity">map</span> treeFromList [<span class="String"><span class="String">"</span>I<span class="String">"</span></span>,<span class="String"><span class="String">"</span>HEARD<span class="String">"</span></span>]
|
||
, <span class="Entity">map</span> treeFromList [<span class="String"><span class="String">"</span>I<span class="String">"</span></span>,<span class="String"><span class="String">"</span>HEARD<span class="String">"</span></span>]
|
||
, <span class="Entity">map</span> treeFromList [<span class="String"><span class="String">"</span>YOU<span class="String">"</span></span>,<span class="String"><span class="String">"</span>LIKE<span class="String">"</span></span>,<span class="String"><span class="String">"</span>TREES<span class="String">"</span></span>] ]))
|
||
</pre>
|
||
|
||
<p>and gives:</p>
|
||
|
||
<pre><code>Binary tree of Binary trees of Char binary trees:
|
||
< < < 'Y'
|
||
: : : `--'O'
|
||
: : `--< 'D'
|
||
: : : |--'A'
|
||
: : : `--'W'
|
||
: : : `--'G'
|
||
: |--< < 'I'
|
||
: | : `--< 'H'
|
||
: | : : |--'E'
|
||
: | : : | `--'A'
|
||
: | : : | `--'D'
|
||
: | : : `--'R'
|
||
: `--< < 'Y'
|
||
: : : `--'O'
|
||
: : : `--'U'
|
||
: : `--< 'L'
|
||
: : : `--'I'
|
||
: : : |--'E'
|
||
: : : `--'K'
|
||
: : `--< 'T'
|
||
: : : `--'R'
|
||
: : : |--'E'
|
||
: : : `--'S'
|
||
</code></pre>
|
||
|
||
<p>Remark how duplicate trees aren’t inserted;
|
||
there is only one tree corresponding to <code>"I","HEARD"</code>.
|
||
We have this for (almost) free, because we have declared Tree to be an instance of <code>Eq</code>.</p>
|
||
|
||
<p>See how awesome this structure is.
|
||
We can make tree containing not only integer, string and char, but also other trees.
|
||
And we can even make a tree containing a tree of trees!</p>
|
||
|
||
<p><a href="code/02_Hard_Part/31_Trees.lhs" class="cut">02_Hard_Part/<strong>31_Trees.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/40_Infinites_Structures.lhs" class="cut">02_Hard_Part/<strong>40_Infinites_Structures.lhs</strong></a></p>
|
||
|
||
<h3 id="infinite-structures">Infinite Structures</h3>
|
||
|
||
<p><img alt="Escher" src="/Scratch/img/blog/Haskell-the-Hard-Way/escher_infinite_lizards.jpg" /></p>
|
||
|
||
<p>It is often stated that Haskell is <em>lazy</em>.</p>
|
||
|
||
<p>In fact, if you are a bit pedantic, you should state that <a href="http://www.haskell.org/haskellwiki/Lazy_vs._non-strict">Haskell is <em>non-strict</em></a>.
|
||
Laziness is just a common implementation for non-strict languages.</p>
|
||
|
||
<p>Then what does not-strict means? From the Haskell wiki:</p>
|
||
|
||
<blockquote>
|
||
<p>Reduction (the mathematical term for evaluation) proceeds from the outside in.</p>
|
||
|
||
<p>so if you have <code>(a+(b*c))</code> then you first reduce <code>+</code> first, then you reduce the inner <code>(b*c)</code></p>
|
||
</blockquote>
|
||
|
||
<p>For example in Haskell you can do:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> numbers = [1,2,..]</span>
|
||
<span class="Entity">numbers</span> :: [<span class="Constant">Integer</span>]
|
||
numbers = 0:<span class="Entity">map</span> (1+) numbers
|
||
|
||
<span class="Entity">take</span>' n [] = []
|
||
<span class="Entity">take</span>' 0 l = []
|
||
<span class="Entity">take</span>' n (x:xs) = x:<span class="Entity">take</span>' (n-1) xs
|
||
|
||
main = <span class="Entity">print</span> $ <span class="Entity">take</span>' 10 numbers
|
||
</pre>
|
||
</div>
|
||
<p>And it stops.</p>
|
||
|
||
<p>How?</p>
|
||
|
||
<p>Instead of trying to evaluate <code>numbers</code> entirely,
|
||
it evaluates elements only when needed.</p>
|
||
|
||
<p>Also, note in Haskell there is a notation for infinite lists</p>
|
||
|
||
<pre><code>[1..] ⇔ [1,2,3,4...]
|
||
[1,3..] ⇔ [1,3,5,7,9,11...]
|
||
</code></pre>
|
||
|
||
<p>And most function will work with them.
|
||
Also there exists the function <code>take</code> equivalent to our <code>take'</code>.</p>
|
||
|
||
<p><a href="code/02_Hard_Part/40_Infinites_Structures.lhs" class="cut">02_Hard_Part/<strong>40_Infinites_Structures.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/02_Hard_Part/41_Infinites_Structures.lhs" class="cut">02_Hard_Part/<strong>41_Infinites_Structures.lhs</strong></a></p>
|
||
|
||
<div style="display:none">
|
||
|
||
This code is mostly the same as the preceding one.
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Debug</span>.<span class="Constant">Trace</span> (trace)
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span>
|
||
<span class="Keyword">data</span> <span class="Constant">BinTree</span> a = <span class="Constant">Empty</span>
|
||
| <span class="Constant">Node</span> a (<span class="Constant">BinTree</span> a) (<span class="Constant">BinTree</span> a)
|
||
<span class="Keyword">deriving</span> (<span class="Constant">Eq</span>,<span class="Constant">Ord</span>)
|
||
</pre>
|
||
</div>
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> declare BinTree a to be an instance of Show</span>
|
||
<span class="Keyword">instance</span> (<span class="Constant">Show</span> a) => <span class="Constant">Show</span> (<span class="Constant">BinTree</span> a) <span class="Keyword">where</span>
|
||
<span class="Comment"><span class="Comment">--</span> will start by a '<' before the root</span>
|
||
<span class="Comment"><span class="Comment">--</span> and put a : a begining of line</span>
|
||
<span class="Entity">show</span> t = <span class="String"><span class="String">"</span>< <span class="String">"</span></span> ++ replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>: <span class="String">"</span></span> (treeshow <span class="String"><span class="String">"</span><span class="String">"</span></span> t)
|
||
<span class="Keyword">where</span>
|
||
treeshow pref <span class="Constant">Empty</span> = <span class="String"><span class="String">"</span><span class="String">"</span></span>
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> <span class="Constant">Empty</span>) =
|
||
(pshow pref x)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x left <span class="Constant">Empty</span>) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> left)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x left right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>|--<span class="String">"</span></span> <span class="String"><span class="String">"</span>| <span class="String">"</span></span> left) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> show a tree using some prefixes to make it nice</span>
|
||
showSon pref before next t =
|
||
pref ++ before ++ treeshow (pref ++ next) t
|
||
|
||
<span class="Comment"><span class="Comment">--</span> pshow replace "\n" by "\n"++pref</span>
|
||
pshow pref x = replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> (<span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span>++pref) (<span class="String"><span class="String">"</span> <span class="String">"</span></span> ++ <span class="Entity">show</span> x)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> replace on char by another string</span>
|
||
replace c new string =
|
||
<span class="Entity">concatMap</span> (change c new) string
|
||
<span class="Keyword">where</span>
|
||
change c new x
|
||
| x == c = new
|
||
| <span class="Keyword">otherwise</span> = x:[] <span class="Comment"><span class="Comment">--</span> "x"</span>
|
||
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p>Suppose we don’t mind having an ordered binary tree.
|
||
Here is an infinite binary tree:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
nullTree = <span class="Constant">Node</span> 0 nullTree nullTree
|
||
</pre>
|
||
</div>
|
||
<p>A complete binary tree were each node is equal to 0.
|
||
Now I will prove you can manipulate this object using the following function:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> take all element of a BinTree </span>
|
||
<span class="Comment"><span class="Comment">--</span> up to some depth</span>
|
||
treeTakeDepth _ <span class="Constant">Empty</span> = <span class="Constant">Empty</span>
|
||
treeTakeDepth 0 _ = <span class="Constant">Empty</span>
|
||
treeTakeDepth n (<span class="Constant">Node</span> x left right) = <span class="Keyword">let</span>
|
||
nl = treeTakeDepth (n-1) left
|
||
nr = treeTakeDepth (n-1) right
|
||
<span class="Keyword">in</span>
|
||
<span class="Constant">Node</span> x nl nr
|
||
</pre>
|
||
</div>
|
||
<p>See what occurs for this program:</p>
|
||
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ treeTakeDepth 4 nullTree
|
||
</pre>
|
||
|
||
<p>This code compile, run and stop giving the following result:</p>
|
||
|
||
<pre><code>< 0
|
||
: |-- 0
|
||
: | |-- 0
|
||
: | | |-- 0
|
||
: | | `-- 0
|
||
: | `-- 0
|
||
: | |-- 0
|
||
: | `-- 0
|
||
: `-- 0
|
||
: |-- 0
|
||
: | |-- 0
|
||
: | `-- 0
|
||
: `-- 0
|
||
: |-- 0
|
||
: `-- 0
|
||
</code></pre>
|
||
|
||
<p>Just to heat your neurones a bit more,
|
||
let’s make a slightly more interesting tree:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
iTree = <span class="Constant">Node</span> 0 (dec iTree) (inc iTree)
|
||
<span class="Keyword">where</span>
|
||
dec (<span class="Constant">Node</span> x l r) = <span class="Constant">Node</span> (x-1) (dec l) (dec r)
|
||
inc (<span class="Constant">Node</span> x l r) = <span class="Constant">Node</span> (x+1) (inc l) (inc r)
|
||
</pre>
|
||
</div>
|
||
<p>Another way to create this tree is to use an higher order function.
|
||
This function should be similar to <code>map</code>, but should work on <code>BinTree</code> instead of list.
|
||
Here is such a function:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> apply a function to each node of Tree</span>
|
||
<span class="Entity">treeMap</span> :: (<span class="Variable">a</span> -> <span class="Variable">b</span>) -> <span class="Constant">BinTree</span> <span class="Variable">a</span> -> <span class="Constant">BinTree</span> <span class="Variable">b</span>
|
||
treeMap f <span class="Constant">Empty</span> = <span class="Constant">Empty</span>
|
||
treeMap f (<span class="Constant">Node</span> x left right) = <span class="Constant">Node</span> (f x)
|
||
(treeMap f left)
|
||
(treeMap f right)
|
||
</pre>
|
||
</div>
|
||
<p><em>Hint</em>: I won’t talk more about this here.
|
||
If you are interested of the generalization of <code>map</code> to other data structure,
|
||
search for functor and <code>fmap</code>.</p>
|
||
|
||
<p>Our definition is now:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">infTreeTwo</span> :: <span class="Constant">BinTree</span> <span class="Constant">Int</span>
|
||
infTreeTwo = <span class="Constant">Node</span> 0 (treeMap (\x -> x-1) infTreeTwo)
|
||
(treeMap (\x -> x+1) infTreeTwo)
|
||
</pre>
|
||
</div>
|
||
<p>Look at the result for </p>
|
||
|
||
<pre class="twilight">
|
||
main = <span class="Entity">print</span> $ treeTakeDepth 4 infTreeTwo
|
||
</pre>
|
||
|
||
<pre><code>< 0
|
||
: |-- -1
|
||
: | |-- -2
|
||
: | | |-- -3
|
||
: | | `-- -1
|
||
: | `-- 0
|
||
: | |-- -1
|
||
: | `-- 1
|
||
: `-- 1
|
||
: |-- 0
|
||
: | |-- -1
|
||
: | `-- 1
|
||
: `-- 2
|
||
: |-- 1
|
||
: `-- 3
|
||
</code></pre>
|
||
|
||
<div style="display:none">
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> $ treeTakeDepth 4 nullTree
|
||
<span class="Entity">print</span> $ treeTakeDepth 4 infTreeTwo
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p><a href="code/02_Hard_Part/41_Infinites_Structures.lhs" class="cut">02_Hard_Part/<strong>41_Infinites_Structures.lhs</strong> </a></p>
|
||
|
||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||
|
||
<p>Congratulation to get so far!
|
||
Now, some of the really hardcore stuff could start.</p>
|
||
|
||
<p>If you are like me, you should get the functional style.
|
||
You should also understand a bit more the advantages of laziness by default.
|
||
But you also don’t really understand were to start to make a real program.
|
||
And in particular:</p>
|
||
|
||
<ul>
|
||
<li>How do you deal with effects?</li>
|
||
<li>Why is there a strange imperative-like notation for dealing with IO?</li>
|
||
</ul>
|
||
|
||
<p>Be prepared, answer might be difficult to get.
|
||
But they all be very rewarding.</p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong></a></p>
|
||
|
||
<h3 id="deal-with-io">Deal With IO</h3>
|
||
|
||
<p><img alt="Magritte, Carte blanche" src="/Scratch/img/blog/Haskell-the-Hard-Way/magritte_carte_blanche.jpg" /></p>
|
||
|
||
<blockquote>
|
||
<p><span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span></p>
|
||
|
||
<p>A typical function doing <code>IO</code> look a lot like an imperative language:</p>
|
||
|
||
<pre><code>f :: IO a
|
||
f = do
|
||
x <- action1
|
||
action2 x
|
||
y <- action3
|
||
action4 x y
|
||
</code></pre>
|
||
|
||
<ul>
|
||
<li>To set a value to an object we use <code><-</code> .</li>
|
||
<li>The type of each line is <code>IO *</code>;
|
||
in this example:
|
||
<ul>
|
||
<li><code>action1 :: IO b</code></li>
|
||
<li><code>action2 x :: IO ()</code></li>
|
||
<li><code>action3 :: IO c</code></li>
|
||
<li><code>action4 x y :: IO a</code></li>
|
||
<li><code>x :: b</code>, <code>y :: c</code></li>
|
||
</ul>
|
||
</li>
|
||
<li>Few objects have the type <code>IO a</code>, this should help you to choose.
|
||
In particular you cannot use pure function directly here.
|
||
To use pure function you could do <code>action2 (purefunction x)</code> for example.</li>
|
||
</ul>
|
||
</blockquote>
|
||
|
||
<p>In this section, I will explain how to use IO, not how they work.
|
||
You’ll see how Haskell separate pure from impure part of the program.</p>
|
||
|
||
<p>Don’t stop because you’re trying to understand the details of the syntax.
|
||
Answer will come in the next section.</p>
|
||
|
||
<p>What to achieve?</p>
|
||
|
||
<blockquote>
|
||
<p>Ask a user to enter a list of numbers.
|
||
Print the sum of the numbers</p>
|
||
</blockquote>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">toList</span> :: <span class="Constant">String</span> -> [<span class="Constant">Integer</span>]
|
||
toList input = <span class="Entity">read</span> (<span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ input ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>)
|
||
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers (separated by comma):<span class="String">"</span></span>
|
||
input <- <span class="Entity">getLine</span>
|
||
<span class="Entity">print</span> $ <span class="Entity">sum</span> (toList input)
|
||
</pre>
|
||
</div>
|
||
<p>It should be straightforward to understand the behavior of this program.
|
||
Let’s analyze the types in more detail.</p>
|
||
|
||
<pre><code>putStrLn :: String -> IO ()
|
||
getLine :: IO String
|
||
print :: Show a => a -> IO ()
|
||
</code></pre>
|
||
|
||
<p>Or more interestingly, we remark each expression in the <code>do</code> block has a type of <code>IO a</code>.</p>
|
||
|
||
<pre>
|
||
main = do
|
||
putStrLn "Enter ... " :: <span class="high">IO ()</span>
|
||
getLine :: <span class="high">IO String</span>
|
||
print Something :: <span class="high">IO ()</span>
|
||
</pre>
|
||
|
||
<p>We should also remark the effect of the <code><-</code> symbol.</p>
|
||
|
||
<pre><code>do
|
||
x <- something
|
||
</code></pre>
|
||
|
||
<p>If <code>something :: IO a</code> then <code>x :: a</code>.</p>
|
||
|
||
<p>Another important remark to use <code>IO</code>.
|
||
All line in a do block must have one of the two forms:</p>
|
||
|
||
<pre><code>action1 :: IO a
|
||
-- in this case, generally a = ()
|
||
</code></pre>
|
||
|
||
<p>or</p>
|
||
|
||
<pre><code>value <- action2 -- where
|
||
-- bar z t :: IO b
|
||
-- value :: b
|
||
</code></pre>
|
||
|
||
<p>These two kind of line will correspond to two different way of sequencing actions.
|
||
The meaning of this sentence should be clearer at the end of the next section.</p>
|
||
|
||
<p><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a></p>
|
||
|
||
<p>Now let’s see how this behave.
|
||
For example, what occur if the user enter something strange?
|
||
Let’s try:</p>
|
||
|
||
<pre><code> % runghc 02_progressive_io_example.lhs
|
||
Enter a list of numbers (separated by comma):
|
||
foo
|
||
Prelude.read: no parse
|
||
</code></pre>
|
||
|
||
<p>Argh! An evil error message and a crash!
|
||
The first evolution will be to answer with a more friendly message.</p>
|
||
|
||
<p>For this, we must detect, something went wrong.
|
||
Here is one way to do this.
|
||
Use the type <code>Maybe</code>.
|
||
It is a very common type in Haskell.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">Maybe</span>
|
||
</pre>
|
||
</div>
|
||
<p>What is this thing? Maybe is a type which takes one parameter.
|
||
Its definition is:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">data</span> <span class="Constant">Maybe</span> a = <span class="Constant">Nothing</span> | <span class="Constant">Just</span> a
|
||
</pre>
|
||
|
||
<p>This is a nice way to tell there was an error while trying to create/compute
|
||
a value.
|
||
The <code>maybeRead</code> function is a great example of this.
|
||
This is a function similar to the function <code>read</code><sup id="fnref:1"><a href="#fn:1" rel="footnote">4</a></sup>,
|
||
but if something goes wrong the returned value is <code>Nothing</code>.
|
||
If the value is right, it returns <code>Just <the value></code>.
|
||
Don’t try to understand too much of this function.
|
||
I use a lower level function than <code>read</code>; <code>reads</code>.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">maybeRead</span> :: <span class="Constant">Read</span> <span class="Variable">a</span> => <span class="Constant">String</span> -> <span class="Constant">Maybe</span> <span class="Variable">a</span>
|
||
maybeRead s = <span class="Keyword">case</span> <span class="Entity">reads</span> s <span class="Keyword">of</span>
|
||
[(x,<span class="String"><span class="String">"</span><span class="String">"</span></span>)] -> <span class="Constant">Just</span> x
|
||
_ -> <span class="Constant">Nothing</span>
|
||
</pre>
|
||
</div>
|
||
<p>Now to be a bit more readable, we define a function which goes like this:
|
||
If the string has the wrong format, it will return <code>Nothing</code>.
|
||
Otherwise, for example for “1,2,3”, it will return <code>Just [1,2,3]</code>.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">getListFromString</span> :: <span class="Constant">String</span> -> <span class="Constant">Maybe</span> [<span class="Constant">Integer</span>]
|
||
getListFromString str = maybeRead $ <span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ str ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>
|
||
</pre>
|
||
</div>
|
||
<p>We simply have to test the value in our main function.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">main</span> :: <span class="Constant">IO</span> ()
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers (separated by comma):<span class="String">"</span></span>
|
||
input <- <span class="Entity">getLine</span>
|
||
<span class="Keyword">let</span> maybeList = getListFromString input <span class="Keyword">in</span>
|
||
<span class="Keyword">case</span> maybeList <span class="Keyword">of</span>
|
||
<span class="Constant">Just</span> l -> <span class="Entity">print</span> (<span class="Entity">sum</span> l)
|
||
<span class="Constant">Nothing</span> -> <span class="Entity">error</span> <span class="String"><span class="String">"</span>Bad format. Good Bye.<span class="String">"</span></span>
|
||
</pre>
|
||
</div>
|
||
<p>In case of error, we prompt a nice error message.</p>
|
||
|
||
<p>Remark the type of each expression in the main’s do block remains of the form <code>IO a</code>.
|
||
The only strange construction is <code>error</code>.
|
||
I’ll say <code>error msg</code> will simply take the needed type (here <code>IO ()</code>).</p>
|
||
|
||
<p>One very important thing to note is the type of all the defined function.
|
||
There is only one function which contains <code>IO</code> in its type: <code>main</code>.
|
||
That means main is impure.
|
||
But main use <code>getListFromString</code> which is pure.
|
||
It is then clear just by looking at declared types where are pure and impure functions.</p>
|
||
|
||
<p>Why purity matters?
|
||
I certainly forget many advantages, but the three main reason are:</p>
|
||
|
||
<ul>
|
||
<li>It is far easier to think about pure code than impure one.</li>
|
||
<li>Purity protect you from all hard to reproduce bugs due to border effects.</li>
|
||
<li>You can evaluate pure functions in any order or in parallel without risk.</li>
|
||
</ul>
|
||
|
||
<p>This is why, you should generally put as most code as possible in pure functions.</p>
|
||
|
||
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a></p>
|
||
|
||
<p>Our next evolution will be to ask the user again and again until it enters a valid answer.</p>
|
||
|
||
<p>We keep the first part:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">Maybe</span>
|
||
|
||
<span class="Entity">maybeRead</span> :: <span class="Constant">Read</span> <span class="Variable">a</span> => <span class="Constant">String</span> -> <span class="Constant">Maybe</span> <span class="Variable">a</span>
|
||
maybeRead s = <span class="Keyword">case</span> <span class="Entity">reads</span> s <span class="Keyword">of</span>
|
||
[(x,<span class="String"><span class="String">"</span><span class="String">"</span></span>)] -> <span class="Constant">Just</span> x
|
||
_ -> <span class="Constant">Nothing</span>
|
||
<span class="Entity">getListFromString</span> :: <span class="Constant">String</span> -> <span class="Constant">Maybe</span> [<span class="Constant">Integer</span>]
|
||
getListFromString str = maybeRead $ <span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ str ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>
|
||
</pre>
|
||
</div>
|
||
<p>Now, we create a function which will ask the user for an integer list
|
||
until the input is right.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
||
askUser = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers (separated by comma):<span class="String">"</span></span>
|
||
input <- <span class="Entity">getLine</span>
|
||
<span class="Keyword">let</span> maybeList = getListFromString input <span class="Keyword">in</span>
|
||
<span class="Keyword">case</span> maybeList <span class="Keyword">of</span>
|
||
<span class="Constant">Just</span> l -> <span class="Entity">return</span> l
|
||
<span class="Constant">Nothing</span> -> askUser
|
||
</pre>
|
||
</div>
|
||
<p>This function is of type <code>IO [Integer]</code>.
|
||
Such a type means, that we retrieved a value of type <code>[Integer]</code> through some IO actions.
|
||
Some people might explain while waving their hands: </p>
|
||
|
||
<blockquote>
|
||
<p>«This is an <code>[Integer]</code> inside an <code>IO</code>»</p>
|
||
</blockquote>
|
||
|
||
<p>If you want to understand the details behind all of this, you’ll have to read the next section.
|
||
But sincerely, if you just want to <em>use</em> IO.
|
||
Just exercise a little and remember to think about the type.</p>
|
||
|
||
<p>Finally our main function is quite simpler:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">main</span> :: <span class="Constant">IO</span> ()
|
||
main = <span class="Keyword">do</span>
|
||
list <- askUser
|
||
<span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
||
</pre>
|
||
</div>
|
||
<p>We have finished with our introduction to <code>IO</code>.
|
||
This was quite a fast. Here are the main things to remind:</p>
|
||
|
||
<ul>
|
||
<li>in the <code>do</code> bloc, each expression must have the type <code>IO a</code>.
|
||
You are then limited in the number of expression you could use.
|
||
For example, <code>getLine</code>, <code>print</code>, <code>putStrLn</code>, etc…</li>
|
||
<li>Try to externalize the pure function as much as possible. </li>
|
||
<li>the <code>IO a</code> type means: an IO <em>action</em> which return an element of type <code>a</code>.
|
||
<code>IO</code> represent action; under the hood, <code>IO a</code> is the type of a function.
|
||
Read the next section if you are curious.</li>
|
||
</ul>
|
||
|
||
<p>If you exercise a bit, you should be able to <em>use</em> <code>IO</code>.</p>
|
||
|
||
<blockquote>
|
||
<p><em>Exercises</em>:</p>
|
||
|
||
<ul>
|
||
<li>Make a program that sum all its argument. Hint: use the function <code>getArgs</code>.</li>
|
||
</ul>
|
||
</blockquote>
|
||
|
||
<p><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong> </a></p>
|
||
|
||
<h3 id="io-trick-explained">IO trick explained</h3>
|
||
|
||
<p><img alt="Magritte, ceci n'est pas une pipe" src="/Scratch/img/blog/Haskell-the-Hard-Way/magritte_pipe.jpg" /></p>
|
||
|
||
<blockquote>
|
||
<p>Here is a <span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span> for this section.</p>
|
||
|
||
<p>To separate pure from impure part,
|
||
the main is defined as a function
|
||
which modify the state of the world</p>
|
||
|
||
<pre><code>main :: World -> World
|
||
</code></pre>
|
||
|
||
<p>A function is granted to have side effect only if it gets this value.
|
||
But look at a typical main function:</p>
|
||
|
||
<pre><code>main w0 =
|
||
let (v1,w1) = action1 w0 in
|
||
let (v2,w2) = action2 v1 w1 in
|
||
let (v3,w3) = action3 v2 w2 in
|
||
action4 v3 w3
|
||
</code></pre>
|
||
|
||
<p>We have a lot of temporary elements (here <code>w1</code>, <code>w2</code> and <code>w3</code>)
|
||
which must be passed to the next action.</p>
|
||
|
||
<p>We create a function <code>bind</code> or <code>(>>=)</code>.
|
||
With <code>bind</code> we need no more temporary name.</p>
|
||
|
||
<pre><code>main =
|
||
action1 >>= action2 >>= action3 >>= action4
|
||
</code></pre>
|
||
|
||
<p>Bonus: Haskell has a syntactical sugar for us:</p>
|
||
|
||
<pre><code>main = do
|
||
v1 <- action1
|
||
v2 <- action2 v1
|
||
v3 <- action3 v2
|
||
action4 v3
|
||
</code></pre>
|
||
</blockquote>
|
||
|
||
<p>Why did we used some strange syntax, and what exactly is this <code>IO</code> type.
|
||
It looks a bit like magic.</p>
|
||
|
||
<p>For now let’s just forget about all the pure part of our program, and focus
|
||
on the impure part:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
||
askUser = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers (separated by commas):<span class="String">"</span></span>
|
||
input <- <span class="Entity">getLine</span>
|
||
<span class="Keyword">let</span> maybeList = getListFromString input <span class="Keyword">in</span>
|
||
<span class="Keyword">case</span> maybeList <span class="Keyword">of</span>
|
||
<span class="Constant">Just</span> l -> <span class="Entity">return</span> l
|
||
<span class="Constant">Nothing</span> -> askUser
|
||
|
||
<span class="Entity">main</span> :: <span class="Constant">IO</span> ()
|
||
main = <span class="Keyword">do</span>
|
||
list <- askUser
|
||
<span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
||
</pre>
|
||
|
||
<p>First remark; it looks like an imperative structure.
|
||
Haskell is powerful enough to make some pure code to look imperative.
|
||
For example, if you wish you could create a <code>while</code> in Haskell.
|
||
In fact, for dealing with <code>IO</code>, imperative style is generally more appropriate.</p>
|
||
|
||
<p>But, you should had remarked the notation is a bit unusual.
|
||
Here is why, in detail.</p>
|
||
|
||
<p>In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||
This hidden variable is accessible by all function of your language.
|
||
For example, you can read and write a file in any function.
|
||
The fact a file exists or not, can be seen as different state of the world.</p>
|
||
|
||
<p>For Haskell this state is not hidden.
|
||
It is explicitly said <code>main</code> is a function that <em>potentially</em> change the state of the world.
|
||
It’s type is then something like:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">main</span> :: <span class="Constant">World</span> -> <span class="Constant">World</span>
|
||
</pre>
|
||
|
||
<p>Not all function could have access to this variable.
|
||
Those who have access to this variable can potentially be impure.
|
||
Functions whose the world variable isn’t provided to should be pure<sup id="fnref:032001"><a href="#fn:032001" rel="footnote">5</a></sup>.</p>
|
||
|
||
<p>Haskell consider the state of the world is an input variable for <code>main</code>.
|
||
But the real type of main is closer to this one<sup id="fnref:032002"><a href="#fn:032002" rel="footnote">6</a></sup>:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">main</span> :: <span class="Constant">World</span> -> ((),<span class="Constant">World</span>)
|
||
</pre>
|
||
|
||
<p>The <code>()</code> type is the null type.
|
||
Nothing to see here.</p>
|
||
|
||
<p>Now let’s rewrite our main function with this in mind:</p>
|
||
|
||
<pre class="twilight">
|
||
main w0 =
|
||
<span class="Keyword">let</span> (list,w1) = askUser w0 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (x,w2) = <span class="Entity">print</span> (<span class="Entity">sum</span> list,w1) <span class="Keyword">in</span>
|
||
x
|
||
</pre>
|
||
|
||
<p>First, we remark, that all function which have side effect must have the type:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Constant">World</span> -> (a,<span class="Constant">World</span>)
|
||
</pre>
|
||
|
||
<p>Where <code>a</code> is the type of result.
|
||
For example, a <code>getChar</code> function should have the type <code>World -> (Char,World)</code>.</p>
|
||
|
||
<p>Another thing to remark is the trick to fix the order of evaluation.
|
||
In Haskell to evaluate <code>f a b</code>, you generally have many choices: </p>
|
||
|
||
<ul>
|
||
<li>first eval <code>a</code> then <code>b</code> then <code>f a b</code></li>
|
||
<li>first eval <code>b</code> then <code>a</code> then <code>f a b</code>.</li>
|
||
<li>eval <code>a</code> and <code>b</code> in parallel then <code>f a b</code></li>
|
||
</ul>
|
||
|
||
<p>This is true, because we should work in a pure language.</p>
|
||
|
||
<p>Now, if you look at the main function, it is clear you must eval the first
|
||
line before the second one since, to evaluate the second line you have
|
||
to get a parameter given by the evaluation of the first line.</p>
|
||
|
||
<p>Such trick works nicely.
|
||
The compiler will at each step provide a pointer to a new real world id.
|
||
Under the hood, <code>print</code> will evaluate as:</p>
|
||
|
||
<ul>
|
||
<li>print something on the screen</li>
|
||
<li>modify the id of the world</li>
|
||
<li>evaluate as <code>((),new world id)</code>.</li>
|
||
</ul>
|
||
|
||
<p>Now, if you look at the style of the main function, it is clearly awkward.
|
||
Let’s try to make the same to the askUser function:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">askUser</span> :: <span class="Constant">World</span> -> ([<span class="Constant">Integer</span>],<span class="Constant">World</span>)
|
||
</pre>
|
||
|
||
<p>Before:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
||
askUser = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers:<span class="String">"</span></span>
|
||
input <- <span class="Entity">getLine</span>
|
||
<span class="Keyword">let</span> maybeList = getListFromString input <span class="Keyword">in</span>
|
||
<span class="Keyword">case</span> maybeList <span class="Keyword">of</span>
|
||
<span class="Constant">Just</span> l -> <span class="Entity">return</span> l
|
||
<span class="Constant">Nothing</span> -> askUser
|
||
</pre>
|
||
|
||
<p>After:</p>
|
||
|
||
<pre class="twilight">
|
||
askUser w0 =
|
||
<span class="Keyword">let</span> (_,w1) = <span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers:<span class="String">"</span></span> <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (input,w2) = <span class="Entity">getLine</span> w1 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (l,w3) = <span class="Keyword">case</span> getListFromString input <span class="Keyword">of</span>
|
||
<span class="Constant">Just</span> l -> (l,w2)
|
||
<span class="Constant">Nothing</span> -> askUser w2
|
||
<span class="Keyword">in</span>
|
||
(l,w3)
|
||
</pre>
|
||
|
||
<p>This is similar, but awkward.
|
||
Look at all these temporary <code>w?</code> names.</p>
|
||
|
||
<p>The lesson, is, naive IO implementation in Pure functional language is awkward!</p>
|
||
|
||
<p>Fortunately, some have found a better way to handle this problem.
|
||
We see a pattern.
|
||
Each line is of the form:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">let</span> (y,w') = action x w <span class="Keyword">in</span>
|
||
</pre>
|
||
|
||
<p>Even if for some line the first <code>x</code> argument isn’t needed.
|
||
The output type is a couple, <code>(answer, newWorldValue)</code>.
|
||
Each function <code>f</code> must have a type of kind:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">f</span> :: <span class="Constant">World</span> -> (<span class="Variable">a,World</span>)
|
||
</pre>
|
||
|
||
<p>Not only this, but we can also remark we use them always
|
||
with the following general pattern:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">let</span> (y,w1) = action1 w0 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (z,w2) = action2 w1 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (t,w3) = action3 w2 <span class="Keyword">in</span>
|
||
...
|
||
</pre>
|
||
|
||
<p>Each action can take 0 to some parameters.
|
||
And in particular, each action can take a parameter from the result of a line above.</p>
|
||
|
||
<p>For example, we could also have:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">let</span> (_,w1) = action1 x w0 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (z,w2) = action2 w1 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (_,w3) = action3 x z w2 <span class="Keyword">in</span>
|
||
...
|
||
</pre>
|
||
|
||
<p>And of course <code>actionN w :: (World) -> (a,World)</code>.</p>
|
||
|
||
<blockquote>
|
||
<p>IMPORTANT, there are only two important pattern for us:</p>
|
||
|
||
<pre><code>let (x,w1) = action1 w0 in
|
||
let (y,w2) - action2 w1 in
|
||
</code></pre>
|
||
|
||
<p>and</p>
|
||
|
||
<pre><code>let (_,w1) = action1 w0 in
|
||
let (y,w2) = action2 w1 in
|
||
</code></pre>
|
||
</blockquote>
|
||
|
||
<p><img alt="Jocker pencil trick" src="/Scratch/img/blog/Haskell-the-Hard-Way/jocker_pencil_trick.jpg" class="left" /></p>
|
||
|
||
<p>Now, we will make a magic trick.
|
||
We will make the temporary world symbol “disappear”.
|
||
We will <code>bind</code> the two lines.
|
||
Let’s define the <code>bind</code> function.
|
||
Its type is quite intimidating at first:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">bind</span> :: (<span class="Constant">World</span> -> (<span class="Variable">a,World</span>))
|
||
-> (a -> (<span class="Constant">World</span> -> (b,<span class="Constant">World</span>)))
|
||
-> (<span class="Constant">World</span> -> (b,<span class="Constant">World</span>))
|
||
</pre>
|
||
|
||
<p>But remember that <code>(World -> (a,World))</code> is the type for an IO action.
|
||
Now let’s rename it for clarity:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">type</span> <span class="Constant">IO</span> a = <span class="Constant">World</span> -> (a, <span class="Constant">World</span>)
|
||
</pre>
|
||
|
||
<p>Some example of functions:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">getLine</span> :: <span class="Constant">IO</span> <span class="Constant">String</span>
|
||
<span class="Entity">print</span> :: <span class="Constant">Show</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Constant">IO</span> ()
|
||
</pre>
|
||
|
||
<p><code>getLine</code> is an IO action which take a world as parameter and return a couple <code>(String,World)</code>.
|
||
Which can be said as: <code>getLine</code> is of type <code>IO String</code>.
|
||
Which we also see as, an IO action which will return a String “embeded inside an IO”.</p>
|
||
|
||
<p>The function <code>print</code> is also interresting.
|
||
It takes on argument which can be shown.
|
||
In fact it takes two arguments.
|
||
The first is the value to print and the other is the state of world.
|
||
It then return a couple of type <code>((),World)</code>.
|
||
This means it changes the world state, but don’t give anymore data.</p>
|
||
|
||
<p>This type help us simplify the type of <code>bind</code>:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">bind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span>
|
||
-> (a -> <span class="Constant">IO</span> b)
|
||
-> <span class="Constant">IO</span> b
|
||
</pre>
|
||
|
||
<p>It says that <code>bind</code> takes two IO actions as parameter and return another IO action.</p>
|
||
|
||
<p>Now, remember the <em>important</em> patterns. The first was:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">let</span> (x,w1) = action1 w0 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (y,w2) = action2 x w1 <span class="Keyword">in</span>
|
||
(y,w2)
|
||
</pre>
|
||
|
||
<p>Look at the types:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">action1</span> :: <span class="Constant">IO</span> <span class="Variable">a</span>
|
||
<span class="Entity">action2</span> :: <span class="Variable">a</span> -> <span class="Constant">IO</span> <span class="Variable">b</span>
|
||
(y,w2) :: <span class="Constant">IO</span> b
|
||
</pre>
|
||
|
||
<p>Doesn’t seem familiar?</p>
|
||
|
||
<pre class="twilight">
|
||
(bind action1 action2) w0 =
|
||
<span class="Keyword">let</span> (x, w1) = action1 w0
|
||
(y, w2) = action2 x w1
|
||
<span class="Keyword">in</span> (y, w2)
|
||
</pre>
|
||
|
||
<p>The idea is to hide the World argument with this function. Let’s go:
|
||
As example imagine if we wanted to simulate:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> ((),w2) = <span class="Entity">print</span> line1 <span class="Keyword">in</span>
|
||
((),w2)
|
||
</pre>
|
||
|
||
<p>Now, using the bind function:</p>
|
||
|
||
<pre class="twilight">
|
||
(res,w2) = (bind <span class="Entity">getLine</span> (\l -> <span class="Entity">print</span> l)) w0
|
||
</pre>
|
||
|
||
<p>As print is of type (World → ((),World)), we know res = () (null type).
|
||
If you didn’t saw what was magic here, let’s try with three lines this time.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> (line2,w2) = <span class="Entity">getLine</span> w1 <span class="Keyword">in</span>
|
||
<span class="Keyword">let</span> ((),w3) = <span class="Entity">print</span> (line1 ++ line2) <span class="Keyword">in</span>
|
||
((),w3)
|
||
</pre>
|
||
|
||
<p>Which is equivalent to:</p>
|
||
|
||
<pre class="twilight">
|
||
(res,w3) = bind <span class="Entity">getLine</span> (\line1 ->
|
||
bind <span class="Entity">getLine</span> (\line2 ->
|
||
<span class="Entity">print</span> (line1 ++ line2)))
|
||
</pre>
|
||
|
||
<p>Didn’t you remark something?
|
||
Yes, there isn’t anymore temporary World variable used anywhere!
|
||
This is <em>MA</em>. <em>GIC</em>.</p>
|
||
|
||
<p>We can use a better notation.
|
||
Let’s use <code>(>>=)</code> instead of <code>bind</code>.
|
||
<code>(>>=)</code> is an infix function like
|
||
<code>(+)</code>; reminder <code>3 + 4 ⇔ (+) 3 4</code></p>
|
||
|
||
<pre class="twilight">
|
||
(res,w3) = <span class="Entity">getLine</span> >>=
|
||
\line1 -> <span class="Entity">getLine</span> >>=
|
||
\line2 -> <span class="Entity">print</span> (line1 ++ line2)
|
||
</pre>
|
||
|
||
<p>Ho Ho Ho! Happy Christmas Everyone!
|
||
Haskell has made a syntactical sugar for us:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">do</span>
|
||
y <- action1
|
||
z <- action2
|
||
t <- action3
|
||
...
|
||
</pre>
|
||
|
||
<p>Is replaced by:</p>
|
||
|
||
<pre class="twilight">
|
||
action1 >>= \x ->
|
||
action2 >>= \y ->
|
||
action3 >>= \z ->
|
||
...
|
||
</pre>
|
||
|
||
<p>Note you can use <code>x</code> in <code>action2</code> and <code>x</code> and <code>y</code> in <code>action3</code>.</p>
|
||
|
||
<p>But what for line not using the <code><-</code>?
|
||
Easy another function <code>blindBind</code>:</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">blindBind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span> -> <span class="Constant">IO</span> <span class="Variable">b</span> -> <span class="Constant">IO</span> <span class="Variable">b</span>
|
||
blindBind action1 action2 w0 =
|
||
bind action (\_ -> action2) w0
|
||
</pre>
|
||
|
||
<p>I didn’t curried this definition for clarity purpose. Of course we can use a better notation, we’ll use the <code>(>>)</code> operator.</p>
|
||
|
||
<p>And</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">do</span>
|
||
action1
|
||
action2
|
||
action3
|
||
</pre>
|
||
|
||
<p>Is transformed into</p>
|
||
|
||
<pre class="twilight">
|
||
action1 >>
|
||
action2 >>
|
||
action3
|
||
</pre>
|
||
|
||
<p>Also, another function is quite useful.</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Entity">putInIO</span> :: <span class="Variable">a</span> -> <span class="Constant">IO</span> <span class="Variable">a</span>
|
||
putInIO x = <span class="Constant">IO</span> (\w -> (x,w))
|
||
</pre>
|
||
|
||
<p>This is the general way to put pure value inside the “IO context”.
|
||
The general name for <code>putInIO</code> is <code>return</code>.
|
||
This is quite a bad name when you learn Haskell. <code>return</code> is very different from what you might be used to. </p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/01_IO/21_Detailled_IO.lhs" class="cut">03_Hell/01_IO/<strong>21_Detailled_IO.lhs</strong></a></p>
|
||
|
||
<p>To finish, let’s translate our example:</p>
|
||
|
||
<pre class="twilight">
|
||
|
||
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
||
askUser = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers (separated by commas):<span class="String">"</span></span>
|
||
input <- <span class="Entity">getLine</span>
|
||
<span class="Keyword">let</span> maybeList = getListFromString input <span class="Keyword">in</span>
|
||
<span class="Keyword">case</span> maybeList <span class="Keyword">of</span>
|
||
<span class="Constant">Just</span> l -> <span class="Entity">return</span> l
|
||
<span class="Constant">Nothing</span> -> askUser
|
||
|
||
<span class="Entity">main</span> :: <span class="Constant">IO</span> ()
|
||
main = <span class="Keyword">do</span>
|
||
list <- askUser
|
||
<span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
||
</pre>
|
||
|
||
<p>Is translated into:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">Maybe</span>
|
||
|
||
<span class="Entity">maybeRead</span> :: <span class="Constant">Read</span> <span class="Variable">a</span> => <span class="Constant">String</span> -> <span class="Constant">Maybe</span> <span class="Variable">a</span>
|
||
maybeRead s = <span class="Keyword">case</span> <span class="Entity">reads</span> s <span class="Keyword">of</span>
|
||
[(x,<span class="String"><span class="String">"</span><span class="String">"</span></span>)] -> <span class="Constant">Just</span> x
|
||
_ -> <span class="Constant">Nothing</span>
|
||
<span class="Entity">getListFromString</span> :: <span class="Constant">String</span> -> <span class="Constant">Maybe</span> [<span class="Constant">Integer</span>]
|
||
getListFromString str = maybeRead $ <span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ str ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>
|
||
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
||
askUser =
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>Enter a list of numbers (sep. by commas):<span class="String">"</span></span> >>
|
||
<span class="Entity">getLine</span> >>= \input ->
|
||
<span class="Keyword">let</span> maybeList = getListFromString input <span class="Keyword">in</span>
|
||
<span class="Keyword">case</span> maybeList <span class="Keyword">of</span>
|
||
<span class="Constant">Just</span> l -> <span class="Entity">return</span> l
|
||
<span class="Constant">Nothing</span> -> askUser
|
||
|
||
<span class="Entity">main</span> :: <span class="Constant">IO</span> ()
|
||
main = askUser >>=
|
||
\list -> <span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
||
</pre>
|
||
</div>
|
||
<p>You can compile this code to verify it continues to work.</p>
|
||
|
||
<p>Imagine what it would look like without the <code>(>>)</code> and <code>(>>=)</code>.</p>
|
||
|
||
<p><a href="code/03_Hell/01_IO/21_Detailled_IO.lhs" class="cut">03_Hell/01_IO/<strong>21_Detailled_IO.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/02_Monads/10_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>10_Monads.lhs</strong></a></p>
|
||
|
||
<h3 id="monads">Monads</h3>
|
||
|
||
<p><img alt="Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document." src="/Scratch/img/blog/Haskell-the-Hard-Way/dali_reve.jpg" /></p>
|
||
|
||
<p>Now the secret can be revealed: <code>IO</code> is a <em>monad</em>.
|
||
Being a monad means you have access to some syntactical sugar with the <code>do</code> notation.
|
||
But mainly, you have access to some coding pattern which will ease the flow of your code.</p>
|
||
|
||
<blockquote>
|
||
<p><strong>Important remarks</strong>:</p>
|
||
|
||
<ul>
|
||
<li>Monad are not necessarily about effects!
|
||
There are a lot of <em>pure</em> monads.</li>
|
||
<li>Monad are more about sequencing</li>
|
||
</ul>
|
||
</blockquote>
|
||
|
||
<p>For the Haskell language <code>Monad</code> is a type class.
|
||
To be an instance of this type class, you must provide the functions <code>(>>=)</code> and <code>return</code>.
|
||
The function <code>(>>)</code> will be derived from <code>(>>=)</code>.
|
||
Here is how the type class <code>Monad</code> is declared (mostly):</p>
|
||
|
||
<pre class="twilight">
|
||
<span class="Keyword">class</span> <span class="Constant">Monad</span> m <span class="Keyword">where</span>
|
||
<span class="Entity">(>>=)</span> :: <span class="Variable">m</span> <span class="Variable">a</span> -> (<span class="Variable">a</span> -> <span class="Variable">m</span> <span class="Variable">b</span>) -> <span class="Variable">m</span> <span class="Variable">b</span>
|
||
<span class="Entity">return</span> :: <span class="Variable">a</span> -> <span class="Variable">m</span> <span class="Variable">a</span>
|
||
|
||
<span class="Entity">(>>)</span> :: <span class="Variable">m</span> <span class="Variable">a</span> -> <span class="Variable">m</span> <span class="Variable">b</span> -> <span class="Variable">m</span> <span class="Variable">b</span>
|
||
f >> g = f >>= \_ -> g
|
||
|
||
<span class="Comment"><span class="Comment">--</span> You should generally safely ignore this function</span>
|
||
<span class="Comment"><span class="Comment">--</span> which I believe exists for historical reason</span>
|
||
<span class="Entity">fail</span> :: <span class="Constant">String</span> -> <span class="Variable">m</span> <span class="Variable">a</span>
|
||
<span class="Entity">fail</span> = <span class="Entity">error</span>
|
||
</pre>
|
||
|
||
<blockquote>
|
||
<p>Remarks:</p>
|
||
|
||
<ul>
|
||
<li>the keyword <code>class</code> is not your friend.
|
||
A Haskell class is <em>not</em> a class like in object model.
|
||
A Haskell class has a lot similarities with Java interfaces.
|
||
A better word should have been <code>typeclass</code>.
|
||
That means a set of types.
|
||
For a type to belong to a class, all function of the class must be provided for this type.</li>
|
||
<li>In this particular example of type class, the type <code>m</code> must be a type that take an argument.
|
||
for example <code>IO a</code>, but also <code>Maybe a</code>, <code>[a]</code>, etc…</li>
|
||
<li>
|
||
<p>To be a useful monad, your function must obey some rule.
|
||
If your construction does not obey these rules strange things might happens:</p>
|
||
|
||
<pre><code>return a >>= k == k a
|
||
m >>= return == m
|
||
m >>= (\x -> k x >>= h) == (m >>= k) >>= h
|
||
</code></pre>
|
||
</li>
|
||
</ul>
|
||
</blockquote>
|
||
|
||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||
|
||
<p>There exists a lot of different type that are instance of <code>Monad</code>.
|
||
One of the easiest to describe is <code>Maybe</code>.
|
||
If you have a sequence of <code>Maybe</code> values, you could use monad to manipulate them.
|
||
It is particularly useful to remove very deep <code>if..then..else..</code> constructions.</p>
|
||
|
||
<p>Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||
if you can afford to follow a list of operation without being negative.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
deposit value account = account + value
|
||
withdraw value account = account - value
|
||
|
||
<span class="Entity">eligible</span> :: (<span class="Constant">Num</span> <span class="Variable">a,Ord</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Constant">Bool</span>
|
||
eligible account =
|
||
<span class="Keyword">let</span> account1 = deposit 100 account <span class="Keyword">in</span>
|
||
<span class="Keyword">if</span> (account1 < 0)
|
||
<span class="Keyword">then</span> <span class="Constant">False</span>
|
||
<span class="Keyword">else</span>
|
||
<span class="Keyword">let</span> account2 = withdraw 200 account1 <span class="Keyword">in</span>
|
||
<span class="Keyword">if</span> (account2 < 0)
|
||
<span class="Keyword">then</span> <span class="Constant">False</span>
|
||
<span class="Keyword">else</span>
|
||
<span class="Keyword">let</span> account3 = deposit 100 account2 <span class="Keyword">in</span>
|
||
<span class="Keyword">if</span> (account3 < 0)
|
||
<span class="Keyword">then</span> <span class="Constant">False</span>
|
||
<span class="Keyword">else</span>
|
||
<span class="Keyword">let</span> account4 = withdraw 300 account3 <span class="Keyword">in</span>
|
||
<span class="Keyword">if</span> (account4 < 0)
|
||
<span class="Keyword">then</span> <span class="Constant">False</span>
|
||
<span class="Keyword">else</span>
|
||
<span class="Keyword">let</span> account5 = deposit 1000 account4 <span class="Keyword">in</span>
|
||
<span class="Keyword">if</span> (account5 < 0)
|
||
<span class="Keyword">then</span> <span class="Constant">False</span>
|
||
<span class="Keyword">else</span>
|
||
<span class="Constant">True</span>
|
||
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> $ eligible 300 <span class="Comment"><span class="Comment">--</span> True</span>
|
||
<span class="Entity">print</span> $ eligible 299 <span class="Comment"><span class="Comment">--</span> False</span>
|
||
</pre>
|
||
</div>
|
||
<p><a href="code/03_Hell/02_Monads/10_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>10_Monads.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a></p>
|
||
|
||
<p>Now, let’s make it better using Maybe and the fact it is a Monad</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">deposit</span> :: (<span class="Constant">Num</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Variable">a</span> -> <span class="Constant">Maybe</span> <span class="Variable">a</span>
|
||
deposit value account = <span class="Constant">Just</span> (account + value)
|
||
|
||
<span class="Entity">withdraw</span> :: (<span class="Constant">Num</span> <span class="Variable">a,Ord</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Variable">a</span> -> <span class="Constant">Maybe</span> <span class="Variable">a</span>
|
||
withdraw value account = <span class="Keyword">if</span> (account < value)
|
||
<span class="Keyword">then</span> <span class="Constant">Nothing</span>
|
||
<span class="Keyword">else</span> <span class="Constant">Just</span> (account - value)
|
||
|
||
<span class="Entity">eligible</span> :: (<span class="Constant">Num</span> <span class="Variable">a</span>, <span class="Constant">Ord</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Constant">Maybe</span> <span class="Constant">Bool</span>
|
||
eligible account = <span class="Keyword">do</span>
|
||
account1 <- deposit 100 account
|
||
account2 <- withdraw 200 account1
|
||
account3 <- deposit 100 account2
|
||
account4 <- withdraw 300 account3
|
||
account5 <- deposit 1000 account4
|
||
<span class="Constant">Just</span> <span class="Constant">True</span>
|
||
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> $ eligible 300 <span class="Comment"><span class="Comment">--</span> Just True</span>
|
||
<span class="Entity">print</span> $ eligible 299 <span class="Comment"><span class="Comment">--</span> Nothing</span>
|
||
</pre>
|
||
</div>
|
||
<p><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/02_Monads/12_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>12_Monads.lhs</strong></a></p>
|
||
|
||
<p>Not bad, but we can make it even better:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">deposit</span> :: (<span class="Constant">Num</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Variable">a</span> -> <span class="Constant">Maybe</span> <span class="Variable">a</span>
|
||
deposit value account = <span class="Constant">Just</span> (account + value)
|
||
|
||
<span class="Entity">withdraw</span> :: (<span class="Constant">Num</span> <span class="Variable">a,Ord</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Variable">a</span> -> <span class="Constant">Maybe</span> <span class="Variable">a</span>
|
||
withdraw value account = <span class="Keyword">if</span> (account < value)
|
||
<span class="Keyword">then</span> <span class="Constant">Nothing</span>
|
||
<span class="Keyword">else</span> <span class="Constant">Just</span> (account - value)
|
||
|
||
<span class="Entity">eligible</span> :: (<span class="Constant">Num</span> <span class="Variable">a</span>, <span class="Constant">Ord</span> <span class="Variable">a</span>) => <span class="Variable">a</span> -> <span class="Constant">Maybe</span> <span class="Constant">Bool</span>
|
||
eligible account =
|
||
deposit 100 account >>=
|
||
withdraw 200 >>=
|
||
deposit 100 >>=
|
||
withdraw 300 >>=
|
||
deposit 1000 >>
|
||
<span class="Entity">return</span> <span class="Constant">True</span>
|
||
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> $ eligible 300 <span class="Comment"><span class="Comment">--</span> Just True</span>
|
||
<span class="Entity">print</span> $ eligible 299 <span class="Comment"><span class="Comment">--</span> Nothing</span>
|
||
</pre>
|
||
</div>
|
||
<p>We have proved Monad are nice to make our code more elegant.
|
||
Note this idea of code organization, in particular for <code>Maybe</code> can be used
|
||
in most imperative language.
|
||
In fact, this is the kind of construction we make naturally.</p>
|
||
|
||
<blockquote>
|
||
<p>An important remark:</p>
|
||
|
||
<p>The first element in the sequence being evaluated to <code>Nothing</code> will stop
|
||
the complete evaluation.
|
||
That means, you don’t execute all lines.
|
||
You have this for free, thanks to laziness.</p>
|
||
</blockquote>
|
||
|
||
<p>The <code>Maybe</code> monad proved to be useful while being a very simple example.
|
||
We saw the utility of the <code>IO</code> monad.
|
||
But now a cooler example, lists.</p>
|
||
|
||
<p><a href="code/03_Hell/02_Monads/12_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>12_Monads.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong></a></p>
|
||
|
||
<h4 id="the-list-monad">The list monad</h4>
|
||
|
||
<p><img alt="Golconde de Magritte" src="/Scratch/img/blog/Haskell-the-Hard-Way/golconde.jpg" /></p>
|
||
|
||
<p>The list monad help us to simulate non deterministic computation.
|
||
Here we go:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Control</span>.<span class="Constant">Monad</span> (guard)
|
||
|
||
allCases = [1..10]
|
||
|
||
<span class="Entity">resolve</span> :: [(<span class="Constant">Int,Int,Int</span>)]
|
||
resolve = <span class="Keyword">do</span>
|
||
x <- allCases
|
||
y <- allCases
|
||
z <- allCases
|
||
guard $ 4*x + 2*y < z
|
||
<span class="Entity">return</span> (x,y,z)
|
||
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">print</span> resolve
|
||
</pre>
|
||
</div>
|
||
<p>MA. GIC. :</p>
|
||
|
||
<pre><code>[(1,1,7),(1,1,8),(1,1,9),(1,1,10),(1,2,9),(1,2,10)]
|
||
</code></pre>
|
||
|
||
<p>For the list monad, there is also a syntactical sugar:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">print</span> $ [ (x,y,z) | x <- allCases,
|
||
y <- allCases,
|
||
z <- allCases,
|
||
4*x + 2*y < z ]
|
||
</pre>
|
||
</div>
|
||
<p>I won’t list all the monads, but there is a lot of monads.
|
||
The usage of monad simplify the manipulation of some notion in pure languages.
|
||
In particular, monad are very useful for: </p>
|
||
|
||
<ul>
|
||
<li>IO,</li>
|
||
<li>non deterministic computation,</li>
|
||
<li>generating pseudo random numbers, </li>
|
||
<li>keeping configuration state, </li>
|
||
<li>writing state,</li>
|
||
<li>…</li>
|
||
</ul>
|
||
|
||
<p>If you have followed me until here, then you’ve done it!
|
||
You know monads<sup id="fnref:03021301"><a href="#fn:03021301" rel="footnote">7</a></sup>!</p>
|
||
|
||
<p><a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a></p>
|
||
|
||
<h2 id="appendix">Appendix</h2>
|
||
|
||
<p>This section is not so much about learning Haskell.
|
||
It is just here to discuss some details further.</p>
|
||
|
||
<hr />
|
||
<p><a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong></a></p>
|
||
|
||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||
|
||
<p>In the section <a href="#infinite-structures">Infinite Structures</a> we saw some simple construction.
|
||
Unfortunately we removed two properties of our tree:</p>
|
||
|
||
<ol>
|
||
<li>no duplicate node value</li>
|
||
<li>well ordered tree</li>
|
||
</ol>
|
||
|
||
<p>In this section we will try to keep the first property.
|
||
Concerning the second one, we must relax this one but we’ll discuss on how to
|
||
keep it as much as possible.</p>
|
||
|
||
<div style="display:none">
|
||
|
||
This code is mostly the same as the one in the [tree section](#trees).
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span>
|
||
<span class="Keyword">data</span> <span class="Constant">BinTree</span> a = <span class="Constant">Empty</span>
|
||
| <span class="Constant">Node</span> a (<span class="Constant">BinTree</span> a) (<span class="Constant">BinTree</span> a)
|
||
<span class="Keyword">deriving</span> (<span class="Constant">Eq</span>,<span class="Constant">Ord</span>)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> declare BinTree a to be an instance of Show</span>
|
||
<span class="Keyword">instance</span> (<span class="Constant">Show</span> a) => <span class="Constant">Show</span> (<span class="Constant">BinTree</span> a) <span class="Keyword">where</span>
|
||
<span class="Comment"><span class="Comment">--</span> will start by a '<' before the root</span>
|
||
<span class="Comment"><span class="Comment">--</span> and put a : a begining of line</span>
|
||
<span class="Entity">show</span> t = <span class="String"><span class="String">"</span>< <span class="String">"</span></span> ++ replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>: <span class="String">"</span></span> (treeshow <span class="String"><span class="String">"</span><span class="String">"</span></span> t)
|
||
<span class="Keyword">where</span>
|
||
treeshow pref <span class="Constant">Empty</span> = <span class="String"><span class="String">"</span><span class="String">"</span></span>
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> <span class="Constant">Empty</span>) =
|
||
(pshow pref x)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x left <span class="Constant">Empty</span>) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> left)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x left right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>|--<span class="String">"</span></span> <span class="String"><span class="String">"</span>| <span class="String">"</span></span> left) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> show a tree using some prefixes to make it nice</span>
|
||
showSon pref before next t =
|
||
pref ++ before ++ treeshow (pref ++ next) t
|
||
|
||
<span class="Comment"><span class="Comment">--</span> pshow replace "\n" by "\n"++pref</span>
|
||
pshow pref x = replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> (<span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span>++pref) (<span class="Entity">show</span> x)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> replace on char by another string</span>
|
||
replace c new string =
|
||
<span class="Entity">concatMap</span> (change c new) string
|
||
<span class="Keyword">where</span>
|
||
change c new x
|
||
| x == c = new
|
||
| <span class="Keyword">otherwise</span> = x:[] <span class="Comment"><span class="Comment">--</span> "x"</span>
|
||
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p>Our first step is to create some pseudo-random number list:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
shuffle = <span class="Entity">map</span> (\x -> (x*3123) <span class="Entity"><span class="Entity">`</span>mod<span class="Entity">`</span></span> 4331) [1..]
|
||
</pre>
|
||
</div>
|
||
<p>Just as reminder here are the definition of <code>treeFromList</code></p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">treeFromList</span> :: (<span class="Constant">Ord</span> <span class="Variable">a</span>) => [<span class="Variable">a</span>] -> <span class="Constant">BinTree</span> <span class="Variable">a</span>
|
||
treeFromList [] = <span class="Constant">Empty</span>
|
||
treeFromList (x:xs) = <span class="Constant">Node</span> x (treeFromList (<span class="Entity">filter</span> (<x) xs))
|
||
(treeFromList (<span class="Entity">filter</span> (>x) xs))
|
||
</pre>
|
||
</div>
|
||
<p>and <code>treeTakeDepth</code>:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
treeTakeDepth _ <span class="Constant">Empty</span> = <span class="Constant">Empty</span>
|
||
treeTakeDepth 0 _ = <span class="Constant">Empty</span>
|
||
treeTakeDepth n (<span class="Constant">Node</span> x left right) = <span class="Keyword">let</span>
|
||
nl = treeTakeDepth (n-1) left
|
||
nr = treeTakeDepth (n-1) right
|
||
<span class="Keyword">in</span>
|
||
<span class="Constant">Node</span> x nl nr
|
||
</pre>
|
||
</div>
|
||
<p>See the result of:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>take 10 shuffle<span class="String">"</span></span>
|
||
<span class="Entity">print</span> $ <span class="Entity">take</span> 10 shuffle
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>treeTakeDepth 4 (treeFromList shuffle)<span class="String">"</span></span>
|
||
<span class="Entity">print</span> $ treeTakeDepth 4 (treeFromList shuffle)
|
||
</pre>
|
||
</div>
|
||
<pre><code>% runghc 02_Hard_Part/41_Infinites_Structures.lhs
|
||
take 10 shuffle
|
||
[3123,1915,707,3830,2622,1414,206,3329,2121,913]
|
||
treeTakeDepth 4 (treeFromList shuffle)
|
||
|
||
< 3123
|
||
: |--1915
|
||
: | |--707
|
||
: | | |--206
|
||
: | | `--1414
|
||
: | `--2622
|
||
: | |--2121
|
||
: | `--2828
|
||
: `--3830
|
||
: |--3329
|
||
: | |--3240
|
||
: | `--3535
|
||
: `--4036
|
||
: |--3947
|
||
: `--4242
|
||
</code></pre>
|
||
|
||
<p>Yay! It ends!
|
||
Beware thought, it will only work if you always have something to put into a branch.</p>
|
||
|
||
<p>For example </p>
|
||
|
||
<pre class="twilight">
|
||
treeTakeDepth 4 (treeFromList [1..])
|
||
</pre>
|
||
|
||
<p>will loop forever.
|
||
Simply because, it will try to access the head of <code>filter (<1) [2..]</code>.
|
||
But filter is not smart enought to understand that the result is the empty list.</p>
|
||
|
||
<p>Nonetheless, it is still a very cool example of what non strict program has to offer.</p>
|
||
|
||
<p>Left as an exercise to the reader:</p>
|
||
|
||
<ul>
|
||
<li>Could you prove that there exists some number <code>n</code> such that <code>treeTakeDepth n (treeFromList shuffle)</code> will enter in an infinite loop.</li>
|
||
<li>Find an upper bound for <code>n</code>.</li>
|
||
<li>Prove there is no <code>shuffle</code> list such that, for any depth, the program ends.</li>
|
||
</ul>
|
||
|
||
<p><a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a></p>
|
||
|
||
<hr />
|
||
<p><a href="code/04_Appendice/01_More_on_infinite_trees/11_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>11_Infinite_Trees.lhs</strong></a></p>
|
||
|
||
<div style="display:none">
|
||
|
||
This code is mostly the same as the preceding one.
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Keyword">import</span> <span class="Constant">Debug</span>.<span class="Constant">Trace</span> (trace)
|
||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">List</span>
|
||
<span class="Keyword">data</span> <span class="Constant">BinTree</span> a = <span class="Constant">Empty</span>
|
||
| <span class="Constant">Node</span> a (<span class="Constant">BinTree</span> a) (<span class="Constant">BinTree</span> a)
|
||
<span class="Keyword">deriving</span> (<span class="Constant">Eq</span>,<span class="Constant">Ord</span>)
|
||
</pre>
|
||
</div>
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Comment"><span class="Comment">--</span> declare BinTree a to be an instance of Show</span>
|
||
<span class="Keyword">instance</span> (<span class="Constant">Show</span> a) => <span class="Constant">Show</span> (<span class="Constant">BinTree</span> a) <span class="Keyword">where</span>
|
||
<span class="Comment"><span class="Comment">--</span> will start by a '<' before the root</span>
|
||
<span class="Comment"><span class="Comment">--</span> and put a : a begining of line</span>
|
||
<span class="Entity">show</span> t = <span class="String"><span class="String">"</span>< <span class="String">"</span></span> ++ replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>: <span class="String">"</span></span> (treeshow <span class="String"><span class="String">"</span><span class="String">"</span></span> t)
|
||
<span class="Keyword">where</span>
|
||
treeshow pref <span class="Constant">Empty</span> = <span class="String"><span class="String">"</span><span class="String">"</span></span>
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> <span class="Constant">Empty</span>) =
|
||
(pshow pref x)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x left <span class="Constant">Empty</span>) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> left)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x <span class="Constant">Empty</span> right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
treeshow pref (<span class="Constant">Node</span> x left right) =
|
||
(pshow pref x) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>|--<span class="String">"</span></span> <span class="String"><span class="String">"</span>| <span class="String">"</span></span> left) ++ <span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span> ++
|
||
(showSon pref <span class="String"><span class="String">"</span>`--<span class="String">"</span></span> <span class="String"><span class="String">"</span> <span class="String">"</span></span> right)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> show a tree using some prefixes to make it nice</span>
|
||
showSon pref before next t =
|
||
pref ++ before ++ treeshow (pref ++ next) t
|
||
|
||
<span class="Comment"><span class="Comment">--</span> pshow replace "\n" by "\n"++pref</span>
|
||
pshow pref x = replace<span class="String"><span class="String"> '</span><span class="StringConstant">\n</span><span class="String">'</span></span> (<span class="String"><span class="String">"</span><span class="StringConstant">\n</span><span class="String">"</span></span>++pref) (<span class="String"><span class="String">"</span> <span class="String">"</span></span> ++ <span class="Entity">show</span> x)
|
||
|
||
<span class="Comment"><span class="Comment">--</span> replace on char by another string</span>
|
||
replace c new string =
|
||
<span class="Entity">concatMap</span> (change c new) string
|
||
<span class="Keyword">where</span>
|
||
change c new x
|
||
| x == c = new
|
||
| <span class="Keyword">otherwise</span> = x:[] <span class="Comment"><span class="Comment">--</span> "x"</span>
|
||
|
||
treeTakeDepth _ <span class="Constant">Empty</span> = <span class="Constant">Empty</span>
|
||
treeTakeDepth 0 _ = <span class="Constant">Empty</span>
|
||
treeTakeDepth n (<span class="Constant">Node</span> x left right) = <span class="Keyword">let</span>
|
||
nl = treeTakeDepth (n-1) left
|
||
nr = treeTakeDepth (n-1) right
|
||
<span class="Keyword">in</span>
|
||
<span class="Constant">Node</span> x nl nr
|
||
</pre>
|
||
</div>
|
||
</div>
|
||
|
||
<p>In order to resolve these problem we will modify slightly our
|
||
<code>treeFromList</code> and <code>shuffle</code> function.</p>
|
||
|
||
<p>A first problem, is the lack of infinite different number in our implementation of <code>shuffle</code>.
|
||
We generated only <code>4331</code> different numbers.
|
||
To resolve this we make a slightly better <code>shuffle</code> function.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
shuffle = <span class="Entity">map</span> rand [1..]
|
||
<span class="Keyword">where</span>
|
||
rand x = ((p x) <span class="Entity"><span class="Entity">`</span>mod` (x+c)) - ((x+c) `div<span class="Entity">`</span></span> 2)
|
||
p x = m*x^2 + n*x + o <span class="Comment"><span class="Comment">--</span> some polynome</span>
|
||
m = 3123
|
||
n = 31
|
||
o = 7641
|
||
c = 1237
|
||
</pre>
|
||
</div>
|
||
<p>This shuffle function has the property (hopefully) not to have an upper nor lower bound.
|
||
But having a better shuffle list isn’t enough not to enter an infinite loop.</p>
|
||
|
||
<p>Generally, we cannot decide whether <code>filter (<x) xs</code> is empty.
|
||
Then to resolve this problem, I’ll authorize some error in the creation of our binary tree.
|
||
This new version of code can create binary tree which don’t have the following property for some of its nodes: </p>
|
||
|
||
<blockquote>
|
||
<p>Any element of the left (resp. right) branch must all be strictly inferior (resp. superior) to the label of the root.</p>
|
||
</blockquote>
|
||
|
||
<p>Remark it will remains <em>mostly</em> an ordered binary tree.
|
||
Furthermore, by construction, each node value is unique in the tree.</p>
|
||
|
||
<p>Here is our new version of <code>treeFromList</code>. We simply have replaced <code>filter</code> by <code>safefilter</code>.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">treeFromList</span> :: (<span class="Constant">Ord</span> <span class="Variable">a</span>, <span class="Constant">Show</span> <span class="Variable">a</span>) => [<span class="Variable">a</span>] -> <span class="Constant">BinTree</span> <span class="Variable">a</span>
|
||
treeFromList [] = <span class="Constant">Empty</span>
|
||
treeFromList (x:xs) = <span class="Constant">Node</span> x left right
|
||
<span class="Keyword">where</span>
|
||
left = treeFromList $ safefilter (<x) xs
|
||
right = treeFromList $ safefilter (>x) xs
|
||
</pre>
|
||
</div>
|
||
<p>This new function <code>safefilter</code> is almost equivalent to <code>filter</code> but don’t enter infinite loop if the result is a finite list.
|
||
If it cannot find an element for which the test is true after 10000 consecutive steps, then it considers to be the end of the search.</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
<span class="Entity">safefilter</span> :: (<span class="Variable">a</span> -> <span class="Constant">Bool</span>) -> [<span class="Variable">a</span>] -> [<span class="Variable">a</span>]
|
||
safefilter f l = safefilter' f l nbTry
|
||
<span class="Keyword">where</span>
|
||
nbTry = 10000
|
||
safefilter' _ _ 0 = []
|
||
safefilter' _ [] _ = []
|
||
safefilter' f (x:xs) n =
|
||
<span class="Keyword">if</span> f x
|
||
<span class="Keyword">then</span> x : safefilter' f xs nbTry
|
||
<span class="Keyword">else</span> safefilter' f xs (n-1)
|
||
</pre>
|
||
</div>
|
||
<p>Now run the program and be happy:</p>
|
||
|
||
<div class="codehighlight">
|
||
<pre class="twilight">
|
||
main = <span class="Keyword">do</span>
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span>take 10 shuffle<span class="String">"</span></span>
|
||
<span class="Entity">print</span> $ <span class="Entity">take</span> 10 shuffle
|
||
<span class="Entity">putStrLn</span> <span class="String"><span class="String">"</span><span class="StringConstant">\n</span>treeTakeDepth 8 (treeFromList shuffle)<span class="String">"</span></span>
|
||
<span class="Entity">print</span> $ treeTakeDepth 8 (treeFromList $ shuffle)
|
||
</pre>
|
||
</div>
|
||
<p>You should realize the time to print each value is different.
|
||
This is because Haskell compute each value when it needs it.
|
||
And in this case, this is when asked to print it on the screen.</p>
|
||
|
||
<p>Impressively enough, try to replace the depth from <code>8</code> to <code>100</code>.
|
||
It will work without killing your RAM!
|
||
The flow and the memory management is done naturally by Haskell.</p>
|
||
|
||
<p>Left as an exercise to the reader:</p>
|
||
|
||
<ul>
|
||
<li>Even with large constant value for <code>deep</code> and <code>nbTry</code>, it seems to work nicely. But in the worst case, it can be exponential.
|
||
Create a worst case list to give as parameter to <code>treeFromList</code>.<br />
|
||
<em>hint</em>: think about (<code>[0,-1,-1,....,-1,1,-1,...,-1,1,...]</code>).</li>
|
||
<li>I first tried to implement <code>safefilter</code> as follow:
|
||
<pre>
|
||
safefilter' f l = if filter f (take 10000 l) == []
|
||
then []
|
||
else filter f l
|
||
</pre>
|
||
<p>Explain why it doesn’t work and can enter into an infinite loop.</p>
|
||
</li>
|
||
<li>Suppose that <code>shuffle</code> is real random list with growing bounds.
|
||
If you study a bit this structure, you’ll discover that with probability 1,
|
||
this structure is finite.
|
||
Using the following code
|
||
(suppose we could use <code>safefilter'</code> directly as if was not in the where of safefilter)
|
||
find a definition of <code>f</code> such that with probability <code>1</code>,
|
||
treeFromList’ shuffle is infinite. And prove it.
|
||
Disclaimer, this is only a conjecture.</li>
|
||
</ul>
|
||
|
||
<pre class="twilight">
|
||
treeFromList' [] n = <span class="Constant">Empty</span>
|
||
treeFromList' (x:xs) n = <span class="Constant">Node</span> x left right
|
||
<span class="Keyword">where</span>
|
||
left = treeFromList' (safefilter' (<x) xs (f n)
|
||
right = treeFromList' (safefilter' (>x) xs (f n)
|
||
f = ???
|
||
</pre>
|
||
|
||
<p><a href="code/04_Appendice/01_More_on_infinite_trees/11_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>11_Infinite_Trees.lhs</strong> </a></p>
|
||
<hr/><div class="footnotes">
|
||
<ol>
|
||
<li id="fn:0001">
|
||
<p>Même si tous les langages récent essayent de les cachés, ils restent présents.<a href="#fnref:0001" rel="reference">↩</a></p>
|
||
</li>
|
||
<li id="fn:2">
|
||
<p>I know I cheat. But I will talk about non-strict later.<a href="#fnref:2" rel="reference">↩</a></p>
|
||
</li>
|
||
<li id="fn:0216">
|
||
<p>You should remark <code>squareEvenSum''</code> is more efficient that the two other versions. The order of <code>(.)</code> is important.<a href="#fnref:0216" rel="reference">↩</a></p>
|
||
</li>
|
||
<li id="fn:1">
|
||
<p>Which itself is very similar to the javascript <code>eval</code> on a string containing JSON).<a href="#fnref:1" rel="reference">↩</a></p>
|
||
</li>
|
||
<li id="fn:032001">
|
||
<p>There are some <em>unsafe</em> exception to this rule. But you shouldn’t see such usage on a real application except might be for some debugging purpose.<a href="#fnref:032001" rel="reference">↩</a></p>
|
||
</li>
|
||
<li id="fn:032002">
|
||
<p>For the curious the real type is <code>data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}</code>. All the <code>#</code> as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.<a href="#fnref:032002" rel="reference">↩</a></p>
|
||
</li>
|
||
<li id="fn:03021301">
|
||
<p>Well, you’ll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.<a href="#fnref:03021301" rel="reference">↩</a></p>
|
||
</li>
|
||
</ol>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<div id="choixrss">
|
||
<a id="rss" href="http://feeds.feedburner.com/yannespositocomfr">
|
||
s'abonner
|
||
</a>
|
||
</div>
|
||
<script type="text/javascript">
|
||
$(document).ready(function(){
|
||
$('#comment').hide();
|
||
$('#clickcomment').click(showComments);
|
||
});
|
||
function showComments() {
|
||
$('#comment').show();
|
||
$('#clickcomment').fadeOut();
|
||
}
|
||
document.write('<div id="clickcomment">Commentaires</div>');
|
||
</script>
|
||
<div class="flush"></div>
|
||
<div class="corps" id="comment">
|
||
<h2 class="first">commentaires</h2>
|
||
<noscript>
|
||
Vous devez activer javascript pour commenter.
|
||
</noscript>
|
||
|
||
<script type="text/javascript">
|
||
var idcomments_acct = 'a307f0044511ff1b5cfca573fc0a52e7';
|
||
var idcomments_post_id = '/Scratch/fr/blog/Haskell-the-Hard-Way/';
|
||
var idcomments_post_url = 'http://yannesposito.com/Scratch/fr/blog/Haskell-the-Hard-Way/';
|
||
</script>
|
||
<span id="IDCommentsPostTitle" style="display:none"></span>
|
||
<script type='text/javascript' src='/Scratch/js/genericCommentWrapperV2.js'></script>
|
||
|
||
</div>
|
||
|
||
<div id="entete" class="corps_spaced">
|
||
<div id="liens">
|
||
<ul><li><a href="/Scratch/fr/">Bienvenue</a></li>
|
||
<li><a href="/Scratch/fr/blog/">Blog</a></li>
|
||
<li><a href="/Scratch/fr/softwares/">Softwares</a></li>
|
||
<li><a href="/Scratch/fr/about/">À propos</a></li></ul>
|
||
</div>
|
||
<div class="flush"></div>
|
||
<hr/>
|
||
<div id="next_before_articles">
|
||
<div id="previous_articles">
|
||
articles précédents
|
||
|
||
<div class="previous_article">
|
||
<a href="/Scratch/fr/blog/Typography-and-the-Web/"><span class="nicer">«</span> La typography et le Web</a>
|
||
</div>
|
||
|
||
|
||
<div class="previous_article">
|
||
<a href="/Scratch/fr/blog/Yesod-tutorial-for-newbies/"><span class="nicer">«</span> Site en Haskell</a>
|
||
</div>
|
||
|
||
|
||
<div class="previous_article">
|
||
<a href="/Scratch/fr/blog/SVG-and-m4-fractals/"><span class="nicer">«</span> Accroître le pouvoir des languages déficients.</a>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
<div id="next_articles">
|
||
articles suivants
|
||
|
||
|
||
|
||
|
||
</div>
|
||
<div class="flush"></div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<div id="bottom">
|
||
<div>
|
||
<a href="http://twitter.com/yogsototh">Suivez-moi</a>
|
||
</div>
|
||
<div>
|
||
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.fr">Droits de reproduction ©, Yann Esposito</a>
|
||
</div>
|
||
<div id="lastmod">
|
||
Écrit le : 08/02/2012
|
||
modifié le : 06/04/2012
|
||
</div>
|
||
<div>
|
||
Site entièrement réalisé avec
|
||
<a href="http://www.vim.org">Vim</a>
|
||
et
|
||
<a href="http://nanoc.stoneship.org">nanoc</a>
|
||
</div>
|
||
</div>
|
||
<div class="clear"></div>
|
||
</div>
|
||
</body>
|
||
</html> |