<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Coder-Studio &#187; fonctionnel</title>
	<atom:link href="http://www.coder-studio.com/blog/tag/fonctionnel/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coder-studio.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 02 Mar 2011 22:17:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>(Petit) Clône de client telnet en Haskell</title>
		<link>http://www.coder-studio.com/blog/petit-clone-de-client-telnet-en-haskell/</link>
		<comments>http://www.coder-studio.com/blog/petit-clone-de-client-telnet-en-haskell/#comments</comments>
		<pubDate>Fri, 28 Aug 2009 11:19:08 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[fonctionnel]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[telnet]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=421</guid>
		<description><![CDATA[Bonjour, L'autre nuit, muni de café, j'ai souhaité m'amuser avec Haskell. J'ai alors consulté le chapitre sur le réseau en Haskell de Real World Haskell et... j'ai écrit un (très petit) clône de client telnet... qui fait 41 lignes. Le seul soucis étant que dans toute application de ce genre, on doit partager habilement la [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour,</p>
<p>L'autre nuit, muni de café, j'ai souhaité m'amuser avec Haskell. J'ai alors consulté le chapitre sur le réseau en Haskell de <a href="http://book.realworldhaskell.org/read/">Real World Haskell</a> et... j'ai écrit un (très petit) clône de client telnet... qui fait 41 lignes. Le seul soucis étant que dans toute application de ce genre, on doit partager habilement la lecture des entrées de l'utilisateur, et l'affichage de ce que l'on nous envoie. Ceci mis à part, tout cela fonctionne très bien !</p>
<p><center><img src="http://haskell.org/logos/logos/logo7000.png" alt="Haskell" title="Haskell" /></center></p>
<p><span id="more-421"></span></p>
<p>Regardons à quoi cela ressemble. Petit détail : à chaque tour, je lance la réception de données réseau dans un autre thread, pour ne pas bloquer l'écriture de l'utilisateur.</p>
<p>On importe d'abord les modules nécessaires.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code8'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4218"><td class="code" id="p421code8"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Concurrent 
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Monad"><span style="color: #cccc00; font-weight: bold;">Monad</span></a> 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>Socket 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>BSD 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span>Environment 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a></pre></td></tr></table></div>

<p>Ensuite, j'ai écrit quelques fonctions pour rendre la connection, l'envoi etc plus faciles.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code9'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p4219"><td class="code" id="p421code9"><pre class="haskell" style="font-family:monospace;"><span style="color: #5d478b; font-style: italic;">-- Ouverture d'une connexion TCP cliente </span>
<span style="color: #5d478b; font-style: italic;">-- Prend en argument l'host et le port/service (qui est une String également) </span>
<span style="color: #5d478b; font-style: italic;">-- Retourne le &quot;Handle&quot; vers le socket en question. </span>
openConnection <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> ServiceName <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> Handle 
openConnection hostname port <span style="color: #339933; font-weight: bold;">=</span> 
  <span style="color: #06c; font-weight: bold;">do</span> 
  addrInfos <span style="color: #339933; font-weight: bold;">&lt;-</span> getAddrInfo Nothing <span style="color: green;">&#40;</span>Just hostname<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Just port<span style="color: green;">&#41;</span> 
  <span style="color: #06c; font-weight: bold;">let</span> serveraddr <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:head"><span style="font-weight: bold;">head</span></a> addrInfos 
  sock <span style="color: #339933; font-weight: bold;">&lt;-</span> socket <span style="color: green;">&#40;</span>addrFamily serveraddr<span style="color: green;">&#41;</span> Stream defaultProtocol 
  setSocketOption sock KeepAlive <span style="color: red;">1</span> 
  connect sock <span style="color: green;">&#40;</span>addrAddress serveraddr<span style="color: green;">&#41;</span> 
  h <span style="color: #339933; font-weight: bold;">&lt;-</span> socketToHandle sock ReadWriteMode 
  hSetBuffering h <span style="color: green;">&#40;</span>BlockBuffering Nothing<span style="color: green;">&#41;</span> 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> h 
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Ferme la connexion dont le Handle est donné </span>
closeConnection <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
closeConnection h <span style="color: #339933; font-weight: bold;">=</span> hClose h 
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Envoie la chaîne donnée sur le Handle donné, et ensuite fait un flush sur ce handle, ce qui force l'envoi immédiat et nettoie les états </span>
sendMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
sendMsg h msg <span style="color: #339933; font-weight: bold;">=</span> hPutStrLn h msg <span style="color: #339933; font-weight: bold;">&gt;&gt;</span> hFlush h 
&nbsp;
<span style="color: #5d478b; font-style: italic;">-- Lis sur le Handle donné une chaîne et la renvoie (dans la monade IO) </span>
recvMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> 
recvMsg h <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  msg <span style="color: #339933; font-weight: bold;">&lt;-</span> hGetContents h  
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> msg</pre></td></tr></table></div>

<p>Voyons maintenant la fonction main.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code10'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42110"><td class="code" id="p421code10"><pre class="haskell" style="font-family:monospace;">main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs 
  <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>host<span style="color: #339933; font-weight: bold;">,</span> port<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">0</span><span style="color: #339933; font-weight: bold;">,</span> args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span></pre></td></tr></table></div>

<p>On récupère les arguments donnés au programme (s'il n'y en a pas assez, cela fera planter le logiciel -- je ne me suis pas vraiment préoccupé de tous les cas d'erreur, mais ce n'était pas ma priorité ici) via la fonction getArgs, et l'on en récupère l'host et le port donnés.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code11'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42111"><td class="code" id="p421code11"><pre class="haskell" style="font-family:monospace;">  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="color: #339933; font-weight: bold;">$</span> <span style="background-color: #3cb371;">&quot;Opening client on &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> host <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;:&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> port <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> 
  hclient <span style="color: #339933; font-weight: bold;">&lt;-</span> openConnection host port 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="background-color: #3cb371;">&quot;Client connected&quot;</span></pre></td></tr></table></div>

<p>Ca y est, on se connecte, en affichant des messages pour tenir l'utilisateur informé. Si la connection échoue, le programme s'arrêtera avec une erreur -- cf remarque ci-dessus.</p>
<p>Et maintenant, la boucle qui permet de lire depuis le réseau et lire depuis l'utilisateur, etc.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code12'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42112"><td class="code" id="p421code12"><pre class="haskell" style="font-family:monospace;">  forever <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span> 
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:getLine"><span style="font-weight: bold;">getLine</span></a> <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> sendMsg hclient 
    forkIO <span style="color: #339933; font-weight: bold;">$</span> recvMsg hclient <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a></pre></td></tr></table></div>

<p>Ici, on a une sorte de boucle "à la while(true)", dans laquelle on va tour à tour récupérer une entrée de l'utilisateur et l'envoyer au serveur, puis, dans un thread séparé, récupérer ce qu'a envoyé le serveur et l'afficher.<br />
Enfin, on ferme la connection (ce code est inutile tant que l'on a pas de possibilité de sortir du forever... qui devra tôt ou tard se transformer en "until" ou autre).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code13'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42113"><td class="code" id="p421code13"><pre class="haskell" style="font-family:monospace;">  closeConnection hclient</pre></td></tr></table></div>

<p>Voilà le code complet :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p421code14'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p42114"><td class="code" id="p421code14"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span>Concurrent 
<span style="color: #06c; font-weight: bold;">import</span> Control<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Monad"><span style="color: #cccc00; font-weight: bold;">Monad</span></a> 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>Socket 
<span style="color: #06c; font-weight: bold;">import</span> Network<span style="color: #339933; font-weight: bold;">.</span>BSD 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span>Environment 
<span style="color: #06c; font-weight: bold;">import</span> System<span style="color: #339933; font-weight: bold;">.</span><a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> 
&nbsp;
openConnection <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> ServiceName <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> Handle 
openConnection hostname port <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  addrInfos <span style="color: #339933; font-weight: bold;">&lt;-</span> getAddrInfo Nothing <span style="color: green;">&#40;</span>Just hostname<span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>Just port<span style="color: green;">&#41;</span> 
  <span style="color: #06c; font-weight: bold;">let</span> serveraddr <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:head"><span style="font-weight: bold;">head</span></a> addrInfos 
  sock <span style="color: #339933; font-weight: bold;">&lt;-</span> socket <span style="color: green;">&#40;</span>addrFamily serveraddr<span style="color: green;">&#41;</span> Stream defaultProtocol 
  setSocketOption sock KeepAlive <span style="color: red;">1</span> 
  connect sock <span style="color: green;">&#40;</span>addrAddress serveraddr<span style="color: green;">&#41;</span> 
  h <span style="color: #339933; font-weight: bold;">&lt;-</span> socketToHandle sock ReadWriteMode 
  hSetBuffering h <span style="color: green;">&#40;</span>BlockBuffering Nothing<span style="color: green;">&#41;</span> 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> h 
&nbsp;
closeConnection <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
closeConnection h <span style="color: #339933; font-weight: bold;">=</span> hClose h 
&nbsp;
sendMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <span style="color: green;">&#40;</span><span style="color: green;">&#41;</span> 
sendMsg h msg <span style="color: #339933; font-weight: bold;">=</span> hPutStrLn h msg <span style="color: #339933; font-weight: bold;">&gt;&gt;</span> hFlush h 
&nbsp;
recvMsg <span style="color: #339933; font-weight: bold;">::</span> Handle <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:IO"><span style="color: #cccc00; font-weight: bold;">IO</span></a> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> 
recvMsg h <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  msg <span style="color: #339933; font-weight: bold;">&lt;-</span> hGetContents h  
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:return"><span style="font-weight: bold;">return</span></a> msg 
&nbsp;
main <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> 
  args <span style="color: #339933; font-weight: bold;">&lt;-</span> getArgs 
  <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>host<span style="color: #339933; font-weight: bold;">,</span> port<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">0</span><span style="color: #339933; font-weight: bold;">,</span> args <span style="color: #339933; font-weight: bold;">!!</span> <span style="color: red;">1</span><span style="color: green;">&#41;</span> 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="color: #339933; font-weight: bold;">$</span> <span style="background-color: #3cb371;">&quot;Opening client on &quot;</span> <span style="color: #339933; font-weight: bold;">++</span> host <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;:&quot;</span> <span style="color: #339933; font-weight: bold;">++</span> port <span style="color: #339933; font-weight: bold;">++</span> <span style="background-color: #3cb371;">&quot;<span style="background-color: #3cb371; font-weight: bold;">\n</span>&quot;</span> 
  hclient <span style="color: #339933; font-weight: bold;">&lt;-</span> openConnection host port 
  <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> <span style="background-color: #3cb371;">&quot;Client connected&quot;</span> 
  forever <span style="color: #339933; font-weight: bold;">$</span> <span style="color: #06c; font-weight: bold;">do</span> 
    <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:getLine"><span style="font-weight: bold;">getLine</span></a> <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> sendMsg hclient 
    forkIO <span style="color: #339933; font-weight: bold;">$</span> recvMsg hclient <span style="color: #339933; font-weight: bold;">&gt;&gt;=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:putStrLn"><span style="font-weight: bold;">putStrLn</span></a> 
  closeConnection hclient</pre></td></tr></table></div>

<p>Compilation :</p>
<blockquote><p>ghc --make -o net net.hs</p></blockquote>
<p>Puis 2 exemples d'exécution...<br />
<code>
<pre>
$ ./net google.fr 80
Opening client on google.fr:80
Client connected
GET / HTTP/1.0
HTTP/1.0 302 Found
Location: http://www.google.fr/
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Set-Cookie: PREF=ID=30b094ad566b5532:TM=1251456529:LM=1251456529:S=94IXp5-SGiaYADWc; expires=Sun, 28-Aug-2011 10:48:49 GMT; path=/; domain=.google.com
Date: Fri, 28 Aug 2009 10:48:49 GMT
Server: gws
Content-Length: 218 

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.fr/">here</A>.
</BODY></HTML> 

^C
</pre>
<p></code><br />
(c'est moi qui ai tapé "GET / HTTP/1.0")<br />
( qui vous dira que la page a été déplacée <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</p>
<p>Et enfin, la surprise...</p>
<blockquote><p>$ ./net towel.blinkenlights.nl 23</p></blockquote>
<p>Qui, une version simplifiée d'un film très connu, vous permettra de voir, Jedi.</p>
<p>Enjoy !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/petit-clone-de-client-telnet-en-haskell/feed/</wfw:commentRss>
		<slash:comments>3006</slash:comments>
		</item>
		<item>
		<title>Bouncing Ball en OCaml avec OCamlSDL</title>
		<link>http://www.coder-studio.com/blog/bouncing-ball-en-ocaml-avec-ocamlsdl/</link>
		<comments>http://www.coder-studio.com/blog/bouncing-ball-en-ocaml-avec-ocamlsdl/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 23:26:17 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[2D]]></category>
		<category><![CDATA[bouncing ball]]></category>
		<category><![CDATA[fonctionnel]]></category>
		<category><![CDATA[ocaml]]></category>
		<category><![CDATA[ocamlsdl]]></category>
		<category><![CDATA[programmation fonctionnelle]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=271</guid>
		<description><![CDATA[Bonsoir, J'ai écrit un petit programme OCaml de Boucing Ball, une balle qui rebondit contre les bords de la fenêtre, où l'on peut augmenter la vitesse en X et en Y avec les touches du clavier. Il utilise OCamlSDL, un binding de la désormais célèbre bibliothèque SDL pour le langage OCaml. Voici ce que cela [...]]]></description>
			<content:encoded><![CDATA[<p>Bonsoir,</p>
<p>J'ai écrit un petit programme OCaml de Boucing Ball, une balle qui rebondit contre les bords de la fenêtre, où l'on peut augmenter la vitesse en X et en Y avec les touches du clavier.<br />
Il utilise OCamlSDL, un binding de la désormais célèbre bibliothèque <a href="http://www.libsdl.org/">SDL</a> pour le langage OCaml.</p>
<p>Voici ce que cela donne.</p>
<p><center><div id="attachment_272" class="wp-caption alignnone" style="width: 410px"><a href="http://www.coder-studio.com/blog/wp-content/uploads/2009/04/bbsdl.png"><img src="http://www.coder-studio.com/blog/wp-content/uploads/2009/04/bbsdl.png" alt="Boucing Ball en action" title="bbsdl" width="400" height="316" class="size-full wp-image-272" /></a><p class="wp-caption-text">Boucing Ball en action</p></div></center></p>
<p>Si vous voulez tester et/ou améliorer ce programme, qui peut soit dit en passant servir de base pour un Pong ou autre jeu de ce genre, vous trouverez le code source ici : <a href="http://mestan.fr/ocaml/bbsdl/bbsdl.tar.gz">bbsdl.tar.gz</a>.</p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/bouncing-ball-en-ocaml-avec-ocamlsdl/feed/</wfw:commentRss>
		<slash:comments>2039</slash:comments>
		</item>
		<item>
		<title>OCaml Batteries Included : un effort pour fournir une bibliothèque standard digne de ce nom pour OCaml</title>
		<link>http://www.coder-studio.com/blog/ocaml-batteries-included-un-effort-pour-fournir-une-bibliotheque-standard-digne-de-ce-nom-pour-ocaml/</link>
		<comments>http://www.coder-studio.com/blog/ocaml-batteries-included-un-effort-pour-fournir-une-bibliotheque-standard-digne-de-ce-nom-pour-ocaml/#comments</comments>
		<pubDate>Sat, 11 Apr 2009 20:36:57 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[batteries]]></category>
		<category><![CDATA[fonctionnel]]></category>
		<category><![CDATA[included]]></category>
		<category><![CDATA[ocaml]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=193</guid>
		<description><![CDATA[Bonsoir, Peut-être avez-vous déjà entendu parler de ce projet ... OCaml Batteries Included. Ce projet couvre pour le moment un certain nombre de domaines. Il fournit une certaine quantité de structures de données, de fonctions pour la programmation concurrente, etc. Qui plus est, il inclut des extensions de syntaxes qui pourront s'avérer très utile, ainsi [...]]]></description>
			<content:encoded><![CDATA[<p>Bonsoir,</p>
<p>Peut-être avez-vous déjà entendu parler de ce projet ... <a href="http://batteries.forge.ocamlcore.org/">OCaml Batteries Included</a>.</p>
<p>Ce projet couvre pour le moment un certain nombre de domaines. Il fournit une certaine quantité de structures de données, de fonctions pour la programmation concurrente, etc. Qui plus est, il inclut des extensions de syntaxes qui pourront s'avérer très utile, ainsi que de nouveaux opérateurs pour rendre le code OCaml plus lisible et concis, ce qui finalement fait gagner en lisibilité (notamment pour l'enchainement de fonctions, comme lorsque l'on appelle une série de fonctions opérant sur une chaîne de caractères, en passant le résultat d'une fonction à la suivante, et ainsi de suite). Je ne vais pas lister les bibliothèques, ce serait trop long.</p>
<p>OCaml Batteries Included est sortie en version Bêta 1 il y a quelques jours. Qui plus est, l'équipe OCaml-Debian-Maintainers a mis à disposition un paquet ocaml-batteries-included qui est dans le dépôt testing officiel, n'hésitez pas !</p>
<p>Pour finir, quelques liens :<br />
<a href="http://batteries.forge.ocamlcore.org/">Site officiel</a><br />
<a href="http://batteries.forge.ocamlcore.org/doc.preview:batteries-beta1/html/api/index.html">Documentation de l'API</a><br />
<a href="http://batteries.forge.ocamlcore.org/doc.preview:batteries-alpha3/html/index.html">Documentation de la plateforme</a><br />
<a href="http://dutherenverseauborddelatable.wordpress.com/2009/04/06/ocaml-batteries-included-beta-1/">Billet de blog sur la publication de la Beta 1</a></p>
<p>Enjoy !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/ocaml-batteries-included-un-effort-pour-fournir-une-bibliotheque-standard-digne-de-ce-nom-pour-ocaml/feed/</wfw:commentRss>
		<slash:comments>2221</slash:comments>
		</item>
		<item>
		<title>Supprimer toutes les instances d&#039;un caractère dans une chaîne en Haskell</title>
		<link>http://www.coder-studio.com/blog/supprimer-toutes-les-instances-dun-caractere-dans-une-chaine-en-haskell/</link>
		<comments>http://www.coder-studio.com/blog/supprimer-toutes-les-instances-dun-caractere-dans-une-chaine-en-haskell/#comments</comments>
		<pubDate>Fri, 27 Feb 2009 08:10:17 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[caractères]]></category>
		<category><![CDATA[chaînes]]></category>
		<category><![CDATA[fonctionnel]]></category>
		<category><![CDATA[haskell]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=80</guid>
		<description><![CDATA[Bonjour, J'inaugure mon compte sur ce blog en y postant mon premier billet, sur Haskell qui plus est ! Je vais vous montrer puis vous expliquer un moyen simple de supprimer toutes les instances d'un caractère donné dans une chaîne, en Haskell... en une ligne, oui. Il s'agit donc par exemple de pouvoir supprimer tous [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour,</p>
<p>J'inaugure mon compte sur ce blog en y postant mon premier billet, sur Haskell qui plus est !</p>
<p>Je vais vous montrer puis vous expliquer un moyen simple de supprimer toutes les instances d'un caractère donné dans une chaîne, en Haskell... en une ligne, oui.<br />
Il s'agit donc par exemple de pouvoir supprimer tous les 'a' dans (je vais faire dans l'original) le titre de ce billet !</p>
<p>"Supprimer toutes les instances d'un caractère dans une chaîne en Haskell"<br />
doit donc devenir :<br />
"Supprimer toutes les instnces d'un crctère dns une chîne en Hskell"</p>
<p><span id="more-80"></span></p>
<p>Voici comment faire, en utilisant la fonction filter que nous expliquerons plus bas.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p80code20'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p8020"><td class="code" id="p80code20"><pre class="haskell" style="font-family:monospace;">strip <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Char"><span style="color: #cccc00; font-weight: bold;">Char</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a>
strip c s <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:filter"><span style="font-weight: bold;">filter</span></a> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">/=</span> c<span style="color: green;">&#41;</span> s</pre></td></tr></table></div>

<p>Premièrement, regardons le type de cette fonction.<br />
Elle prend a deux arguments : un caractère et une chaîne de caractères (qui, en Haskell, est définie comme une liste de caractères <em>[Char]</em>). Elle retourne une chaîne de caractères ; c'est bien ce que l'on désire.</p>
<p>Regardons ensuite la seconde ligne : <em>c</em> désigne le fameux caractère à supprimer et <em>s</em> la chaîne dans laquelle le supprimer.</p>
<p>Nous faisons ensuite appel à la fonction filter qui prend un prédicat à un argument (une fonction d'un argument qui retourne un booléen) et qui s'applique ensuite sur une liste, donnée en second argument. Elle retourne une liste où seuls les éléments vérifiant le prédicat sont restés. Je tiens à rappeler que Haskell étant un langage fonctionnel, on ne modifie pas la liste, on en retourne une nouvelle. N'ayez crainte, ça ne va pas faire des programme lourd, il y a de belles optimisations qui tournent derrière.</p>
<p>Mettez le code précédent dans un fichier strip.hs par exemple, et chargez-le dans GHCi via <em>:load strip.hs</em> (en vous assurant que vous êtes dans le bon répertoire). Puis testons :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p80code21'); return false;">View Code</a> PRELUDE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p8021"><td class="code" id="p80code21"><pre class="prelude" style="font-family:monospace;">*Main&gt; strip 'a' &quot;Supprimer toutes les instances d'un caractères dans une chaîne en Haskell&quot;
&quot;Supprimer toutes les instnces d'un crctères dns une chîne en Hskell&quot;</pre></td></tr></table></div>

<p>Notons toutefois que le code ci-dessus peut-être encore plus court !<br />
En effet, nous avons indiqué la chaine "s" alors que l'on peut s'en passer et écrire cela :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p80code22'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p8022"><td class="code" id="p80code22"><pre class="haskell" style="font-family:monospace;">strip <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Char"><span style="color: #cccc00; font-weight: bold;">Char</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a>
strip c <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:filter"><span style="font-weight: bold;">filter</span></a> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">/=</span> c<span style="color: green;">&#41;</span></pre></td></tr></table></div>

<p>Et encore, on sent que strip n'est définissable qu'avec filter et l'opérateur /= ... Et bien tout à fait !</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p80code23'); return false;">View Code</a> HASKELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p8023"><td class="code" id="p80code23"><pre class="haskell" style="font-family:monospace;">strip <span style="color: #339933; font-weight: bold;">::</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:Char"><span style="color: #cccc00; font-weight: bold;">Char</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a> <span style="color: #339933; font-weight: bold;">-&gt;</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#t:String"><span style="color: #cccc00; font-weight: bold;">String</span></a>
strip <span style="color: #339933; font-weight: bold;">=</span> <a href="http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:filter"><span style="font-weight: bold;">filter</span></a> <span style="color: #339933; font-weight: bold;">.</span> <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">/=</span><span style="color: green;">&#41;</span></pre></td></tr></table></div>

<p>Cette propriété se nomme <strong>êta-réduction</strong> et rend le code bien plus sobre, concis et clair. En effet, en Haskell, après un certain temps, on parvient à écrire du code qui n'est presque qu'un enchainement de compositions de fonctions, de sorte qu'une ligne ne soit presque qu'une phrase, si l'on nomme bien les fonctions. </p>
<p>Je rappelle que le '.' est tout simplement l'opérateur de composition de fonctions, et il suffit de regarder son type pour s'en convaincre :<br />
Tapez <em>:t (.)</em> dans GHCi pour vous en convaincre, il vous dira ceci :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p80code24'); return false;">View Code</a> PRELUDE</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p8024"><td class="code" id="p80code24"><pre class="prelude" style="font-family:monospace;">*Main&gt; :t (.)
(.) :: (b -&gt; c) -&gt; (a -&gt; b) -&gt; a -&gt; c</pre></td></tr></table></div>

<p>Ce qui signifie en gros : </p>
<blockquote><p>Pour tous types a, b et c (<em>polymorphisme inside</em>), l'opérateur <em>.</em> prend deux fonctions, l'une (disons g) du type b vers le type c, l'autre (disons f) du type a vers le type b, et elle en fait la composition pour obtenir une fonction qui va du type a vers le type c.</p></blockquote>
<p>C'est exactement ce que fait l'opérateur '<em>o</em>' en Mathématiques ; en effet, <em>g . f</em> en Haskell est équivalent à <em>g o f</em> en Mathématiques.</p>
<p>Voilà pour mon premier billet ici. </p>
<p>Si vous avez découvert Haskell par ce billet et que vous souhaitez vous y mettre, voici quelques liens essentiels :<br />
<a href="http://www.haskell.org/">http://www.haskell.org/</a> : Site officiel, où l'on peut télécharger compilateur, interpréteur, outils &#038; bibliothèques divers et variés mais également consulter des tutoriels/cours sur Haskell  - c'est le QG de tous les programmeurs Haskell<br />
<a href="http://en.wikibooks.org/wiki/Haskell">http://en.wikibooks.org/wiki/Haskell</a> : Le Wikibook sur Haskell<br />
<a href="http://book.realworldhaskell.org/read/">http://book.realworldhaskell.org/read/</a> : Le livre 'Real World Haskell' qui est disponible gratuitement en lecture en ligne<br />
Et pour terminer, il y a le salon #haskell (et #haskell.fr, mais ce dernier est peu actif) sur le réseau IRC Freenode.</p>
<p>A bientôt !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/supprimer-toutes-les-instances-dun-caractere-dans-une-chaine-en-haskell/feed/</wfw:commentRss>
		<slash:comments>1637</slash:comments>
		</item>
	</channel>
</rss>

