tag:blogger.com,1999:blog-73491307503524998312024-03-05T04:48:47.160-08:00productive detourdanidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.comBlogger26125tag:blogger.com,1999:blog-7349130750352499831.post-86263306086036491432016-07-02T01:18:00.000-07:002016-07-03T09:14:50.288-07:00The Top 100 German Verbs (German with Jenny video)<br />
<div>
From <a href="https://www.youtube.com/watch?v=AJxieXyATaY">this helpful video</a> from the <a href="https://www.youtube.com/channel/UClBrbJXNh2sFxOuvH4o5H9g">German with Jenny</a> YouTube channel.</div>
<div>
<ol>
<li><a href="https://youtu.be/AJxieXyATaY?t=22">ich lerne / ich lernte / ich habe gelernt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=56">ich wohne / ich wohnte / ich have gewohnt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=89">ich spreche / ich sprach / ich have gesprochen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=120">ich kommen / ich kan / ich bin gekommen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=153">ich arbeite / ich arbeitete / ich have geatbeitet</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=188">ich esse / ich aß / ich have gegessen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=221">ich trinke / ich trank / ich have getrunken</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=251">ich habe / ich hatte / ich habe gehabt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=283">ich bin / ich war / ich bin gewessen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=312">ich verstehe / ich verstand / ich habe verstanden</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=343">ich spiele / ich spielte / ich habe gespielt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=376">ich schlafe / ich schlief / ich have geschlafen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=405">ich fahre / ich fuhr / ich bin gefahren</a></li>
<li><a href="https://www.youtube.com/watch?v=AJxieXyATaY&t=439"><span id="goog_1307006288"></span>ich gehe / ich ging / ich bin gegangen<span id="goog_1307006289"></span></a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=474">ich mache / ich machte / ich habe gematch</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=508">ich sage / ich sagte / ich habe gesagt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=541">ich kauge / ich kaufte / ich habe gekauft</a></li>
<li><a href="https://www.youtube.com/watch?v=AJxieXyATaY&t=574">ich bezahle / ich bezahlte / ich habe behalt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=611">ich nehme / ich nahm / ich habe genommen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=644">ich mag / ich mochte</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=686">ich will / ich wollte</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=708">ich kann / ich konnte</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=734">ich darf / ich durfte</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=761">ich soll / ich sollte</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=790">ich möchte / ich wollte</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=842">ich weiß / ich wusste / ich habe gewusst</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=876">ich kenne / ich kannte / ich habe gekannt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=909">ich denke / ich dachte / ich habe gedatch</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=944">ich sehe / ich sah / ich habe gesehen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=976">ich höre / ich hörte / ich habe gehört</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1009">ich gebe / ich gab / ich habe gegeben</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1045">ich zeige / ich zeigte / ich habe gezeigt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1080">ich sitze / ich saß / ich habe gegessen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1114">ich liege / ich lag / ich habe gelegen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1156">ich stehe / ich stand / ich habe gestanden</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1198">ich laufe / ich lief / ich bin gelaufen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1238">ich bringe / ich brachte / ich habe gebracht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1272">ich fühle / ich fühlte / ich habe gefült</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1302">ich glaube / ich glaubte / ich habe geglaubt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1334">ich heiße / ich heiß</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1367">ich ziehe / ich zog / ich habe gezogen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1401">ich verliere / ich verlor / ich habe verloren</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1438">ich gewinne / ich gewann / ich habe gewonnen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1473">ich brauche / ich brauchte / ich habe gebraucht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1505">ich schreibe / ich schreib / ich habe geschrieben</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1536">ich leibe / ich liebte / ich habe geliebt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1570">ich schwimme / ich schwamm / ich bin geschwommen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1603">ich baue / ich baute / ich habe gebaut</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1636">ich schicke / ich schickte / ich habe geschickt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1667">ich lache / ich lachte / ich habe gelacht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1722">ich trage / ich trug / ich habe getragen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1756">ich werde / ich wurde / ich bin geworden</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1791">ich lasse / ich ließ / ich habe gelassen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1825">ich folge / ich folgte / ich bin gefoldgt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1858">ich tue / ich tat / ich habe getan</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1892">es schmeckt / es schmeckte / es hat geschmeckt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1926">es regnet / es regnete / es hat geregnet</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1961">ich warte / ich wartete / ich habe gewartet</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=1995">ich helfe / ich half / ich habe geholfen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2029">ich lese / ich las / ich habe gelesen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2064">ich lege / ich legte / ich habe gelegt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2098">ich suche / ich suchte / ich habe gesucht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2132">ich lebe / ich lebte / ich habe gelebt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2167">ich falle / ich fiel / ich bin gefallen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2201">ich rede / ich redete / ich habe geredet</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2224">ich reise / ich reiste / ich bin gereist</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2257">ich fliege / ich flog / ich bin geflogen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2294">es kostet / es kostete / es hat gekostet</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2324">ich singe / ich sang / ich habe gesungen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2357">ich danke / ich dankte / ich habe gedankt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2387">ich tanze / ich tanzte / ich habe getanzt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2420">ich antworte / ich antwortete / ich habe geantwortet</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2456">es passiert / es passierte / es ist passiert</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2488">ich probiere / ich probierte / ich habe probiert</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2522">ich repariere / ich reparierte / ich habe repariert</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2559">ich studiere / ich studierte / ich habe studiert</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2595">ich biete an / ich bot an / ich habe angeboten</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2632">ich fange an / ich fing an / ich habe angefangen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2671">ich stehe auf / ich stand auf / ich bin aufgestanden</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2710">ich rufe an / ich rief an / ich habe angerufen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2748">ich mache auf / ich machte auf / ich habe aufgemacht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2785">ich sehe aus / ich sah aus / ich habe ausgesehen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2820">ich lade ein / ich lud ein / ich habe eingeladen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2861">ich steige ein / ich stieg ein / ich bin eingestiegen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2903">ich mache zu / ich machte zu / ich habe zugemacht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2939">ich bestelle / ich bestellte / ich habe bestellt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=2975">ich bekomme / ich bekam / ich habe bekommen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3010">ich bestehe / ich bestand / ich habe bestanden</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3044">ich besuche / ich besuchte / ich habe besucht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3075">ich entwickle / ich entwickelte / ich habe entwickelt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3114">ich erkenne / ich erkannte / ich habe erkannt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3147">ich erkläre / ich erklärte / ich habe erklärt</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3179">ich erwarte / ich erwartete / ich habe erwartet</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3214">ich gehöre / ich gehörte / ich habe gehört</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3248">ich vergesse / ich vergaß / ich habe vergessen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3280">ich vergleiche / ich verglich / ich habe verglichen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3316">ich versuche / ich versuchte / ich habe versucht</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3349">ich sehe mir an / ich sah mir an / ich habe mir angesehen</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3383">ich interessiere mich / ich interessierte mich / ich habe mich interessiert</a></li>
<li><a href="https://youtu.be/AJxieXyATaY?t=3418">ich treffe mich / ich traf mich / ich habe mich getroffen</a></li>
</ol>
<div>
<br /></div>
</div>
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-26976902558295335152016-04-25T00:22:00.001-07:002016-04-25T00:22:44.390-07:00Videos for "2013 Fall: 15-819 Advanced Topics in Programming Languages"<br />
<div>
Course imparted by Robert Harper. I believe they are following the <a href="https://homotopytypetheory.org/book/">Homotopy Type Theory</a> book. See also Harper's <a href="https://existentialtype.wordpress.com/">blog</a> and the latest edition of his <a href="https://www.goodreads.com/book/show/29885382-practical-foundations-for-programming-languages">Practical Foundations for Programming Languages book</a>. See also the <a href="https://www.cs.uoregon.edu/research/summerschool/summer12/curriculum.html">"proof theory foundations"</a> videos linked in the <a href="http://purelytheoretical.com/sywtltt.html">"So you want to learn type theory... but where to start?"</a> page.</div>
<ol>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=0945cc7f-48b7-4803-81af-e7193a3f461d">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=23fe0158-7e3b-49f2-a5e2-b20096f2b958">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=38e5ee9e-c2bc-4cba-9990-8faae69faa45">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=c1717cb9-3655-445d-824a-77c0666e5430">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a5c05b3b-1b65-45ad-8f70-d63e64fb34b1">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=c5fb4805-6504-4368-a219-2f13bfb37e6a">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=ba77d4f6-3fbe-42cd-90c8-8265af95e508">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=bbe4f042-a4df-4024-adde-1b2ad5900166">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=2ea7a2f2-a16d-4735-a665-7cfbd3e7718e">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=534b5318-0bfd-41e5-89f2-7dea26bc0a66">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=a433f5aa-2e57-4ee4-abe3-7c88f4596512">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=429215dd-124f-4bce-a66f-e0c4d40ab6e7">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=78e4fd66-67a9-4802-b300-db9889da35f0">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=2e9ea3ca-5167-41dc-9e3b-513d62bb41d8">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=97132471-3551-4bb2-a32c-753122a96cea">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=287f3f12-fb20-4496-b99d-cbcceb8eefb0">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=ac7edbff-ef18-4204-b2d4-d45f58bf3b34">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=64e2d296-c577-4ea6-a7d0-644cba9ad1e6">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=1ea06bf8-10eb-4ecf-98f1-4e21df5be53f">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=e293b1ec-052b-4246-8d2a-9aebffde1285">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=7dcc0d88-6ae9-4bad-861e-d00cadd51712">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=7011b342-153d-4709-b443-9c47fd4b3c63">video</a>. </li>
<li><a href="https://scs.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=c36a205f-3d1f-4475-8771-194b4f5040ce">video</a>. </li>
</ol>
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-65325038402760836402015-05-19T05:44:00.001-07:002015-05-19T05:45:42.655-07:00representable functorsA nugget of insight about <a href="http://en.wikipedia.org/wiki/Representable_functor">representable functors</a> from <a href="https://www.youtube.com/channel/UC5Y9H2KDRHZZTWZJtlH4VbA">The Catsters</a>, episode <a href="https://www.youtube.com/watch?v=TLMxHB19khE">Representables and Yoneda 3</a>, around minute <a href="https://youtu.be/TLMxHB19khE?t=61">1:00</a>.<br />
<br />
<blockquote class="tr_bq">
as it turns out, these are very very closely controlled, there's very little that they can do and they are completely controlled by very small amounts of data [...] we think that a lot is going on, when in fact we have very little choice in what's going on, and everything that's going on everywhere is just controlled by one really small bit </blockquote>
<br />danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-79771152896503045722015-05-13T08:59:00.000-07:002016-08-29T15:37:51.952-07:00a cabal sandbox for scripting<b>Later edit:</b> this post is now obsolete, thanks to <a href="https://github.com/commercialhaskell/stack">Stack</a>.<br />
<br />
As a way to facilitate Haskell scripting, I have created the <a href="https://github.com/danidiaz/hs-scripts">hs-scripts</a> repo on GitHub.<br />
<br />
The idea is being able to run interpreted Hakell scripts, without having to install any package at the global level.<br />
<br />
To test it, clone the repo, create a sandbox, and install the library. The repo should also be added to the PATH variable.<br />
<br />
The library is empty at the moment, but is intended to hold common functions and definitions shared by multiple scripts.<br />
<br />
You can invoke <b>cabal repl</b> in the repo to open a GHCi session with a lot of useful packages available (a poor man's Haskell Platform, if you will).<br />
<div>
<br /></div>
There are two batch scripts, <b>hs.bat</b> for Windows and <b>hs.sh</b> for Linux. They take a Haskell script name (without extension) as parameter and execute the script in the context of the sandbox. Scripts are searched in the current directory first and then in the <b>/scripts</b> subfolder of the repository.<br />
<br />
Scripts are easy to compile, if necessary.<br />
<br />
So far there's only one script, a replica of Python's ever-useful <b>python -m SimpleHTTPServer</b>.<br />
<br />
<br />danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-14786612635396023602015-04-24T10:18:00.003-07:002015-04-25T10:00:31.697-07:00Videos for "Structure and Interpretation of Computer Programs" (1986)<br />
<ul>
<li><a href="https://www.youtube.com/watch?v=2Op3QLzMgSY">1A</a></li>
<li><a href="https://www.youtube.com/watch?v=dlbMuv-jix8">1B</a></li>
<li><a href="https://www.youtube.com/watch?v=erHp3r6PbJk">2A</a></li>
<li><a href="https://www.youtube.com/watch?v=ymsbTVLbyN4">2B</a></li>
<li><a href="https://www.youtube.com/watch?v=2QgZVYI3tDs">3A</a> Around <a href="https://youtu.be/2QgZVYI3tDs?t=4088">1:08</a>, the idea of program design as creating layers of languages.</li>
<li><a href="https://www.youtube.com/watch?v=X21cKVtGvYk">3B</a></li>
<li><a href="https://www.youtube.com/watch?v=amf5lTZ0UTc">4A</a></li>
<li><a href="https://www.youtube.com/watch?v=h6Z7vx9iUB8">4B</a></li>
<li><a href="https://www.youtube.com/watch?v=jl8EHP1WrWY">5A</a> Interesting that they don't introduce assignment and mutability until this lecture.</li>
<li><a href="https://www.youtube.com/watch?v=SsBxcpkyMMw">5B</a></li>
<li><a href="https://www.youtube.com/watch?v=a2Qt9uxhNSM">6A</a></li>
<li><a href="https://www.youtube.com/watch?v=DCub3iqteuI">6B</a> Around minute <a href="https://youtu.be/DCub3iqteuI?t=2265">38</a>, a mention of <a href="http://en.wikipedia.org/wiki/Miranda_%28programming_language%29">Miranda</a>, a predecessor to Haskell. Lazy evaluation as "decoupling time in the programs from time in the machine". Explanation of the disadvantages of lazy evaluation (incompatibility with side effects, "dragging tails" a.k.a. space leaks).</li>
<li><a href="https://www.youtube.com/watch?v=0m6hoOelZH8">7A</a> Meta-circular evaluator, fixed points, Y combinator, denotational semantics.</li>
<li><a href="https://www.youtube.com/watch?v=t5EI5fXX8K0">7B</a> "There are many languages that have made a mess of themselves by adding huge numbers of features". Implementing dynamic binding and call by name.</li>
<li><a href="https://www.youtube.com/watch?v=cyVXjnFL2Ps">8A</a></li>
<li><a href="https://www.youtube.com/watch?v=R3uRidfSpc4">8B</a></li>
<li><a href="https://www.youtube.com/watch?v=jPDAPmx4pXE">9A</a></li>
<li><a href="https://www.youtube.com/watch?v=SLcZXbyGC3E">9B</a></li>
<li><a href="https://www.youtube.com/watch?v=kNmiTTKiYd4">10A</a></li>
<li><a href="https://www.youtube.com/watch?v=2s2_FAf-yQs">10B</a></li>
</ul>
<div>
A version of the book in .mobi format (suitable for Kindle) can be found <a href="https://github.com/twcamper/sicp-kindle/blob/master/sicp.mobi">here</a>.</div>
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-49928950441565259222015-03-29T01:08:00.000-07:002015-03-29T08:24:09.988-07:00Is ExceptT over IO really an anti-pattern ?I was reading this <a href="https://github.com/commercialhaskell/haskelldocumentation/blob/master/content/exceptions-best-practices.md">exceptions best practice</a> guide for Haskell. It contains good advice, for example about how masking all exceptions is a terrible idea. However, I sort of disagree about the "ExceptT over IO being an antipattern" part.<br />
<br />
One of the reasons given is that "it's non-composable". I actually think that making errors explicit in the types can be <i>more </i>composable, especially if you want to combine or transform the errors in some manner. Wrapping an exception to provide additional context tends to be more cumbersome than mapping over the error type with <a href="http://hackage.haskell.org/package/transformers-0.4.3.0/docs/Control-Monad-Trans-Except.html#v:withExceptT">withExceptT</a> (or <a href="http://hackage.haskell.org/package/bifunctors-4.2.1/docs/Data-Bifunctor.html#v:first">first</a> from <a href="http://hackage.haskell.org/package/bifunctors-4.2.1/docs/Data-Bifunctor.html#t:Bifunctor">Bifunctor</a>).<br />
<br />
When you compose multiple exception-throwing functions, if you aren't careful your result funcion will end up (maybe even unbeknownst to you!) throwing a zoo of unrelated exceptions with scant context.<br />
<br />
(Digression: the recent <a href="http://hackage.haskell.org/package/pipes-cliff">pipes-cliff</a> library actually does a good job in wrapping every IOException that it encounters, <a href="http://hackage.haskell.org/package/pipes-cliff-0.6.0.0/docs/Pipes-Cliff.html#g:4">tagging it with extra information</a>.)<br />
<br />
On the other hand, I admit that making all the errors explicit in the signature complicates it, and it becomes annoying if you consider those errors as "fatal" anyway and you don't intend to handle them, or at least not at the current layer.<br />
<br />
Which brings us to the other main criticism: that using "ExceptT over IO" doesn't really ensure the absence of exceptions, even if it seems to imply it, and that it only provides a second, largely redundant, channel for communincating errors. In my opinion, there <i>can </i>be cases when we might want two separate error channels: if we want to distinguish between outright fatal vs. recoverable errors that we may want to handle, for example. Or between errors we want to annotate/map over/compose easily versus errors we just want to pass to upper layers unchanged.<br />
<br />
In my <a href="http://hackage.haskell.org/package/process-streaming">process-streaming</a> and <a href="http://hackage.haskell.org/package/conceit">conceit</a> libraries I actually employ this dual approach. The execution functions re-throw any IO exceptions they encounter, but you can also have an explicit error type. If case the error type is never used, it remains polymorphic and we can use functions that have a simpler signature but require the error type to unify with <a href="http://hackage.haskell.org/package/void">Void</a>.<br />
<br />
<br />
<br />
<br />
<br />danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-88301447788678117632015-02-22T05:49:00.000-08:002015-02-22T15:45:56.955-08:00A dynamically generated FromJSON instanceSuppose you need to invoke a function (one like <a href="http://hackage.haskell.org/package/pipes-aeson-0.4.1.2/docs/Pipes-Aeson.html#v:decode">decode</a> from <a href="http://hackage.haskell.org/package/pipes-aeson-0.4.1.2/docs/Pipes-Aeson.html">pipes-aeson</a>) that has a <span style="font-family: Courier New, Courier, monospace;"><a href="http://hackage.haskell.org/package/aeson-0.8.0.2/docs/Data-Aeson.html#t:FromJSON">FromJSON</a> </span>constraint, but the exact parsing method required for the JSON is not fully known until runtime. Perhaps because field names in the JSON have some prefix that is only determined through reading a configuration file, or by asking the user.<br />
<br />
One solution is to use the tools provided by <a href="http://hackage.haskell.org/package/reflection">reflection</a> package to dynamically generate the <span style="font-family: Courier New, Courier, monospace;">FromJSON </span>instance at runtime, <i>after </i>having constructed the parse function.<br />
<br />
The reflection repository already contains an <a href="https://github.com/ekmett/reflection/blob/master/examples/Monoid.hs">example</a> of a dynamically generated <span style="font-family: Courier New, Courier, monospace;">Monoid </span>instance. I have adapted it for the <span style="font-family: Courier New, Courier, monospace;">FromJSON </span>case; the code can be found in <a href="https://gist.github.com/danidiaz/2bf98df3799c33ee5e9f">this gist</a>.<br />
<br />
Some tips for defining these kinds of local instances:<br />
<br />
<ul>
<li>You never ever have to declare a <a href="http://hackage.haskell.org/package/reflection-1.5.1.1/docs/Data-Reflection.html#t:Reifies"><span style="font-family: Courier New, Courier, monospace;">Reifies</span></a> instance, this is done by the internal machinery of the reflection package, through some dark magic I don't understand, even if it's explained <a href="https://www.fpcomplete.com/user/thoughtpolice/using-reflection">here</a>.</li>
<li>Instead, you use <span style="font-family: Courier New, Courier, monospace;">Reifies </span>as a <i>precondition </i>for the instance you are actually declaring (<span style="font-family: Courier New, Courier, monospace;">FromJSON </span>in this case). You are expressing something like "whenever this phantom type <span style="font-family: Courier New, Courier, monospace;">s</span> reifies a typeclass dictionary at the type level, I can reflect it back and use the recovered dictionary to implement the methods of my instance".</li>
<li>The actual value passed to the <span style="font-family: Courier New, Courier, monospace;"><a href="http://hackage.haskell.org/package/reflection-1.5.1.1/docs/Data-Reflection.html#v:reflect">reflect</a> </span>function is ignored, it only serves to tell the function what type reifies the value we want to reflect. Assuming you have a <span style="font-family: Courier New, Courier, monospace;">Reifies s a</span> constraint, you can always pass something like <span style="font-family: Courier New, Courier, monospace;">Proxy :: Proxy s </span>to <span style="font-family: Courier New, Courier, monospace;">reflect </span>and obtain an <span style="font-family: Courier New, Courier, monospace;">a</span>.</li>
<li>At some point, you will need a small auxiliary function to convince the compiler that the phantom type in your datatype is the same as the phantom type in the <span style="font-family: Courier New, Courier, monospace;"><a href="http://hackage.haskell.org/package/base-4.7.0.1/docs/Data-Proxy.html#t:Proxy">Proxy</a> </span>supplied by <span style="font-family: Courier New, Courier, monospace;"><a href="http://hackage.haskell.org/package/reflection-1.5.1.1/docs/Data-Reflection.html#v:reify">reify</a></span>. Otherwise the <span style="font-family: Courier New, Courier, monospace;">Reifies </span>constraint won't be satisfied, and your instance won't kick in!</li>
<li>Notice that, thanks to parametricity, the phantom type in the <span style="font-family: Courier New, Courier, monospace;">Proxy </span>supplied by <span style="font-family: Courier New, Courier, monospace;">reify </span>can never escape the callback. So be sure to strip from your result any newtype that still carries the phantom type!</li>
</ul>
<div>
See also <a href="http://stackoverflow.com/questions/28649854/function-from-mappend-function-to-monoid-instance/28651952#28651952">this answer</a> on Stack Overflow.</div>
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-3574738917729948152014-12-23T01:16:00.000-08:002015-06-19T09:49:34.769-07:00Connecting to Denodo Virtual DataPort from GoPerhaps I can reuse the setup of my <a href="http://productivedetour.blogspot.com.es/2014/12/connecting-to-denodo-virtual-dataport.html">previous post</a> for another database connectivity experiment, this time from <a href="https://golang.org/">Go</a>.<br />
<br />
I have very little knowledge of Go. It seems like a pragmatic language with good tooling. And there exists a <a href="https://github.com/lib/pq">PostgreSQL driver written in pure Go</a> that I can use.<br />
<br />
The first step is to <a href="http://golang.org/doc/install#windows">install Go</a> and <a href="http://golang.org/doc/code.html">set up the environment</a>. Once ready, the PostgreSQL driver can be installed in the workspace with the command <span style="font-family: Courier New, Courier, monospace;">go get github.com/lib/pq</span>.<br />
<br />
Then we create a project named <span style="font-family: Courier New, Courier, monospace;">github.com/danidiaz/hellopq</span> in the workspace, with the following Go file:<br />
<br />
<code data-gist-id="a9bbcba7070c3af75f9f"></code>
The code was adapted from the one shown in <a href="https://gophercasts.io/lessons/4-postgres-basics">this video</a>. The connection parameters were taken from <a href="http://godoc.org/github.com/lib/pq">here</a>.<br />
<br />
Executing the program, it seems to work!<br />
<br />
But I have a remaining doubt: how to properly handle the nullability of the <span style="font-family: Courier New, Courier, monospace;">last_updated </span>column?<br />
<br />danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-25629590958256645312014-12-22T12:20:00.000-08:002015-06-19T09:49:14.566-07:00Connecting to Denodo Virtual DataPort from HaskellMy employer Denodo has released an "Express" version of its <a href="http://www.denodo.com/denodo-platform/denodo-express">data virtualization platform</a>. The Virtual DataPort component lets you do cool things like joining tables that reside in completely different databases (say, one table in Oracle and another in MySQL). And it comes with a boatload of connectors for a wide range of data sources.<br />
<br />
I'm interested in accessing all that data goodness from Haskell. There are a couple of ways of doing it.<br />
<br />
One would be to use Virtual DataPort's REST interface. That's a valid option and maybe the subject of another post.<br />
<br />
Another is to connect through the ODBC interface on port 9996. As it happens, the wire protocol aims to be compatible with that of PostgreSQL, so maybe I could just use Haskell's popular <a href="http://hackage.haskell.org/package/postgresql-simple">postgresql-simple</a> library. Let's try it out.<br />
<br />
<h3>
Musicbrainz</h3>
<br />
First, we need an underlying database instance that we can "wrap" with Virtual DataPort. Let's use the <a href="https://musicbrainz.org/">Musicbrainz</a> database, a perennial favorite for testing. We can <a href="https://musicbrainz.org/doc/MusicBrainz_Server/Setup">download it as a virtual machine</a> and run it on <a href="https://www.virtualbox.org/">Virtual Box</a>. I usually set the <a href="https://www.virtualbox.org/manual/ch06.html#natforward">guest networking to NAT</a> and only forward PostgreSQL's port, which is 5432.<br />
<br />
<h3>
Virtual DataPort</h3>
<br />
Then we download and install Denodo Express, start the Virtual DataPort server, and launch the graphical administration tool.<br />
<br />
From the administration tool's GUI, we have to import a few tables from the Musicbrainz database. First we create a JDBC data source:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqVm8aWDl1dZAT-Mej4LMgozrspCkwpSlrkGaXqjEGpxWWaVW0mjgQU6M9YvovlFXN_6rH12VvahN6G6QjcIpJ6rqDUQKtnhCdThmaCO8CI9uL1ovR7aDCdqb2xtvkEB1Q84jo0gCeUN0/s1600/musicbrainz_1.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="277" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqVm8aWDl1dZAT-Mej4LMgozrspCkwpSlrkGaXqjEGpxWWaVW0mjgQU6M9YvovlFXN_6rH12VvahN6G6QjcIpJ6rqDUQKtnhCdThmaCO8CI9uL1ovR7aDCdqb2xtvkEB1Q84jo0gCeUN0/s1600/musicbrainz_1.JPG" width="400" /></a></div>
<br />
(The Musicbrainz database is called <span style="font-family: Courier New, Courier, monospace;">musicbrainz_db</span>, the user/password is <span style="font-family: Courier New, Courier, monospace;">musicbrainz</span>/<span style="font-family: Courier New, Courier, monospace;">musicbrainz</span>.)<br />
<br />
And then import the <span style="font-family: Courier New, Courier, monospace;">artist_name</span> and <span style="font-family: Courier New, Courier, monospace;">release</span> tables:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijCQm_aJMpx7ALJFdNEVLmwZp-Cy3rYNoPdMH0Kwfp4pNoc9PsbAFlFIvZkhLQ0xhpixWH8ZhzHrjAsdcNvkJAZ10eECT2k1JbUfckJ0p8vMV1Ig9ICBPTAp9v3SpOIIPPm-Ox-o2knR8/s1600/musicbrainz_2.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="371" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijCQm_aJMpx7ALJFdNEVLmwZp-Cy3rYNoPdMH0Kwfp4pNoc9PsbAFlFIvZkhLQ0xhpixWH8ZhzHrjAsdcNvkJAZ10eECT2k1JbUfckJ0p8vMV1Ig9ICBPTAp9v3SpOIIPPm-Ox-o2knR8/s1600/musicbrainz_2.JPG" width="400" /></a></div>
<br />
<h3>
Haskell</h3>
<br />
Ok, now for the Haskell part. postgresql-simple depends on native libraries. In CentOS 7 for example, we'll have to install the package <span style="font-family: Courier New, Courier, monospace;">postgresql-devel</span> using yum, before invoking <span style="font-family: Courier New, Courier, monospace;">cabal install postgresql-simple</span>.<br />
<br />
Once we have the required dependencies, we can dabble with the following snippet (notice that we are connecting to Virtual DataPort, not directly to Musicbrainz):
<br />
<br />
<code data-gist-id="5e956df81262b488db2a"></code>
...and it works! A sweet stream of data flows from the Musicbrainz database, passes through Virtual DataPort and arrives at our Haskell client.<br />
<br />
And thanks to the virtualization capabilities of Virtual DataPort, that stream could potentially represent the combined flow of a number of affluents.
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-85883557550447427492014-11-14T10:39:00.000-08:002014-11-14T19:03:32.335-08:00Pawn shops, refrigerators, and contravariant functorsRecently, I learned (by <a href="http://hackage.haskell.org/package/contravariant-1.2/docs/Data-Functor-Contravariant-Compose.html">reading instance declarations in Haskell</a>) that the composition of contravariant functors is covariant.<br />
<br />
In <a href="http://www.infoq.com/presentations/covariance-contravariance-joy-of-coding-2014">this</a> talk (around 27:30) Erik Meijer tells a colorful analogy for contravariance in subtyping. The analogy involves trashcans, which apparently are contravariant. I wonder if I can find a similar analogy for the case of composition, because I find it difficult to gain an intuition for it.<br />
<br />
So, consider bananas. Bananas are a type of fruit.<br />
<br />
Consider refrigerators as well. There are different types of refrigerators. Some have a technology advanced enough to freeze any fruit, but some are more modest and can only freeze bananas.<br />
<br />
The refrigerators that can freeze any fruit are a subtype of the refrigerators that can freeze bananas. Because, any time you need to freeze a banana, you can freeze it in one of the refrigerators than can handle any kind of fruit. <br />
<br />
In other words, refrigerators are contravariant.<br />
<br />
Now consider pawn shops. Paws shops are contravariant as well: anything you can sell to a pawn shop that only takes rings, you can sell to a pawn shop that takes any jewelry. The pawn shops that take any jewelry are a subtype of the pawn shops that take rings.<br />
<br />
There are also pawn shops for refrigerators. For example pawn shops for refrigerators that can freeze any fruit, or pawn shops for refrigerators that can freeze bananas. (Yes, they are quite specialized pawn shops, but bear with me.)<br />
<br />
The pawnbrokers are very meticulous. Before accepting a refigerator for sale, they put inside it a viand of the type associated with the pawn shop, to check that the refrigerator indeed works.<br />
<br />
Can you sell to the pawn shop of refrigerators that freeze bananas everything you could sell to the pawn shop of refrigerators that freeze any fruit? The answer is yes. You take the refrigerator that freezes any fruit to the pawn shop, the pawnbroker puts a banana on it, and it gets frozen. Deal!<br />
<br />
So pawn shops for refrigerators are covariant on the type of viands that the refrigerators can freeze.<br />
<br />
Whew, that was convoluted.danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-31517132774741144522014-11-10T23:37:00.000-08:002014-11-10T23:42:43.405-08:00Two new "validation" applicativesThere exists an Either-like Applicative (usually called "Validation") that either collects <b>all </b>the errors, or returns a success. This is different from the Monad instance of Either, that stops at the first error encountered.<br />
<br />
The type can be found at the <a href="http://hackage.haskell.org/package/validation">validation</a> package. However, that package incurs on a heavy <a href="http://hackage.haskell.org/package/lens">lens</a> dependency.<br />
<br />
Recently, the type has cropped up without the lens dependency in both transformers (as the <a href="http://hackage.haskell.org/package/transformers-0.4.2.0/docs/Control-Applicative-Lift.html#g:2">Errors</a> type synonym) and either (as <a href="http://hackage.haskell.org/package/either-4.3.2/docs/Data-Either-Validation.html">Validation</a>).<br />
<br />
The version in the <a href="http://hackage.haskell.org/package/either-4.3.2">either</a> package has a more precise type, as it only requires the error values to form a <a href="http://hackage.haskell.org/package/semigroups-0.15.4/docs/Data-Semigroup.html#">Semigroup</a>, but not necessarily a Monoid. So you can use a <a href="http://hackage.haskell.org/package/semigroups-0.15.4/docs/Data-List-NonEmpty.html">NonEmpty</a> to accumulate errors.danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-44894284094130372702014-10-23T23:59:00.000-07:002014-10-24T06:47:40.760-07:00conceit 0.2.1.0I have released a <a href="http://hackage.haskell.org/package/conceit">new version</a> of the <a href="http://productivedetour.blogspot.com.es/2014/10/conceit-0100.html">conceit</a> package with the following changes:<br />
<br />
The <span style="font-family: Courier New, Courier, monospace;">Applicative </span>instance now doesn't require those ugly <span style="font-family: Courier New, Courier, monospace;">(Show e, Applicative e)</span> constraints on the error type.<br />
<br />
There's a <span style="font-family: Courier New, Courier, monospace;">Monad</span> instance for <span style="font-family: Courier New, Courier, monospace;">Conceit</span>. I initially made the <span style="font-family: Courier New, Courier, monospace;">>></span> operator concurrent, like <span style="font-family: Courier New, Courier, monospace;">*></span>, but that was a <a href="http://stackoverflow.com/questions/26522053/is-my-concurrency-monad-a-valid-instance-of-monadthrow">bad idea</a>. In the end, the <span style="font-family: Courier New, Courier, monospace;">Monad </span>instance has sequential operations and the <span style="font-family: Courier New, Courier, monospace;">Applicative</span> concurrent ones, like it happens in <span style="font-family: Courier New, Courier, monospace;"><a href="http://hackage.haskell.org/package/haxl">Haxl</a></span>.<br />
<br />
There are also <span style="font-family: Courier New, Courier, monospace;"><a href="http://hackage.haskell.org/package/exceptions-0.6.1/docs/Control-Monad-Catch.html">MonadThrow</a></span>, <span style="font-family: Courier New, Courier, monospace;">MonadCatch </span>and <span style="font-family: Courier New, Courier, monospace;">MonadError </span>instances. The first two work throwing and catching exceptions from <span style="font-family: Courier New, Courier, monospace;">IO</span>, the last one works more like <span style="font-family: Courier New, Courier, monospace;">ExceptT</span>.<br />
<br />
A special run function was added for when the error is "impossible": <span class="kt" style="background-color: white; box-sizing: border-box; color: #445588; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; font-weight: bold; line-height: 13.4399995803833px; white-space: pre;">Conceit</span><span style="background-color: white; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 13.4399995803833px; white-space: pre;"> </span><span class="kt" style="background-color: white; box-sizing: border-box; color: #445588; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; font-weight: bold; line-height: 13.4399995803833px; white-space: pre;">Void</span><span style="background-color: white; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 13.4399995803833px; white-space: pre;"> </span><span class="n" style="background-color: white; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 13.4399995803833px; white-space: pre;">a</span><span style="background-color: white; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 13.4399995803833px; white-space: pre;"> </span><span class="ow" style="background-color: white; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; font-weight: bold; line-height: 13.4399995803833px; white-space: pre;">-></span><span style="background-color: white; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 13.4399995803833px; white-space: pre;"> </span><span class="kt" style="background-color: white; box-sizing: border-box; color: #445588; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; font-weight: bold; line-height: 13.4399995803833px; white-space: pre;">IO</span><span style="background-color: white; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 13.4399995803833px; white-space: pre;"> </span><span class="n" style="background-color: white; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 13.4399995803833px; white-space: pre;">a. </span>This makes easier to use <span style="font-family: Courier New, Courier, monospace;">Conceit </span>in place of <span style="font-family: Courier New, Courier, monospace;">Concurrently</span>.<br />
<br />
The <a href="https://github.com/danidiaz/conceit/blob/hackage-0.2.1.0/src/Control/Concurrent/Conceit.hs">internals </a>of this new version of <span style="font-family: Courier New, Courier, monospace;">conceit </span>have been copied from <a href="http://hackage.haskell.org/package/async-2.0.1.6/docs/src/Control-Concurrent-Async.html#race">those of </a><span style="font-family: Courier New, Courier, monospace;"><a href="http://hackage.haskell.org/package/async-2.0.1.6/docs/src/Control-Concurrent-Async.html#race">Concurrently</a> </span>in Simon Marlow's <span style="font-family: Courier New, Courier, monospace;">async</span> package, with modifications to support the new behaviour.<br />
<br />danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-66065357614040513792014-10-19T08:18:00.000-07:002014-10-19T08:18:57.088-07:00Colchis, yet another JSON-RPC 2.0 client<p>There's no <a href="http://hackage.haskell.org/packages/search?terms=json-rpc">shortage</a> of <a href="http://www.jsonrpc.org/specification">JSON-RPC 2.0</a> libraries on Hackage, as any cursory search will show. I have just added my own, called <a href="http://hackage.haskell.org/package/colchis">Colchis</a>.</p>
</p>It is a pipes-based client that makes use of bidirectional pipes. It doesn't have a lot of features, in particular the only supported transport is raw TCP. I think HTTP transport support would be easy to add, but I don't have the need right now. No notifications or batched requests, either.</p>
<p>My aim is to be able to communicate with <a href="https://github.com/briandilley/jsonrpc4j">jsonrpc4j</a> servers in "streaming" mode.</p>
<p>Check <a href="https://github.com/danidiaz/colchis/blob/hackage-0.1.0.0/examples/Main.hs">the examples folder in the repo</a> for some examples of usage.</p>danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-66186334157977771612014-10-06T13:12:00.000-07:002014-10-06T13:12:19.453-07:00conceit 0.1.0.0<p>I have updloaded to Hackage a tiny package called <a href="http://hackage.haskell.org/package/conceit">conceit</a>. It contains a slight variation on the <a href="http://hackage.haskell.org/package/async-2.0.1.6/docs/Control-Concurrent-Async.html#t:Concurrently">Concurrently</a> type from the <a href="http://hackage.haskell.org/package/async">async </a>package.</p>
<p>Concurrently is hugely useful. A instance of Applicative, its <code><*></code> executes two IO actions concurrently (duh!) and, if one of the threads throws an exception, the other one is killed before re-throwing the exception. Very handy to ensure proper cleanup.</p>
<p><a href="http://hackage.haskell.org/package/conceit">Conceit </a>is similar to Concurrently, but the IO actions return an Either value. If both actions return with Right, the return values are combined. But if one of the actions returns with Left, the other action is immediately terminated and the Left value is returned. One could say that Conceit behaves like <a href="http://hackage.haskell.org/package/async-2.0.1.6/docs/Control-Concurrent-Async.html#v:race">race</a> for errors and like Concurrently for successful return values.</p>
<p>A <a href="http://hackage.haskell.org/package/bifunctors-4.1.1.1/docs/Data-Bifunctor.html">Bifunctor</a> instance is provided to help "massage" the errors.</p>danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-27413055794373660002014-10-02T13:26:00.000-07:002014-10-02T13:26:18.716-07:00process-streaming 0.6.0.0<p>I have released (a few days ago already) version <a href="http://hackage.haskell.org/package/process-streaming-0.6.0.0">0.6.0.0</a> of <a href="http://hackage.haskell.org/package/process-streaming">process-streaming</a>, my library of <a href="http://hackage.haskell.org/package/pipes">pipes</a>-based helpers built on top of the <a href="http://hackage.haskell.org/package/process">process</a> package.</p>
<p>The API of version <a href="http://hackage.haskell.org/package/process-streaming-0.3.0.0">0.3.0.0</a> proved to be too convoluted, with bloated and obscure function signatures. Hopefully the API for the new version is more intuitive.</p>
<p>The central abstraction if that of a <a href="http://hackage.haskell.org/package/process-streaming-0.6.0.0/docs/System-Process-Streaming.html#g:4">Siphon</a>. A Siphon represents a computation that either drains a <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes-Core.html#t:Producer">Producer</a> completely, or fails early aborting the consumption of the Producer. stdout and stderr can only be consumed through Siphons. Siphons can be created out of regular <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes.html#g:3">Consumers</a>, <a href="http://hackage.haskell.org/package/pipes-4.1.2/docs/Pipes-Prelude.html#g:4">pipes folds</a>, or <a href="http://hackage.haskell.org/package/pipes-parse-3.0.2/docs/Pipes-Parse.html#t:Parser">Parsers</a> from <a href="http://hackage.haskell.org/package/pipes-parse-3.0.2">pipes-parse</a>.</p>
<p>Why do we need Siphons? When consuming both stdin and stderr of an external process, it is important that the two are drained to completion, because otherwise the process may block due to an output buffer that is not being read and fills up.</p>
<p>Siphons have an Applicative instance that "forks" a producer and feeds it to two computations. This Applicative instance made the support for <a href="http://hackage.haskell.org/package/process-streaming-0.6.0.0/docs/System-Process-Streaming.html#g:6">branching pipelines of processes</a> easy to implement.</p>
<p>The <a href="https://github.com/danidiaz/process-streaming/blob/hackage-0.6.0.0/tests/test.hs">test suite</a> contains several examples of usage.</p>danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-7879631597697129042014-06-30T14:27:00.000-07:002014-06-30T14:59:33.271-07:00The lazy Writer monad<p>I found an interesting example of the <a href="http://blog.melding-monads.com/2009/12/30/fun-with-the-lazy-state-monad/">lazy State monad</a> that uses "head recursion".</p>
<p>I tried to adapt the example for the lazy Writer monad but it proved difficult. If you naively consume the head of the infinite accumulator, it will hang, even with the lazy version of the monad:</p>
<code data-gist-id="c76e45da271c2bff1c16" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="1-14"></code>
<p>The trick is to use <code>Dual</code> from <code>Data.Monoid</code>:</p>
<code data-gist-id="c76e45da271c2bff1c16" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="16-30"></code>
<p>Maybe I suffer from a failure of imagination, but I can't think of any practical problem in which the lazy Writer monad offers an advantage over the strict version.</p>danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-36927515980648965582014-06-09T14:19:00.000-07:002014-07-06T07:56:34.437-07:00process-streaming 0.3.0.0<p>I have released version <a href="http://hackage.haskell.org/package/process-streaming-0.3.0.0">0.3.0.0</a> of <a href="http://hackage.haskell.org/package/process-streaming">process-streaming</a>, my library of <a href="http://hackage.haskell.org/package/pipes">pipes</a>-based helpers built on top of the <a href="http://hackage.haskell.org/package/process">process</a> package.</p>
<p>It contains <a href="http://hackage.haskell.org/package/process-streaming-0.3.0.0/changelog">breaking changes</a>. Some functions have new names, and a few newtypes have been introduced in order to hide unnecessarily complex signatures. Hopefully the changes make the library a bit more intuitive.</p>
<p>You might find this library useful if:</p>
<ul>
<li>You want an easy way to consume the standard streams of an external process using the tools provided by the pipes ecosystem.</li>
<li>You want concurrent, streaming access to both the stdout and stderr of an external process, without fear of deadlocks caused by full output buffers.</li>
<li>You want to consume stdout and stderr combined in a single stream.</li>
<li>You want to be relieved of tedious bookkeeping like: automatically killing the external process on the face of errors and exceptions, ensuring the termination of threads spawned for concurrent reads, and so on.</li>
</ul>
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-75660204783813595052014-05-12T13:19:00.000-07:002014-05-12T23:28:16.662-07:00The IO monad has a non-strict bind<p>The Maybe monad has a bind function that is strict in its arguments:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="1-2"></code>
<p>The IO monad however has a non-strict bind function:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="2-4"></code>
<p>And so does the strict State monad:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="5-7"></code>
<p>It's easy to see in the <a href="http://hackage.haskell.org/package/transformers-0.4.1.0/docs/src/Control-Monad-Trans-State-Strict.html#State">source code</a>:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="8-10"></code>
<p>To reduce <code>m >>= k</code> to <a href="http://stackoverflow.com/questions/6872898/haskell-what-is-weak-head-normal-form">Weak Head Normal Form</a>, you only need to go as far as the <code>StateT</code> constructor; you don't need to touch any of the parameters. I suppose something similar happens with IO.</p>
<p>What's so strict then about the IO monad and the <i>strict</i> State monad? Their run functions. This:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="11-13"></code>
<p>As opposed to this:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="14-16"></code>
<p>Notice how in the strict case putting the expression in WHNF with <code>seq</code> is enough to trigger the exception.</p>
<p>Of course, with IO we don't have a explicit run function (one that isn't evil, I mean). We just put the IO action into <code>main</code>.</p>
<p>Notice however that even the strict State monad is not <i>too</i> strict:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="17-21"></code>
<p>This doesn't trigger an exception, either:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="22-24"></code>
<p>But this does:</p>
<code data-gist-id="8d4fe599430198e5b06e" data-gist-hide-footer="true" data-gist-hide-line-numbers="true" data-gist-line="25-27"></code>
<p>Some good links about laziness <a href="http://apfelmus.nfshost.com/blog/2013/08/21-space-invariants.html">here</a>, <a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">here</a>, <a href="http://blog.ezyang.com/2011/04/evaluation-on-the-haskell-heap/">here</a>, <a href="http://blog.ezyang.com/2011/04/io-evaluates-the-haskell-heap/">here</a>, <a href="http://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/">here</a> and <a href="http://users.aber.ac.uk/afc/stricthaskell.html">here</a>.</p>
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-58291648756640604412014-05-05T14:27:00.000-07:002014-05-08T23:02:10.664-07:00Understanding representable functors<p>Representable functors are put to good use in the <a href="http://hackage.haskell.org/package/linear-1.10.1.1">linear</a> library, and they can be a useful tool in other contexts. Here's a (hopefully not completely misleading) post on the subject.</p>
<h1>The general idea</h1>
<p>Consider the functor that carries a type <code>a</code> to the type of infinite lists of elements of type <code>a</code>. Let's call that functor <code>Stream</code>. So <code>Stream Bool</code> is the type of infinite lists of boolean values, <code>Stream Char</code> is the type of infinitely long strings, and so on.</p>
<p>There is a type with which the <code>Stream</code> functor has a special relationship: the type <code>ℕ</code> of natural numbers. Think about it: any value of type <code>Stream a</code> can be alternately represented by a function of type <code>ℕ -> a</code>. To recover the stream, we just have iterate over the naturals, applying the function at each step. Conversely, we can regard a <code>Stream a</code> value as a "memoized" version of a <code>ℕ -> a</code> function. We can recover the function by indexing on the stream.</p>
<p>There are other functors that have a similar "special relationship" with a certain type. That type need not be <code>ℕ</code>. Consider the following very simple functor:</p>
<code data-gist-id="c20833dd5bb88ce543b4" data-gist-hide-footer="true"></code>
<p>This <code>Pair</code> functor has a special relationship with the <code>Bool</code> type. A value of type <code>Pair a</code> can be alternately represented by a function <code>Bool -> a</code>. Conversely, we can regard a value of type <code>Pair a</code> as a memoized or tabulated version of a <code>Bool -> a</code> function.</p>
<p>There seems to be a pattern here!</p>
<p>One more example: the <code>Identity</code> functor is represented by the trivial unit type <code>()</code>, that has only one value and carries no information. <code>Identity a</code> is just <code>a</code>, so there are no "positions" over which to "range", so to speak.</p>
<h1>Composition, products, sums</h1>
<p>Functors have the nice property that the composition of two functors is still a functor. We can ask ourselves if the composition of two representable functors is still representable. The answer is yes.</p>
<p>The <a href="http://hackage.haskell.org/package/transformers-0.4.0.0/docs/Data-Functor-Compose.html">composition</a> (think of it as "nesting") of two functors is represented by the product of the representations of the original functors. Think of the type <code>Stream (Stream a)</code>. It is like an infinite bidimensional array of <code>a</code> values. To index into it, we need two coordinates. So it is represented by <code>(ℕ,ℕ)</code>.</p>
<p>The <a href="http://hackage.haskell.org/package/transformers-0.4.0.0/docs/Data-Functor-Product.html">product</a> of two functors is a functor as well. And the product of two representable functors is again representable! It is represented by the <a href="http://hackage.haskell.org/package/base-4.7.0.0/docs/Prelude.html#t:Either">sum</a> of the representations of the original functors. Supose you have a pair <code>(Stream a, Stream a)</code>. If we want to index into it, we must first choose a side, and then drill into the stream of that side. So the product is represented by <code>Either ℕ ℕ</code>.</p>
<p>A third way of combining functors is <a href="https://hackage.haskell.org/package/transformers-0.4.0.0/docs/Data-Functor-Sum.html">summing them</a>. Is a sum of representable functors representable? I don't know about the theory, but intuitively the answer seems to be no. We can't "index" on sum types, because we might attempt to target a branch that isn't there!</p>
<h1>The Haskell implementation</h1>
<p>The <a href="http://hackage.haskell.org/package/adjunctions-4.0.3/docs/Data-Functor-Rep.html#g:1">Representable</a> typeclass can be found in module <a href="http://hackage.haskell.org/package/adjunctions-4.0.3/docs/Data-Functor-Rep.html">Data.Functor.Rep</a> of the <a href="http://hackage.haskell.org/package/adjunctions-4.0.3">adjunctions</a> package. It has the <a href="http://hackage.haskell.org/package/distributive-0.4/docs/Data-Distributive.html#t:Distributive">Distributive</a> class as a prerrequisite. <code>Distributive</code> can be understood as the class of functors with a "fixed shape" whose values can be zipped together easily.</p>
<p>If you <a href="http://hackage.haskell.org/package/adjunctions-4.0.3/docs/src/Data-Functor-Rep.html#index">check the source</a>, you'll see that the <a href="http://www.haskell.org/haskellwiki/GHC/Type_families">type families</a> extension is used to associate each instance of <code>Representable</code> with its representation. It is instructive to explore which correspond to which. For example, <code>Rep Identity = ()</code> as we have alredy mentioned.</p>
<p>You might wonder, why is <code>Stream</code> missing from the list of instances, after having been used many times as an example? It's there, actually, but you have to squint a little.</p>
<p>The <code>Stream</code> functor can be defined as <code>Cofree Identity</code> (the definition of <code>Cofree</code> is <a href="http://hackage.haskell.org/package/free-4.5/docs/Control-Comonad-Cofree.html#t:Cofree">here</a>). <code>Cofree Identity</code> is represented by sequences of unit <code>()</code> values. And the type of sequences of <code>()</code> is isomorphic to the natural numbers.</p>
danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-47550254068016522682014-05-03T02:09:00.000-07:002014-05-03T05:51:36.149-07:00Applicative vs. Monad<p>In an <a href="http://www.haskell.org/haskellwiki/Typeclassopedia#Applicative">Applicative</a>, effects build the railroad upon which the locomotive of function application will travel. All the effects take place while building the railroad, not when the locomotive moves. The locomotive cannot change its course in any way.</p>
<p>A <a href="http://www.haskell.org/haskellwiki/Typeclassopedia#Monad">Monad</a> is like having a locomotive in a railroad which is still under construction. Passengers can actually yell to the construction crew a few meters ahead to tell them things like "I like the scenery on this side, please lay the tracks a bit more towards the right" or "you can stop laying tracks, I get out right here". Of course, for this strange railway, the company can't provide a timetable or a fixed list of stops that can be checked before embarking on the train.</p>danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-77895328532496730502014-02-23T12:43:00.001-08:002014-02-24T11:11:46.115-08:00process + pipes = process-streaming<p>There are a number of good libraries for launching external processes already in Hackage. Basic libraries like <a href="http://hackage.haskell.org/package/process">process</a>, and libraries that build on top of it like <a href="http://hackage.haskell.org/package/shelly">shelly</a> and <a href="http://hackage.haskell.org/package/process-conduit">process-conduit</a> (there is also module <a href="http://hackage.haskell.org/package/io-streams-1.1.4.2/docs/System-IO-Streams-Process.html">System.IO.Streams.Process</a> from <a href="http://hackage.haskell.org/package/io-streams-1.1.4.2">io-streams</a>).</p>
<p>An official <b>pipes-process</b> package hasn't come out yet. After working recently with Ruby's <a href="http://www.ruby-doc.org/stdlib-2.1.0/libdoc/open3/rdoc/Open3.html">Open3</a> package, and becoming inspired by <a href="https://groups.google.com/forum/#!topic/haskell-pipes/JFfyquj5HAg">this thread</a> in the <a href="https://groups.google.com/forum/#!forum/haskell-pipes">Haskell Pipes Google group</a>, I decided to cobble together my own experiment. <a href="http://hackage.haskell.org/package/process-streaming">process-streaming</a> is the result (<a href="https://github.com/danidiaz/process-streaming">git repo here</a>).</p>
<p>I wanted to scratch a number of itches:</p>
<ul>
<li>To my knowledge, neither <b>shelly</b> nor <b>process-conduit</b> provide concurrent streaming access to <i>both</i> the <i>stdout</i> and the <i>stderr</i> of a process, which is sometimes necessary. (<b>shelly</b> does provide direct access to the handles, but you have to orchestrate the concurrency by yourself.)</li>
<li><b>shelly</b> and <b>process-conduit</b> use exceptions for signaling errors. This makes for simpler signatures. I wanted to test if a purely Either-based approach to errors could work without making the signatures excessively complicated.</li>
<li>Combining <i>stdout</i> with <i>stderr</i> is a frequent use case with some subtleties in the implementation. You have to be careful not to <a href="http://unix.stackexchange.com/questions/114182/can-redirecting-stdout-and-stderr-to-the-same-file-mangle-lines
">mangle lines</a>, and also ensure that both streams are drained continuously (because otherwise you can get yourself into a <a href="https://groups.google.com/d/msg/haskell-pipes/JFfyquj5HAg/aTgsWckCzsUJ
">blocking scenario</a>).</li>
<li>Besides using plain <a href="http://hackage.haskell.org/package/pipes-4.1.0/docs/Pipes.html#g:3">Consumers</a>, it should be easy to consume <i>stdout</i> and <i>stderr</i> using folds from <a href="http://hackage.haskell.org/package/pipes-4.1.0/docs/Pipes-Prelude.html#g:4">Pipes.Prelude</a> (and <a href="http://hackage.haskell.org/package/pipes-text">pipes-text</a> and <a href="http://hackage.haskell.org/package/pipes-bytestring">pipes-bytestring</a> and <a href="http://hackage.haskell.org/package/pipes-group">pipes-group</a>) and also parsers from the <a href="http://hackage.haskell.org/package/pipes-parse">pipes-parse</a> package. And it would be nice if <a href="http://stackoverflow.com/questions/21691252/join-two-consumers-into-a-single-consumer-that-returns-multiple-values/21695919#21695919">two parsers could be run in parallel</a> over the same Producer.</li>
</ul>
The haddock documentation for the <code>System.Process.Streaming</code> module is <a href="http://hackage.haskell.org/package/process-streaming-0.0.1/docs/System-Process-Streaming.html">here</a>. A tutorial with some examples can be found <a href="http://hackage.haskell.org/package/process-streaming-0.0.1/docs/System-Process-Streaming-Tutorial.html">here</a>.
<p>If nothing else, this experiment has served me to understand the pipes ecosystem a little better. I really like the <i>pipes-text</i> approach for handling decoding leftovers (putting them in the return values of pipes) and the <a href="http://hackage.haskell.org/package/pipes-text-0.0.0.9/docs/Pipes-Text.html#v:lines">FreeT-based</a> <a href="http://hackage.haskell.org/package/pipes-group">approach</a> for parsing lines without never having to keep a whole line in memory at any time.</p> danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-64551466825014711722013-11-30T03:21:00.001-08:002013-11-30T03:21:55.214-08:00Compiled Heist insight, with no Snap in sight<p>A few weeks ago, I wrote a tutorial on <a href="http://snapframework.com/docs/tutorials/compiled-splices">compiled Heist</a> at <a href="https://www.fpcomplete.com/school">School of Haskell</a>, but for some reason I forgot to post the link. <a href="https://www.fpcomplete.com/user/danidiaz/compiled-heist-insight-with-no-snap-in-sight?show=tutorials">Here it is</a>.</p>danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-41851244920080004522013-11-18T05:18:00.002-08:002013-11-19T07:23:28.095-08:00My solution to the Twitter waterflow problem<p>The Twitter waterflow problem originated in <a href="http://qandwhat.apps.runkite.com/i-failed-a-twitter-interview/">this post</a>. After becoming aware of the existence of functional solutions in <a href="http://chrisdone.com/posts/twitter-problem-loeb">this other post</a>, I decided to roll my own in Haskell before looking at them.</p>
<p>It turned out to be more tricky than I had expected. The first version of the algorithm was hideously ugly and verbose, and I couldn't make it to work. I tried a new approach and came up with the following:</p>
<script src="https://gist.github.com/danidiaz/7518431.js"></script>
<p>I haven't tested it extensively but I think it works.</p>
<p>I "compress" consecutive columns of equal height, so instead of working with a list of heights, I work with a list of <code>(height,width)</code> pairs. The initial list with uncompressed columns is created in the <code>(zip l (repeat 1))</code> expression.</p>
<p>I traverse the list from left to right, carrying an accumulator parameter for the volume, and also an axiliary list of the "high" columns visited so far. These columns can potentially enclose water if another sufficiently high column is encountered on the other side of a "valley".</p>
<p>The algorithm ensures that the columns in the auxiliary list (a stack, really) are strictly increasing in height, and have all been "compressed".</p>
<p>Lines 3-4 purge columns that go "uphill" from the left border, since these columns can't possibly contain a valley. Once we find the first "peak", we put it into the auxiliary list.</p>
<p>Line 7 compresses "valley floors".</p>
<p>Line 8 identifies "valleys" whose floors have already been compressed. We find how much water that portion of the valley will hold by multiplying the width of the floor with the height of the lowest wall. We add the volume to the accumulator and then fill that portion of the valley with concrete (so to speak) to avoid double-counting that volume in future iterations.</p>danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-90710911049582267342013-05-31T08:26:00.000-07:002013-05-31T10:33:09.259-07:00Haskell equivalents of some Clojure formsWhile trying to learn Clojure, I keep confusing <b>doall</b>, <b>dorun</b>, and <b>doseq</b>. What are their differences, and when to use each one?<br />
<br />
The functional language I know best is Haskell, so I will find what Haskell functions correspond to the Clojure ones, using <a href="http://www.haskell.org/hoogle/">Hoogle</a>.<br />
<br />
<h2>
<b>doall.</b> </h2>
<br />
The documentation <a href="http://clojuredocs.org/clojure_core/clojure.core/doall">says</a>:<br />
<blockquote class="tr_bq">
When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time. </blockquote>
Ok, we have a list where each element is produced through a side effect. Using <b>doall </b>we perform all these effects "up front" and get the whole list as a result.<br />
<br />
In Haskell, values which are obtained through side effects are "tagged" with the <span style="font-family: Courier New, Courier, monospace;">IO </span>monad, to distinguish them from pure values. A value of type <span style="font-family: Courier New, Courier, monospace;">IO a</span> could be understood as "a description of a program that, when run, produces a value of type <span style="font-family: Courier New, Courier, monospace;">a</span>".<br />
<br />
We want a function with a type like this:<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[IO a] -> IO [a] </span></blockquote>
<span style="font-family: Courier New, Courier, monospace;">[]</span> is the type constructor for lists. <span style="font-family: Courier New, Courier, monospace;">-></span> means a function from some type to another. For simplicity, in this post we only deal with lists whose elements are all of the same type.<br />
<br />
We put the signature in Hoogle, we find the following<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">sequence :: Monad m => [m a] -> m [a] </span></blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">Evaluate each action in the sequence from left to right, and collect the results.</span></blockquote>
The type is more general but, when <span style="font-family: Courier New, Courier, monospace;">m </span>is <span style="font-family: Courier New, Courier, monospace;">IO</span>, this is the function we are looking for.<br />
<br />
<h2>
<b>dorun.</b> </h2>
<br />
The documentation says:<br />
<blockquote class="tr_bq">
When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil.</blockquote>
In Haskell, functions which are executed only for side effects return values of type <span style="font-family: Courier New, Courier, monospace;">()</span>. There is only one such value, also named <span style="font-family: Courier New, Courier, monospace;">()</span>. It's roughly similar to <span style="font-family: Courier New, Courier, monospace;">void </span>in C and Java.<br />
<br />
Let's then search for the signature<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[IO a] -> IO ()</span></blockquote>
We find<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">sequence_ :: Monad m => [m a] -> m () </span></blockquote>
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">Evaluate each action in the sequence from left to right, and ignore the results.</span></blockquote>
The trailing underscore is a notational convention. It means that this is a function that behaves like the one without the underscore, but ignores the return value.<br />
<br />
<h2>
<b>doseq.</b> </h2>
<br />
The documentation says:<br />
<blockquote class="tr_bq">
Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by "for". Does not retain the head of the sequence. Returns nil.</blockquote>
Ok, it seems that now the values in the input list are "pure", but we want to apply an effectful function to each one of them. And we do not care about the return value.<br />
<br />
So we must search Hoogle for something like<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">[a] -> (a -> IO b) -> IO () </span></blockquote>
We find<br />
<blockquote class="tr_bq">
<span style="font-family: Courier New, Courier, monospace;">forM_ :: Monad m => [a] -> (a -> m b) -> m ()</span></blockquote>
So that's it. <b>doall </b>is <b>sequence</b>, <b>dorun </b>is <b>sequence_</b>, <b>doseq </b>is <b>forM_</b>. I won't confuse them anymore!<br />
<br />
A good introduction to Haskell IO can be found <a href="http://www.haskellforall.com/2013/01/introduction-to-haskell-io.html">here</a>.danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0tag:blogger.com,1999:blog-7349130750352499831.post-28504026593272622522012-12-31T07:18:00.001-08:002013-01-02T14:53:43.737-08:00Evaluating probabilistic cellular automata is comonadic, too! (part II)<br />
Part I is <a href="http://productivedetour.blogspot.com.es/2012/12/evaluating-probabilistic-cellular.html">here</a>. The complete code is <a href="https://gist.github.com/4413623">here</a>.<br />
<br />
We have defined our CA datatype and a local update rule for it. Since our CA is probabilistic, the update rule has a monadic effect in the <a href="http://hackage.haskell.org/packages/archive/MonadRandom/0.1.8/doc/html/Control-Monad-Random.html#t:Rand">Rand</a> monad.<br />
<br />
To perform a "global update" of the CA, we pass the current CA state and the local update rule to the <a href="http://hackage.haskell.org/packages/archive/comonad/3.0.0.2/doc/html/Control-Comonad.html#v:extend">extend</a> function of <span style="font-family: Courier New, Courier, monospace;">Comonad</span>:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>extend localRule ca :: EnvT Probs U (Rand StdGen Bool)</span><br />
<br />
The returning type is almost, but not quite, what we need. We now have a CA in which each cell is a monadic random effect. What we would like is to have the whole CA inside the Rand monad, so that a single call to <span style="font-family: Courier New, Courier, monospace;">runRand</span> or <span style="font-family: Courier New, Courier, monospace;">evalRand</span> gives us a value of <span style="font-family: Courier New, Courier, monospace;">EnvT Probs U Bool</span>. We need a way to aggregate the monadic effects of each singular cell into a global monadic effect for the whole CA.<br />
<br />
This is similar to the problem of transforming a list of IO actions into an IO action that returns a list. List is an instance of <a href="http://www.haskell.org/haskellwiki/Typeclassopedia#Traversable">Traversable</a>, so we can use the <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html#v:sequence">sequence</a> function on it. Likewise, we must make our type U an instance of <span style="font-family: Courier New, Courier, monospace;">Traversable</span>.<br />
<br />
The easiest way is to have the instance derived for you automatically. Just use the <a href="http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/deriving.html">DeriveTraversable</a> extension and add <span style="font-family: Courier New, Courier, monospace;">Traversable </span>to the <span style="font-family: Courier New, Courier, monospace;">deriving </span>clause when declaring the U datatype.<br />
<br />
But it doesn´t work. More precisely, it works only for one half of the universe! I wanted to print the CA's new state, 8 cells around the center (the <span style="font-family: Courier New, Courier, monospace;">showca</span> function is defined in the <a href="https://gist.github.com/4413623">gist</a>):<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> putStrLn . showca 8 </span><br />
<span style="font-family: Courier New, Courier, monospace;"> . lower </span><br />
<span style="font-family: Courier New, Courier, monospace;"> . flip evalRand (mkStdGen 7) </span><br />
<span style="font-family: Courier New, Courier, monospace;"> . sequence </span><br />
<span style="font-family: Courier New, Courier, monospace;"> $ extend localRule ca</span><br />
<br />
This printed only the left side of the universe. When it tried to print the first cell to the right, the whole computation just hanged. Why?<br />
<br />
<a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html#v:sequence">sequence</a> is defined in terms of <a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Traversable.html#v:traverse">traverse</a>. The default definition provided by the compiler first traverses the left side of the universe, then the center cell and the right side last. The <span style="font-family: Courier New, Courier, monospace;">StdGen</span> generator is threaded throughout. But each side is infinite; when traversing the left side, we can get the updated generator to use on the right side only after an infinite number of steps. Laziness doesn't help here, because there is a data dependency.<br />
<br />
This stumped me for a while, but finally I came up with an alternate version of <span style="font-family: Courier New, Courier, monospace;">traverse </span>which doesn't suffer this problem:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"> instance Traversable U where</span><br />
<span style="font-family: Courier New, Courier, monospace;"> traverse f (U lstream focus rstream) = </span><br />
<span style="font-family: Courier New, Courier, monospace;"> let pairs = liftA unzip </span><br />
<span style="font-family: Courier New, Courier, monospace;"> . sequenceA . fmap (traversepair f) </span><br />
<span style="font-family: Courier New, Courier, monospace;"> $ zip lstream rstream </span><br />
<span style="font-family: Courier New, Courier, monospace;"> traversepair f (a,b) = (,) <$> f a <*> f b</span><br />
<span style="font-family: Courier New, Courier, monospace;"> rebuild c (u,v) = U u c v</span><br />
<span style="font-family: Courier New, Courier, monospace;"> in rebuild <$> f focus <*> pairs</span><br />
<br />
The trick is to zip the two streams together before traversing them, and unzip them afterwards inside the monad. This way, accessing the value in the first cell to the right doesn't require an infinite number of steps.<br />
<br />
That solved, there is still one problem left. When we use <span style="font-family: Courier New, Courier, monospace;">evalRand </span>to obtain the new state of the CA, we don't get an updated generator alongside it. And we can't use <span style="font-family: Courier New, Courier, monospace;">runRand </span>to get it because the CA is potentially infinite. As we lazily consume the returned CA state, the generator we supplied is still used "under the hood" for generating new values. If we feed the updated generator returned by <span style="font-family: Courier New, Courier, monospace;">runRand </span>to the following iteration, the whole computation would hang, again.<br />
<br />
Fortunately, the <a href="http://hackage.haskell.org/packages/archive/MonadRandom/0.1.8/doc/html/Control-Monad-Random-Class.html">MonadRandom</a> class provides a <span style="font-family: Courier New, Courier, monospace;">getSplit</span> operation which "bifurcates" a generator. At each iteration, we split the generator, throwing one half into the black hole of <span style="font-family: Courier New, Courier, monospace;">evalRand</span>, and keeping the other half for the next iteration. We now know enough to define a function that, given a generator and an initial state of the CA, produces a lazy stream of all the succesive states of the automaton:<br />
<br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>evolve :: EnvT Probs U Bool -> Rand StdGen (EnvT Probs U Bool)</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>evolve ca = sequence $ extend localRule ca</span><br />
<span style="font-family: Courier New, Courier, monospace;"><br /></span>
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>history :: StdGen -> EnvT Probs U Bool -> Stream (EnvT Probs U Bool)</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span>history seed initialca = </span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> let unfoldf (ca,seed) = </span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> let (seed',seed'') = runRand getSplit seed </span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> nextca = evalRand (evolve ca) seed'</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> in (nextca,(nextca,seed''))</span><br />
<span style="font-family: Courier New, Courier, monospace;"><span class="Apple-tab-span" style="white-space: pre;"> </span> in unfold unfoldf (initialca,seed)</span><br />
<br />
That's all folks! Happy New Year.<br />
<br />
<b>Edit</b>: I wasn't sure of the correctness of my <span style="font-family: Courier New, Courier, monospace;">Traversable</span> instance, so <a href="http://stackoverflow.com/questions/14110671/do-traversables-really-require-to-be-traversed-left-to-right">I posted a question</a> on Stack Overflow.danidiazhttp://www.blogger.com/profile/00202497971909513168noreply@blogger.com0